This is an old revision of the document!
This guide walks through creating an Arma 3 Advanced Flight Model RotorLib XML profile for a custom helicopter. It is written to match the RotorLib XML Profile Builder workflow and assumes the final XML will be tested in Arma 3 with Advanced Flight Model enabled.
The first XML is not a finished flight model. Treat it as a structured, documented starting point. Every estimated value should be recorded, tested, and replaced when better source data becomes available.
Before entering values, collect these files and references:
RotorLibHelicopterProperties / RTDconfig reference.Use the closest proven RotorLib XML as the baseline. Match by:
Keep the selected baseline recorded in the tool. Some sections, especially drive trains and control-system conventions, are easier to preserve from a working profile than to recreate from documentation.
RotorLib coordinates use:
| Axis | Direction |
|---|---|
X | Right |
Y | Forward |
Z | Up |
All position values must be converted into this coordinate system. Do not assume Arma model-space labels or visual axes match the value names without checking the model and a known working XML.
Useful rules:
X moves a point to the aircraft right side.Y moves a point toward the nose.Z moves a point upward.If the exact datum is unclear, compare the baseline XML values against visible geometry and memory points. Preserve the same convention when adapting it.
Enter:
| Value | Where To Find It | Notes |
|---|---|---|
| Profile name | XML file name or aircraft class name | Use a readable name such as RTD_MyHelicopter. |
| Vehicle class | CfgVehicles target class | Must be the exact class that will reference the XML. |
| XML path in addon | Planned packed PBO path | Use addon-relative paths only. Do not use Q:\, C:\, or other local absolute paths. |
| Closest baseline XML | Bundled BIS XML or another working profile | Record this for later comparison and tuning notes. |
Example Arma config pattern:
class RotorLibHelicopterProperties { RTDconfig = "\my_addon\air\RTD_MyHelicopter.xml"; };
Verify the exact placement and property names against a working vanilla helicopter config before packing.
Enter mass in kilograms.
Best sources, in order:
Start with a realistic operating/test mass, not necessarily the absolute maximum load. Later, test loaded and unloaded behavior separately.
Enter approximate dimensions in meters:
| Value | How To Measure |
|---|---|
| Length | Nose to tail extent, excluding main rotor unless using it deliberately for rough inertia. |
| Width | Left-right body/gear/skid span. For ground stability, gear/skid span is often more useful than fuselage width. |
| Height | Bottom contact point to upper fuselage/mast area. Use a consistent rough body height for inertia estimates. |
These dimensions are used for first-pass inertia and generated contact positions. They are not a substitute for measured contact or rotor stations.
Enter center of gravity offsets in meters:
| Value | Meaning |
|---|---|
CG X | Lateral CG offset. Positive is right. |
CG Y | Longitudinal CG offset. Positive is forward. |
CG Z | Vertical CG offset. Positive is up. |
Where to derive it:
For a first symmetric scaffold, keep CG X near zero. Small CG Y and CG Z changes can strongly affect hover trim, pitch, and ground attitude.
Use sourced moments of inertia if available. If not, estimate them temporarily from mass and dimensions:
Ixx = 1/12 * mass * (length^2 + height^2) Iyy = 1/12 * mass * (width^2 + height^2) Izz = 1/12 * mass * (width^2 + length^2)
Use Iyz = 0 for a first symmetric scaffold unless you have asymmetric mass data.
These estimates only unblock first flight. If the helicopter rotates too quickly, too slowly, or oscillates, revisit inertia before over-tuning dampers.
| Value | How To Find Or Calculate It |
|---|---|
| Radius | Measure hub center to blade tip. Rotor diameter / 2. |
| Chord | Average blade width. Use real blade data or measure the model blade. |
| Blade count | Count visible main rotor blades. |
| Design RPM | Use real aircraft data, baseline XML, or stable in-game RotorLib RPM from a close aircraft. |
| Clockwise | Determine from model animation or baseline. Wrong direction can invert yaw/control behavior. |
| Twist | Use blade data if available; otherwise start from the closest baseline. |
| Swash phase | Preserve from the baseline unless cyclic response demands a deliberate change. |
Main rotor radius has a large effect because disc area is:
disc_area = pi * radius^2
Do not tune lift primarily by abusing mass or power. First verify radius, blade count, RPM, collective range, and aerodynamic tables.
Measure the main rotor hub in RotorLib coordinates:
| Value | Direction |
|---|---|
| Hub X | Right positive |
| Hub Y | Forward positive |
| Hub Z | Up positive |
Use model memory points, animation axes, or measured geometry. The hub station affects moments because rotor thrust is applied at the hub and resolved into aircraft motion.
| Value | Source Guidance |
|---|---|
| Rotor inertia | Copy from a similar rotor or estimate cautiously. Affects spool-up and autorotation. |
| Blade flapping inertia | Prefer a baseline value. Affects cyclic response and damping. |
| Hinge offset | Use rotor head geometry or baseline. |
| Brake torque | Use source data or baseline. Only relevant when rotor brake behavior is modelled. |
Measure or derive:
| Value | Guidance |
|---|---|
| Radius | Tail rotor diameter / 2. |
| Chord | Average tail blade width. |
| Blade count | Visible tail rotor blade count. |
| Design RPM | Baseline drive-train ratio or real aircraft data. |
| Position X/Y/Z | Tail rotor hub station in RotorLib coordinates. Y distance from CG is the yaw moment arm. |
| Rotation direction | Preserve from a working baseline until yaw sign is verified. |
| Twist / lift slope | Use real data or closest baseline. |
Tail rotor setup is a common cause of uncontrollable yaw. Verify sign and authority in hover before tuning forward flight.
Enter horsepower references:
| Value | Meaning |
|---|---|
| Emergency power HP | Short-term maximum/emergency power. Current Arma RTD XML uses emergencyPowerHP. |
| Takeoff power HP | Short-duration takeoff power reference. |
| Continuous power HP | Maximum continuous operating power. |
Sources:
If max torque is unavailable, estimate:
torque_Nm = power_hp * 745.699872 / (rpm * 2 * pi / 60)
Use the shaft RPM expected by the engine/controller, not necessarily visible rotor RPM unless the drive train is 1:1.
| Value | Guidance |
|---|---|
| Target RPM | Copy from baseline or derive from rotor RPM and drive-train ratio. |
| Rotation resistance | Preserve baseline value first. Tune only after RPM behavior is understood. |
| Controller P/I/D/offset | Copy from working profiles unless you know the controller behavior. |
Drive-train XML is not fully described by the BIS page. Preserve it from the closest working profile unless you have a specific reason to change shaft names, gear ratios, or rotor connections.
RotorLib actuator variables such as MainRotor/theta0, MainRotor/A1, MainRotor/B1, and TailRotor/theta0 are radians in the control system, even when the wizard accepts practical degree ranges.
| Value | Guidance |
|---|---|
| Collective min deg | Lower blade pitch range. Too high causes excessive lift at low collective. |
| Collective max deg | Upper blade pitch range. Too low prevents liftoff. |
Tune so the helicopter lifts and hovers at plausible collective for the test mass.
| Value | Guidance |
|---|---|
| Lateral min/max | Roll cyclic authority. Verify sign in game. |
| Longitudinal min/max | Pitch cyclic authority. Verify sign in game. |
If pitch or roll is reversed, check A1/B1 signs, swash phase, rotor rotation direction, and coordinate conversion before changing unrelated values.
Pedal min/max maps to tail rotor collective. Wrong sign or tail rotor direction usually causes immediate yaw problems.
Test:
Ground contacts define how the helicopter stands, rolls, skids, compresses, bounces, steers, brakes, and takes landing damage.
RotorLib examples use FGGroundContact200 contacts. The tool supports three authoring intents:
| Contact Kind | Use For | XML Notes |
|---|---|---|
| Wheel | Nose, main, tail wheels | Uses wheel radius, roll axis, brake torque, friction, steering, suspension. |
| Skid | Skid shoes, skid contact pads | Uses a small proxy radius and high sliding friction. Usually not steerable or brakable. |
| Fixed hull point | Tail bumper, belly point, auxiliary hard contact | Uses zero/short suspension and small proxy radius. Usually no steering/braking. |
The XML still exports compatible FGGroundContact200 structure. The contact kind is written into the XML comment so the authoring intent remains visible.
Do not force every aircraft into nose-left-right wheel layout.
Use as many contacts as needed:
For skids, use several contact points along the skid length. A single point per skid can cause unstable tipping or unrealistic pivoting.
MountStation is the suspension attach/reference point in aircraft coordinates. It is not automatically the wheel midpoint.
| Attribute | Direction |
|---|---|
x | Right positive |
y | Forward positive |
z | Up positive |
For a wheel contact:
SuspensionLength is the uncompressed distance from MountStation to the wheel midpoint along SliderAxis.SliderAxis x=“0” y=“0” z=“1” is common.For a skid contact:
MountStation at the skid contact/reference point or the nearest simple suspension reference.SuspensionLength and high sliding friction.For a fixed hull point:
MountStation at the physical hard-contact point.SuspensionLength = 0 or a very small value.maxCompression = 0 or a very small value.Common structure:
<Suspension> <MountStation x="-0.896" y="-2.34" z="-1.71" /> <SliderAxis x="0" y="0" z="1" /> <SuspensionLength length="0.35" /> <SpringParameters springConstant="76300" damperConstant="7234.76" maxCompression="0.2" /> </Suspension>
Definitions:
| Value | Meaning |
|---|---|
SliderAxis | Direction of suspension travel. Vertical contacts usually use 0,0,1. |
SuspensionLength | Uncompressed distance from MountStation to wheel midpoint or contact reference. |
maxCompression | Maximum compression travel. It should not exceed SuspensionLength. |
If the aircraft sinks into the ground:
MountStation Z.SuspensionLength.If the aircraft bounces:
A useful first spring estimate:
springConstant = supported_weight_per_contact_N / desired_static_compression_m
Where:
supported_weight_per_contact_N = mass_kg * 9.81 / number_of_primary_contacts
Example:
mass = 4500 kg primary contacts = 3 desired static compression = 0.18 m supported_weight = 4500 * 9.81 / 3 = 14715 N springConstant = 14715 / 0.18 = 81750 N/m
Damper is normally copied from a similar BIS XML, then tuned. Too little damping causes bounce. Too much damping can make touchdown feel dead or cause odd settling.
| Value | How To Derive |
|---|---|
| Wheel radius | Tyre diameter / 2. Measure the model or use real wheel data. |
| Wheel mass | Real wheel/gear mass if known, otherwise baseline value. |
| RollAxis | Wheel axle direction. Most main wheels use x=“1” y=“0” z=“0”. |
For skids and hull points, the tool uses a small proxy radius because the RotorLib contact block still contains a Wheel element. Treat this as a contact-model proxy, not a visible wheel.
| Value | Guidance |
|---|---|
slidingFriction | Higher values resist sideways sliding. Skids usually need higher friction than wheels. |
resistanceTorqueNoBrake | Rolling resistance with no brake. |
resistanceTorqueFullBrake | Brake resistance torque at full brake. |
isBrakable | True for wheels that should brake. Usually false for skids and hull points. |
Taxi and landing rollout should be tuned in game. Friction values that look reasonable in XML can still produce bad ground behavior.
Use steering only where the contact physically steers.
| Value | Guidance |
|---|---|
isSteerable | True for steerable nose/tail wheels. |
maxTorque | Steering motor authority. |
maxRotSpeed | Steering rotation speed. |
controllerGain | Response gain. Too high may oscillate. |
inverseRotation | Flip if visual steering turns opposite to input. |
keepCenter | Usually true for nose wheels. |
Skids and hull contacts should normally be non-steerable.
Damage thresholdLoad is the contact load where damage/failure should occur.
Start around several times the static supported load per contact:
thresholdLoad = static_supported_load_per_contact * 3 to 6
Then tune hard landings. If normal landings break gear, raise it. If severe impacts never damage the gear, lower it.
Export:
Before testing:
Q:\ in the final addon config.Use this order. Do not tune forward flight before ground and hover basics work.
| Symptom | Check First |
|---|---|
| XML does not load | XML syntax, schema names, packed path, RTDconfig path. |
| Aircraft sinks into ground | Contact Z, SuspensionLength, radius, spring constant. |
| Aircraft bounces | Damper, spring constant, maxCompression, contact placement. |
| Aircraft tips on ground | Contact width/length, CG, missing skid/hull points. |
| Cannot lift | Mass, rotor radius, RPM, collective range, lift tables, engine torque. |
| Climbs too aggressively | Collective minimum, lift coefficients, rotor RPM, mass. |
| Spins uncontrollably | Tail rotor sign, rotation direction, pedal mapping, tail rotor station. |
| Pitch or roll reversed | A1/B1 signs, swash phase, rotor rotation direction. |
| Cyclic too twitchy | Moments of inertia, cyclic range, dampers, flapping values. |
| RPM unstable | Engine controller, torque, rotation resistance, drivetrain ratio. |
Every RotorLib XML handoff should include:
If a value is not sourced, say so directly. A clear estimate is better than a false precision value.