Categories and/or tags

  • It happens so many times in mapmaking that you have to list the same things over and over. And when you later decide that something actually shouldn't be on the list, you have to check 30k lines of xml and edit your list 100 times. An example from Total World War:

    <attachment name="unitAttachment" attachTo="spanishAntiTankGun" javaClass="games.strategy.triplea.attachments.UnitAttachment" type="unitType">
          <option name="attack" value="1"/>
          <option name="defense" value="3"/>
          <option name="isAAforCombatOnly" value="true"/>
          <option name="mayOverStackAA" value="true"/>
          <option name="typeAA" value="AntiTankGun"/>
          <option name="isInfantry" value="true"/>
          <option name="targetsAA" value="germanMech.Infantry:germanTank:germanHeavyTank:italianMech.Infantry:italianTank:italianHeavyTank:japaneseMech.Infantry:japaneseTank:japaneseHeavyTank:swedishTank:turkishTank:brazilianTank:russianMech.Infantry:russianTank:russianHeavyTank:britishMech.Infantry:britishTank:britishHeavyTank:americanMech.Infantry:americanTank:americanHeavyTank:chineseMech.Infantry:chineseTank:spanishTank:swedishTank:turkishTank:brazilianTank"/>
          <option name="maxAAattacks" value="1"/>
          <option name="transportCost" value="2"/>
          <option name="movement" value="1"/>
          <option name="attackAA" value="2"/>
          <option name="damageableAA" value="true"/>
          <option name="canInvadeOnlyFrom" value="none"/>

    And then you have the same list of targetsAA for germanAntiTankGun and everyothernationsAntiTankGun. This is not even the worst of the cases by far, because you can simply do massed find-and-replace on it, but anyway, this is the example I'm going to use. (Just so that I don't use my own maps as examples.)

    Solution #1: Categories

    First define a category of things, which is basically a list. What sort of things the category contains is defined by the "type" property. Things can be units, territories, support attachments, trigger attachments, technologies, production frontiers, etc., sky is the limit. Anywhere where you could use a colon delimited list, you can use the name of a category instead. In effect it should be exactly as if you listed every element of that category. (A simple special case of a macro, if you will.) So basically the example code becomes

        <category name="anyMech.Infantry" type="unit">
            <element name="germanMech.Infantry"/>
            <element name="italianMech.Infantry"/>
            <element name="japaneseMech.Infantry"/>
            <!--etc. won't list all-->
        <category name="anyTank" type="unit">
            <element name="germanTank"/>
            <element name="italianTank"/>
            <element name="japaneseTank"/>
            <!--etc. won't list all-->
        <category name="anyHeavyTank" type="unit">
            <element name="germanHeavyTank"/>
            <element name="italianHeavyTank"/>
            <element name="japaneseHeavyTank"/>
            <!--etc. won't list all-->
        <category name="targetedByATGun" type="unit">
            <element name="anyMech.Infantry"/>
            <element name="anyTank"/>
            <element name="anyHeavyTank"/>

    somewhere around the beginning of the xml, and then the spanishAntiTankGun only requires

    <option name="targetsAA" value="anyMech.Infantry:anyTank:anyHeavyTank"/>


    <option name="targetsAA" value="targetedByATGun"/>

    depending on which results in simpler xml.

    Solution #2: Tags
    The inverse of a category, sort of. Every attachment can have multiple "tag" elements, like

    <attachment name="unitAttachment" attachTo="spanishTank" javaClass="games.strategy.triplea.attachments.UnitAttachment" type="unitType">
          <option name="movement" value="2"/>
          <option name="attack" value="6"/>
          <option name="defense" value="4"/>
          <option name="transportCost" value="4"/>
          <option name="canBlitz" value="true"/>
          <option name="canInvadeOnlyFrom" value="none"/>
          <tag name="AT_target">

    This should function exactly as if there was a category named "AT_target", containing exactly the things that have the "AT_target" tag. In some cases, categories would be more convenient, sometimes tags, but either one of them would be a great improvement over nothing.

    The most important question is: Can I reliably expect either of the two implemented by, say, this summer at the very latest? If not, then I'll have no choice but to unilaterally fall back to

    Solution #3: I'll write a script that generates functional game xml from a much simpler code

    And the degree of my annoyment with the tediousness of the map creation process leads me to conclude that this project will actually result in a complete map creator alongside with no free time for me in the next year or two.

  • Donators Moderators Admin

    I like the categories portion a lot.

    However I don't quite understand the exact functionality of the tag.

  • Admin

    @alkexr Yeah, I strongly agree that we need some way to define a sort of "variable" where map makers can define certain elements and then reference them with a single name (tag, category, etc). I've thought about it a little bit but haven't thought it all the way through or which approach would be best though looking at something like TWW XML and imagining how to make it more concise would be a good exercise.

    That being said, I doubt anyone will make a guarantee if/when it would be implemented. Also rewriting or massively improving the map creator would be great.

  • @redrum I've already started putting out the fire and written a script that basically implements tags - generates plain old format game xml from another one which uses tags. Xml horror down to manageable levels atm.

  • Donators Moderators Admin

    @alkexr I love this idea.

    Question.... would this be back compatible? Or would something like TWW need to be completely rewritten?

  • Donators Moderators Admin


    Would be very awesome if you could share the script once completed. So others can utilize it.