Aircraft Model

By Unknown

This tutorial is intended to give modellers an overview of the process of creating art assets for BF1942, and more specifically, a working aircraft. The aircraft I chose to model is the Boulton Paul Defiant, an aircraft that in all reality was heavy, underpowered, easily exploited and used in a limited capacity during WW2 before it was given a new lease on life as a target tug.

But that's beside the point. In an ideal world, ie BF1942, it becomes a formidable weapon with it's 4 Browning .303 Machine guns with the ability to attack all 360 degrees within a limited elevation above the plane. But without further ado, on to the tutorial

Recipe for Disaster

You will need:

Before you start with any form of model tinkering, first thing you'll have to do is extract the entire contents of standardMesh.RFA, texture.RFA, and objects.RFA, all into your root BF1942 folder. Once you've done this, rename the RFA files so the game won't find them and look for the uncompressed data files.

Second up, put Rexman's scripts into the right place. Usually /3dsmax/scripts, and create a directory on your C: called "tmpmax" which is optional but very useful.

Das Modell

I'm not going to explain the process of modelling but I will give some pointers and guidelines for what you should be aiming toward.

I'm in the Import/Export Business

At this point, I'm assuming you've got a model all ready to go.

Note the orderly naming scheme, applied texture, and position. Position is of the utmost importance, because the origin works as the Centre of Gravity. My first export had the origin just above the landing gear, and it kept tipping forward if you tried to slow it down during a landing.

Now, if you haven't done so already, you'll need to save out individual files with the various components. Once you've done that, we start the exporting.


This is the main part of your model, and is the first thing you'll think about bundling up. Run Rexman's script and select the appropriate models. You want your main visible mesh to be the fuselage itself, the first collision box is your higher detail collision box, the second is the lower detail one. For the time being export with simple shaders, up to 6 LOD levels, and a Mat ID of 61. In a later tutorial we'll look at shaders and materials a little more in depth.

With any luck, the export should complete succesfully. (if not check out Rexman's FAQ for a little bit of troubleshooting, or post here on the forums)


We'll start our moving parts export with what is probably the simplest. Open up the file that contains your elevators. You can export them as a single object if you'd like as they are both going to move in unison, but I exported them as separate objects just because that's how my mind decided to rationalise them.

Now, take a look at their position. You'll want to write it down somewhere. The easiest way to do this for Max 4 and 5 users is to look just below your viewports at this:

Or you can do it the old school way by either right-clicking your Move tool button or hitting F12 to bring up the Transform Type-In dialogue:

IMPORTANT: BF1942 has differing axes to 3DSMax. X still corresponds to lateral horizontal movement (side to side) but Y corresponds to vertical and Z corresponds to longitudinal horizontal movement. So what that means to you, is switch your Y and Z values when you write them down. Now divide the values by 10, and we'll come back to them later.

Once you've written the position down, you can right click on the spinners to centre the object pivot point on the origin. Because you should have already moved you pivot points into the appropriate positions, when BF1942 rotates an object around the origin, it should all be correct as per your specifications.


With your Ailerons you basically want to do exactly as you've just done with the elevators, however, chances are, you want the rotation of your ailerons to be on a slight angle so they stay even with the wing.

As a (slightly exaggerated) example, take a look at what happens if the ailerons of my Defiant are rotated along a cardinal axis:

Obviously that's going to look a little funky in game, so let's rotate the aileron itself so it lines up with an axis, but make sure you take note of exactly how far you rotate it and write it down with the position co-ordinates. You should end up with something like this:


Now for whatever reason, you can't seem to execute a ObjectTemplate.setInputToPitch function for a Wing object. More on this later, but for the time being, take my word regarding the rudder.

Do as above, writing down the co-ords and centring the rudder to the origin, and now rotate it 90 degrees along Max's Z-axis so it looks something like:

Landing Gear

I found for simplicities sake it was best to have the landing gear in it's extended position for export, although you will have to take notice of how far it need to rotate in order to retract.

The Rest

And here's where I hand it over to you, because from the above you should know all you need to know about exporting bits and pieces to be rotational. The landing gear, propeller, turrets, guns and anything else you have all abide by the same sort of guidelines as above. To reiterate:

.CONstruction in Progress

Now we start with our .CON files which tell the engine how the plane behaves and fits together. The first thing we have to do is point the engine to our geometry that we've just exported, so copy all the .SM and .RS files from your C:\tmpmax\standardmesh folder into .\standardmesh\ in your BF1942 folder.

Now go to .\objects\vehicles\air\ and create a folder for your aircraft. Mine is called "Defiant" In that folder create a text file and rename it to "Geometries.CON", open it up and make with the bits and pieces.

Each piece of mesh needs to have a Geometry Template created, and you can do so with the following functions:

GeometryTemplate.create StandardMesh [GeometryName]  GeometryTemplate.file [FileName]

...where [GeometryName] is the name you are going to use to reference the Geometry Template you are creating, and [FileName] is the name of the .SM file you wish to use, minus the .SM extension. So for example:

GeometryTemplate.create StandardMesh Defiant_Fuselage  GeometryTemplate.file Defiant_Fuselage

The next thing you'll want to add are the LOD distances for that object. Something like:

GeometryTemplate.setLodDistance 0 0  GeometryTemplate.setLodDistance 1 10  GeometryTemplate.setLodDistance 2 15  GeometryTemplate.setLodDistance 3 30  GeometryTemplate.setLodDistance 4 50  GeometryTemplate.setLodDistance 5 100

...but the values can be whatever you want. The above example is a fairly steepish falloff, and is ideal for objects with lots of polys like the fuselage, but you might want a smooth progression for objects that are already fairly simple, such as ailerons.

For objects that should cast shadows (currently unsupported by the export tools) you can add:

GeometryTemplate.hasDynamicShadow 1

...and for most aircraft this is the fuselage only. Considering it makes up most of the aircraft, theres not much point in the performance hit that all objects casting shadows would cause.

Here's the Geometries.con file for my Defiant as a text file for your perusal.

.CONcentrate Now

...because this is where it starts to require a bit more attention. We're going to do this bit by bit, and the first thing you have to do is create an Objects.con file. Open it up, and let's get into it.

First of all all vehicles need to have at least one Player Control Object. This is how the player "interfaces" with a vehicle.

rem *** Defiant ***  ObjectTemplate.create PlayerControlObject [Vehicle]

...where [Vehicle] is the name of your vehicle. Mine will eventually be Defiant, but to make it possible for me to see and use my plane without any map editing, I'm replacing the AichiVal, so my line reads "ObjectTemplate.create PlayerControlObject AichiVal".

ObjectTemplate.setNetworkableInfo AichiVal_body_info

I'm ignoring this line for the time being, as the aircraft is not networkable until we get mod support from DICE, so I've copied the Network.con file from the AichiVal, and I am using it's NetworkableInfo.

ObjectTemplate.saveInSeparateFile 1

Not entirely sure what this does, but it's a good idea to add it.

objectTemplate.cullRadiusScale 5

This scales the LODing of the object. The values you have in the Geometries.con file are affected by a factor of 5. I haven't done any tests, but I assume this to mean multiplied by 5.

ObjectTemplate.hasMobilePhysics 1  ObjectTemplate.hasCollisionPhysics 1  ObjectTemplate.hasResponsePhysics 1

You obviously want your aircraft to move, collide and respond to controls, so add these three lines.

ObjectTemplate.hasDynamicShadow 1

This seems a little redundant with shadows also being specified according to individual geometry templates, but throw it in.

ObjectTemplate.drag 0.65  ObjectTemplate.mass 3500  ObjectTemplate.inertiaModifier 1.02/0.855/0.922

Some more physics values.

ObjectTemplate.explosionRadius 8  ObjectTemplate.explosionDamage 5  ObjectTemplate.explosionForceMod 15

When your vehicle is destroyed, and let's face it, it's likely to happen repeatedly, it blows up in a ball of flame. You can specify the degree of damage and the size of the explosion, and also how far it's likely to throw any nearby objects.

ObjectTemplate.angleMod 1  ObjectTemplate.speedMod 2

Haven't experimented with these at all.

ObjectTemplate.hasArmor 1  ObjectTemplate.hitpoints 130  ObjectTemplate.maxHitpoints 130  ObjectTemplate.material 60

Most aircraft have armour, so it's a good idea. Not sure of the effects of not having armour, but it's liekyl that it affects the pilot when damage is taken. Hitpoints are pretty self-explanatory, and the material affects sprite effects when bullets strike, and possibly armour, but I haven't experimented.

ObjectTemplate.criticalDamage 20  ObjectTemplate.hpLostWhileCriticalDamage 1.5

I'm fairly sure this is a percentile chance, and also the modifier should that critical chance come into play. Adds a little spice to the battle.

ObjectTemplate.hpLostWhileUpSideDown 10  ObjectTemplate.damageFromWater 1  ObjectTemplate.hpLostWhileDamageFromWater 10

Upside down constitutes being at rest (on land or water) and being upside down, being airborne will not affect it. If the plane is non-amphibious then it should take damage from water, obviously aircraft like the Catalina shouldn't take damage.

ObjectTemplate.addArmorEffect 65 em_AichiValDamage 0/0.102/2.11  ObjectTemplate.addArmorEffect 65 em_PlaneDamage 0/-0.303/2.21  ObjectTemplate.addArmorEffect 20 e_AichiValFire 0/1/2.11  ObjectTemplate.addArmorEffect 0 e_ExplGas 0/0/0  ObjectTemplate.addArmorEffect 0 e_ScrapMetal_AichiVal 0/0/0  ObjectTemplate.addArmorEffect -1 WaterWaterExplosion 0/0/0

When the HitPoint of the aircraft drop to a certain value, then certain effects are triggered. At half damage (65/130) it starts to smoke, at (20/130) it catches fire, and at 0 it explodes, spawning scrap metal and an explosion.

ObjectTemplate.aiTemplate AichiVal

I plan to delve into AI Scripts at a later date, but for the time being, the AI pilots can treat it as an Aichi Val.

ObjectTemplate.addTemplate lodDefiant

Very Important. This is where the engine decides what mesh(es) to render, and is created later in the .CON file.

ObjectTemplate.setSoldierExitLocation -2.8/0.203/-3.9 0/0/0

When the pilot exits the plane, he must be spawned at the apprpriate location. You can work this out in 3DSMax fairly easily. The second set of 3 values I haven't played with, but I'm assuming it's an angle vector.

ObjectTemplate.GUIIndex 27

This displays the little icon down in the bottom left corner, in this case the front seat position of an Aichi Val.

ObjectTemplate.setVehicleCategory VCAir  ObjectTemplate.setVehicleType VTFighter

Unsure how these affect the game, but I'm assuming it's something to do with spawn points.

And that's our control object. This will allow the player to get in and out and control the plane, but not by itself. There is yet much to learn.

rem *** lodDefiant ***  ObjectTemplate.create LodObject lodDefiant  ObjectTemplate.hasMobilePhysics 1  ObjectTemplate.hasCollisionPhysics 1  ObjectTemplate.hasResponsePhysics 1

ObjectTemplates are something you'll deal with a LOT. Here we're creating a LODObject, which enables LOD controls, and adds templates for the various model detail levels. Like it's parent it too has physics.

ObjectTemplate.addTemplate DefiantComplex  ObjectTemplate.addTemplate DefiantSimple  ObjectTemplate.addTemplate DefiantWreck

The three objects that may be displayed are listed here. The plane can either be the Complex bundle, (with moving parts and high detail mesh) the Simple object (a static, low-detail mesh) or the Wrecked version of the model. But how does it know which one to use? Because...

ObjectTemplate.lodSelector DefiantLodSelector

...all LODObjects should have a lodselector, which is specified below.

rem *** DefiantLodSelector ***  LodSelectorTemplate.create DistCompareSelector2 DefiantLodSelector  LodSelectorTemplate.hasDestroyedLod 1  LodSelectorTemplate.addLodDistance 200

Here we create the LodSelector template using DistCompareSelector2. Don't ask me about it, just take my word. The template has a destroyed version of the object, and a LodDistance of 200. I don't know for sure, but I'm fairly sure this takes the list specified in the LodObject (above) and treats the first added template as the highest detail and the last as the destroyed version, as it never explicitly specifies according to name.

rem *** DefiantComplex ***  ObjectTemplate.create Bundle DefiantComplex  ObjectTemplate.hasMobilePhysics 1  ObjectTemplate.hasCollisionPhysics 1  ObjectTemplate.hasResponsePhysics 1

Our next step is to create the Complex version of the aircraft, which must be a Bundle object to keep all the various bits of the model together. Note physics bools are all true again.

ObjectTemplate.addTemplate lodDefiantCockpit

Another LOD object we'll see later in the piece, this time to decide whether the player sees the fuselage of the plane, or the cockpit.

ObjectTemplate.addTemplate DefiantEngine  ObjectTemplate.setPosition 0/0.3/4

The engine, and what is going to get our plane moving. The object itself is in Physics.con and it will be further explained there. The position offset pertains to the propellor location.

ObjectTemplate.addTemplate DefiantCamera  ObjectTemplate.setPosition 0.011/0.963/0.75  ObjectTemplate.addTemplate DefiantEntry  ObjectTemplate.setPosition 0/0/0.25  ObjectTemplate.addTemplate DefiantSeat  ObjectTemplate.setPosition 0/-0.45/0.15

These three all pertain to the cockpit, the first is the internal Camera position, the second is the entry point object, which will put the player inside the plane when they use it within range and the third is the seat itself which spawns a pilot model sitting inside the plane. More on them later.

ObjectTemplate.addTemplate DefiantFlaps1  ObjectTemplate.addTemplate DefiantFlaps2

These two templates are contained within the Physics.con file, which we'll look at shortly.

ObjectTemplate.addTemplate DefiantBodyWing  ObjectTemplate.setPosition 0/0/0.35  ObjectTemplate.setRotation 0/0/-89.999

This is another physics object.

ObjectTemplate.addTemplate DefiantAileronLeft  ObjectTemplate.setPosition -4.143/-0.11/0.45  ObjectTemplate.setRotation 10/0/0  ObjectTemplate.addTemplate DefiantAileronRight  ObjectTemplate.setPosition 4.139/-0.09/0.45  ObjectTemplate.setRotation -10/0/0

The two Ailerons. Positioning taken from the Max coords written down earlier, and Rotation from the small rotation made to line up the ailerons with the axis. The actual objects are also in Physics.con

ObjectTemplate.addTemplate DefiantElevatorLeft  ObjectTemplate.setPosition -0.9/0.464/-4.335  ObjectTemplate.addTemplate DefiantElevatorRight  ObjectTemplate.setPosition 0.87/0.464/-4.335

The elevators, positions once again derived from Max coords, and the objects in Physics.con

ObjectTemplate.addTemplate DefiantRudder  ObjectTemplate.setPosition 0/0.85/-4.46  ObjectTemplate.setRotation 0/0/-90

The Rudder, positions once again derived from Max coords, and when we go through Physics.con, we'll see why we rotated the rudder model in max and then rotated it back again here.

ObjectTemplate.addTemplate DefiantWheelBack  ObjectTemplate.setPosition 0/-0.187/-3.95

The rear wheel, created later on as a rotational bundle so it can turn along with the rudder.

ObjectTemplate.addTemplate DefiantCanopy  ObjectTemplate.setPosition 0/0/1.25  ObjectTemplate.addTemplate DefiantExhaust  ObjectTemplate.setPosition 0/0/1.25

Two redundant objects that should have been exported as part of the fuselage.

ObjectTemplate.addTemplate DefiantBombRack

A reference to Weapons.con that will attach the Bomb weapon to the aircraft.

ObjectTemplate.addTemplate DefiantRearGunControl  ObjectTemplate.setPosition 0/0.52/-0.42  ObjectTemplate.setRotation -180/0/0

The second control point in the aircraft for whoever is manning the turret. Exported facing forwards, and rotated to it's default position facing the tail.

Big Bundle o' Love

Okay, now we move on to all the objects that make up the Complex bundle:

rem *** lodDefiantCockpit ***  ObjectTemplate.create LodObject lodDefiantCockpit  rem -------------------------------------  ObjectTemplate.addTemplate DefiantCockpitExternal  ObjectTemplate.addTemplate DefiantCockpitInternal  ObjectTemplate.setPosition 0/-1.599/0.11  rem -------------------------------------  ObjectTemplate.lodSelector DefiantCockpitSelector

Another LOD object, this time to determine whether to render the internal model for the cockpit. It's set a little higher and a little to the rear of the central point, and once again has a LOD selector.

rem *** DefiantCockpitExternal ***  ObjectTemplate.create SimpleObject DefiantCockpitExternal  ObjectTemplate.hasDynamicShadow 1  ObjectTemplate.geometry Defiant_Fuselage

Here we have the external cockpit, ie the fuselage of the plane. I've created it as a SimpleObject, because its a single piece of geometry and nothing more.

rem *** DefiantCockpitInternal ***  ObjectTemplate.create SimpleObject DefiantCockpitInternal  ObjectTemplate.geometry 1p_Aichi_Val_m1

An Aichi Val cockpit because I haven't yet modelled my internals. Simple object again, although if you really wanted to, you could quite easily have a Bundle here that incorporates an artificial horizon, and possibly some gauges, but they would be more difficult to implement.

rem *** DefiantCockpitSelector ***  LodSelectorTemplate.create DistCompareSelector DefiantCockpitSelector  LodSelectorTemplate.addLodDistance 20  LodSelectorTemplate.addLodComparison 0.5

Another LOD Selector, this time a DistCompareSelector (as opposed to the DistCompareSelector2 we saw earlier. Not sure what the distinction is.) A short LOD distance, and a LOD comparison. Unsure of what function that serves.

rem *** DefiantCamera ***  ObjectTemplate.create Camera DefiantCamera  ObjectTemplate.setMinRotation -45/-40/0  ObjectTemplate.setMaxRotation 45/14/0  ObjectTemplate.setMaxSpeed 90/-90/0  ObjectTemplate.setAcceleration 5000/5000/0  ObjectTemplate.setInputToYaw c_PIMouseLookX  ObjectTemplate.setInputToPitch c_PIMouseLookY  ObjectTemplate.toggleMouseLook 1  ObjectTemplate.OutsideHudOffset 0.004/0/3.5

Now our first Camera object, this time the pilot's view. The first few variables were ripped straight from the Aichi Val, and while I suspect they affect the pitch and roll rates of the aircraft, I can't confirm it. The MaxSpeed and acceleration should be set to something high, as a lower rate probably makes the aircraft less responsive to player input. The camera is set to take its input from the mouse's X and Y movements, which I assume is fed on to the control surface in Physics.con, and I'll try to confirm some of these grey areas over the weekend. The final variable is the offset for NoseCam, and you can work out the appropriate Offset by working out the desired nose position in Max, and then working out the difference between that and the position of the camera object.

rem *** DefiantEntry ***  ObjectTemplate.create EntryPoint DefiantEntry  ObjectTemplate.setEntryRadius 6

The Entrypoint is require for players to actually use the plane, and it needs a variable to specify the active radius. Whenever the player uses the plane within this radius, they are attached to the Player Control Object that is the parent of the Entry Point.

rem *** DefiantSeat ***  ObjectTemplate.create SeatObject DefiantSeat  ObjectTemplate.seatFlags c_SeatShowHalfBodySoldier

This one is nice and simple. Half a soldier model is placed in the seat location, and his movements are tied into the MouseLook automatically.

rem *** DefiantCanopy ***  ObjectTemplate.create SimpleObject DefiantCanopy  ObjectTemplate.geometry Defiant_Glass
rem *** DefiantExhaust ***  ObjectTemplate.create SimpleObject DefiantExhaust  ObjectTemplate.geometry Defiant_Engine

These are the two redundant objects I mentioned earlier. They should be part of the fuselage, but it serves to illustrate a point. You can put anything in a Bundle.

rem *** DefiantWheelBack ***  ObjectTemplate.create RotationalBundle DefiantWheelBack  ObjectTemplate.hasMobilePhysics 1  ObjectTemplate.hasCollisionPhysics 1  ObjectTemplate.hasResponsePhysics 1

A Rotational Bundle, which works exactly like a normal bundle, except that it's pitch, roll and yaw can receive input and funnily enough, rotate. More physics.

ObjectTemplate.addTemplate DefiantWheelBackSpring  ObjectTemplate.setPosition 0/-0.26/0

This Object is in Physics.con and once again an unconfirmed piece of info - The position offset determines the spring length.

ObjectTemplate.setMinRotation -20/0/0  ObjectTemplate.setMaxRotation 20/0/0  ObjectTemplate.setMaxSpeed 200/0/0  ObjectTemplate.setAcceleration -110/0/0  ObjectTemplate.setInputToYaw c_PIYaw  ObjectTemplate.setAutomaticReset 1

The above chunk doesn't actually affect the wheel rolling but limits the wheel so that it can only rotate a little when taxiing the plane. The Yaw input is tied into the player input, and theoretically you could allow a wider rotation and your plane to rotate almost on the spot, which is handy for carrier born aircraft.

rem *** lodDefiantPropeller ***  ObjectTemplate.create LodObject lodDefiantPropeller

Another LOD object with yet another purpose. This time to display the appropriate propeller. Either the static mesh, or the flat plane with the blur.

ObjectTemplate.addTemplate DefiantPropellerStatic  ObjectTemplate.addTemplate DefiantPropellerBlurred  rem -------------------------------------  ObjectTemplate.lodSelector DefiantPropSelector

You should understand this portion by now. The two options for the LOD selector, and the reference to the object itself.

rem *** DefiantPropellerStatic ***  ObjectTemplate.create SimpleObject DefiantlPropellerStatic  ObjectTemplate.geometry Defiant_Prop_Static
rem *** DefiantPropellerBlurred ***  ObjectTemplate.create SimpleObject DefiantPropellerBlurred  ObjectTemplate.geometry Defiant_Prop_Blur

And the two objects in question for the LODing. Both simple, as they inherit their rotation from their parent object, the engine, which we'll see a bit later in Physics.con.

rem *** DefiantPropSelector ***  LodSelectorTemplate.create CompareSelector DefiantPropSelector  LodSelectorTemplate.addLodComparison 0.07

And a different LOD selector once more, this time a CompareSelector, which doesn't take distance into account at all. As of yet, I have no idea what comparison is being made here, but it's obviously got something to do with the throttle and/or the rate of rotation for the props.

Get Your Gear On

Okay, well most of the plane is now there, with the exception of the Dorsal Turret and the simple and wrecked versions of the fuselage.

rem *** DefiantLandingGearRight ***  ObjectTemplate.create LandingGear DefiantLandingGearRight

Our first LandingGear object. These are pretty nifty and fairly well automated. As children of the engine object, they take altitude and throttle into account.

ObjectTemplate.loadSoundScript ../Common/Sounds/LandingGear.ssc

And our first sound script. I'll cover them in a later turorial, but for now add in that line as is, and you'll get some sound feedback when your gear extends/retracts.

ObjectTemplate.geometry Defiant_Undercarriage_Right  ObjectTemplate.hasMobilePhysics 1  ObjectTemplate.hasCollisionPhysics 1  ObjectTemplate.hasResponsePhysics 1

You know this already right? Attaching a bit of geometry and the usual physics stuff.

ObjectTemplate.addTemplate DefiantWheelCoverRight  ObjectTemplate.setPosition 0/-0.5/0  ObjectTemplate.addTemplate DefiantWheel1  ObjectTemplate.setPosition -0.1/-1/0.1

Okay here we have two objects, the first one is pretty much redundant, and an artifact of my "advanced" landing gear that didn't quite work. However it does illustrate one thing that wigged out on me. I've attached the Wheel Cover (a simple object) and the wheel itself here, after simply attaching the wheel to the wheel cover. This resulted in my wheels losing their collision properties due to some heirarchical mix up. I may try to shorten up the Y offset for the wheel object, as it seems to make the spring fairly deep, and at times the plane sinks far enough for the landing gear mesh to clip.

ObjectTemplate.setMinRotation 0/0/-86  ObjectTemplate.setMaxSpeed 0/0/28  ObjectTemplate.setAcceleration 0/0/-90  ObjectTemplate.setGearDownHeight 25  ObjectTemplate.setGearUpHeight 23  ObjectTemplate.setGearDownEngineInput 0.55

Okay here's an interesting bit. When the landing gear is extended, it's at its minimum rotation, and when it's retracted, it's at the maximum. The speed will affect how slowly the gear extends and retracts so it's good to have it set around 20-30 so it seems fairly realistic, and makes landings more calculated.

The Up and Down heights refer to the altitude the plane must be above or below before the gear considers working. The engine input variable indicates what percentage of the maximum speed the plane must be travelling below before the gear will extend, which forces the player to slow down for landings.

rem *** DefiantLandingGearLeft ***  ObjectTemplate.create LandingGear DefiantLandingGearLeft

Second verse, same as the first. A couple of changes to Min and max rotation, as well as offsets but it's not worth posting.

rem *** DefiantWheelCoverRight ***  ObjectTemplate.create SimpleObject DefiantWheelCoverRight  ObjectTemplate.geometry Defiant_LandingGear_Right    rem *** DefiantWheelCoverLeft ***  ObjectTemplate.create SimpleObject DefiantWheelCoverLeft  ObjectTemplate.geometry Defiant_LandingGear_Left

The wheel covers. Elegant simplicity, and would have been better as part of the Undercarriage mesh.

rem *** DefiantWheelFlapRight ***  ObjectTemplate.create LandingGear DefiantWheelFlapRight  ObjectTemplate.loadSoundScript ../Common/Sounds/LandingGear.ssc  ObjectTemplate.geometry Defiant_WheelFlap_Right  ObjectTemplate.hasMobilePhysics 1  ObjectTemplate.hasCollisionPhysics 1  ObjectTemplate.hasResponsePhysics 1  rem -------------------------------------  ObjectTemplate.setMaxRotation 0/0/94  ObjectTemplate.setMaxSpeed 0/0/28  ObjectTemplate.setAcceleration 0/0/90  ObjectTemplate.setGearDownHeight 25  ObjectTemplate.setGearUpHeight 23  ObjectTemplate.setGearDownEngineInput 0.55

Another landing gear object, this one without a wheel attached. This one is a tiny piece of mesh that folds in the opposite direction to the one bearing the wheel, and serves only to completely seal the undercarriage bay.

Dorsal Tourette's

Now we move on to the turret, and thankfully the uncontrollable fits of cursing I went through when trying to get my first turret (B-17 + AichiVal) working are a thing of the past. This time around it was a breeze.

rem *** DefiantRearGunControl ***  ObjectTemplate.create PlayerControlObject DefiantRearGunControl  ObjectTemplate.setNetworkableInfo AichiVal_body_info  ObjectTemplate.aiTemplate AichivalMGAI

Our second Player Control Object, this time for the Dorsal Turret. The Network and AI functions are placeholders because for the time being they're kind of useless. I could have applied a B-17 turret AI, or simply modified the AichivalMG script so that the AI knows it can shoot in all 360 degrees, but I'll save that for another day.

ObjectTemplate.addTemplate DefiantDorsalTurret  rem ObjectTemplate.setPosition 0/0.65/0.4  ObjectTemplate.addTemplate DefiantEntry  ObjectTemplate.setPosition 0/-0.191/0

Here we have another Entry Point, which hopefully you should be familiar with, and a reference to a rotational bundle we'll meet soon.

ObjectTemplate.setSoldierExitLocation -3/0.05/1 0/0/0  ObjectTemplate.GUIIndex 54  ObjectTemplate.setVehicleCategory VCLand  ObjectTemplate.setVehicleType VTDiveBomber

Another Exit Location that will dump the gunner in the right place when he jumps out. The GUIIndex here applies to the rear seat of an Aichi Val, and the Vehicle Category is VCLand for for the sole reason that that's what DICE have for their machine gun positions on aircraft.

rem *** DefiantDorsalTurret ***  ObjectTemplate.create RotationalBundle DefiantDorsalTurret  ObjectTemplate.setNetworkableInfo AichiVal_body_info  ObjectTemplate.loadSoundScript Sounds/TurretDorsal.ssc  ObjectTemplate.geometry Defiant_Turret

Another Rotational Bundle and the mesh for the turret. The most interesting thing here is a sound script to play a mechanical sound when the turret rotates, but more on that at a later date.

ObjectTemplate.addTemplate DefiantTurretGuns  ObjectTemplate.setPosition 0/0.4/0.1  rem -------------------------------------  ObjectTemplate.setMaxSpeed 90/0/0  ObjectTemplate.setAcceleration 5000/0/0  ObjectTemplate.setInputToYaw c_PIMouseLookX

Here, we add another rotational bundle, and you'll notice that this bundle is only tied into yaw. The way the turret is set up is that the entire unit can rotate a full 360 degrees according to the mouse's X axis movement, and the guns, well... we'll see. The speed and acceleration are nice and high so the turret should turn just as fast as the player can mouselook.

rem *** DefiantTurretGuns ***  ObjectTemplate.create RotationalBundle DefiantTurretGuns  ObjectTemplate.setNetworkableInfo AichiVal_body_info  ObjectTemplate.setAttachToListener 1  ObjectTemplate.loadSoundScript Sounds/TurretVentral.ssc  ObjectTemplate.geometry Defiant_Guns

Okay, and here's another sound script, and an attach to listener that I don't quite understand, but lifted from the b-17s .CON file.

ObjectTemplate.addTemplate DefiantRearCamera  ObjectTemplate.setPosition 0/0/0  ObjectTemplate.addTemplate Defiant_4xBrowning

Now we add the camera that the player will look through while gunning, and the guns themselves, which are contained within the Weapons.con file along with the bombrack from earlier.

ObjectTemplate.setMinRotation 0/-60/0  ObjectTemplate.setMaxRotation 0/0/0  ObjectTemplate.setMaxSpeed 0/90/0  ObjectTemplate.setAcceleration 0/5000/0  ObjectTemplate.setInputToPitch c_PIMouseLookY

The gun object already inherits it's yaw from it's parent object, the dorsal turret, and so we only need some pitch, which is taking it's input from the mouse's Y-axis, and this time we've added in some rotation limits so the player can't aim the guns too high.

rem *** DefiantRearCamera ***  ObjectTemplate.create Camera DefiantRearCamera  ObjectTemplate.setMaxSpeed 200/200/0  ObjectTemplate.setAcceleration 1000/1000/0

And the rear camera object, much simpler than it's forward facing counterpart. All it needs to do is point in the direction the guns are aiming.

rem *** DefiantSimple ***  ObjectTemplate.create SimpleObject DefiantSimple  ObjectTemplate.geometry Defiant_LowDetail    rem *** DefiantWreck ***  ObjectTemplate.create SimpleObject DefiantWreck  ObjectTemplate.geometry Wreck_Defiant

And the grand finale of the Objects.con file si somewhat of an anticlimax. Two mundane, simple items, but never fear, because we shall now move on to the Physics and Weapons .CON files.

Let's Get Physical

It's time to delve into our next .CON file, which you should create if you haven't already. Name it "Physics.con" and open it up in your favourite text editor.

rem *** DefiantFlaps1 ***  ObjectTemplate.create Wing DefiantFlaps1  ObjectTemplate.setNetworkableInfo AichiVal_wing_info

Here's something new. A Wing object. All of the control surfaces are wings and they are required to give your aircraft lift, unless you've got a rocket engine or something. We've got another piece of Aichi Val network stuff that we don't really care about at this point.

What we do care about however is that these objects are flaps, and in real-life flaps are put on planes to provide extra lift during takeoff and landing, and also to increase drag, which slows the airspeed. In BF1942, they provide a similar function, although I haven't done enough testing to determine whether or not they only function during take-off and landing or whether they are permanent.

ObjectTemplate.setMinRotation 0/-2/0  ObjectTemplate.setMaxRotation 0/2/0  ObjectTemplate.setMaxSpeed 0/30/0  ObjectTemplate.setAcceleration 0/120/0

You've seen these functions before, and should know what they do by now.

ObjectTemplate.setPitchOffset 0.5  ObjectTemplate.setPositionOffset -1.778/0.302/0.12

Okay, the position offset is fairly self explanatory, and I assume the PitchOffset rotates the object according to pitch, but I'm not entirely sure, as that could easily be done through ObjectTemplate.setRotation.

ObjectTemplate.setFlapLift 2  ObjectTemplate.setRegulateToLift 3  ObjectTemplate.setWingToRegulatorRatio 1

I have no idea about the Regulate functions, but the Flap Lift is important, as it will get your plane into the air.

rem *** DefiantFlaps2 ***  ObjectTemplate.create Wing DefiantFlaps2

More of the same...

rem *** DefiantBodyWing ***  ObjectTemplate.create Wing AichiValBodyWing  ObjectTemplate.setAutomaticReset 1  ObjectTemplate.setPositionOffset 0/0/-0.1  ObjectTemplate.setWingLift 2  ObjectTemplate.setFlapLift 0

If you recall, this was rotated 90 degrees when it was added in Objects.con and I'm not entirely sure of it's purpose, but it seems like something the BF1942 standard panes have, so it was added.

rem *** DefiantAileronRight ***  ObjectTemplate.create Wing DefiantAileronRight  ObjectTemplate.setNetworkableInfo AichiVal_wing_info  ObjectTemplate.loadSoundScript ../Common/Sounds/HullRight.ssc  ObjectTemplate.geometry Defiant_Aileron_Right

Now we start with our ailerons, which have a mesh, another soundscript and more networkable info.

ObjectTemplate.setMinRotation 0/-25/0  ObjectTemplate.setMaxRotation 0/25/0  ObjectTemplate.setMaxSpeed 0/150/0  ObjectTemplate.setAcceleration 0/150/0

More familiar stuff.

ObjectTemplate.setInputToPitch c_PIRoll  ObjectTemplate.setAutomaticReset 1  ObjectTemplate.setPitchOffset 0.5

The pitch for the Ailerons is tied into the roll from the player input. The automatic reset brings them back to neutral position if there is no player input, and the pitch offset shifts the angle slightly

ObjectTemplate.setWingLift 1.8  ObjectTemplate.setFlapLift 1.8

And as you can see, these little guys are creating quite a bit of lift, so when they rotate they actually roll the plane.

rem *** DefiantAileronLeft ***  ObjectTemplate.create Wing DefiantAileronLeft

Another very similar function because clone movies always sell at the box office.

rem *** DefiantElevatorLeft ***  ObjectTemplate.create Wing DefiantElevatorLeft  ObjectTemplate.setNetworkableInfo AichiVal_wing_info  ObjectTemplate.geometry Defiant_Elevator_Left  ObjectTemplate.setMinRotation 0/-10/0  ObjectTemplate.setMaxRotation 0/20/0  ObjectTemplate.setMaxSpeed 0/60/0  ObjectTemplate.setAcceleration 0/-60/0  ObjectTemplate.setInputToPitch c_PIPitch  ObjectTemplate.setAutomaticReset 1  ObjectTemplate.setPositionOffset 0.5/0/0  ObjectTemplate.rememberExcessInput 1  ObjectTemplate.setWingLift 0.5  ObjectTemplate.setFlapLift 0.5

This stuff should be looking pretty samey by now, but we can see this time the rotation is tied to pitch, and that ExcessInput is remembered. I haven't tested this extensively, but it should serve to make the automatic reset happen a little later if you are really yanking back/pushing the stick.

rem *** DefiantElevatorRight ***  ObjectTemplate.create Wing DefiantElevatorRight


rem *** DefiantRudder ***  ObjectTemplate.create Wing DefiantRudder  ObjectTemplate.setNetworkableInfo AichiVal_wing_info  ObjectTemplate.geometry Defiant_Rudder  ObjectTemplate.setMinRotation 0/-15/0  ObjectTemplate.setMaxRotation 0/15/0  ObjectTemplate.setMaxSpeed 0/60/0  ObjectTemplate.setAcceleration 0/60/0  ObjectTemplate.setInputToPitch c_PIYaw  ObjectTemplate.setAutomaticReset 1  ObjectTemplate.setPositionOffset 0/-0.5/0  ObjectTemplate.setWingLift 1.5  ObjectTemplate.setFlapLift 1.5

The rudder, and as we noted before during our export, it was rotated 90 degrees. It seems that the Wing object doesn't respond to ObjectTemplate.setInputToYaw and so we use pitch instead and rotate it 90 degrees. A bit of a pain in the arse, but that's how DICE have their aircraft set up, so we run with it.

rem *** DefiantWheelBackSpring ***  ObjectTemplate.create Spring DefiantWheelBackSpring  ObjectTemplate.geometry Defiant_RearWheel  ObjectTemplate.hasMobilePhysics 1  ObjectTemplate.hasCollisionPhysics 1  ObjectTemplate.hasResponsePhysics 1  ObjectTemplate.Grip c_PGFRollGripWhenOccupied  ObjectTemplate.setStrength 24  ObjectTemplate.setDamping 12

A new object type, this time a Spring with a few new variable setting functions. The Grip function makes the wheel roll as the vehicle moves (provided it's occupied) and the strength and damping set the characteristics of the spring. A higher strength means increases the reaction of the spring, as it releases after being pushed in and the dampening smooths the motion a little. At high strength the plane tends to bounce in a jittery kind of fashion.

rem *** DefiantWheel1 ***  ObjectTemplate.create Spring DefiantWheel1  ObjectTemplate.geometry rh_aichi_rwhe_M1  ObjectTemplate.hasMobilePhysics 1  ObjectTemplate.hasCollisionPhysics 1  ObjectTemplate.hasResponsePhysics 1  ObjectTemplate.Grip c_PGFRollGripWhenOccupied  rem -------------------------------------  ObjectTemplate.addTemplate e_wdustPlane  ObjectTemplate.addTemplate e_wdustPlaneL  rem -------------------------------------  ObjectTemplate.setStrength 24  ObjectTemplate.setDamping 2

More of the same, with the addition of collision effects, spawning dust when the wheels roll. I'm using the Aichi wheels here until I can resolve my Mat ID issues.

rem *** DefiantWheel2 ***  ObjectTemplate.create Spring DefiantWheel2

Rinse. Wash. Repeat.

rem *** DefiantEngine ***  ObjectTemplate.create Engine DefiantEngine  ObjectTemplate.setNetworkableInfo AichiVal_engine_info  ObjectTemplate.loadSoundScript Sounds/AichiValEngine.ssc

We now introduce the Engine object, and an associated sound script.

ObjectTemplate.addTemplate lodDefiantPropeller  ObjectTemplate.addTemplate DefiantLandingGearLeft  ObjectTemplate.setPosition -1.52/-0.69/-2.786  ObjectTemplate.addTemplate DefiantLandingGearRight  ObjectTemplate.setPosition 1.52/-0.69/-2.786  ObjectTemplate.addTemplate DefiantWheelFlapLeft  ObjectTemplate.setPosition -0.26/-0.79/-2.786  ObjectTemplate.setRotation -4.5/0/0  ObjectTemplate.addTemplate DefiantWheelFlapRight  ObjectTemplate.setPosition 0.26/-0.79/-2.786  ObjectTemplate.setRotation 4.5/0/0

And here we firstly add the prop LOD object, and then any landing gear objects, which require input from the engine for speed limits. All of the coords here need to be offset be the engine position as specified in Objects.con.

ObjectTemplate.setMinRotation -0.3/0/-3000  ObjectTemplate.setMaxRotation 0.3/0/5000  ObjectTemplate.setMaxSpeed 1000/0/500  ObjectTemplate.setAcceleration 500/0/1000  ObjectTemplate.setInputToRoll c_PIThrottle  ObjectTemplate.setAutomaticReset 1  ObjectTemplate.setEngineType c_ETPlane

These are all pretty standard across the suite of planes offered by DICE, and the Rotation, Speed and Acceleration don't seem to affect anything other than the visuals of the prop spinning. The Automatic Reset kills the throttle if the player takes their hand off it, and could make things interesting if set to false. The engine type is a bit of a no brainer. I have no idea what would happen if you dropped a jeep engine into a plane, but it probably wouldn't be good.

ObjectTemplate.setTorque 15  ObjectTemplate.setDifferential 5  ObjectTemplate.setGearUp 0.6  ObjectTemplate.setGearDown 0.3  ObjectTemplate.setNoPropellerEffectAtSpeed 70

The Torque controls the effectiveness of the engine. A high torque means the engine is rotating faster, and outputting more thrust. I haven't played with the differential, but I have a feeling it's a modifier to the torque. Gear up and down affect the landing gear, and while I haven't experimented with the NoPropEffect, I think it's basically there to cap the speed of the aircraft.

Luft Waffen

Now we're getting toward the end of this tutorial which is probably a good thing, because the beers are starting to kick in, and it's probably best if I keep this thing legible.

rem *** Defiant_4xBrowning ***  ObjectTemplate.create FireArms Defiant_4xBrowning  ObjectTemplate.loadSoundScript Sounds/DefiantGuns.ssc  ObjectTemplate.setNetworkableInfo PlaneFireArmInfo

A new object - FireArms, a soundscript and networkable info to leave until a later date.

ObjectTemplate.visibleBarrelTemplate e_MuzzHeavy

This adds a muzzle effect whenever the gun is fired, and this can be set to just about anything in the .\objects\effects\ folder. I went with e_MuzzHeavy because it seemed appropriate and looked good enough for me to have little to no desire look any further.

ObjectTemplate.projectileTemplate DefiantProjectile  ObjectTemplate.projectilePosition 0/0/2  ObjectTemplate.setTracerTemplate Tracer_Projectile CRD_NONE/3/0/0

Here we can give the weapon a projectile. Defiant Projectile (which actually deals the damage) is defined below, and the tracer gives the player an idea of where their gun is shooting.

ObjectTemplate.magSize 600  ObjectTemplate.numOfMag 1  ObjectTemplate.velocity 400  ObjectTemplate.roundOfFire 10

Now we deal with some of the properties of the weapon itself. Here we have a 600 round magazine, with no reloads, a muzzle velocity of 400 and a rate of fire of 10.

ObjectTemplate.addFireArmsPosition 0.28/0.106/0.79 0/0/0  ObjectTemplate.addFireArmsPosition -0.28/0.106/0.79 0/0/0  ObjectTemplate.addFireArmsPosition 0.28/-0.106/0.79 0/0/0  ObjectTemplate.addFireArmsPosition -0.28/-0.106/0.79 0/0/0

Here we have offsets relative to the Parent object, in this case the DefiantTurretGuns object. Offsets calculate through 3DSMax.

ObjectTemplate.AmmoType 10

I haven't got a definitive list of ammo types, but this is what the B-17 turrets use so it seemed logical.

rem *** DefiantProjectile ***  ObjectTemplate.create Projectile DefiantProjectile  ObjectTemplate.createNotInGrid 1  ObjectTemplate.loadSoundScript ../../../Common/Sounds/Projectile.ssc  ObjectTemplate.hasMobilePhysics 1  ObjectTemplate.hasCollisionPhysics 1  ObjectTemplate.hasResponsePhysics 1

Projectile now, and the only unfamiliarity is the NotInGrid, which I am not familiar with myself, but it seems a staple of most projectiles, so in it goes.

ObjectTemplate.timeToLive CRD_NONE/2/0/0  ObjectTemplate.gravityModifier 1  ObjectTemplate.material 224  ObjectTemplate.material2 -1  ObjectTemplate.stopAtEndEffect 1  ObjectTemplate.hasCollisionEffect 1

Here we can control range with the timeToLive, although I haven't experimented a great deal. For most aircraft weapons there is a gravity modifier of 0, as otherwise it makes accurate shooting quite difficult. I upped it to 1 to make the turret a little more challenging, and a little less uber. Materials will be covered in a later tute, and the last two lines are pretty self-explanatory.

rem *** DefiantBombDummy ***  ObjectTemplate.create FireArms DefiantBombRack  ObjectTemplate.setNetworkableInfo PlaneFireArmInfo  ObjectTemplate.aiTemplate AichiValBombs  ObjectTemplate.projectileTemplate DiveBomberBomb  ObjectTemplate.projectilePosition 0/-0.4/-0.2  ObjectTemplate.magSize 30  ObjectTemplate.numOfMag 1  ObjectTemplate.velocity 0  ObjectTemplate.roundOfFire 0.2  ObjectTemplate.setInputFire c_PIAltFire  ObjectTemplate.addFireArmsPosition -3.299/-0.199/0 0/0/0  ObjectTemplate.addFireArmsPosition 3.299/-0.199/0 0/0/0  ObjectTemplate.AmmoType 7

Lifted straight from the AichiVal. When I play with it some more I'll update this little section.

And that about concludes the first part of this tute, so post/flame away, and please help me to fill in the grey areas where I've just posted some vague rants. Enjoy.