The 3rd Age

Return of Shadow

Return of Shadow

A large scale mod that greatly expands the game.

Button for The 3rd AgeButton for The Dwarf HoldsButton for The Elven AllianceButton for Helm's Deep Last HopeButton for GothmogtheOrcButton for BFME+Button for The Four AgesButton for HDR HeadquartersButton for Middle Earth CenterButton for Project Perfect Mod

Become an affiliate!

   

Quick Lists

Top Rated Popular New Updated Last Comments Users

Register and log in to move these advertisements down

Adding a new unit

Avatar of Hostile

Hostile

Category: Code
Level: Intermediate
Created: Monday March 26, 2007 - 13:03
Updated: Saturday June 27, 2009 - 18:46
Views: 17889
Summary: The basics of a units code

Rating

Staff says

3.0

Members say

2.8

Average

2.9/5.0

10 votes

The Basics - Adding A New Unit

Written by: Hostile

The purpose of this tutorial is to go step by step on explaining each major part of the object code. This doesn't cover every single aspect or the tutorial would run for pages. But does cover enough of the basics to give you an idea of how it works.

There are basic parts of a unit that I will list here.
Object Code - coding the unit
Model/Skin/Animations - this tutorial assumes you have these ready
Upgrades
Special Powers/Spells
Command Buttons

Before embarking on this challenge of adding a New Unit, I suggest you read the beginner tutorials so that you know how to extract the INI's and use your edited INI's.

All the tools you need to add your new faction can also be found in the Downloads section. So, let's get started.

I'm going to start with the object code as it is the most detailed and important. Also the easiest to make a mistake on. I've broken down the object code into sections that will address differant parts of the new unit. I'm going to be working with Mordor Goblin Fighters because I believe they are simple but allow enough variations for a good example.

Open up the object ini file for Mordor Goblin Fighter located at \data\ini\object\evilfaction. I've included a seperate text file for you to view so you can just click here for a copy of just this file instead.

OBJECT CODE
Art Code
Models
Animations
Condition States

The code begins with the art for this unit.

              
Code
ButtonImage = BuildingNoArt

But most have a portrait here such a gondor soldier.
              
Code
SelectPortrait = UPGondor_Soldier

Draw = W3DHordeModelDraw ModuleTag_01

OkToChangeModelColor = Yes

StaticModelLODMode = Yes
; specify options for static LODs
LodOptions = LOW
AllowMultipleModels = ALLOW_MULTIPLE_MODELS_LOW
MaxRandomTextures = MAX_RANDOM_TEXTURES_LOW
MaxRandomAnimations = MAX_RANDOM_ANIMATIONS_LOW
MaxAnimFrameDelta = 0 ;These guys are out of a horde more often than in, so they need permission to diverge.
End
RandomTexture = MUGblnSwrd.tga 0 MUGblnSwrd.tga
RandomTexture = MUGblnSwrd2.tga 0 MUGblnSwrd.tga
RandomTexture = MUGblnSwrd3.tga 0 MUGblnSwrd.tga
DefaultModelConditionState
Model = MUGblnSwrd_SKN
Skeleton = MUGblnSwrd_SKL
End


It starts by naming the image ini to use, in this case it is not a button, no art necessary. But most units name a portrait image to be seen in the display when you click on it. The next line DRAW = W3DHordeModelDraw ModuleTag_01 is a basic command telling the game that this is a unit that will eventually form a horde. You'll use this often for new units.

I've included a section of the next code because it sets up how the art is done over differant resolutions. I would just copy paste all three LodOptions. It's standard...

The next code gives the options for random textures for our goblins, so they don't all look alike. MUGblnSwrd2.tga 0 MUGblnSwrd.tga, means that sometimes instead of the standard skin, substitute it for the first one. Lastly here we set our default model and skin. So the game knows what the model and the skeleton is we are working from.

Next starts the real art code. It states a condition state and what animation should be used when this condition state is true.
Example:
FALLING

              
Code
AnimationState = PASSENGER
Animation = Wiggling
AnimationName = MUGblnSwrd_FLLA
AnimationMode = LOOP
End
End

AnimationState = THROWN_PROJECTILE
StateName = STATE_Flying
Animation = Thrown
AnimationName = MUGblnSwrd_FLYA
AnimationMode = LOOP
End
End

AnimationState = FREEFALL
Animation = Falling
AnimationName = MUGblnSwrd_FLYB
AnimationMode = LOOP
AnimationBlendTime = 10
AnimationSpeedFactorRange = 0.7 0.7
End
End


The first animation (condition) state describes when the goblin becomes a passenger. Namely this means when an eagle grabs one. Hence you can understand why it is called "wiggling". This animation state exists until the unfortunate goblin is dropped. Than it assumes the FREEFALL state.

The THROWN_PROJECTILE state exists when the goblin is hit by something like a rock from an Ent. He flies back from the force. These are an example of how condition states work and react when units are interacted with.

Now I'm not going to explain every condition state and how it relates. But by looking close at the code you'll notice you can code random dying animations and such based on how goblins land on the ground and such. Figuring this out is best left to the modder. That is part of the advanture.

This finishes up the art section of the object code. I'll now get into the Design Parameters for the unit code. Layed out as such...

OBJECT CODE
Design Parameters
Basics
Weaponset
Armorset
Mmore Basics
Commandset

Let's start with the basics of DESIGN PARAMETERS
              
Code
Side = Mordor
IsTrainable = No
EditorSorting = UNIT
ThreatLevel = 1.0
ThingClass = HORDE_UNIT
CommandPoints = 1

TransportSlotCount = 1

Side = Mordor, Tells us this unit works for Mordor. A unit cannot work if it is being built by a side it does not work for. So if you want Sauramon to work for Mordor you have to copy paste his object code and change the name and side = to Morder from Isengard.

IsTrainable = No Why would this be here? Because Mordor Goblins do not gain rank. That is the only time you would use this feature. Most units don't have it.

EditorSorting = UNIT World Builder needs to know what group it should be listing under. This one is a unit.

ThingClass = HORDE_UNIT/CommandPoints = 1 What is this item and how many command point does it take?

TransportSlotCount = 1 If I load this unit into something, how many spaces does it take up?


Next we move onto WEAPONSET. WEAPONSET is the weapon that the unit will use. This is a direct reference to the WEAPON.INI file located in data/ini/weapon.ini. A unit can have up to three weapons: PRIMARY, SECONDARY, TERTIARY.
              
Code
WeaponSet
Conditions = None
Weapon = PRIMARY MordorGoblinSword
AutoChooseSources = PRIMARY FROM_PLAYER FROM_SCRIPT FROM_AI
End


Conditions sets when this weaponset is to be used. This can be None, Updraded, and so on. You may have multiple weaponsets based on the units statis. This can include upgrades, veterency, health, and so on. Many options to choose from. Look at the existing units for other options.

Example: the Gondor soldier
              
Code
WeaponSet
Conditions = PLAYER_UPGRADE
Weapon = PRIMARY GondorSwordUpgraded
AutoChooseSources = PRIMARY FROM_PLAYER FROM_SCRIPT FROM_AI
End


Weapon = PRIMARY This can also include SECONDARY and TERTIARY weapons. You can define them all here. As many as you can think of. PRIMARY with an upgrade or veterency, SECONDARY with the same parameters. You can even state a condition state like REALLYDAMAGED. If you feel that your unit will change it's weaponset if it's really damaged. This is the condition to use. There are set condition states though. You cannot just make them up.

If a goblin can use swords and bows than it would look like this:
              
Code
WeaponSet
Conditions = None
Weapon = PRIMARY MordorGoblinSword
Weapon = SECONDARY MordorGoblinBow
AutoChooseSources = PRIMARY FROM_PLAYER FROM_SCRIPT FROM_AI
End


That finishes WEAPONSET, let's move on to ARMORSET.
              
Code
ArmorSet
Conditions = None
Armor = CreepArmor
DamageFX = NormalDamageFX
End


Conditions should now already be explained, Armor is listed in the armor.ini file. You can have an armor, an upgraded armor, veterency armor, and such. Not much to explain here. The armor ini can be located at /data/ini/armor.ini

And some more of the basics. Such as:
              
Code
VisionRange = VISION_STANDARD_MELEE
DisplayName = OBJECT:GoblinSwordsman
CrushableLevel = 0 ;What am I?: 0 = for infantry, 1 = for trees, 2 = general vehicles
CrusherLevel = 0 ;What can I crush?: 0 = small animals, 1 = infantry, 2 = trees, 3 = vehicles
BountyValue = MORDOR_FIGHTER_BOUNTY_VALUE
CrushRevengeWeapon = BasicInfantryCrushRevenge

VisionRange = VISION_STANDARD_MELEE Most units have this melee vision range. How far can I see and engage enemies.
DisplayName = OBJECT:GoblinSwordsman This is the CSF file entry. What shows up when I hover over this unit?
CRUSHABLE items are self explanitory here.
BountyValue = This is set in the gamedata.ini and gives a dollar value for when this unit is killed if you have such an ability to gain Bounty kills.

CommandSet = MordorFighterCommandSet


This will list the actions that this unit can perform. This is directly referenced in the CommandSet.ini file located in /data/ini/commandset.ini

              
Code
VoiceSelect = UrukVoiceSelect ; MordorOrcHordeVoiceSelect
VoiceMove = UrukVoiceMove ; MordorOrcHordeVoiceMove
VoiceMove2 = OrcVoiceMove2
VoiceAttack = UrukVoiceAttack ; MordorOrcHordeVoiceAttack
VoiceAttack2


This is where you assign the voices to be used for your unit. You can record your own. But you must code them in the audio.ini file. Than you can reference your new ones here.

OBJECT CODE
Engineering Parameters
Health
Locomotor

              
Code
RadarPriority = UNIT
KindOf = PRELOAD SELECTABLE CAN_CAST_REFLECTIONS INFANTRY PATH_THROUGH_EACH_OTHER CAN_USE_SIEGE_TOWER SCORE THROWN_OBJECT ARMY_SUMMARY ORC GRAB_AND_DROP

Body = ActiveBody ModuleTag_02
MaxHealth = MORDOR_GOBLIN_SWORDSMAN_HEALTH ;BALANCE Orc Warrior Health
MaxHealthDamaged = 5
;RecoveryTime = 5000
End

Behavior = AIUpdateInterface ModuleTag_03
AutoAcquireEnemiesWhenIdle = Yes ATTACK_BUILDINGS
MoodAttackCheckRate = 500
AILuaEventsList = MordorFighterFunctions
AttackPriority = AttackPriority_Infantry
End

RadarPriority = UNIT Tells us this unit will show up as a unit on the radar map, not a structure or hero.
KindOf = Tells us how the computer should view this unit. This should be considered infantry, be selectable, pass through each other, and such.

Body = ActiveBody moduletag gives the unit life. MaxHealth is referenced right from the gamedata.ini, though you can just place a number here. That is accepted.

Behavior = AIUpdateInterface This open up the doors for letting the AI use this unit. Tells the AI abit about the unit and how it should behave.

LocomotorSet
Locomotor = HumanLocomotor
Condition = SET_NORMAL
Speed = 32
End


Locomotors tell the computer how fast or how agile a unit is. It is defined in locomotor.ini located in /data/ini/locomotor.ini You may add other locomotors based on condition states such as upgraded, veterency, so on.

The next part of the unit code is behaviors. Most flexible of the code and the most powerful. Sarumon cannot cast fireballs without a behavior being in his code to allow him to do this.

              
Code
;;; FIRE BALL SPECIAL POWER ;;;
Behavior = UnpauseSpecialPowerUpgrade ModuleTag_FireballEnabler
SpecialPowerTemplate = SpecialAbilitySarumanFireball
TriggeredBy = Upgrade_SarumanFireBall
End


Nor can units recieve upgrades without some code here to support it.

              
Code
Behavior = SubObjectsUpgrade Armor_Upgrade
TriggeredBy = Upgrade_GondorHeavyArmor
UpgradeTexture = GUManAtArms.tga 0 GUManAtArms_HA.tga
RecolorHouse = Yes
ExcludeSubobjects = Forged_Blade
End


Heroes need to be respawned, but they won't know that without having the code to support it.

              
Code
Behavior = RespawnUpdate ModuleTag_RespawnUpdate
DeathAnim = DYING
;DeathAnim = STUNNED ;Model condition to play when killed-to-respawn
DeathFX = FX_SarumanDieToRespawn ;FXList to play when killed-to-respawn
DeathAnimationTime = 5500 ;1133 ;How long DeathAnim will take.
InitialSpawnFX = FX_SarumanInitialSpawn
RespawnAnim = LEVELED ;Animation to play when respawning.
RespawnFX = FX_SarumanRespawn ;FXList to play when respawning.
RespawnAnimationTime = 2000 ;Time it takes for respawn to play.
AutoRespawnAtObjectFilter = NONE +CASTLE_KEEP ;Respawn at this location -- and at it's exit production point if possible.
ButtonImage = HISaruman

;RespawnEntries determine the ruleset for how a character can be revived. Some units may automatically respawn, others
;may require a specific revive action performed on him. You can specify different values for each level... or use Level:Any
RespawnRules = AutoSpawn:No Cost:1200 Time:120000 Health:100% ;DEFAULT VALUES
RespawnEntry = Level:2 Cost:1400 Time:120000 ;For other levels, only override what is different.
RespawnEntry = Level:3 Cost:1600 Time:120000
RespawnEntry = Level:4 Cost:1800 Time:120000
RespawnEntry = Level:5 Cost:2000 Time:180000
RespawnEntry = Level:6 Cost:2200 Time:180000
RespawnEntry = Level:7 Cost:2400 Time:180000
RespawnEntry = Level:8 Cost:2600 Time:180000
RespawnEntry = Level:9 Cost:2800 Time:180000
RespawnEntry = Level:10 Cost:3000 Time:180000
End


Some units can auto heal based on this behavior:

              
Code
Behavior = AutoHealBehavior ModuleTag_SarumanHealing
StartsActive = Yes
HealingAmount = HERO_HEAL_AMOUNT
HealingDelay = 1000
StartHealingDelay = HERO_HEAL_DELAY
HealOnlyIfNotInCombat = Yes
End


Behaviors do so much more than I can begin to explain here. They are the backbone of all the special abilites of units. So I'll end that part here. The last part I'll finish with is geometry.

              
Code
Geometry = CYLINDER
GeometryMajorRadius = 8.0
GeometryMinorRadius = 8.0
GeometryHeight = 19.2
GeometryIsSmall = Yes
Shadow = SHADOW_DECAL
ShadowSizeX = 11;
ShadowSizeY = 11;
ShadowTexture = ShadowI;


The model, believe it or not, has limited uses other than showing the player what is happening. The geometry of the unit tells the computer the size of the area that this unit actually makes up. This is what the game factors really use when determining how close one unit is to another.

That finishes up the object code. Once this is complete to your liking than you have to add a commandbutton to build it and the command buttons to upgrade the unit and any other command buttons such as activating a spell and such.

These command buttons are than added to the units commandset and the command button used to build the unit is than added to the structure that you would like to have build this unit. You must really look at the existing units to get a good grasp of just how all this fits together. See Command Button Tutorial.

I hope this answers a few questions regarding the object code for your new unit. Any further questions about this tutorial can be answered by coming to our forums.

Credits

GothmogtheOrcporting the tutorial to the new site

Comments

Display order: Newest first

memocarvajal - Thursday December 6, 2012 - 18:21

you can make a video of each step to create a unit if possible friend
tell me your facebook and msm for your best friend to tell me
I speak Spanish but I understand English not worry about it

please help me because friend and tried many times to create a unit and not succeeded and please help me friend

--------

Friend you also have noticed that in BFME2 troops can form freely if possible friend I would also like to explain to me why porfabor friend thanks

Emperor of the East - Friday November 20, 2009 - 23:30

I am trying to make new units out of existing files for my Men of the East faction and my Rohan faction, and this is getting to be confusing due to the differences between these guidelines and the units I downloaded off of here.

Akhôrahil - Friday August 24, 2007 - 18:00

It's a article that tells you how to add new units, not new skins.

Ultama - Sunday August 19, 2007 - 9:56

This really dosnt tell me about adding new skins to troops =/
How can i add new skins/Models to troops/exisiting troops (using Map.ini :D)

Go to top

 

"One site to rule them all, one site to find them,
one site to host them all, and on the network bind them."

 
11:58:30