GAE/Guide

Upgrades
The upgrade xml format is extended while retaining legacy support for existing upgrades. This is in the file /factions//upgrades//.xml. The new format cleans up the xml file somewhat by not requiring you to have nodes present for attributes your upgrade does not effect, while extending upon the number of attributes you can modify with an upgrade. In addition, attributes can be modified using a multiplier as well as a static value, allowing you to scale the effect across units of varying power.

The following is a sample upgrade.xml file which does the exact same thing as the existing "Energy Sharpening" upgrade.

           

Note that nodes under &lt;static-modifiers&gt; and &lt;multipliers&gt; are optional and default to 0 and 1.0, respectively. If you wanted to increase the attack strength by 30% instead, you could use the following code for the static-modifiers and multipliers tags.

 <attack-range value="1"/> </static-modifiers> <attack-strength value="1.3"/>

Common Attribute List
The following is a complete list of attributes that can be modified by either a static amount or a multiplier in either the upgrade or effects XML structures and each should have a "value" attribute. Static values take a positive or negative number and default to zero (no modification). Multipliers take a floating point number, the default to 1.0 (multiply by one, or no modification). Note that this is not notated as a percentage. If you enter 100.0 for a multiplier, it means that the value increases 100 times. These are also covered in the reference section.

<max-hp> <hp-regen> <max-ep> <ep-regen> <attack-strength> <attack-range> <attack-speed>    &lt;-- increases or decreases rate of attack --&gt; <move-speed> <production-speed> <repair-speed> <harvest-speed>

Effects
Effects are embedded in the &lt;skill&gt; tag of the &lt;unit&gt;. At this time, only attack skills and emanations (described in the next section) are supported, but a new "cast spell" skill type will be later added to allow effects to be put on friendly units or. The below is an example of an extended attack of the archer adding a poison to the arrows which causes blindness and 50 damage per second for 8 seconds. Note that the only part of this snippet that is modified from the original is the addition of the &lt;effects&gt; tag.

Example Skill With Effects <name value="attack_skill"/> <ep-cost value="0"/> <anim-speed value="50"/> <animation path="models/archer_attacking.g3d"/> <sound enabled="true" start-time="0.5"> <sound-file path="sounds/archer_attack1.wav"/> <sound-file path="sounds/archer_attack2.wav"/> <sound-file path="sounds/archer_attack3.wav"/> <sound-file path="sounds/archer_attack4.wav"/> <attack-strenght value="100"/> <attack-var value="50"/> <attack-range value="10"/> <attack-type value="piercing"/> <attack-start-time value="0.5"/> <attack-fields> </attack-fields> <particle value="true" path="particle_proj.xml"/> <sound-file path="sounds/arrow_hit1.wav"/> <sound-file path="sounds/arrow_hit2.wav"/> <sound-file path="sounds/arrow_hit3.wav"/> <sound-file path="sounds/arrow_hit4.wav"/> <sound-file path="sounds/arrow_hit5.wav"/> <effect name="blinding_poison" bias="detrimental" stacking="overwrite" target="any" chance="100.0" duration="8" image="../../../../placeholders/icon.bmp">  <hp-regeneration value="-50"/> </static-modifiers> <sight value="0.2"/> <fields-added/> <fields-removed/> <recourse-effects/>

By using the multiplier of 0.2 for sight, their sight is reduced to 20% of normal. Reducing it further may result in a sight of zero, which would make them incapable of attacking even targets directly adjacent to them, and that probably wouldn't be a very balanced attack, but it would be funny. :)

Effects can be used on attacks with a splash effect as well, this will cause all units in the splash radius to be effected. By default, all units are effected equally, even if they are on the very edge of the splash radius. However, by adding the flag &lt;apply-splash-strength&gt; to the &lt;flags&gt; section of the effect, this behavior can be overridden causing the strength of the effect to be weaker on units further from the point of impact. The strength of the effect isn't exposed through the XML interface, but it effects all attribute modifications (both positive and negative). Below is an example a theoretical effect added to the ice attack of an archmage. Presuming that the ice is cold, let's say that this will temporarily reduce the movement and attack speed of the target. However, the effect will be relative to where they in the splash radius. Also in this snippet, we omit tags and attributes that are not used, as most are now optional.

<effect name="icy_chill" bias="detrimental" stacking="stack" target="all" chance="100.0" duration="8">  <attack-speed value="-25"/> <move-speed value="-30"/> </static-modifiers> <sight value="0.0"/> <apply-splash-strength/>

(I could not make "<apply-splash-strength/>" work for me so if it also does not work for you just remove that line and the slowdown effect should work )

You may have noticed that the "stacking" attribute of the effect tag was set to "stack" this time instead of "overwrite". This means that successive attacks which cause this effect will accumulate, increasing the total effect. Each instance of the effect has it's own timer, so they will wear off one at a time. When set to "overwrite", the previous effect is simply overwritten and the duration reset. This isn't recommended for use with apply-splash-strength however because a second effect may be weaker and overwrite a stronger one.

Now let's go overboard and improve the initiate's attack. This will cause their targets to take damage over time, encouraging them to run fast, set them on fire spewing out fiery particles with a sizzling sound and causing them to glow red for the duration. In addition the initiate will get a recourse effect, which gives them some extra energy regeneration and movement speed so he can follow his victim around and watch for as long as the bastard is burning up. Unused tags are again omitted.

<effect name="burning_bastard" bias="detrimental" stacking="stack" target="any" chance="100.0" duration="8">  <hp-regeneration value="-25"/> </static-modifiers> <movement-speed value="2.0"/> <light enabled="true" red="0.8" green="0.1" blue="0.1"/> <sound enabled="true" start-time="0.0" loop="true" path="sounds/sizzle.wav"/> <particle enabled="true" path="firey_particles.xml"/> <recourse-effects> <effect name="pyromania" bias="beneficial" stacking="stack" target="any" chance="100.0" duration="8">  <ep-regeneration value="25"/> </static-modifiers> <movement-speed value="2.0"/> <sound enabled="true" start-time="1.0" loop="true" path="sounds/manic-giggling.wav"/> </recourse-effects>

Emanations
An emanation is a special ability which causes all applicable units surrounding the emanating unit to be effected. Emanations are both passive and are constantly "on", applying their effect on surrounding units every tick. In general, an emanation should use the  stacking value, unless an accumulated effect is desired for some reason. Here is an example of an emanation that causes nearby friendly units to receive extra regeneration and causing them to glow to indicate their being effected. ...        ....         <emanation name="tranquility" bias="beneficial" stacking="overwrite" target="ally" chance="100.0" duration="2">  <hp-regeneration value="15"/> <ep-regeneration value="15"/> </static-modifiers> <light enabled="true" red="0.1" green="0.0" blue="0.8"/>

Guard Command
A guard command has been added. However, the command must be added to the xml of the unit before it can be used. It is identical to attack commands except that a max-distance tag must be specified to dictate the maximum distance the guarding unit must be to their target before they consider themselves to have arrived (stop moving). When guarding a static position on the ground, they will not neccisarily return to the exact point they were told to guard, but will get back to a distance of max-distance from that point before stopping. When guarding another unit, they will follow them, at a distance of max-distance. If this value is too small, they will get in the way of the unit they are guarding. If it is too large, they will not see when the unit they are guarding is being attacked.

<image path="../../../../placeholders/icon.bmp"/> <unit-requirements/> <upgrade-requirements/> <move-skill value="move_skill"/> <attack-skill value="attack_skill"/> <max-distance value="4"/>

Patrol Command
The patrol command works very like the guard command and shares the exact same parameters. When the patrol command is activated, and a "patrol to" target is specified, the unit will behave as though they are attacking to the specified position. Once they arrived (within max-distance of their target), they will head back to the position they started at. If the "patrol to" target is another unit, the patrolling unit will go out to meet the "patrol to" unit each iteration. If the "patrol to" unit dies, then the patrolling unit will switch to patrolling to the location that the "patrol to" unit was when they died.

<image path="../../../../placeholders/icon.bmp"/> <unit-requirements/> <upgrade-requirements/> <move-skill value="move_skill"/> <attack-skill value="attack_skill"/> <max-distance value="4"/>

In the future, the patrol command may optionally accept a second move-skill, so that they have one they use while patrolling (usually a slower move skill) and another that they use when an enemy is encountered. This can be helpful for units that expend energy to move faster. Additionally, multiple attack-skills may be added later so that patrolling units with both land and air attacks can automatically attack either target if they are encountered.

Subfactions
Subfactions is a mechanism that allows a single faction to have multiple overlapping definitions that allow the rules of what commands, units, buildings, skills, upgrades, morphs, etc. are available to change. Subfactions generally progress from the "base" subfaction (i.e., no "sub" in the faction) on to more advanced subfactions. This progression may be linear, or it may branch allowing multiple paths of progression. Some examples of similar mechanism in other RTS games are the progression to different "ages" in Age of Empires or Empire Earth, although I'm not aware of any RTSs that allow alternate (and mutually exclusive) progression paths.

Implementation note: There is currently a hard limit of 32 subfactions per faction. This can be easily changed, but is undesirable to deter code bloat.

How They Work
When not defined, each faction has only the "base" subfaction (which is to say none). To use subfactions, you must first add them to the <tech-tree>/ .xml file. The following example is taken from the Four Path Magitech's four_path_magitech/factions/magic/magic.xml. ...        <subfaction name="path_of_nature"/> <subfaction name="path_of_corruption"/> This will cause the magic faction to posses the subfactions "base" (the default), "path_of_nature" and "path_of_corruption". In Four Path Magitech we allow players to choose an advanced subfaction once a basic infrastructure is built. When the game starts, the the Mage Tower can produce initiates, but there are also two upgrades, "Path of Corruption" and Path of Nature" which are greyed out until the summoner's guild and library are built, where upon they both become available. Once either of these upgrades complete, the subfaction advances and the option to upgrade the other disappears.  In fact, all producible commands will disappear if they are not available in the new subfaction.

Subfaction restrictions can be applied to any command, unit (including buildings) or upgrade by specifying a list of subfactions that the item is allowed in with a <subfaction-restrictions> tag. If <subfaction-restrictions> tag is not present, then all subfactions are allowed (i.e., no restrictions). For units, the <subfaction-restrictions> tag is added to the node; for commands, they go directly under the node and for upgrades, they go directly under the node. Here is an excerpt from the four_path_magitech/factions/magic/upgrades/path_of_corruption/path_of_corruption.xml file: <image path="images/corruption.bmp"/> <image-cancel path="../../../../../magitech/factions/magic/upgrades/ancient_summoning/images/magic_upgrade_cancel.bmp"/> <unit-requirements> </unit-requirements>  <resource name="gold" amount="200"/> <resource name="wood" amount="200"/> <resource name="stone" amount="200"/> </resource-requirements> <subfaction-restrictions> </subfaction-restrictions> <advances-to-subfaction name="path_of_corruption" is-immediate="false"/>

The first thing you may notice is that this upgrade is only available in the "base" subfaction. This upgrade could have added statistical bonuses to some units if we wanted to do that, but it exists solely for the purpose of allowing path of corruption units to be built, this is done with the <advances-to-subfaction> tag. This is the tag that actually causes a producible type (upgrade or unit) to invoke a subfaction advancement. If the is-immediate attribute is set to true, the advancement will occur as soon as the building, upgrading, morphing or producing begins. Otherwise, the advancement will occur once it is completed.

In FPM, we decided to move some of the original units around to better fit the story line. Since we didn't feel it would be normal for magicians who later embraced nature, life and all things good to be summoning giant daemons and researching hell gates, we moved these to the path of corruption. This means that when you first build your library, you will not see the ability to research Hell Gate at all until (and unless) you research the path_of_corruption upgrade (which causes the advancement). This behavior is again caused by adding the <subfaction-restrictions> tag. <image path="../../../../../magitech/factions/magic/upgrades/hell_gate/images/hell_gate.bmp"/> <image-cancel path="../../../../../magitech/factions/magic/upgrades/ancient_summoning/images/magic_upgrade_cancel.bmp"/> <unit-requirements/>  <resource name="wood" amount="200"/> <resource name="gold" amount="200"/> </resource-requirements> <subfaction-restrictions> <subfaction name="path_of_corruption"/> </subfaction-restrictions>

Off-Screen Attack Notification
This feature is functional as of version 0.2.8. This feature will play a random sound file from a collection (or just a single one) if one of your units is being attacked off screen. You should basically create a "sounds" directory directly under each faction subdirectory to put your sound file(s) there and add this code into your faction.xml file: ....    <attack-notice enabled="true" min-delay="30"/> <sound-file path="sounds/attacked1.wav"/> <sound-file path="sounds/attacked2.wav"/> <sound-file path="sounds/attacked3.wav"/> <sound-file path="sounds/attacked4.wav"/> <sound-file path="sounds/attacked5.wav"/> </attack-notice> .... This will cause one of the 5 sound files to be played when you are attacked off screen, but not more often than once every 30 seconds. A similar <enemy-notice> feature may be added later that will give you notice if one of your units spots an enemy off screen as well.

Pets (initial implementation)
A very limited owner/pet relationship has been implemented. This is subject to change and most probably will within a few months. The current implementation allows a creating unit to produce one or more pets. A pet is a unit that will guard their master when idle, will attack the position of their master and will die when their master dies. The restriction on the number of pets a unit can have is specified in the produce skill -- this is something that will definitely change. Unfortunately, a separate produce skill has to be created for each type of pet that the unit can have if you want to specify a different number of maximum pets. Each maximum pet restriction applies to the unit type of the pet, not the total number of pets. The below example (an excerpt from the necromancer.xml unit definition file) will allow the necromancer to skeletons and zombie giants, but restricts him to a max of 4 skeletons and 1 zombie giant. Each summoned unit will be bonded to him as his pet (or "minion" if you prefer):

<name value="summon_skel"/> <ep-cost value="5"/> <anim-speed value="100"/> <animation path="../../../../placeholders/sphere.g3d"/> <sound enabled="true" start-time="0.3"> <sound-file path="../../../../../magitech/factions/magic/units/summoner/sounds/summoner_summon1.wav"/> <sound-file path="../../../../../magitech/factions/magic/units/summoner/sounds/summoner_summon2.wav"/> <sound-file path="../../../../../magitech/factions/magic/units/summoner/sounds/summoner_summon3.wav"/> <sound-file path="../../../../../magitech/factions/magic/units/summoner/sounds/summoner_summon4.wav"/> <pet value="true" max="4"/> <name value="summon_zombie"/> <ep-cost value="3"/> <anim-speed value="100"/> <animation path="../../../../placeholders/sphere.g3d"/> <sound enabled="true" start-time="0.3"> <sound-file path="../../../../../magitech/factions/magic/units/summoner/sounds/summoner_summon1.wav"/> <sound-file path="../../../../../magitech/factions/magic/units/summoner/sounds/summoner_summon2.wav"/> <sound-file path="../../../../../magitech/factions/magic/units/summoner/sounds/summoner_summon3.wav"/> <sound-file path="../../../../../magitech/factions/magic/units/summoner/sounds/summoner_summon4.wav"/> <pet value="true" max="1"/>