My Total World War project



  • One of the 'little' things that has always bothered me while playing this map is the 'germanInfantry'. The tooltip begins 'germanInfantry (Germany)'. Even in the purchase screen, as the German player, it is 'germanInfantry'.

    Now I know why this is done. But to me this 'side-effect' is annoying.

    And my background. Well I spent several years in the American Army as a cook and driver. I've also worked on an assembly line building lifts and booms. And these last 15 years as a janitor in a auto assembly plant. So I have extensive experience in not programming.

    So back to my TWW project. The reason for 'germanInfantry' is the way Technology Advances' are done in the xml. And if anyone has looked over this 36,000 lines, I give a tip of the hat to @Hepps and @Rolf-Larsson and all the others that worked on this masterpiece! To do the first listed Technology 'SpecialWarfare' takes:

    <!-- Grant the Technology -->
    <attachment name="conditionAttachmentgermanSpecialWarfare" attachTo="Germany" javaClass="RulesAttachment" type="player">
       <option name="techs" value="SpecialWarfare" count="1"/>
    </attachment>
    
    <!-- Create the Technology -->
    <attachment name="triggerAttachmentgermanSW1" attachTo="Germany" javaClass="TriggerAttachment" type="player">
       <option name="trigger" value="conditionAttachmentgermanSpecialWarfare"/>
       <option name="unitType" value="germanMarine"/>
       <!-- isMarine takes a value does this still work? -->
       <option name="unitProperty" value="isMarine" count="true"/>
       <option name="uses" value="1"/>
    </attachment>
    <attachment name="triggerAttachmentgermanSW2" attachTo="Germany" javaClass="TriggerAttachment" type="player">
        <option name="trigger" value="conditionAttachmentgermanSpecialWarfare"/>
        <option name="unitType" value="germanInfantry:germanAlpineInfantry:germanParatrooper:germanCombatEngineer"/>
       <option name="unitProperty" value="canInvadeOnlyFrom" count="all"/>
       <option name="uses" value="1"/>
    </attachment>
    <attachment name="triggerAttachmentgermanSW3" attachTo="Germany" javaClass="TriggerAttachment" type="player">
       <option name="trigger" value="conditionAttachmentgermanSpecialWarfare"/>
       <option name="support" value="supportAttachmentAirtrangerman"/>
       <option name="uses" value="1"/>
    </attachment>
    <attachment name="triggerAttachmentgermanSW4" attachTo="Germany" javaClass="TriggerAttachment" type="player">
        <option name="trigger" value="conditionAttachmentgermanSpecialWarfare"/>
       <option name="territoryEffects" value="Hills"/>
       <option name="territoryEffectProperty" value="combatOffenseEffect" count="2:germanAlpineInfantry"/>
       <option name="when" value="before:germanyCombatMove"/>
       <option name="uses" value="1"/>
    </attachment>
    <attachment name="triggerAttachmentgermanSW5" attachTo="Germany" javaClass="TriggerAttachment" type="player">
        <option name="trigger" value="conditionAttachmentgermanSpecialWarfare"/>
        <option name="territoryEffects" value="Urban"/>
       <option name="territoryEffectProperty" value="combatOffenseEffect" count="2:germanCombatEngineer"/>
       <option name="when" value="before:germanyCombatMove"/>
       <option name="uses" value="1"/>
    </attachment>
    <attachment name="triggerAttachmentgermanSW6" attachTo="Germany" javaClass="TriggerAttachment" type="player">
       <option name="trigger" value="conditionAttachmentgermanSpecialWarfare"/>
       <option name="territoryEffects" value="Mountain"/>
       <option name="territoryEffectProperty" value="combatOffenseEffect" count="2:germanAlpineInfantry"/>
       <option name="when" value="before:germanyCombatMove"/>
       <option name="uses" value="1"/>
    </attachment>
    

    And this is what I envision:

    <!-- Grant the Technology is the same -->
    <attachment name="conditionAttachmentgermanSpecialWarfare" attachTo="Germany" javaClass="RulesAttachment" type="player">
       <option name="techs" value="SpecialWarfare" count="1"/>
    </attachment>
    
    <!-- Creating the Technology -->
    <attachment name="techAbilityAttachment" attachTo="SpecialWarfare" javaClass="games.strategy.triplea.attachments.TechAbilityAttachment" type="technology">
       <option name="isMarineBonus" value="1:marine"/> <!-- done -->
       <!-- value could also be a list of units: value="infantry:transport:airTransport:truck" -->
       <option name="canInvadeOnlyFromBonus" value="infantry:all"/> <!- almost -->
       <option name="canInvadeOnlyFromBonus" value="alpineInfantry:all"/>
       <option name="canInvadeOnlyFromBonus" value="paratrooper:all"/>
       <option name="canInvadeOnlyFromBonus" value="combatEngineer:all"/>
       <option name="combatOffenseEffectBonus" value="alpineInfantry:1:Hills:Mountain"/> <!-- done -->
       <option name="combatOffenseEffectBonus" value="combatEngineer:1:Urban"/>
    </attachment>
    <!-- The support attachment change would be the same -->
    <attachment name="triggerAttachmentgermanSW3" attachTo="Germany" javaClass="TriggerAttachment" type="player">
       <option name="trigger" value="conditionAttachmentgermanSpecialWarfare"/>
       <option name="support" value="supportAttachmentAirtrangerman"/>
       <option name="uses" value="1"/>
    </attachment>
    

    For all the other players, just remove the triggers but the Grant Technology and change support. Also the units are listed out as "infantry", "alpineInfantry", etc...

    I'm just trying to simplify, what to me seem to be a needed hack and an xml mess. But it is also fun!

    Cheers...

    P.S. I've also allowed the 'bonus' for supportAttachment's to take fractions. Good times all around!


  • Admin

    @wc_sumpton the suggestion is clearly a simpler XML. I don't like disparaging things too much since they have been so valuable, though the XML modeling as can be seen in this example is under-designed.

    There are a number of challenges with making such a change:
    (1) You probably can go further in simplifications. Given that the XML gets baked into maps, to some extent it's worthwhile to reduce the number of variations that are supported (which makes it harder to change this as it's much easier to work at it gradually compared to solving more problems all at once).

    (2) How can we deal with existing maps? If we support existing maps, the complexity of the either/or logic could become difficult to manage.

    There was a discussion to switch map configs to YAML to solve a number of other problems. I think that is perhaps our best hope for a grand re-design that would fix a number of problems.



  • @LaFayette

    Thank you for commenting!!

    I have developed the following tech abilities:
    isMarineBonus pos/neg to the isMarine option
    canInvadeOnlyFromBonus add units to the canInvadeOnlyFrom option
    combatDefenseEffectBonus pos/neg to the combatDefenseEffect for territoryEffects
    combatOffenseEffectBonus pos/neg to the combatOffenseEffect for territoryEffects
    hitPointBonus pos/neg to hitPoints

    Besides those I used 'movementBonus', 'attackBonus' and 'defenseBonus' along with some 'foreach variables' and have so far reduced the xml now to under 20,000 lines, about half its size. And there is more that can be done.

    Also because these are new 'TechAbilityAttachment's there would be no effect on existing maps. Just like TWW, if its not used it has no effect.

    All I'm trying to do is show that there is a different way to handle some of these 'upgrades' then just copying the same block of triggers over and over again.

    Cheers...


  • Admin

    Gotchya, there needs to be care though. Any spec we release we'll always need to support. This means if we make further improve, then we'll have intermediate versions that we're supporting and it can sum up to be quite complex to maintain it all.

    There is also some tension when a new map is launched that the current version does not support. Be what it may, not much to do to solve that one right now.


  • Admin

    To the point Cernel made, would it make sense to create a base ability for 'non-combat' move? I assume a bit that these technologies are there more to change behavior rather than be things that would be researched. Or, are these truly to be researched?



  • @LaFayette said in My Total World War project:

    Gotchya, there needs to be care though. Any spec we release we'll always need to support. This means if we make further improve, then we'll have intermediate versions that we're supporting and it can sum up to be quite complex to maintain it all.

    This I understand. And makes my point. If the complexities aren't maintained at the engine level, then it's pushed off to the map maker. Second these 'tech' are through a established system, and I don't think they add much to that overall complexities, but the benefits to the map maker mean much simpler xml to maintain.

    @LaFayette said in My Total World War project:

    To the point Cernel made, would it make sense to create a base ability for 'non-combat' move? I assume a bit that these technologies are there more to change behavior rather than be things that would be researched. Or, are these truly to be researched?

    Creating a base ability would go against your above point about complexity. Does this new ability show an addition/subtraction to movement? Total movement for that phase? Does it tie into movement, or will there be a whole new Non Combat entries.

    So the question is: Make it a base ability and if so what is it purpose, and who creates it. Or allow it to be a 'Tech' added ability which does what I think is its intended purpose.

    Hope to get other to help answer this.

    Cheers...


  • Admin

    The map maker complexity is pretty unreal, I'll grant you that. In turn though, all that complexity is in the code too. Adding more variations makes the code yet even worse. TripleA for a long time has been at a tipping point and beyond. Essentially, ths addition, that addition, and repeat N times for 15 years and it's become a BBOM.

    If you add something small to the code, you are probably okay. Testing it by hand is okay, modifying a few lines okay. But good luck modifying anything. You then have to repeat all of those tests-by hand, verifying every combination of what was done, and repeat that any time you modify the code. "Adding code is easy, modifying and maintaining is difficult".

    The situation is severe enough that it was debated whether the code would have been better off just being frozen a few years ago as any efforts would far exceed available time for almost no benefit and certain regression. Basically, "the brittle code is too brittle to change", which makes it too brittle to fix up so it's not brittle. It's Jenga tower development

    My opinion is the most important thing for us to do is to simplify and add testing so that we can do anything more in the code base with reasonable safety and efficiency.


  • Admin

    @wc_sumpton

    Creating a base ability would go against your above point about complexity.

    Not necessarily. Allowing multiple formats for technologies is intrinsically complex. Having a base ability would be far more direct. For example, rather than having to define so many technologies and attachments, when you define the unit, you'd only need to define the non-combat move ability just once. That would be quite a bit more direct from both engine and map maker perspective. If adding a technology only to hack the fact that there is no base ability, it seems not hacking is the better thing to do. Having technologies to hack missing abilities to then simplify the hacking does seem a bit like the wrong direction. With that said, simplifying technology config should be done. Yet, we do need to answer how we can balance that against all the other tensions like keeping existing engines working and being able to sanely test and modify the code.

    Does this new ability show an addition/subtraction to movement? Total movement for that phase?

    I think the same questions are raised as a technology, so it's equal. As a base ability it would probably be more understood to be the total movement.

    Does it tie into movement, or will there be a whole new Non Combat entries.

    I think this involves adding a movement tag under a unit, eg:

    <movement>
      <!-- <baseMovement>1</baseMovement> --> <!-- default -->
       <!--<combat>1</noncombat>-->  <!-- default-->
       <nonCombat>2</nonCombat>
    </movement>
    

  • Admin

    @wc_sumpton I'm pretty sure a grand re-write of map spec is going to take too long. If we freeze the current spec and have everyone wait, it'll be painful. Perhaps the key will be instead to just accept the complexity and create alternative forms of the XML so that it's flexible and we can get the expressiveness gains that you're seeking.

    I'm working on a system to upload maps to server, but that's really running into trouble with various technical debt issues and to do that properly I need to start from the beginning and clean up how we deal with maps. It won't be a quick project, but I think we can probably get in a position where supporting alternative XML forms will be easier and we can then add it in.

    At that rate I'd rather we go further with simplifications and really do it right.

    With that said, using technology for a base ability does seem like duct tape. With that said, I think if we want non-combat movement to be different from combat, we should build it in first class. WDYT at this point?


Log in to reply