Can I set multiple "endRound" delegates in the middle of any turns?


  • Moderators

    Let me clarify this is a question for the developers. Let me also clarify that I'm not asking if it factually works, as I've tested it does.

    The question here is if I can have multiple "endRound" delegates wherever I want, in the sequence.
    Specifically, I want to have an "endRound" delegate after each "battle" delegate, so to test reaching the "Economic Victory" condition at that point (meaning anytime), rather than only at end of round.
    It appears working fine, but I wonder if it is legitimate to do such a thing.
    I also wonder if the only purpose of the "endRound" delegate is to test victory conditions (and nothing else).
    If this is the case, then I would also like to update pos2 clarifying that the "endRound" delegate is only for testing victory conditions, doesn't have to be at the end of the round (despite its own name), and can be present in multiple istances at whatever point in the sequence, and should be preferably outright absent if the game doesn't have victory conditions relying on the presence of such step (as having such a step would be, if this is the case, pointless).

    This would be the code for my "270BC 40%" game. Is it fine (I know that it works fine)?

    <sequence>
                            <step name="gameInitDelegate" delegate="initDelegate" maxRunCount="1"/>
                         
                            <!-- Bidding Phase -->
                            <step name="CarthageBid" delegate="bid" player="Carthage" maxRunCount="1"/>
                            <step name="CarthageBidPlace" delegate="placeBid" player="Carthage" maxRunCount="1"/>
                            
                            <step name="RomanRepublicBid" delegate="bid" player="RomanRepublic" maxRunCount="1"/>
                            <step name="RomanRepublicBidPlace" delegate="placeBid" player="RomanRepublic" maxRunCount="1"/>
                            
                            <step name="GreekCityStatesBid" delegate="bid" player="GreekCityStates" maxRunCount="1"/>
                            <step name="GreekCityStatesBidPlace" delegate="placeBid" player="GreekCityStates" maxRunCount="1"/>
                            
                            <step name="MacedoniaBid" delegate="bid" player="Macedonia" maxRunCount="1"/>
                            <step name="MacedoniaBidPlace" delegate="placeBid" player="Macedonia" maxRunCount="1"/>
    
                            <step name="EgyptBid" delegate="bid" player="Egypt" maxRunCount="1"/>
                            <step name="EgyptBidPlace" delegate="placeBid" player="Egypt" maxRunCount="1"/>
              
                            <step name="SyriaBid" delegate="bid" player="Syria" maxRunCount="1"/>
                            <step name="SyriaBidPlace" delegate="placeBid" player="Syria" maxRunCount="1"/>
            
                            <step name="ParthiaBid" delegate="bid" player="Parthia" maxRunCount="1"/>
                            <step name="ParthiaBidPlace" delegate="placeBid" player="Parthia" maxRunCount="1"/>
            
                            <step name="NumidiaBid" delegate="bid" player="Numidia" maxRunCount="1"/>
                            <step name="NumidiaBidPlace" delegate="placeBid" player="Numidia" maxRunCount="1"/>
    
                            <!-- Carthage Game Sequence -->
                            <step name="CarthageCombatMove" delegate="move" player="Carthage"/>
                            <step name="CarthagePurchase" delegate="purchase" player="Carthage"/>
                            <step name="CarthageBattle" delegate="battle" player="Carthage"/>
                            <step name="CarthageEndRoundStep" delegate="endRound"/>
                            <step name="CarthageNonCombatMove" delegate="move" player="Carthage" display="Non Combat Move">
                            <stepProperty name="repairUnits" value="true"/>
                            </step>
                            <step name="CarthagePlace" delegate="place" player="Carthage"/>
                            <step name="CarthageEndTurn" delegate="endTurn" player="Carthage"/>
                          
                            <!-- RomanRepublic Game Sequence -->
                            <step name="RomanRepublicCombatMove" delegate="move" player="RomanRepublic"/>
                            <step name="RomanRepublicPurchase" delegate="purchase" player="RomanRepublic"/>
                            <step name="RomanRepublicBattle" delegate="battle" player="RomanRepublic"/>
                            <step name="RomanRepublicEndRoundStep" delegate="endRound"/>
                            <step name="RomanRepublicNonCombatMove" delegate="move" player="RomanRepublic" display="Non Combat Move">
                            <stepProperty name="repairUnits" value="true"/>
                            </step>
                            <step name="RomanRepublicPlace" delegate="place" player="RomanRepublic"/>
                            <step name="RomanRepublicEndTurn" delegate="endTurn" player="RomanRepublic"/>
                            
                            <!-- GreekCityStates Game Sequence -->
    						<step name="GreekCityStatesCombatMove" delegate="move" player="GreekCityStates"/>
                            <step name="GreekCityStatesPurchase" delegate="purchase" player="GreekCityStates"/>
                            <step name="GreekCityStatesBattle" delegate="battle" player="GreekCityStates"/>
                            <step name="GreekCityStatesEndRoundStep" delegate="endRound"/>
                            <step name="GreekCityStatesNonCombatMove" delegate="move" player="GreekCityStates" display="Non Combat Move">
                            <stepProperty name="repairUnits" value="true"/>
                            </step>
                            <step name="GreekCityStatesPlace" delegate="place" player="GreekCityStates"/>
                            <step name="GreekCityStatesEndTurn" delegate="endTurn" player="GreekCityStates"/>
    
                            <!-- Macedonia Game Sequence -->
                            <step name="MacedoniaCombatMove" delegate="move" player="Macedonia"/>
                            <step name="MacedoniaPurchase" delegate="purchase" player="Macedonia"/>
                            <step name="MacedoniaBattle" delegate="battle" player="Macedonia"/>
                            <step name="MacedoniaEndRoundStep" delegate="endRound"/>
                            <step name="MacedoniaNonCombatMove" delegate="move" player="Macedonia" display="Non Combat Move">
                            <stepProperty name="repairUnits" value="true"/>
                            </step>
                            <step name="MacedoniaPlace" delegate="place" player="Macedonia"/>
                            <step name="MacedoniaEndTurn" delegate="endTurn" player="Macedonia"/>
    						
                            <!-- Egypt Game Sequence -->
    						<step name="EgyptCombatMove" delegate="move" player="Egypt"/>
                            <step name="EgyptPurchase" delegate="purchase" player="Egypt"/>
                            <step name="EgyptBattle" delegate="battle" player="Egypt"/>
                            <step name="EgyptEndRoundStep" delegate="endRound"/>
                            <step name="EgyptNonCombatMove" delegate="move" player="Egypt" display="Non Combat Move">
                            <stepProperty name="repairUnits" value="true"/>
                            </step>
                            <step name="EgyptPlace" delegate="place" player="Egypt"/>
                            <step name="EgyptEndTurn" delegate="endTurn" player="Egypt"/>
                            
                            <!-- Syria Game Sequence -->
    						<step name="SyriaCombatMove" delegate="move" player="Syria"/>
                            <step name="SyriaPurchase" delegate="purchase" player="Syria"/>
                            <step name="SyriaBattle" delegate="battle" player="Syria"/>
                            <step name="SyriaEndRoundStep" delegate="endRound"/>
                            <step name="SyriaNonCombatMove" delegate="move" player="Syria" display="Non Combat Move">
                            <stepProperty name="repairUnits" value="true"/>
                            </step>
                            <step name="SyriaPlace" delegate="place" player="Syria"/>
                            <step name="SyriaEndTurn" delegate="endTurn" player="Syria"/>
                            
                            <!-- Parthia Game Sequence -->
                            <step name="ParthiaCombatMove" delegate="move" player="Parthia"/>
                            <step name="ParthiaPurchase" delegate="purchase" player="Parthia"/>
                            <step name="ParthiaBattle" delegate="battle" player="Parthia"/>
                            <step name="ParthiaEndRoundStep" delegate="endRound"/>
                            <step name="ParthiaNonCombatMove" delegate="move" player="Parthia" display="Non Combat Move">
                            <stepProperty name="repairUnits" value="true"/>
                            </step>
                            <step name="ParthiaPlace" delegate="place" player="Parthia"/>
                            <step name="ParthiaEndTurn" delegate="endTurn" player="Parthia"/>
                            
                            <!-- Numidia Game Sequence -->
                            <step name="NumidiaCombatMove" delegate="move" player="Numidia"/>
                            <step name="NumidiaPurchase" delegate="purchase" player="Numidia"/>
                            <step name="NumidiaBattle" delegate="battle" player="Numidia"/>
                            <step name="NumidiaEndRoundStep" delegate="endRound"/>
                            <step name="NumidiaNonCombatMove" delegate="move" player="Numidia" display="Non Combat Move">
                            <stepProperty name="repairUnits" value="true"/>
                            </step>
                            <step name="NumidiaPlace" delegate="place" player="Numidia"/>
                            <step name="NumidiaEndTurn" delegate="endTurn" player="Numidia"/>
                    </sequence>
    

    The "endRound" delegates in the code above are only supposed to test for the Economic Victory (default set at 152), as per the following property:

    		<property name="Economic Victory" value="true" editable="false">
    			<boolean/>
    		</property>
    
    		<property name="AntiRomanAlliance Economic Victory" value="152" editable="true">
    			<number min="127" max="252"/>
    		</property>
    
    		<property name="RomanAlliance Economic Victory" value="152" editable="true">
    			<number min="127" max="252"/>
    		</property>
    

    What all the above is doing (I tested it factually works fine) is enforcing a victory condition making you win anytime your alliance reaches 152+ production total, testing it before non combat movement (instead of the usual Economic Victory of WWII Classic, that is tested at the end of the round only (that is, after the turn of the last player in the round)).


  • Admin

    @Cernel It appears the only things it does are:

    1. Check for various victory conditions
    2. Sets uses for triggers that round

    So as long as you don't have triggers that have limited uses then it should be fine. If you do then you'd need to make sure that they function properly with the multiple end round delegates.


  • Moderators

    @redrum It looks to me there is an undocumented element, then, here. Since some years it was added the possibility for a trigger to have multiple "when". So, you are saying that such trigger will substantially fail to be limited by its uses number. For example, if I have a trigger with two "when" and "uses" equal to 1, it will still potentially fire twice within the same round, unless you have an endround delegate in between of each "when". If it is so, this should be documented, as I've no idea how a mapmaker can dream it works this way. Even better, why uses aren't just set whenever the trigger fires? I assumed it worked this way, and, if feasible, I would suggest changing the process to work this way. Failing that, I suppose documenting this matter in pos2.


  • Admin

    @Cernel Not really sure why "uses" are done by round rather than by when it actually fires. But given that "uses" is done by round, it makes sense that if you have multiple end round delegates and it fired in between them that it would decrement remaining uses.

    "when" and "uses" are somewhat separate as one has to do with how many rounds it could fire in and the other is when the trigger is checked in terms of phases (or if not specified then some default phase). For example, you could have a trigger with multiple "whens" but waiting on a condition so it really is only going to fire at certain times and the "when" is just indicating when it is checked.

    I really don't think end round delegates were intended to be allowed to be put in multiple times like you are doing here. That's probably why its not documented.


  • Moderators

    @redrum So we go back to the starting question whether having multiple endrounds per turn, or even only having it not as the last step in the round, is legitimate or a hack.

    For example, in World At War the victory condition (a minimum number of specific territories, being the capitals) is checked after each conduct combat phases, but there it is obtained without any delegates. On the other hand, checking for total production needs the endround delegate, as currently there is not a proper way for checking total production with conditions.


  • Admin

    @Cernel As it sits today, I'd say multiple end round delegates per true "round" is a hack and kind of use at your own risk. Victory conditions are primarily based on the standard A&A games. There are some available options around victory conditions in conditions/triggers and really this is probably how all victory conditions should be handled not hard coded into end round delegate:

    victory			values: the string message from notifications.properties to be displayed if the condition is true. victory can be used to play sounds as well. victory will use victory value + "_sounds" as the key in notifications.properties file, and then will use "defeat_" or "victory_" + the notifications.properties value as the new key to look for in the sounds.properties file.
    
    notification		values: this is a popup window containing a message that will be given to the trigger players. the message will be whatever is the value for the key equal to this notification value, in the notifications.properties file. both "victory" and "notification" will look in the "notifications.properties" in your maps root folder for a string with the value's name, and then it will use whatever is to the right of the = sign. notification can be used to play a sound as well. notifications will use the notification value + "_sounds" for the key in notifications.properties file, and will then use "notification_" + the notification.properties value as the new key to look for in the sounds.properties file.
    

    IMO, there should be a condition option to count total production owned just like you can count territories owned. Then you could trigger victory off of it.


  • Moderators

    @redrum The other nice thing about the currently hardcoded victory condition is that it is a property, you can show in the game's settings. This is good both because people will clearly see that 152 victory requirement in there and they can also customize it (say you think that 152 is too much or too few).

    So, for a victory trigger to fully cover the matter, it would be also needed that conditions can see numeral properties (currently only Boolean is supported).


  • Moderators

    So, since I want it both production based and to be achieved any time, rather than at end round only, and much prefer it showing clearly in the customizable settings, I'll use this hack of having multiple endrounds, as it doesn't appear causing any troubles (and the game is not meant to ever have any triggers). But I'm open to refactor it if it would be possible to achieve the same result with victory triggers/conditions, eventually.

    I guess since we assume multiple endrounds is not intentionally supported, no reasons to document it.

    Still, I have to say that personally doesn't like the fact that this endround step manages both hardcoded victories and sets uses for triggers, as they seem unrelated matters, and, in my mind, it should have rather been called "victory" step, doing only that (traditionally as the last step in the sequence).


Log in to reply