Game XML Tips & Examples


  • Admin

    So after doing some work on TWW XML and seeing some of the other recent map XMLs, I thought it would be helpful to map makers to provide some examples on how to make their XML easier to write and maintain. Feel free to ask questions or provide examples of your own.

    1. Multiple when lines and how uses works
    2. Reusing conditions
    3. Complex trigger with multiple types of actions and multiple of each action
    4. Complex UserAction which activates multiple triggers and number of attempts depend on conditions

  • Admin

    1. Automatic unit placement when a territory is conquered in TWW
    • Places an infantry in Algeria once its captured by the Allies (Algeria is set to be given to ExiledAllies when captured). The placement happens after the Allied non-combat move who captures it.
    • Shows how multiple when lines can be used in the same trigger
    • Shows how uses works when using when

    Old XML

        <attachment name="conditionAttachmentUnitsEAAlgeria" attachTo="ExiledAllies" javaClass="games.strategy.triplea.attachments.RulesAttachment" type="player">
          <option name="directOwnershipTerritories" value="Algeria" count="1"/>
          <option name="switch" value="true"/>
        </attachment>
        
        <attachment name="triggerAttachmentUnitsEAAlgeria1" attachTo="ExiledAllies" javaClass="games.strategy.triplea.attachments.TriggerAttachment" type="player">
          <option name="conditions" value="conditionAttachmentUnitsEAAlgeria"/>
          <option name="placement" value="Algeria:britishInfantry"/>
          <option name="playerAttachmentName" value="RulesAttachment" count="conditionAttachmentUnitsEAAlgeria"/>
          <option name="playerProperty" value="switch" count="false"/>
          <option name="uses" value="1"/>
          <option name="when" value="after:britainNonCombatMove"/>
        </attachment>
        <attachment name="triggerAttachmentUnitsEAAlgeria2" attachTo="ExiledAllies" javaClass="games.strategy.triplea.attachments.TriggerAttachment" type="player">
          <option name="conditions" value="conditionAttachmentUnitsEAAlgeria"/>
          <option name="placement" value="Algeria:britishInfantry"/>
          <option name="playerAttachmentName" value="RulesAttachment" count="conditionAttachmentUnitsEAAlgeria"/>
          <option name="playerProperty" value="switch" count="false"/>
          <option name="uses" value="1"/>
          <option name="when" value="after:chinaNonCombatMove"/>
        </attachment>
        <attachment name="triggerAttachmentUnitsEAAlgeria3" attachTo="ExiledAllies" javaClass="games.strategy.triplea.attachments.TriggerAttachment" type="player">
          <option name="conditions" value="conditionAttachmentUnitsEAAlgeria"/>
          <option name="placement" value="Algeria:britishInfantry"/>
          <option name="playerAttachmentName" value="RulesAttachment" count="conditionAttachmentUnitsEAAlgeria"/>
          <option name="playerProperty" value="switch" count="false"/>
          <option name="uses" value="1"/>
          <option name="when" value="after:russiaNonCombatMove"/>
        </attachment>
        <attachment name="triggerAttachmentUnitsEAAlgeria4" attachTo="ExiledAllies" javaClass="games.strategy.triplea.attachments.TriggerAttachment" type="player">
          <option name="conditions" value="conditionAttachmentUnitsEAAlgeria"/>
          <option name="placement" value="Algeria:britishInfantry"/>
          <option name="playerAttachmentName" value="RulesAttachment" count="conditionAttachmentUnitsEAAlgeria"/>
          <option name="playerProperty" value="switch" count="false"/>
          <option name="uses" value="1"/>
          <option name="when" value="after:usaNonCombatMove"/>
        </attachment>
    

    Simplified XML

        <attachment name="conditionAttachmentUnitsEAAlgeria" attachTo="ExiledAllies" javaClass="games.strategy.triplea.attachments.RulesAttachment" type="player">
          <option name="directOwnershipTerritories" value="Algeria" count="1"/>
        </attachment>
        
        <attachment name="triggerAttachmentUnitsEAAlgeria" attachTo="ExiledAllies" javaClass="games.strategy.triplea.attachments.TriggerAttachment" type="player">
          <option name="conditions" value="conditionAttachmentUnitsEAAlgeria"/>
          <option name="placement" value="Algeria:britishInfantry"/>
          <option name="uses" value="1"/>
          <option name="when" value="after:britainNonCombatMove"/>
          <option name="when" value="after:chinaNonCombatMove"/>
          <option name="when" value="after:russiaNonCombatMove"/>
          <option name="when" value="after:usaNonCombatMove"/>
        </attachment>
    

    So the original XML was using 4 separate triggers for each of the 4 Allies that could capture Algeria and used setting the switch on the condition for those 4 triggers so that only the first of the triggers that fired would disable the rest. This can be simplified to use 1 trigger that has 4 when lines (1 for each of the 4 Allies) and relying on uses to ensure this trigger only fires for the first when it hits.

    Now this also gives some insight into the 2 ways the uses can work. If there is no when set on a trigger then instead of using up a use with every fire, it instead uses up a use if the trigger is fired during this round. This is in order to let a trigger that contains multiple actions, fire all of them in a single use. Otherwise if a trigger has 1 or more when lines set then it uses up a use every time it fires. This means that its generally better to set when on your triggers so its more clear when they fire and you have more control over uses.


  • Admin

    1. TWW Protectorates
    • Protectorate territories don't give any income to the owner but instead contribute to an objective which give free materials to certain nations.
    • Shows how conditions can be reused instead of duplicated

    Old XML

        <attachment name="conditionAttachmentBritishDutch1EA" attachTo="ExiledAllies" javaClass="games.strategy.triplea.attachments.RulesAttachment" type="player">
          <option name="directPresenceTerritories" value="Sumatra" count="1"/>
          <option name="unitPresence" value="Protectorate" count="1"/>
        </attachment>    
        <attachment name="objectiveAttachmentBritishDutch1" attachTo="ExiledAllies" javaClass="games.strategy.triplea.attachments.RulesAttachment" type="player">
          <option name="conditions" value="conditionAttachmentBritishDutch1EA:conditionAttachmentYes"/>
          <option name="conditionType" value="AND"/>
          <option name="objectiveValue" value="-2"/>
        </attachment>
               
        <attachment name="conditionAttachmentBritSum" attachTo="ExiledAllies" javaClass="games.strategy.triplea.attachments.RulesAttachment" type="player">
          <option name="directPresenceTerritories" value="Sumatra" count="1"/>
          <option name="unitPresence" value="Protectorate" count="1"/>
        </attachment>   
        <attachment name="conditionAttachmentAusMat" attachTo="Australia" javaClass="games.strategy.triplea.attachments.RulesAttachment" type="player">
          <option name="conditions" value="conditionAttachmentBritSum:conditionAttachmentBritBor:conditionAttachmentBritJav:conditionAttachmentBritDEI:conditionAttachmentBritCel:conditionAttachmentBritGui"/>
          <option name="conditionType" value="1-6"/>
        </attachment>
    

    Simplified XML

        <attachment name="conditionAttachmentBritishDutch1EA" attachTo="ExiledAllies" javaClass="games.strategy.triplea.attachments.RulesAttachment" type="player">
          <option name="directPresenceTerritories" value="Sumatra" count="1"/>
          <option name="unitPresence" value="Protectorate" count="1"/>
        </attachment>
        <attachment name="objectiveAttachmentBritishDutch1" attachTo="ExiledAllies" javaClass="games.strategy.triplea.attachments.RulesAttachment" type="player">
          <option name="conditions" value="conditionAttachmentBritishDutch1EA"/>
          <option name="objectiveValue" value="-2"/>
        </attachment>
        <attachment name="conditionAttachmentAusMat" attachTo="Australia" javaClass="games.strategy.triplea.attachments.RulesAttachment" type="player">
          <option name="conditions" value="conditionAttachmentBritishDutch1EA:conditionAttachmentBritishDutch2EA:conditionAttachmentBritishDutch3EA:conditionAttachmentBritishDutch4EA:conditionAttachmentBritishDutch5EA:conditionAttachmentBritishDutch6EA"/>
          <option name="conditionType" value="1-6"/>
        </attachment>
    

    Instead of having 2 separate conditions for checking if Sumatra has a Protectorate unit, these can be combined into a single condition that is used to both nullify the income from the territory owner and check for free material conditions.


  • Admin

    1. TWW Germany Takes Over Vichy North Africa
    • Once the Allies capture Morrocco or Algeria, the Vichy Protectorate no longer generates a free material and Germany takes over the North African Vichy territories
    • Show a complex triggers with multiple types of actions and multiple of each of those actions (removeUnits, placement, changeOwnership)
        <attachment name="conditionAttachmentVichyMat" attachTo="VichyFrance" javaClass="games.strategy.triplea.attachments.RulesAttachment" type="player">
          <option name="conditions" value="conditionAttachmentMorroccoVichy:conditionAttachmentAlgeriaVichy"/>
          <option name="conditionType" value="2"/>
        </attachment>
        <attachment name="conditionAttachmentVichyProtectorateLost" attachTo="VichyFrance" javaClass="games.strategy.triplea.attachments.RulesAttachment" type="player">
          <option name="conditions" value="conditionAttachmentVichyMat"/>
          <option name="invert" value="true"/>
        </attachment>  
        
        <attachment name="triggerAttachmentVichyMedTurnsGerman" attachTo="VichyFrance" javaClass="games.strategy.triplea.attachments.TriggerAttachment" type="player">
          <option name="conditions" value="conditionAttachmentVichyProtectorateLost"/>
          <option name="uses" value="1"/>
          <option name="removeUnits" value="Morrocco:Protectorate"/>
          <option name="removeUnits" value="Algeria:Protectorate"/>
          <option name="placement" value="Vichy France:Occupation"/>
          <option name="changeOwnership" value="Morrocco:VichyFrance:Germany:false"/>
          <option name="changeOwnership" value="Algeria:VichyFrance:Germany:false"/>
          <option name="changeOwnership" value="Tunisia:VichyFrance:Germany:false"/>
          <option name="changeOwnership" value="Southwestern Algeria:VichyFrance:Germany:false"/>
          <option name="changeOwnership" value="Southern Algeria:VichyFrance:Germany:false"/>
          <option name="when" value="after:russiaBattle"/>
          <option name="when" value="after:chinaBattle"/>
          <option name="when" value="after:britainBattle"/>
          <option name="when" value="after:usaBattle"/>
        </attachment>
    

    The trigger only fires after Morrocco or Algeria is captured by the Allies and only fires once. It uses multiple when so that it can fire after any of the 4 Allies capture on of them. Its does the following actions:

    • removeUnits - Removes any remaining Protectorate units from Morrocco or Algeria. Since one of them was conquered, it will already have removed one of the Protectorate units but its fine to still use removeUnits even if the unit isn't there.
    • placement - Adds an Occupation unit to VichyFrance territory so that Germany now collect the income from it.
    • changeOwnership - Changes ownership of any of the Vichy controlled North African territories to Germany (if they were conquered by the Allies then won't turn German since it specifies VichyFrance as the current owner)

  • Admin

    1. TWW Prevent Scuttling of Toulon Fleet
    • Use UserActions to give Germany the option to attempt to prevent scuttling of Toulon Fleet
    • Shows how to use UserActions which activate multiple triggers and number of attempts depend on conditions
        <attachment name="conditionAttachmentVichyMat" attachTo="VichyFrance" javaClass="games.strategy.triplea.attachments.RulesAttachment" type="player">
          <option name="conditions" value="conditionAttachmentMorroccoVichy:conditionAttachmentAlgeriaVichy"/>
          <option name="conditionType" value="2"/>
        </attachment>    
        <attachment name="conditionAttachmentVichyProtectorateLost" attachTo="VichyFrance" javaClass="games.strategy.triplea.attachments.RulesAttachment" type="player">
          <option name="conditions" value="conditionAttachmentVichyMat"/>
          <option name="invert" value="true"/>
        </attachment> 
        <attachment name="conditionAttachmentSZ44VichyBattleship" attachTo="Germany" javaClass="games.strategy.triplea.attachments.RulesAttachment" type="player">
          <option name="directPresenceTerritories" value="44 Sea Zone" count="1"/>
          <option name="unitPresence" value="vichyBattleship:vichyBattleship-damaged" count="1"/>
        </attachment>
        
        <attachment name="triggerAttachmentSZ44RemoveVichyBattleship" attachTo="Germany" javaClass="games.strategy.triplea.attachments.TriggerAttachment" type="player">
          <option name="removeUnits" value="44 Sea Zone:vichyBattleship"/>
          <option name="removeUnits" value="44 Sea Zone:vichyBattleship-damaged"/>
        </attachment>
        <attachment name="triggerAttachmentSZ44PlaceGermanBattleship" attachTo="Germany" javaClass="games.strategy.triplea.attachments.TriggerAttachment" type="player">
          <option name="chance" value="2:12"/>
          <option name="placement" value="44 Sea Zone:germanBattleship"/>
        </attachment>
        
        <attachment name="userActionAttachmentGermanySaveVichyBattleship" attachTo="Germany" javaClass="games.strategy.triplea.attachments.UserActionAttachment" type="player">
          <option name="conditions" value="conditionAttachmentVichyProtectorateLost:conditionAttachmentSZ44VichyBattleship"/>
          <option name="activateTrigger" value="triggerAttachmentSZ44RemoveVichyBattleship:1:false:false:false:false"/>
          <option name="activateTrigger" value="triggerAttachmentSZ44PlaceGermanBattleship:1:false:false:false:true"/>
          <option name="text" value="GERMANS_SAVE_BATTLESHIP"/>     
          <option name="costResources" value="1:PUs"/>
          <option name="attemptsPerTurn" value="99"/>
        </attachment>
    

    This UserAction which deals with the Toulon Fleet battleship uses conditions on the Vichy protectorate being lost and the battleship still existing in SZ44 (damaged or undamaged). The user is presented the user action only when those are true during Germany's UserAction phase and it cost them 1 PU to have a 2/12 chance of saving the battleship. If selected, it fires 2 triggers: 1 to remove the Vichy battleship which always fires and 1 to add a German battleship which uses chance to have a 2/12 chance of success. The UserAction has 99 attemptsPerTurn (essentially unlimited) so is really limited by the condition on there being a Vichy battleship in SZ44 so the option will appear to the user for as many battleships as are in the Toulon Fleet. Similar UserActions are used for each of the other type of ship in the Toulon Fleet.


Log in to reply