Battletech Developer Journal - 03

Published April 21, 2019
Advertisement

I'm Chris Eck, and I'm the tools developer at HBS for the Battletech project. I've recently been given permission to write up articles about some of the things I work on which I hope to post on a semi regular basis. Feel free to ask questions about these posts or give me suggestions for future topics. However, please note I am unable to answer any questions about new/unconfirmed features.

A few weeks ago we started a more stringent code review process where everyone is supposed to put changes on a feature branch and then get those changes code reviewed and tested before merging it back in. For most devs I imagine that's between 1-2 feature branches a week. But my task list is a bunch of small, unrelated changes all over the system so that was 1-3 feature branches per day. 

Needless to say, everyone has been super busy working on Urban Warfare (and things are looking awesome by the way) so I had a big backlog of these. That couple with a Jira/Confluence hiccup meant I spent most of last week implementing code review feedback and merging my code back in. But I still worked on a couple of interesting things and I have 3 years of working on Battletech to pull from. So if I don't write one of these Journals it's cause I'm being lazy. :P

 

New Region Types

Until recently, we only had a few region types: Positive(Gold), Negative(Red), and Hidden defined by a RegionType enumeration (enum) in code. In the early days we felt like this would be enough to differentiate and identify the different region types. But after we shipped, there was still a bit of confusion about particular regions. Like the Escort Destination region in Capture Escort - is the player supposed to stand there? Or the Ambush Convoy mission has a Negative escape region for the enemy. The purpose is to prevent the enemy from getting there, but standing there is actually a good thing.

To clear up this confusion we decided to implement new region types, and expose more data to the user like varying regions by color and then adding region labels. At first I was just going to add more values to the RegionType enum, but as I worked through it, I became more aware of the hard coded switch statements tied to its label and color. Bleh.

Even though it was more work right now, I refactored RegionType to be a new RegionDef data file. For each region type there will exist one of these RegionDef files. There, we can specify what colors, the labels, and descriptions of the regions.
 


// Original enumeration
enum RegionDisplayType
{
	Hidden = 0,
  	Positive = 1,
  	Negative = 2,
}

// Sample of some hardcoded colors tied to different region types
public Color GetRegionColor(RegionDisplayType regionDisplayType)
{
	Color regionColor;
    switch (regionType)
    {
        case RegionDisplayType.Hidden:
        default:
            regionColor = Color.clear;
            break;
        case RegionDisplayType.Positive:
            regionColor = UIManager.Instance.UIColorRefs.GetUIColor(UIColor.Gold);
            break;
        case RegionDisplayType.Negative:
            regionColor = UIManager.Instance.UIColorRefs.GetUIColor(UIColor.Red);
            break;
    }
    return regionColor;
}

// New RegionDef files get one file per Region Type.
{
    "Description" : {
        "Id" : "regionDef_EvacZone",
        "Name" : "Evac Zone",
        "Details" : "When active, move all of your units into this zone to evacuate your units.",
        "Icon" : ""
    },
    "FutureColorHex" : "#F79B2680",
    "ActiveColorHex" : "#F79B26FF",
    "FutureLabel" : "Future Evac Zone",
    "ActiveLabel" : "Evac Zone"
}

Now the only code I have to write is letting the designers choose which region they want and drive the choices off of the files in the RegionDef folder. All those hardcoded switch statements get converted over to just using the appropriate bits of data like selectedRegionType.ActiveLabel. And now, any time a designer wants a new region type, they can add it themselves by just creating a new Region Def file instead of pestering me. :)

 

Localization

Since we're going to be showing region labels now, that's some new text in the game. New text in the game means new translations to be made. The developer who normally handles Localization tasks was busy doing other things so after a quick 15 minute discussion on how things worked, he sent me on my way. 

First I needed to write up a RegionDefStringsCollector class. Since I'm working with a json file, it's pretty simple. I inherit from a Json String Collector base class, tell it my ResourceType (RegionDef) and just override my Collect method. Then there's a Localization class that has a list of all the Collectors. I add an entry to my new class and then the next time the strings get collected for localization, all my new data will get collected.
 


    public class RegionDefStringsCollector : JSONDataStringCollectorBase
    {
        // Tell the JSON collector what type we are
        public RegionDefStringsCollector() : base(BattleTechResourceType.RegionDef) { }

        // Collect our strings into the locTable
        protected override void Collect(string jsonText, EditorLocTable locTable, string source)
        {
            RegionDef def = new RegionDef();
            try
            {
                def.FromJSON(jsonText);
                if (def.Description != null)
                {
                    Util.CollectDescription(locTable, def.Description, source+".Description");
                }

				Util.AddToLocTable(locTable, def.ActiveLabel, source + ".ActiveLabel");
				Util.AddToLocTable(locTable, def.FutureLabel, source + ".FutureLabel");
            }
            catch (System.Exception e)
            {
                Debug.LogError("Error reading " + source + " " + e);
                return;
            }
        }
    }

 

Work Bench

And this weekend I was productive at home too. I ordered a bunch of lumber for some projects around the house and knocked out my work bench. Somebody said look at all those tools in the blog post image that he doesn't use. Well here's proof that I do! :D

WorkBench01.jpg.566244153fbe0983287fefc6c5879293.jpgWorkBench02.jpg.494aad47bb32f1f8ae2d01d2ca5a858a.jpgWorkBench03.jpg.6d187547807ee2fd7456862f2213a387.jpgWorkBench04.jpg.6510d3f27bee467cad83f6e0f4146f34.jpg

 

Tips from your Uncle Eck

Be careful with your use of enums, they can be a code smell that something isn't quite right. If you find yourself hardcoding logic to specific enum values, you should definitely consider switching to a data driven system. That way when people change their minds, they can just change the data in a file instead of having to change code and cut a new build. Plus it makes modding your game that much easier.

 

Links

 

2 likes 5 comments

Comments

NubDevice

The lone wolf maybe thinks about it a little different because he's already in there but yup, smells like that here for certain. Data driven you say? Thanks for the nudge.

April 21, 2019 06:02 PM
Eck
Eck

I'm happy to help. :) When I first discovered enums oh so long ago, I thought, "These things are awesome! It's a strongly typed value I can use and bring clarity to my code." And that's mostly true. It's honestly not too much trouble to keep bolting on more hard coded logic any time you want to add a new type.

But once you start working on bigger projects with people who want new things... and they can't code the new stuff themselves... UGH! Now I have to take time out of my day to do some boring grunt work when it should be as simple as someone copying/pasting a file and changing a few values.

April 21, 2019 06:09 PM
NubDevice

This blows me away because it's exactly what I do. First with string ID then ah, cool a numeric ID. Now I've hit the more you learn the more you realize you don't know thing. Nice one. 

April 21, 2019 06:12 PM
tragic

I love your write ups so far. I thought Piranha Games was the only outfit developing anything from the good ole days of the BT universe. I'll have to pick up Battletech on payday and get some more of my mech fix.

April 22, 2019 03:00 AM
Eck
Eck

I think it's crazy that some Battletech fans still haven't heard of this game. It blows my mind! :)

The game isn't a direct table-top port, but it's definitely faithful to the table-top experience. I wrote up a guide that's pretty useful for learning the game's mechanics. Feel free to check it out.

https://steamcommunity.com/sharedfiles/filedetails/?id=1365402907

- Eck

April 22, 2019 04:52 PM
You must log in to join the conversation.
Don't have a GameDev.net account? Sign up!
Advertisement