ODF

Object Definition Files (ODFs) are text files that define the properties of every object in the game. All examples were included with the assets of the levels that shipped with the game. ODF files contain information that defines an object's presence in the editor as well as in the game. This page is from the BF2 Jedi Creation.doc and odf_guide.doc.

Important: If your text-editing application likes to insert curly quotes “” instead of straight quotes "", USE A DIFFERENT ONE. Curly quotes will break everything. We recommend Notepad, Ultraedit, or Notepad++; Microsoft Word and Wordpad are bad.

Structure

File Properties

At the top of every ODF are lines that look like this:

[GameObjectClass]
ClassLabel = "someclasslabel"
GeometryName = "somefilename.msh"

[Properties]

The [GameObjectClass] section defines the properties needed by Zeroedtor to view and manipulate the object.
ClassLabel refers to the object's functional class. This is for use in the game primarily, but in some cases it is used to expose an object's properties within the editor.
GeometryName is the mesh file reference that ultimately makes an object visible in the editor.
[Properties] is where the beginning of the in game properties are defined.
In addition to GameObjectClass there are other classes that are defined in ODFs that are not viewed in the editor. These include WeaponClass and ExplosionClass. These headers are applied to ODFs that are typically called by other ODFs as child objects. For example a weapon is always attached to a unit, vehicle, or building, and an explosion is always attached to a type of ordnance or an object.

ClassLabels

There are over 60 ClassLabels attached to objects in the game. A list of these can be found below but it should be noted that many of these are redundant.

animatedbuilding
animatedprop
armedbuilding
armedbuildingdynamic
beacon - used for orbital strike
beam - ordnance
binoculars
bolt - ordnance
building
bullet - ordnance
cannon - weapon
catapult - obsolete?
cloudcluster
commandarmedanimatedbuilding
commandhover - mobile command post
commandpost
commandwalker - mobile command post
destruct
destructablebuilding
detonator - obsolete?
disguise - weapon
dispenser - weapon
droid
dusteffect
emitterordnance
explosion
fatray
flyer - vehicle class
godray - lighting effect
grapplinghook
grapplinghookweapon

grasspatch
grenade
haywire
hologram
hover - vehicle class
launcher - weapon
leafpatch
Light
melee - weapon
mine
missile
powerupitem
prop
remote
repair
rumbleeffect
shell
shield
soldier
SoundAmbienceStatic - *
SoundAmbienceStreaming - *
sticky
towcable
towcableweapon
trap
vehiclepad - obsolete? **
vehiclespawn
walker - vehicle class
walkerdroid
water
weapon

* used to display speakers in editor when adding ambient emitters
** once used for LAAT-C to drop ATTEs

ODF Hierarchy

A hierarchy system in Battlefront II was used to keep commonly used functions within one ODF file. This benefit to this system is that it allowed for sweeping changes to be made to everything linked to this one file in one shot.

For instance, every faction’s rocket launcher class weapon was linked to a "parent" rocket launcher. This allowed for all of the rocket launcher classes to be balanced the same, for the most part, so there was no need to change how much damage each rocket would be able to inflict from one faction to another. Rather than giving each of the faction’s ODF files its own unique "MaxDamage" function, "MaxDamage" was instead placed within the parent file. If it were decided that rocket launcher classes were doing too little damage, this allowed one file to be changed rather than having to update four files. Since the parent was changed, everything that linked to the parent would change as well.

This how the rocket launcher example looks in the assets.

Go to … \data\Sides\imp folder.
Open up the ODF file: imp_weap_inf_rocket_launcher_ord.odf.
Notice up top, the "ClassParent" – you will find these commonly shared ("com") files in …\data\Sides\Common
Open up the ODF file: com_weap_inf_rocket_launcher_ord.odf.

Now that you have these two ODF files open side by side. Notice that the child file (imp_weap_inf_rocket_launcher_ord) only contains the information necessary to distinguish itself from another faction’s rocket ordnance – the trail effect ODF file, the color it displays, and the explosion ODF file it references. The rest of the functions you’ll find in the parent file (com_weap_inf_rocket_launcher_ord). All of these functions are shared between the four factions in SWBFII – Republic, CIS, Alliance, Imperial. If you make a change in this file, it will affect every rocket launcher class’ ordnance.

Let’s say you want one class to have a different "MaxDamage" than another class. Keep this in mind; any function put into the child file will overwrite the function in the parent file. It won’t overwrite it for everything it’s linked to, just the child file you placed "MaxDamage" in. So, if you wanted to make the Imperial rocket launcher’s damage value different than everyone else’s, add the function "MaxDamage" to imp_weap_inf_rocket_launcher_ord and change the value to whatever number you’d like it to be.
Let’s throw out another example, a bit more complicated.

Go to your … \data\Sides\rep folder.
Open up the ODF file: rep_inf_rifleman.odf.

Notice its "ClassParent", rep_inf_default_rifleman.odf. We separated the two files to allow two people to edit various aspects of the Republic assault trooper without stepping on each others toes. The rep_inf_rifleman file adjusts the visual properties of the soldier; the armor he wears, etc., while rep_inf_default_rifleman allows someone else to adjust the weapon properties. In this case, rep_inf_default_rifleman is the parent which is found in the same folder. Parent files don’t have to be within a specific folder, they just need to exist within the data directory. In this case, it’s not found within the Common folder because this particular hierarchy has four steps.

The file it links to next, rep_inf_default.odf, is also found within the same folder. All of the default Republic ODF infantry files (these files control the weapon loadouts for each class) can share several of the same functions. The ones that need to be unique are found within each of the specific unit’s ODF file. The ones that can be shared among them will be found in rep_inf_default.

Since a lot of the Republic soldiers share similar properties (most notably sounds, animations, etc.), it made sense to group them up into a single parent file. Notice though, within this parent file, there is a link to yet another parent file. This file links to the data\Common folder (not the data\Sides\Common folder), where you’ll find com_inf_default.odf.

We did this for the same reason we did it to the rocket launcher files. All of the infantrymen have similar properties. They fire the same types of weapons (not visually, but rather numerically they are similar), have the same range, move at the same speed, etc. There’s no need to copy and paste all of this information multiple times.

Parent files were a great help to us as we developed SWBFII, and we hope they’ll help you get your own mods up and running faster as well. If you have a hard time tracking down a parent file, just run a search for it in the data directory.

Vehicle ODF Files

Note that vehicles can change from one to another. Some have multiple seating, some are hovers, some walk, others fly, and some have unique abilities. It would take a book to give you an idea of how to get every one of them working, so let’s just start with something simple and hopefully you can take it from there.

Let’s use the CIS Snailtank for our example.

Go to …\data\Sides\cis\odf
Open: cis_tread_snailtank.odf

ClassLabel

The type of vehicle this is. This is used to determine whether or not it’s a walker, a hover, a flyer, etc. This definition is important since various vehicles have properties the other type won't. For instance, imperial walkers, along with any other walker vehicle, rely heavily on animations. Hovers can get over obstacles other ground based vehicles can’t. Flyers can… well, fly. Changing the ClassLabel will cause you problems if you don’t add in the necessary functions to make the new ClassLabel work.

GeometryName

This is the actual mesh that’s being called in through the ODF.

VehicleType

This plays into the collision system and how the vehicle will interact with the world.

ReserveOneForPlayer

Determines whether or not an AI unit can jump into the vehicle.

MapTexture, HealthTexture

The 2D image displayed on your HUD.

VehiclePosition

Where the player’s character will sit once they’ve entered the vehicle.

MapScale

How close you are zoomed in to the mini-map.

Explosion, ExplosionCritical, ExplosionDestruct

Various states of destruction. You will call the appropriate ODF file depending on the cause of “death” to the vehicle.

FirstPersonFOV

What your frame of view will be when seated inside the vehicle.

CockpitTension, CollisionScale, CollisionThreshold

Various functions that deal with the vehicle’s collision against other vehicles, objects, etc.

MaxHealth

The vehicle’s maximum health value.

HealthType

This determines whether it can be healed by a fusion cutter or not, and other conditions.

HitLocation

The location of its critical hit point. The number at the end determines its multiplier. For instance, the “4” means this location causes 4x the normal damage.

TimeRequiredToEject

How long it will take to hack someone out of the vehicle.

EjectResistance

The higher this resistance it, the more it opposes the the hacking attempt, thus making the TimeRequiredToEject higher and regenerate back to full quicker.

TimeTilReboard

After the person is hacked out, how long it takes for anyone to be allowed to re-enter the vehicle.

SetAltitude, GravityScale, LiftSpring, LiftDamp

These adjust the hover proerties of the vehicle and how they collide with the world.

Acceleration, Deceleration, Traction, ForwardSpeed, ReverseSpeed, StrafeSpeed

Adjust the speed values of the vehicle in its various states of movement.

FloatsOnWater

Whether or not it can float on water as a hover vehicle type.

EnergyBar, EnergyOverheat, EnergyAutoRestore, EnergyBoostDrain, BoostSpeed, BoostAcceleration, BoostFOV

These values adjust the vehicle’s energy, and how quickly it uses this value, regenerates it, boost speed and the frame of view when boosting.

From AddSpringBody down to OmegaZDamp

These values play into where the “collision spheres” are located on the hover vehicle. Hovers use a procedurally created collision system, which are simply spheres placed at different X,Y, Z coordinates of the vehicle.

SpinRate, TurnRate, TurnFilter, PitchRate, LevelSpring, LevelDamp

These affect the control of the vehicle through a peripheral, such as a mouse, joystick, etc.

EyePointOffset, TrackCenter, TrackOffset, TiltValue, NormalDirection

Camera placement parameters that use an X, Y, Z orientation system.

PitchLimits, YawLimits

The limitations of how far the camera can pitch or yaw until it hits a “wall”.

WHEELSECTION

This section controls the Snailtanks’s tread animation.

WEAPONSECTION

A vehicle can have two weapon sections. Each will call its own weapon ODF file and have its own properties. These properties will control where the ordnance is firing from, how many guns there are that fire the ordnance, the ammo count, etc.

FLYERSECTION

NOTE that the Snailtank doesn’t have a FLYERSECTION since it’s a one-man vehicle. Untrue to its name, any vehicle that can support a passenger has a FLYERSECTION. These use functions found through the regular vehicle’s ODF file, so check out a vehicle (such as the CIS’s AAT, the Imperial AT-ST, etc.) that has multiple positions for an example on how it’s set up.

WakeEffect

The water animation played when the vehicle is touching water.

CHUNKSECTION

These sections define the vehicle when it has exploded. They determine what geometry is used, how they will disperse, etc.

AISizeType

This plays into the collision system and how the vehicle will interact with the world.

DamageStartPercent, DamageStopPercent, DamageEffect, DamageAttachPoint

The damage effects played at various health levels of the vehicle.

EngineSound down to FoleyFXGroup

Will manipulate the sounds the vehicles will use, the music you’ll hear and the sound effects that can play while inside them.

Infantry ODF Files

Infantry units use a lot of the hierarchy system we’ve set up for SWBFII. Bear with me as we jump through them all.

Let’s use the CIS Battledroid for our example.

Go to …\data\Sides\cis\odf
Open: cis_inf_rifleman.odf

This odf file specifically deals with the way our infantry unit will look. These functions will call in the mesh to be used, the type of unit it is, and where its head collision is found (used for critical headshots). This file is pretty straightforward.

Let’s move to the next file.

Go to …\data\Sides\cis\odf
Open: cis_inf_default_rifleman.odf

This is where the weapons are found and specific class VO (voice over sounds) functions are found. From here it links to specific weapon ODF files and the specific VO used when the player uses his F-key shortcuts.

After that we move to another parent file.

Go to …\data\Sides\cis\odf
Open: cis_inf_default.odf

Here’s a file that’s shared among the CIS infantry units. This section is mainly reserved to call the CHUNKSECTION (explosion effects) and universal sounds each of the CIS infantry units will make. Changing something here will change the properties in all of the CIS infantry units.

Last, but not least, we have our last file.

Go to …\data\Common\odfs
Open: com_inf_default.odf

This file covers all of the infantry units (minus ones like the Droideka, which is a completely different entity and much more like a vehicle). Changing something here will change every infantry unit. You’ll be able to control their speeds when running, strafing and crouching, the camera at these different positions, the energy they have and the energy cost for various abilities. It will also affect the drop rate of the health, ammo and special canisters, and what will drop from them. Most of the function names are self-explanatory, and others share the same properties as the ones found in the Vehicle ODF documentation.

Note: Assets and ".option" files:

For soldiers’ purposes, "assets" are models or textures, and they are generally placed in the "MSH" directory. Each asset can have an associated ".option" file – for example, if I have test.msh, then I can create test.msh.option as well. Option files are simply text files that contain various parameters to direct the munge process to treat those assets differently. For example, a MSH option file can contain "-nocollision", which will cause the munger not to generate collision for that mesh, or a TGA option file can contain "-maps 1" to direct the engine never to use a less-detailed mipmap for that texture. Soldier MSHs generally do have "-nocollision", and soldier TGAs generally do have "-maps 1", but there are many other parameters that option files can provide. These are covered in the .option File Parameters page.

For a typical soldier, there is:
- A character model and texture – for example all_inf_tatooinelukeskywalker.msh and .tga.
- A lowres model - all_inf_tatooinelukeskywalker_low1.msh and .tga.
- And any other models and textures needed (for example, lightsaber model and texture).

These assets are all placed in the MSH directory and are reference by the soldier’s ODF, and various ODFs for weapons and other things.

Creating an ODF

A blank ODF file is created by creating a new text document and naming it [object].odf. For the example, I'll call this jdi_demojedi.odf since demojedi is the name of the unit and jdi is the name of the side.

So, now we’ve got a blank ODF and we want to create a Jedi from it. MUCH of this section is going to assume you already have a model and texture and animations created, because creating those is outside the scope of this document. If you need, for learning purposes, feel free to “borrow” models and animations and things from one of the shipped game’s sides. Personally I like the Wampa, but for a more human feel we’re going to use Tatooine Luke (who was made, but never appeared in the game, unfortunately).

Note: For lots of things, there are Jet parameters. The only difference between a Jedi and a Jet Trooper (or Dark Trooper) is that a Jedi has a lightsaber as a weapon. If your soldier has a lightsaber, they will force-jump or Vader-style hover. If not, they will Dark- or Jet-Trooper-style jet-jump or hover. There is no way around this, although you can control the action type (jump vs. hover) and you can provide a different animation for each one.

A Jedi ODF generally looks like this, the comments come before the code the reference.

Any text following two slashes is a comment the section following [GameObjectClass] is for MUST include ClassParent, which is used by Battlefront 2 to determine which class this soldier derives from. Alternately to ClassParent, you may use ClassLabel = "soldier" however, the ODF for “com_jedi_default” sets up values we like, so we leave this class deriving from it.

[GameObjectClass]
ClassParent = "com_jedi_default"

The Properties section defines everything else about the soldier

[Properties]

Which type of connections this soldier will follow on the AI path graph for the level
- soldiers are generally “SOLDIER”, but
- those that can jet, jetjump, or forcejump are “HOVER”

AISizeType = "HOVER"

Don't take damage from collisions with objects in the world

CollisionScale      = "0.0 0.0 0.0" // x, y, then z scales

The model (filename ends in .msh, and is located in the // MSH folder) to use for our character
NOTE: Omit the .msh from the name!

GeometryName = "all_inf_tatooinelukeskywalker"

The model to use for our character when he is far away (Generally this model is cheaper to render). If this line is not present the model will disappear when viewed from far away, and this geometry CANNOT be the same file as the high-res geometry!

GeometryLowRes = "all_inf_tatooinelukeskywalker_low1"

The next line can be one of 3 choices:
- Not included (blank), if the model wants to use the “human_sabre” skeleton and animations. (Those are Luke Skywalker’s animations, but we will be defining our own so we are going to use this line anyway).
- AnimationName if this model uses the basic human skeleton, but wants to provide its own animations as a set of files in the “munged” folder.
- SkeletonName if this model wants to use its own skeleton in addition to its own animations.

NOTE – if this model’s animation set does not define an animation, such as “stand_walkforward”, the default animation from the current weapon will be used instead. For example, if he is carrying a rifle, it will use human_rifle_stand_walkforward, and if he is carrying a lightsaber it will use human_sabre_stand_walkforward. For specialized additional animations such as melee attacks, they MUST be defined by this model’s animation set.

For the demo, we will be using the base skeleton but redefining SOME of the animations.

AnimationName = "tat_luke"

There may also optionally be a SkeletonNameLowRes or an AnimationNameLowRes if the low-res animations are different from the high-res ones…

The following lines are the default Jedi parameters. They are fairly straightforward and usually not changed, so mess with them if you see fit. Force Jump ignores the Jet numbers and just uses the Jump numbers, but they still must be defined.

The initial jump-push given when enabling the jet

JetJump = "10.0"

The constant push given while the jet is enabled (20 is gravity)
JetPush = "0.0"

For characters with jet jump, use this acceleration for in-air control
JetAcceleration = "10.0"

The particle effect to show while jetting
JetEffect = ""

Additional fuel per second (fuel is 0 to 1)
JetFuelRechargeRate = "0.0"

Optional, tells this character to hover (Darth Vader, Jet Trooper) versus jump (Luke Skywalker, Dark Trooper)

//JetType = "hover"

Vader used JetFuel to control how long he can hover, even though it's not visible in the HUD

Cost per second when hovering (only used for jet-hovers) (fuel is 0 to 1)

JetFuelCost = "0.0"

Initial cost when jet jumping(fuel is 0 to 1)
JetFuelInitialCost = "0.0"

Minimum fuel to perform a jet jump(fuel is 0 to 1)
JetFuelMinBorder = "0.0"

Display the meter for jet fuel, or don’t display it
JetShowHud = 0

How much Sprint energy to take away per jet activation or force-jump
JetEnergyDrain = 40.0

The foley effects to use when walking around, falling, rolling, etc. Generally this doesn’t deviate from rep_inf_soldier, cis_inf_soldier, all_inf_soldier, imp_inf_soldier, or wok_inf_soldier (for Wookiees).

FoleyFXClass = "rep_inf_soldier"

We are skipping the rest of the sound section (grunts, groans, hero voiceovers) for this guide.

Tentacles and cloth go here, if any… (see below for an explanation of these lines)

ClothODF = “all_inf_tatooinelukeskywalker_cloth”

Now for weapons – you can have up to 8 different weapons. Each one is defined in a WEAPONSECTION. Parameters include:
- WeaponName – the name of the ODF that defines it. This ODF can come from common, sides/common, or the side itself. It can also come from a different side, but only if that side is loaded before this soldier in your mission LUA. Otherwise, BF2 will crash.
- WeaponAmmo – max number of ammo clips this weapon holds. It will start with this much ammo. Zero is infinite ammo, used for lightsabers and force powers and such. (The amount of Sprint energy a weapon drains, and how much ammo is actually in each clip are defined in the weapon’s ODF.)
- WeaponChannel = 1 optional line, this line indicates that the weapon is part of the secondary line of weapons (i.e. thermal detonators, force powers). It will be activated by the Secondary Fire button or the Force Power button, and the character will never be shown carrying it, only using it.

NOTE: “Bonus” weapons are equipped below as well, they lock or unlock themselves based upon Medal-status values set in the weapon’s ODF.

WEAPONSECTION = 1
WeaponName = "jdi_weap_demo_saber"
WeaponAmmo = 0

WEAPONSECTION = 2
WeaponName = "com_weap_inf_force_push"
WeaponAmmo = 0
WeaponChannel = 1

WEAPONSECTION = 3
WeaponName = "com_weap_inf_sabre_throw"
WeaponAmmo = 0
WeaponChannel = 1

This is the end of the ODF…

Note: If you want to test your Jedi, you can get rid of WeaponSections 2 and 3, and replace the weapon in WeaponSection 1 with “com_weap_inf_fusioncutter”, which is a weapon with no geometry or special things associated with it, that will enable your soldier to run around so you can see him.

Cloth

In Battlefront 2, cloth is a way to make a polygon mesh distort itself in real-time based on gravity and wind and things. In layman’s terms, it makes good looking skirts and capes. If your model has cloth on it, which our demo model does because Luke loves his skirt, then you will need to do 2 things to enable that cloth. (If you don’t enable it, it will not appear in-game at all.)

In the cloth ODF

You need to create a cloth ODF for the cloth, in the ODFs directory. The ODF name is simply the name of the cloth piece with “.odf” appended – in our case, “all_inf_tatooinelukeskywalker_cloth.odf”. Inside, you will find…

Top section, same as any other ODF

[GameObjectClass]

this is cloth, so…

ClassLabel          = "cloth"

properties section – small for cloth

[Properties]

This tells us the name of the model that the cloth piece is attached to. In our case, “all_inf_tatooinelukeskywalker”

AttachedMesh = "all_inf_tatooinelukeskywalker"

In our soldier’s ODF

You need to tell it that it uses this cloth ODF, which gives us this line in our ODF above:

ClothODF = “all_inf_tatooinelukeskywalker_cloth”

And that’s it! Assuming your artist did the right thing and attached the cloth where it needed to be, as well as put in cloth collision for it (XSI primitives in the .msh, named c_whateverNameIWant) it should function.

Note: A soldier may have as many cloth ODFs as you wish – each one simply needs to be referenced. One ODF must be created per cloth piece on the model, and they can each have different properties.

list of optional cloth parameters

There are other properties that you may have in a cloth ODF – we have rarely had occasion to use them, but they are:
(Note that [parameter] means a number, like 20.4, not [20.4])

Angle of the wind, phi and theta

WindDirection = “[angle1 in degrees] [angle2 in degrees]”

Wind speed, in m/s

WindSpeed = [speed]

Dampening coefficient – in some unit or other :^) Default is 0.5

Dampening = [number]

Drag coefficient, also in some unit – default is -2.0

Drag = [number]

Mass of each cloth “particle” (in Kg?) – default is 1.0

ParticleMass = [number]

Maximum world acceleration, in m/s/s – default is 20

MaxAcceleration = [number]

Priority – cloth with lower priority is skipped if not enough time is left this frame – used for the Emperor; Default is 0

Priority = [number]

Does this cloth have an alpha channel? 1 or 0, Default is 0

Transparent = [value]

BF2 has 3 different types of constraints it satisfies each frame when computing the cloth:
- “Bend” constraints keep the cloth’s shape.
- “Stretch” constraints keep the cloth’s size.
- “Cross” constraints keep individual pieces of cloth from shearing.
You can turn these on or off individually by specifying a zero for the constraint. For example, if you turn off “stretch” constraints the cloth can grow longer or shorter…

CrossConstraint = [zero or one]
BendConstraint = [zero or one]
StretchConstraint = [zero or one]

Tentacles

Well, “tentacles” is a misnomer. Technically, what these are is bones that are animated by the game engine (not the animator) according to physics and the model’s movement. They can be used for hair (as on the Wookiee Warrior) or pouches that move (as on Chewbacca) or anything else you like…they can even be used to animate weapons.
Unfortunately, Luke is a plain old human, and he isn’t too fond of hippie hairdos or long belts, so there are no tentacles in this example. But I will explain how they work, and encourage a look at the Wookiee Warrior or Ms. Secura as an edifying example. Actual implementation is left as an exercise for the reader.
Tentacles are pretty simple, really. The artist needs to include bones named bone_string1 through bone_string# (maximum is 45) and make sure they are in the base pose and properly parented to each other. Then you need to tweak the soldier’s ODF slightly:

Straight from rep_hero_aalya.odf we have:

NumTentacles * BonesPerTentacle = total bones, bone_string1 to N
Note that the max tentacles is 9, and the max bones per tentacle is 5. However if you have one long tentacle, as long as the bone number ends up correct, that’s okay too. So a 12-bone tentacle can be done as 4 3-bone tentacles and it will work fine.

NumTentacles        = "2"
BonesPerTentacle    = "3"

TentacleCollType specifies which type of auto-generated collision the game should use. 0 is the one that works best, which is sideways rectangular box centered around the shoulders. 1 and 2 are never used, but they are a sphere and a cylinder, respectively. Good luck with that.

TentacleCollType    = "0"

Melee Class

Remember the line:

WeaponName = "jdi_weap_demo_saber"

from our Jedi’s ODF? Well, the other two weapons – com_weap_inf_sabre_throw and com_weap_inf_force_push - found in sides/common already exist, but now we have to make our Jedi’s main weapon.
First thing you have to do is create the ODF, in our case jdi_weap_demo_saber.odf in ODFs folder. You also need to place the geometry (.msh) for the handle into the MSH folder. It is possible to create a lightsaber just attached to the character’s bone, with no extra geometry, Darth Maul does this, and it is explained below, but a .msh is the best. For the Wampa and the Acklay, extra invisible lightsabre geometry was actually created to guarantee the blade goes the correct direction, so we’ll assume you have geometry. Different geometry is required for each hand (for example, Aayla Secura has two) since the blades go different ways, and the geometry must contain a hard point (called hp_whatever) that you reference to determine where the blade comes from. If there are to be multiple blades, then there must be multiple hardpoints, because two blades coming from the same point of the same geometry will be considered the same blade.
In the case of this demo, I’ll be stealing Luke’s saber from the Alliance side, so I swiped all_weap_inf_lightsabre.msh and all_weap_inf_lightsabre.msh.option and put them into our MSH folder. I also swiped the blade’s texture, greenlightsabre.tga and greenlightsabre.tga.option.

[WeaponClass]
This is always “melee” for a lightsaber
ClassLabel          = "melee"
ClassParent            = "com_weap_inf_lightsaber"

[Properties]

Three parameters here:
- First, the parent animation bank – usually “human_sabre” – this is where any animation that we didn’t override will be taken from.
- Second, the parent weapon class – this is ALWAYS “melee”.
- Third, the name of the combo file without the “.combo”.

ComboAnimationBank    = "human_sabre melee jdi_demojedi"

If the weapon has an explosion associated with it, like Mace Windu's or the Wampa's, this is the name.
In our case, there is an explosion just to demonstrate how to use one. Explosions are specified in ODFs – in our case, it’s in jdi_demojedi_exp.odf.

ExplosionName = "jdi_demojedi_exp"

How many blades – up to 4.

NumDamageEdges = 1

From here on, everything is divided up, and the information for each blade is given separately. We only have one blade, but
I will put in a second section that is commented out, just for show.

The sabre’s handle. We are terribly inconsistent with saber/sabre.

GeometryName        = "all_weap_inf_lightsabre"

The hardpoint in the geometry that the blade comes out from.

FirePointName       = "hp_fire"

Note: FirePointName can be replaced with OffhandFirePointName. What’s the difference? FirePointName means that this geometry is attached to hp_weapons on the model. OffhandFirePointName takes an extra parameter, which is which hard point or bone to attach this weapon to. The first argument is still the hard point in the weapon from which the blade emanates. For example, the line we used is the same as: OffhandFirePointName = “hp_fire hp_weapons”

How long and how wide, in meters, the blade is.

LightSaberLength    = "1.0"
LightSaberWidth        = "0.25"

Optional. Which texture to use, from the MSH folder, for the blade. Note that it is not required for the blade to have a texture, in which case all you will get is damage, like for the Wampa.

LightSaberTexture     = "greenlightsabre"

Optional. In RGBA format, the color of the trail left by this edge. Edges only leave trails when they can hit things / are attacking.

LightSaberTrailColor = "82 255 7 128"

One thing we did use is a blade with no texture, but a trail. This was, among other things, used for Kit Fisto’s punches and kicks. A blade with no texture and no trail was used for the Wampa and the Acklay – in fact, the Wampa has 3…

The texture to use as the glow effect around the saber. This is generally left unchanged, because com_weap_inf_lightsaber has a glow on it which is kept, but if we wish to get rid of the glow on our saber, we can specify “notexture”.

// LightSaberGlowTexture     = "notexture"

If we had more blades, we would repeat that section again for each blade. However, the 2nd, 3rd, and 4th weapons would use OffhandGeometryName in place of GeometryName (same argument though) and OffhandFirePointName.

Additionally, if you want two blades to be part of the same weapon, do not specify the OffhandGeometryName for the second blade, use GeometryName, just the OffhandFirePointName. See Darth Maul as an example.

And that’s the end of the ODF.
There’s also a way to make a blade without all that nonsense, and with a whole new set of nonsense. If you just want a blade to come off a character’s bone or hardpoint without creating your own geometry, you can do the following…please note that ONLY Darth Maul uses this, because he was one of the first Jedi created. This method is very difficult, and if you can, have an artist create your invisible handle instead.

Rather than saying GeometryName and FirePointName, you can simply use the following (“simply”, that is): AttachedFirePoint. The first parameter is the bone name. The next 3 are the X, Y, and Z components of the direction that the blade extends, in bone-local space. The last 3 are the X, Y, and Z offsets from the bone’s position, again in bone-local space. If you didn’t understand any of that, then this is NOT something you want to use.

Taken from Darth Maul. Create an edge extending from bone_l_calf down the X-axis of the bone, offset by 0.35 meters (the X-length of the bone, in this case).

AttachedFirePoint    = "bone_l_calf 1.0 0.0 0.0 0.35 0.0 0.0"

Collision

These are the default values for CollisionThreshold and CollisionScale:
CollisionThreshold = "10.0 3.0 0.0"
CollisionScale = "1.0 0.0 0.0"

If the impact velocity exceeds the collision threshold:
Damage = collision scale * (impact velocity - collision threshold) ^ 2

VehicleType = "light"

This plays into the collision system and how the vehicle will interact with the world. Specifically how a vehicle detects objects in the environment and reacts such as AI turning in time or moving around the object.

Options include:

  • fighter
  • transport
  • scout
  • remoteterminal
  • light
  • medium
  • heavy

Attached Effects

Full Section: Attaching an Effect

AttachDynamic = “1”

AttachOdf = “<odf_name>”
AttachToHardpoint = “<hardpoint_name>”

AttachEffect = “<fx_name>”
AttachToHardpoint = “<hardpoint_name> [respawn_delay_min] [_max]”
Unless otherwise stated, the content of this page is licensed under Creative Commons Attribution-NonCommercial-ShareAlike 3.0 License