Skip to content

Translate this page to: German French Portuguese Spanish

First steps in modding practice

- by BilboBeutlin
Created: 5th May 2006
Last Edited: 8th June 2006

We can't discuss all details within this short tour - just the most important aspects. But it will hopefully be sufficient to have a first overview. The rest is as always do-it-yourself. Exploring and understanding the data files is much more efficient than doing all steps after a guide.

The folder "data" contains the three most used data files for modding: proto.xml, techtree.xml and stringtable.xml. These are also suitable for rookies to get more experience with "learning by doing" or also "trial and error".
Alone with these files the most commonly wanted changes can be already done.

These three files don't need to be re-converted to .xmb - they are also accepted as raw xml files. The .xmb version is only taken if the source .xml is missing or perhaps corrupted.
So - if not touched - the .xmb can be seen as 'emergency-backup'.



The Stringtable

We begin our journey with the simpliest and easiest to understand datas: the file data\stringtable.xml contains all texts to be displayed - be it within the game itself, for the user interface, for ESO, for the scenario editor, etc.
So the texts are all together in one file, it's easy to adapt the version to another language - only the stringtable has to be swapped (apart from voice files).

The basic structure of a stringtable entry is
    <String _locID="{number}">{text}</String>
It can be expanded by some additional attributes, like eg. symbol= , gamecharacter= , soundfilename= , but this isn't interesting in general.
Only important for us is the string ID, which is referred from all other files.

Notice!
Be careful when editing the stringtable: many entries are very long - some lines have far more than 1000 characters. An unwanted reformat could wreck the file.

Example: changing a unit's display name
To change an ingame unit name, you have to look for the appropriate ID in proto (see below). Then search this ID in stringtable and change the following text according own wishes.

Hint:
If you perhaps later want to publish, distribute a mod: it's not the worst idea if you leave the original content untouched and only append a file to insert in the stringtable - manually or via installer. So the original language file is preserved.



The Proto File

The prototype file data\proto.xml contains the descriptions and stats of all units, buildings and other objects.
Each object has it's own proto entry from format
    <Unit id ='{number}' name ='{notation}'>
    ... {data tags} ...
    </Unit>


As example we examine a typical proto for a unit - the Musketeer:

    <Unit id ='214' name ='Musketeer'>
Unique UnitID and name. Units in game are referenced by the name only. The UnitID is used in saved games, scenarios and for debugging purposes.

    <DBID>3</DBID>
A database ID obviously only for Ensemble's internal use.
Comment: I never saw this DBID referenced in other files and it works also without this tag. But perhaps for future compatibility the tag should be retained.

    <DisplayNameID>22805</DisplayNameID>
A text ID to display the unit name. Referring to stringtable.

    <EditorNameID>25023</EditorNameID>
Same as above, but for notation in scenario editor.

    <PopulationCount>1</PopulationCount>
The amount of population slots a unit takes.

    <ObstructionRadiusX>0.4900</ObstructionRadiusX>
    <ObstructionRadiusZ>0.4900</ObstructionRadiusZ>

The size, extent of the unit for the collision detection.

    <FormationCategory>Ranged</FormationCategory>
Depending on this flag the unit is arrayed in a formation.

    <MaxVelocity>4.0000</MaxVelocity>
This is the normal movement speed for the unit.

    <MaxRunVelocity>6.0000</MaxRunVelocity>
Some actions can enhance temporary the basic speed upto this value.

    <MovementType>land</MovementType>
Where the unit moves. Can be "land", "water" or "air".

    <TurnRate>18.0000</TurnRate>
The 'agility' of the unit.

    <AnimFile>units\infantry_ranged\musketeer\musketeer.xml</AnimFile>
The appropriate animation file in the "art" folder. The anim file contains all model information for outlook, attachments, action animations, textures, etc.

    <ImpactType>Flesh</ImpactType>
    <PhysicsInfo>dude</PhysicsInfo>

Mainly descriptions for the havoc physics engine and damage system.

    <Icon>units\infantry_ranged\musketeer\musketeer_icon_64x64</Icon>
Unit icon which appears eg. in the building's train queues. Located in "art" folder.

    <PortraitIcon>units\infantry_ranged\musketeer\musketeer_portrait</PortraitIcon>
Unit's portrait for the user interface. Located in "art" folder.

    <RolloverTextID>22812</RolloverTextID>
    <ShortRolloverTextID>25669</ShortRolloverTextID>

Describing text which appears when hovering with mouse about the unit or icon.

    <InitialHitpoints>150.0000</InitialHitpoints>
The Hitpoints a unit has when just trained/built.

    <MaxHitpoints>150.0000</MaxHitpoints>
The basic maximum Hitpoints of the unit. Normally both HP values are equal, but for special effects initial HP can be different.

    <LOS>16.0000</LOS>
The unit's line-of-sight.

    <ProjectileProtoUnit>InvisibleProjectile</ProjectileProtoUnit>
The projectile(s) for ranged units. More than one projectile entry is possible.

    <UnitAIType>RangedCombative</UnitAIType>
Determines 'Artificial Intelligence' behavior of unit.

    <TrainPoints>30.0000</TrainPoints>
How long it takes to train (or build) a unit.

    <Bounty>10.0000</Bounty>
The XP points the opponent gets when destroying the unit.

    <BuildBounty>10.0000</BuildBounty>
The XP points for the player when building the unit.

    <Cost resourcetype ='Food'>75.0000</Cost>
    <Cost resourcetype ='Gold'>25.0000</Cost>

The costs for training/building an object. Usually from type 'Food', 'Wood', 'Gold'. But also 'Ships' (=shipments) is used for mercenaries.

    <AllowedAge>1</AllowedAge>
The minimum age for building a unit - begins with Age 0 = Discovery Age.

    <Armor type ='Hand' value ='0.2000'></Armor>
The resistance against attacks. Can be type 'Hand', 'Ranged' or 'Siege'. Only one type can be defined - more are ignored. The value ranges from 0.00 - 1.00 (0% - 100%).
The type 'Siege' can be defined, but the value is ignored.

Now comes a bunch of lines from format
    <UnitType>....</UnitType>
These type flags are mainly 'passive', they assign the unit to certain unit categories.
The 'LogicalType...' flags are used to validate several actions.
The 'Abstract...' flags are eg. used to enhance a whole class of units or for display and statistic purposes.
From notation the meaning is mostly self-explanatory.
    <UnitType>LogicalTypeValidSharpshoot</UnitType>
    <UnitType>LogicalTypeNeededForVictory</UnitType>
    <UnitType>LogicalTypeHandUnitsAutoAttack</UnitType>
    <UnitType>LogicalTypeLandMilitary</UnitType>
    <UnitType>LogicalTypeScout</UnitType>
    <UnitType>LogicalTypeValidSPCUnitsDeadCondition</UnitType>
    <UnitType>LogicalTypeGarrisonInShips</UnitType>
    <UnitType>LogicalTypeRangedUnitsAutoAttack</UnitType>
    <UnitType>LogicalTypeVillagersAttack</UnitType>
    <UnitType>LogicalTypeHandUnitsAttack</UnitType>
    <UnitType>LogicalTypeRangedUnitsAttack</UnitType>
    <UnitType>LogicalTypeMinimapFilterMilitary</UnitType>
    <UnitType>Military</UnitType>
    <UnitType>UnitClass</UnitType>
    <UnitType>Unit</UnitType>
    <UnitType>AbstractGunpowderTrooper</UnitType>
    <UnitType>AbstractInfantry</UnitType>
    <UnitType>AbstractHeavyInfantry</UnitType>
    <UnitType>HasBountyValue</UnitType>
    <UnitType>Ranged</UnitType>
    <UnitType>AbstractCavalryInfantry</UnitType>
    <UnitType>CountsTowardMilitaryScore</UnitType>
    <UnitType>AbstractRangedInfantry</UnitType>
    <UnitType>ConvertsHerds</UnitType>


According to above are following lines from format
    <Flag>....</Flag>
These effect mainly instructions for the game engine itself - also in most cases self-explanatory.
    <Flag>CollidesWithProjectiles</Flag>
    <Flag>ApplyHandicapTraining</Flag>
    <Flag>CorpseDecays</Flag>
    <Flag>ShowGarrisonButton</Flag>
    <Flag>DontRotateObstruction</Flag>
    <Flag>ObscuredByUnits</Flag>
    <Flag>Tracked</Flag>

    <Command page ='10' column ='1'>Stop</Command>
    <Command page ='10' column ='0'>Garrison</Command>
    <Command page ='10' column ='2'>Delete</Command>

These entries effect the appearance of additional function buttons in the user interface.
Here are also usually defined the special abilities and the build/train buttons.

    <Tactics>musketBayonet.tactics</Tactics>
A reference to unit's tactics file - located in "data\tactics". A tactics file contains explicite technical descriptions for each unit action. It can be seen as connective link between proto and anim file.


Finally all proto action stats of the unit are defined. Apart from attack modes also gather, build, heal abilities can be listed here.
        <ProtoAction>
            <Name>BuildingAttack</Name>
            <Damage>20.000000</Damage>
            <DamageType>Siege</DamageType>
            <ROF>3.000000</ROF>
        </ProtoAction>
        <ProtoAction>
            <Name>DefendHandAttack</Name>
            <Damage>13.000000</Damage>
            <DamageType>Hand</DamageType>
            <ROF>1.500000</ROF>
            <DamageBonus type ='AbstractCavalry'>3.000000</DamageBonus>
        </ProtoAction>
        <ProtoAction>
            <Name>DefendRangedAttack</Name>
            <Damage>23.000000</Damage>
            <DamageType>Ranged</DamageType>
            <MaxRange>12.000000</MaxRange>
            <ROF>3.000000</ROF>
        </ProtoAction>
        <ProtoAction>
            <Name>MeleeHandAttack</Name>
            <Damage>13.000000</Damage>
            <DamageType>Hand</DamageType>
            <ROF>1.500000</ROF>
            <DamageBonus type ='AbstractCavalry'>3.000000</DamageBonus>
        </ProtoAction>
        <ProtoAction>
            <Name>StaggerHandAttack</Name>
            <Damage>13.000000</Damage>
            <DamageType>Hand</DamageType>
            <ROF>1.500000</ROF>
            <DamageBonus type ='AbstractCavalry'>3.000000</DamageBonus>
        </ProtoAction>
        <ProtoAction>
            <Name>StaggerRangedAttack</Name>
            <Damage>23.000000</Damage>
            <DamageType>Ranged</DamageType>
            <MaxRange>12.000000</MaxRange>
            <ROF>3.000000</ROF>
        </ProtoAction>
        <ProtoAction>
            <Name>VolleyHandAttack</Name>
            <Damage>13.000000</Damage>
            <DamageType>Hand</DamageType>
            <ROF>1.500000</ROF>
            <DamageBonus type ='AbstractCavalry'>3.000000</DamageBonus>
        </ProtoAction>
        <ProtoAction>
            <Name>VolleyRangedAttack</Name>
            <Damage>23.000000</Damage>
            <DamageType>Ranged</DamageType>
            <MaxRange>12.000000</MaxRange>
            <ROF>3.000000</ROF>
        </ProtoAction>

The general format for an attack is
    <Name>{AttackName}</Name>  name refers to action in tactics file
    <Damage>{value}</Damage>  the base damage
    <DamageType>{type}</DamageType>  can be 'Hand', 'Ranged', 'Siege'
    <ROF>{value}</ROF>  the 'rate-of-fire' = 'reload-time'
    <DamageBonus type ='{category}'>{value}</DamageBonus>  a damage multiplier

The DamageBonus can be also < 1 to reduce damage to certain types. The effective damage is calculated as (base damage) * (bonus value)

Units with area, splash damage have additionally
    <DamageArea>{area}</DamageArea>  the expanse of damage
    <DamageFlags>{category}</DamageFlags>  important: determines, what is touched by area damage


Also values normally in tactics file can be overridden here with
    <MaxRange> or <MinRange>  the maximum or minimum attack range
    <DamageCap>  a damage delimiter
    <Projectile>  a special projectile, if not already defined otherwhere



At the very last we have the terminating proto tag
    </Unit>


A rookie's question, which often appears: How do I find a certain unit in proto file?
You can use your editor's search function and input some key letters, then searching until found the right proto.
There are also proto lists around the web - just use a web search like Google.
Or you place the unit within scenario editor - menu 'Objects' -> 'ObjectInfo' delivers the proto name.


Modifying the proto file

Changing an existing proto is quite simple: edit the according proto tag value to desired - save file - ready. At next game start the unit has the changed stats.

But often it is wished to preserve the original unit and to add a new, modified one.
For this you copy the suitable unit's proto and insert (paste) it at end of file, but before the terminating
    </Proto>
Here the unit gets a new, unique ID and name. Then edit the unit stats to desired values.
For making the new unit available in game, we must enable it in techtree.



The Techtree

The file data\techtree.xml contains all civilization specific techs, enhancements and descriptions for homecity shipments. It enables/disables certain techs, units and buildings at defined ages. In opposite to proto - which is valid for all - a change in techtree effects mostly only a particular player.
All techs can be also called within scenario editor by the trigger effect 'Set Tech Status'.

In general, each civ begins with an 'Age0{Civ}' description, where the most stuff is determined or pre-defined. Each age progress calls another tech '{Age}{Civ}' (Age= Colonialize.., Fortressize.., Industrialize.., Imperialize..), like eg. 'FortressizeBritish' or 'IndustrializeSpanish'.
Also all unit upgrades are defined in techtree usually in the order 'VeteranUnit', 'GuardUnit', 'ImperialUnit'. Also enhancements available in Market, Church, Arsenal, Capitol are specified here.
And finally important aspects for the homecity shipments are determined in techtree - these begin always with 'HC...', unit shipments usually with 'HCShip...'.

The techtree is a mighty instrument, much more flexible than the fixed data structures of proto. It has already a little the character of a script language. Techs can have conditions, can call other techs, even itself and can have (theoretically) unlimited amount of effects.

The basic structure of a tech is
    <Tech name ='....' type ='Normal'>
        <DBID>....</DBID>
        <Status>UNOBTAINABLE</Status>
        <Effects>
        ....
        </Effects>
    </Tech>


Also the techs are identified and referenced by name, so the tech name must be unique.
The (unique) DBID is obviously for Ensemble's internal use. See comment for proto DBID.
The Status flag is normally set by the game logic and initially always UNOBTAINABLE.

Optional possible additional tags:
    Icon : icon appearing in user interface
    DisplayNameID : stringtable ID for the tech's displayed notation
    RolloverTextID : stringtable ID to display description eg. when hovering with mouse about icon
    ResearchPoints : the bonus points when researched this tech
    Cost resourcetype =.... : can be 'Food', 'Wood', 'Gold', 'Ships' (shipments)
    Flag : various flags
    HomeCityLevel : is already a condition, the tech is only available at a certain HC level
    Prereq : prerequisite(s) to enable the tech, mostly a certain age or an already active tech

Unluckily the techs have no assigned ID like the protos. They are automatically numbered continously at game startup. However for some purposes like RM triggers the tech ID is needed. There are lists around the web or use a simple trick: create a dummy scenario, add a trigger with wanted tech, quick start the scen. and examine USERDIR:trigger\trigtemp.xs - this delivers the tech ID.
The auto-numbering is also a reason one should never insert a new tech - always append at end of techtree.


The effects

An effect always has the structure
    <Effect type ='..' .. {attributes} .. >{target}</Effect>
The order of attributes isn't important. The possible combinations of attributes within the 'Effect' tag are nearly infinite. So we must restrict here on some most used effect types.
It is recommanded to explore the techtree for examples of other effects.


    <Effect type ='TechStatus' status ='..'>{tech name}</Effect>
This effect enables/disables other techs. The status can be
    'active' : the tech is immediately enabled and the associated code is executed
    'obtainable' : the tech can be researched by the player
    'unobtainable' : resets the status, forbids the tech - but no data changes are made, the tech is not regressed


    <Effect type ='Data' subtype ='..' [other attributes] amount ='{value}' relativity ='{mode}'>
        <Target type ='ProtoUnit'>{proto unit}</Target></Effect>

This is the general format for modifying datas of any kind.

The amount is always a (signed) float number.

The relativity determines how to handle the value:
    'Absolute' is a +/- change relative to the base value
    'Assign' directly overwrites the base value
    'BasePercent' means: the amount is a multiplier for the base value (eg. 2.00 doubles, 0.50 halves).

The subtype is the sort of data to be changed. When the effect modifies a proto value, the subtype refers to a proto tag and is often named identically, but not always!

The target can be a single unit/object or a unit type/class eg. 'Hero' or 'AbstractInfantry' like defined in proto tags 'UnitType'. But not all effects work properly on whole classes.


Notice!
Many techs are reliant on their predecessors, so all Age techs and the unit improvements.
If you execute eg. 'IndustrializeBritish' from Age0, the previous age enhancements are skipped - they are not automatically included and some important stuff might be missing.
The same is valid for unit upgrades - always upgrade in steps Veteran -> Guard -> Imperial.
Finally there are some 'PostAge..' techs which are called when the player begins in a later age. In this case several previous techs/enhancements are skipped and if you inserted stuff there, it will never be executed.


Examples

Following some effect templates for the most usual concerns.
The code can be placed within any tech structure - certainly the appropriate tech has to be called (active) to make the changes working. For age dependent initialization place it in the 'Age0{Civ}' or '{Age}{Civ}' tech. But of course it can be inserted also in a HC shipment or in an improvement tech.


Changing the hitpoints of a unit
    <Effect type ='Data' subtype ='Hitpoints' amount ='{num}' relativity ='Absolute'>
        <Target type ='ProtoUnit'>{proto unit}</Target></Effect>

This adds num HP to unit's base value.


Modifying the attack of a unit
    <Effect type ='Data' subtype ='Damage' allactions ='1' amount ='{factor}' relativity ='BasePercent'>
        <Target type ='ProtoUnit'>{proto unit/class}</Target></Effect>

This multiplies the base damage by the factor for all attack modes.
An additional damage bonus can be set with
    <Effect type ='Data' subtype ='DamageBonus' allactions ='1' unittype ='{effected unit/class}' amount ='{factor}' relativity ='Assign'>
        <Target type ='ProtoUnit'>{proto unit/class}</Target></Effect>

The damage bonus acts only on specified unittype and is a multiplier to the base damage.
If you want to modify the damage only for a certain attack mode, you have to replace ".. allactions ='1' .." with ".. action ='{proto action}' .."


Modifying the costs of a unit
    <Effect type ='Data' subtype ='Cost' resource ='{type}' amount ='{num}' relativity ='Assign'>
        <Target type ='ProtoUnit'>{proto unit}</Target></Effect>

This sets the cost for specified resource type to defined amount. The type can be 'Food', 'Wood', 'Gold' - 'Ships' (=shipments) is used for mercenaries.


Setting the population slots for a certain unit
    <Effect type ='Data' subtype ='PopulationCount' amount ='{value}' relativity ='Assign'>
        <Target type ='ProtoUnit'>{proto unit}</Target></Effect>



Enabling a non-available unit
    <Effect type ='Data' subtype ='Enable' amount ='1.00' relativity ='Assign'>
        <Target type ='ProtoUnit'>{proto unit}</Target></Effect>

Also disabling is possible with " ... amount ='0.00' relativity ='Assign' ..." or " ... amount ='-1.00' relativity ='Absolute' ...".
For standard units this is sufficient - the train locations (buildings) are mostly pre-defined.
Else do the next step:


Adding a unit/building to a certain building/unit's train queue
    <Effect type ='Data' subtype ='AddTrain' unittype ='{proto unit/bulding}' amount ='1.00' relativity ='Assign'>
        <Target type ='ProtoUnit'>{target building/unit}</Target></Effect>

Unluckily this makes no difference between units and buildings, so it is always added to the first train/build row.


Enabling a unit's special ability
Some unit actions (eg. special attacks) are only available after explicitely allowing them:
    <Effect type ='Data' subtype ='ActionEnable' action ='{proto action}' amount ='1.00' relativity ='Assign'>
        <Target type ='ProtoUnit'>{proto unit}</Target></Effect>



Getting free units, eg. by a shipment
    <Effect type ='Data' subtype ='FreeHomeCityUnit' unittype ='{proto unit}' amount ='{num}' relativity ='Absolute'>
        <Target type ='Player'></Target></Effect>

The units will appear just like habitual shipments.


Training mercenaries at buildings
We enable the unit with
    <Effect type ='Data' subtype ='Enable' amount ='1.00' relativity ='Assign'>
        <Target type ='ProtoUnit'>{mercenary}</Target></Effect>

We assign a training location with
    <Effect type ='Data' subtype ='AddTrain' unittype ='{mercenary}' amount ='1.00' relativity ='Assign'>
        <Target type ='ProtoUnit'>{target building}</Target></Effect>

Finally we have to adjust the cost 'Ships' to zero, else each single unit would require one shipment
    <Effect type ='Data' subtype ='Cost' resource ='Ships' amount ='0.00' relativity ='Assign'>
        <Target type ='ProtoUnit'>{mercenary}</Target></Effect>




Final words

Not all can be explained here elaborately, else this guide would easily fill 200 pages. But it's hopefully sufficient for a first orientation.
Now it's on you to expand your knowledge by trying and testing. Examining and understanding the described files is essential for own modding.
You can't expect for all concerns a ready-to-use recipe. But browsing in the forums, using search function will help a lot.
After the first steps with these basic data files you perhaps wish to go deeper into the 'abyss of modding', perhaps working on tactics or anim files. This requires good knowledge of the files' coherences. Study the default Ensemble files. Look how other people made it by downloading and exploring examples.

Modding = Examining + Thinking + Drawing Conclusions + Implementing + Testing