Changing Object Behaviour

Changing How a Unit, Structure or Game Behavior Works

To change the behavior of how a unit works, you need to first determine which XML tag is used for the desired effect. These are usually pretty obvious (for example, MaxSpeed controls movement speed). A basic rule is: if the change is game-wide, the tag likely resides in GameConstants.XML. If the change is for a specific unit or structure, then the tag will reside in an XML file specific to that object.

Example 1

In this example, we want to change how much care packages cost from world map purchase menu. Since this is a global change and not specific to any one object, we look in GameConstants.XML to find this block:

<StrategicPurchaseCarePackageCostResources>
  <entry> 600 </entry> <!-- Spend X Resources for researched Care Package 1 -->
  <entry> 600 </entry> <!-- Spend X Resources for researched Care Package 2 -->
  <entry> 600 </entry> <!-- Spend X Resources for researched Care Package 3 -->
</StrategicPurchaseCarePackageCostResources>

Example 2

In this example, we want to make the Mark I British Tank move faster. Because this is a specific object, we are looking for an XML file named for the object. We find Unit_VEH_Tank_British_MkI_00.XML and open that. Inside you will find the Unit_VEH_Tank_British_MkI_00 unit object with its list of components. Since we are adjusting speed, we look for the WalkLocomotorCompoent:

<WalkLocomotorComponent>
  <MaxSpeed>165</MaxSpeed>
  <Acceleration>10000</Acceleration>
  <Deceleration>10000</Deceleration>
  <MaxRateOfTurn>120</MaxRateOfTurn>
  <AngularAcceleration>250</AngularAcceleration>
  <AngularDeceleration>250</AngularDeceleration>
  <MaxSpeedPercentForBigTurns>50</MaxSpeedPercentForBigTurns>
  <MinSpeedPercentForBigTurns>50</MinSpeedPercentForBigTurns>
  <MovementClass>VehicleNormalSpawnZone</MovementClass>
  <PathLookAheadRange>1000</PathLookAheadRange>
  <TurnInPlace>True</TurnInPlace>
  <MoveInReverse>True</MoveInReverse>
  <TurningRadius>0</TurningRadius>
  <OrientToTerrain network="client">True</OrientToTerrain>
  <MovementWeight>1000</MovementWeight>
  <StandingWeight>1000</StandingWeight>
  <CanBePushed>False</CanBePushed>
  <ResolvesCollisionsWithNonPushable>True</ResolvesCollisionsWithNonPushable>
  <ResolvesWithUnpushableLayerAgents>True</ResolvesWithUnpushableLayerAgents>
  <CloseEnoughDistance>300</CloseEnoughDistance>
  <UsesTrenchCrossingBehavior>true</UsesTrenchCrossingBehavior>
  <TrenchCrossingMovementClass>GroundCliffJumper</TrenchCrossingMovementClass>
</WalkLocomotorComponent>

As you can see, there is a lot of data that can fine tune the movement of the tank in a number of ways. At the simplest level, we can speed the tank up by adjusting MaxSpeed up to whatever we wish. Note that the system will not stop you from doing something that breaks gameplay unless you put in a number that is REALLY large or smaller than the system allows. When adjusting numbers, always adjust in reasonable increments and test your work - you will avoid crashes this way.

Example 3

Let’s try something more complex. We want to change the damage for the cannon on the French FT Light tank. Anything that involves an action that something can use repeatedly is an ability. First, we find the XML for the tank: Unit_VEH_Tank_French_FT_01.XML

Next, we take a look within the tank data for this:

<AbilityManagerComponent>
  <DefaultAbility>Tank_FrenchFT_Cannon_Attack_Ability</DefaultAbility>
</AbilityManagerComponent>

The ability manager component lists all of the abilities that the unit can use. This component can have multiple abilities in the list, but it is best to avoid multiple abilities that have the same target type (for example, having a machine gun that fires at long range and a shotgun that fires at short range can cause targeting conflicts). That’s not an issue here, but something to keep in mind if you want to experiment.

In most cases, abilities are included in the same file with the unit that uses them, so we can scroll down until we find Tank_FrenchFT_Cannon_Attack_Ability Abilities are made up of two parts: the ability object type that determines when the object can use the ability (including range, area effect, target types, etc.) and the component (Weapon or Effect) that determines what happens when the ability activates.

In most cases, if an ability fires a projectile of some kind, it will be a weapon type ability. If it does something strange like fire bolts of lightning or clouds of gas, then it will be an effect type ability. Since we are changing damage for a cannon, it will be a weapon type:

<WeaponAbilityComponent>
  <Speed>10000</Speed>
  <Damage>0</Damage>
  <MoraleDamage>0</MoraleDamage>
  <AoEDamage>90</AoEDamage>
  <AoEDamagesTarget network="server">True</AoEDamagesTarget>
  <AOETargetFilternetwork="server">FAR_Base_Tank_Cannon_Target_Filter</AOETargetFilter>
  <TypeOfDamage>Damage_Cannon</TypeOfDamage>
  <ProjectileType>Tank_British_MkIV_Cannon_Projectile</ProjectileType>
  <MuzzleBoneNamePrefix network="client">muzzleA</MuzzleBoneNamePrefix>
  <SelfRecoilMagnitude network="client">0.5f</SelfRecoilMagnitude>
  <TargetImpactMagnitude network="client">1.0f</TargetImpactMagnitude>
  <DeathImpactMagnitude network="client">100.0f</DeathImpactMagnitude>
  <RecycleParticles network="client">true</RecycleParticles>
  <OnHitVisualFXTypes network="client"><Entry>SURFACEFX_UNIT_GENERIC_ARTILLERY_HIT</Entry></OnHitVisualFXTypes>
</WeaponAbilityComponent>

There are a few things to note in this data block. First, we see that the Damage tag is set to zero. This is because the cannon does area-of-effect damage and is marked to damage the target. If you wanted to, you could have a different damage value for the target and anything else in the blast radius. The AoEDamage tag is currently serving as damage for everything, so the standard Damage tag is unused.

Next, the TypeOfDamage tag shows you the damage type that is applied to the target. This is important since each damage type affects targets differently depending on their armor type. For example, infantry takes less damage from cannon damage than another tank would. If you are interesting and seeing how that works, you can look at the DamageToAttribute.xml file.