Engines: DA_EnginePart

This page covers one aircraft part – DA_EnginePart (UDA_EnginePart).
It defines the thrust-vectoring limits and axis multipliers for each engine.
The actual deflection angle is calculated at runtime from the pilot’s flight-control input.

For ModKit thrust vectoring, this is the only Data Asset that defines the runtime deflection limits and axis multipliers.

1. Create and assign the part

  1. Content Browser → Add → Miscellaneous → Data Asset → class DA_EnginePart (UDA_EnginePart).
  2. Name – Latin characters, no spaces, for example DA_MyPlaneEnginesDefault.
  3. The asset goes into the mod content: Plugins/GameFeatures/<ModName>/Content/DataAssets/.

2. Structure

  • ModeGroups[] – optional mode records. For thrust vectoring, only one Mode = VTOL record is used.
    • Mode – the record’s mode: VTOL / Plane / Ground
      • Engines[] – one record per ENGINE (order = engine order in the JSBSim config)
        • KinematicGroup – the config carrier for THIS engine
          • GroupName – any name: an editor label (the runtime does not read it)
          • BoneStates[0] – the ENGINE CONFIG; the only record that is read
            • BoneName – any non-empty name: an editor label
            • OpenRotationDegrees – defines the the maximum rotation applied around the engine’s X, Y, and Z axes. In FPS2, these components are exposed as Roll, Pitch, and Yaw.
            • OpenTranslation – multiplier: deflection direction and scale
          • BoneStates[1..] – NOT part of the deflection config: it reads the first one only

For engines KinematicGroup is not animation but a config carrier: only its first bone record is read, and only two of its fields. The names (GroupName, BoneName) are labels for your own order in the asset: thrust vectoring matches records by position, not by name.

For VTOL this is critical. Thrust vectoring works only through KinematicGroup records: no Mode = VTOL record, or no Engines[i] record for an engine – physics has nothing to read and the engine will not deflect.

3. Maximum deflection angles – OpenRotationDegrees

A 3D vector representing angular limits in degrees (X = Roll, Y = Pitch, Z = Yaw).
These values define the maximum deflection for each axis, not a static rotation. Neutral stick produces zero deflection, while full stick drives each axis toward its configured limit, subject to the runtime thrust-vectoring envelope.
The runtime flight model calculates the instantaneous angle each frame based on pilot input.

ComponentAxisWhat it sets
XRollMaximum thrust vector deflection on roll command
YPitchMaximum thrust vector deflection on pitch command
ZYawMaximum deflection on yaw command (differential tilt on paired engines produces a yaw moment)

What matters:

  • The configured value is the maximum angle for that axis, subject to the runtime thrust-vectoring envelope.
  • The system enforces a conical gimbal envelope constrained by the effective pitch limit (Y × OpenTranslation.Y). Consequently, if the pitch limit resolves to zero, the total angular envelope collapses, preventing any yaw vectoring as well.
  • (0, 0, 0) – the engine does not deflect at all (normal for fixed/mid engines).
  • The validator does not impose a range on these values.

4. The multiplier – OpenTranslation

Despite its name, OpenTranslation is not a position or translation value. In the engine configuration it acts as a per-axis multiplier.

ValueWhat it does
1as is
−1mirrored: deflection in the opposite direction on that axis
0.5, 2, …scales the resulting deflection angle
0the engine does not deflect on that axis

Formula: Actual deflection angle = normalized stick input × maximum angle × axis multiplier.

The multiplier is how paired engines are differentiated: Z = −1 on one and Z = 1 on the other gives differential yaw.
With symmetric engines and equal thrust, equal Z signs make the engines vector in the same yaw direction, so they do not produce a differential yaw moment.

5. The deflection config comes from the first bone only

The thrust vectoring config is read from exactly one record of the group – BoneStates[0]: its OpenRotationDegrees and OpenTranslation. Records after the first take no part in that config: they belong to other bones of the engine (nacelle petals, for example) with their own angles and do not affect thrust vectoring.

Why this matters:

  • Limits and multipliers placed outside the first record of the group are invisible to physics: the engine will not deflect, and no error appears – the asset stays valid.
  • A KinematicGroup represents one engine. Each Engines[i] entry must have its own group.
  • An engine equals its own Engines[i] record with its own KinematicGroup.

For thrust vectoring only the first record of the group matters: the order of the remaining records does not affect it.

6. Order is critical

Engines[i] is engine #i in the order of your aircraft’s JSBSim config (the engines section of Propulsion.xml). Matching is by record position, not by name: neither GroupName nor BoneName affects it.

  1. Open the aircraft’s JSBSim config (.../Resources/aircraft/<JSBSimConfigName>/Propulsion.xml).
  2. Determine the order in which the engines are declared in Propulsion.xml.
  3. Create the Engines[] records in exactly that order.

Get the order wrong and the limits and signs go to the wrong engine: the wrong engine receives the deflection parameters, and the corresponding nacelle animation will also be incorrect.

The order of the mode records themselves does not matter: the required record is looked up by the Mode field.

7. How it works

[your DA_EnginePart asset]
   -> when the aircraft is granted to a player: the aircraft's server-side record (a copy of your groups)
   -> when the flight model initializes: physics takes the config ONLY from the Mode = VTOL record,
      one config per engine
   -> every frame: actual angle = stick × maximum angle × multiplier
   -> the calculated orientation is applied to the engine's thrust vector in JSBSim
      and into the animation state: the same calculated orientation is used by the animation system to rotate the nacelle
  • The part provides limits and multipliers, not animation poses: the pose is computed every frame by the flight model from the player’s current stick position.
  • The config is captured once when the flight model initializes (and when it is recreated). Editing the asset “on the fly” for an already granted aircraft will not be picked up – respawn or recreate the aircraft to reload the configuration.
  • The very same angle goes to both physics and visuals: the nacelle always shows the real thrust vector direction.

8. Plane mode: no record is required

A record with Mode = Plane is not needed, and its absence is normal: no error appears.

  • Thrust vectoring physics reads the config only from the Mode = VTOL record.
  • The Plane mode engine layer does not use DA_EnginePart for engine vectoring.

So a Plane record, if you add one, affects nothing. Engine/nacelle animation in Plane mode is controlled by the AnimBP, not by DA_EnginePart.

9. Visuals are not here

Nacelles are driven by the animation graph: Get Engine State (Index – engine number) → FinalRotation. Maximum angles and multipliers are already accounted for inside that angle.
The AnimBP must read FinalRotation and apply it to the nacelle.
See the AnimBlueprint page for details.

10. Validation

ErrorWhat is wrong
Mode = NoneA mode record has no mode selected
duplicate ModeMore than one record with the same Mode
mode record without enginesEngines holds no records
empty GroupNameThe KinematicGroup has no name
group without bonesBoneStates is empty
empty BoneNameA bone record has no name

The following are not errors: an empty ModeGroups (an empty part is valid), zero and any other OpenRotationDegrees / OpenTranslation values, duplicate bone names (only a non-empty name is required).

Contract validation is separate: the part’s AircraftIds must contain the contract’s AircraftId.

11. Verify

Verify functionality by observing physics and animation in-game: switch the aircraft to VTOL mode and deflect the flight control sticks.

What you seeCauseWhat to do
Engines do not vectorAircraft is not in VTOL modeSwitch flight mode to VTOL
One engine remains staticMissing `Engines[i]` array entryAdd the corresponding engine entry
Neither pitch nor yaw deflectionPitch limit resolves to zero (Y × OpenTranslation.Y = 0)Set non-zero `Y` rotation and multiplier
Wrong engine vectorsArray order does not match JSBSimReorder `Engines[]` entries to match `Propulsion.xml`
Engines vector in sync, but no yaw is producedPaired engines share identical Z signsInvert one side: set Z = -1 on one and Z = 1 on the other
Nacelles do not rotate visuallyAnimBP missing state reading nodeAdd Get Engine State to the AnimGraph
Changes not reflected in-gameAsset modified after aircraft spawnedRespawn or recreate the aircraft to reload the configuration.

The nacelle shows the actual angle, not the maximum from the part: if at full stick it does not reach the expected angle, the engine-vectoring configuration is the first thing to check (limit too small, zero or wrong multiplier, no record) – not the animation.

12. Example: full stick – 45°

WhereValue
ModeGroups[0].ModeVTOL
Engines[0].KinematicGroup.GroupNameEngine_FR
Engines[0].KinematicGroup.BoneStates[0].OpenRotationDegrees45, 45, 45
Engines[0].KinematicGroup.BoneStates[0].OpenTranslation1, 1, −1
Engines[1].KinematicGroup.GroupNameEngine_FL
Engines[1].KinematicGroup.BoneStates[0].OpenRotationDegrees45, 45, 45
Engines[1].KinematicGroup.BoneStates[0].OpenTranslation1, 1, 1

The result:

  • Pitch – both engines deflect 45° in the same direction.
  • Yaw – the engines deflect in opposite directions, producing a differential yawing moment.
  • Roll – the configured roll component reaches 45° at full input.

Example part in the kit: /ModExample/DataAssets/DA_ModExampleEngine_Default – one VTOL record and two engine records.

13. Checklist

  •  The DA_EnginePart asset exists and is assigned in the contract (Engine Part).
  • AircraftIds contains the contract’s AircraftId.
  • A Mode = VTOL record exists (exactly one).
  • It holds one record per engine in the JSBSim config order.
  • Every record has its first bone filled in: OpenRotationDegrees and OpenTranslation.
  • No Plane / Ground records are added, and none are needed.
  • Part and contract validation pass without errors.
  • In VTOL, the nacelles follow the calculated thrust-vector deflection and reach the configured maximum at full input.
Scroll to Top