Skip to content

Input & Controls

PFC defines the shared PFC_* action set and the "Airplane" tab in the Controls menu. The actions merge into the vanilla CarContext, so they're active whenever the player is the active pilot of a car-based aircraft. Downstream flight mods (Jet Flight Core and the aircraft built on it or on PFC) read the same actions, so every fixed-wing aircraft shares one binding set and one controls tab.

PFC_FlightController reads the flight axes, smooths them with per-axis slew limits, and exposes them to the flight model.

Flight actions & default bindings

Defined in Configs/System/chimeraInputCommon.conf. These are the actions the PFC core itself reads:

Action Keyboard Gamepad Joystick
PFC_Pitch W/S right stick Y axis1 (push = nose down)
PFC_Roll A/D right stick X axis0
PFC_Yaw Q/E left stick X axis5 (twist)
PFC_ThrottleUp Shift left stick up button4 (hold)
PFC_ThrottleDown Ctrl left stick down button5 (hold)
PFC_ThrottleAxis - - throttle lever (second device, axis2)

The gamepad layout mirrors the vanilla helicopter scheme - right stick is pitch/roll, left stick is throttle (vertical) and rudder (horizontal) - so a heli player is immediately at home, and the triggers and bumpers stay free. Joystick axis numbers are generic defaults and vary by device; players remap in the Controls menu.

Each analog axis (Pitch/Roll/Yaw) is built as an InputSourceSum of signed +/- halves, following the vanilla convention (the negative half carries an InputFilterValue Multiplier -1).

Systems actions (for variants)

The shared set also defines systems actions the core itself never reads. Variant controllers bind to these so every aircraft answers to the same keys and shows up in the same tab:

Action Purpose
PFC_GearToggle Landing gear up/down
PFC_Flaps Flaps toggle
PFC_Airbrake Airbrake toggle
PFC_FCSOverride FCS override toggle (direct law / limiters off)
PFC_ReverseThrust Reverse thrust / beta range
PFC_TrimUp / PFC_TrimDown / PFC_TrimReset Pitch trim
PFC_WheelBrake / PFC_WheelBrakePersistent Wheel brake (hold / parking)
PFC_EngineStart / PFC_EngineStop Engine start/stop
PFC_LightsTaxiToggle / PFC_LightsLandingToggle Taxi / landing lights

The Airplane controls tab

Configs/System/keyBindingMenu.conf adds one SCR_KeyBindingCategory named Airplane, with separator rows splitting it into Flight Controls, Systems, and Advanced.

Resource-merge pitfall

The engine loads exactly one copy of each of these configs, so a mod's version only merges if its .meta reuses the vanilla resource identity instead of a freshly generated one. This applies to chimeraInputCommon.conf, the control-hints AvailableActions.conf, and keyBindingMenu.conf (see the .meta files shipped with PFC). With a fresh identity nothing errors - the actions simply never load (GetActionValue returns 0 forever) or the controls tab never appears.

Cold start only

Input configs merge at cold engine start. A Workbench "Reload Game" or resource reimport does not re-merge them - do a full restart after editing.

Input smoothing

PFC_FlightController doesn't pass raw input to the model - it slews each axis toward its target at a per-axis rate, so control response is smooth and a little "heavy" like a real aircraft:

Attribute Default (prefab) Meaning
m_fControlRate 3.5 Roll slew rate (units/sec; 1.0 = full deflection in 1 s)
m_fPitchControlRate 3 Pitch slew rate (slower - heavy elevator)
m_fYawControlRate 3.5 Yaw slew rate
m_fPitchInputScale 1 Caps max pitch input magnitude (0..1)
m_fThrottleRate 0.5 Throttle change per second while held

Note

The component's attribute defaults differ from the values set on the Cessna prefab (shown above). The prefab is the source of truth for the reference airframe.

Persistent pitch

With m_bPersistentPitch enabled, pitch input stops being spring-loaded: holding W/S moves the virtual yoke (center-to-full in m_fPersistentPitchSeconds), releasing holds it in place, and opposite input walks it back. This eliminates the keyboard pitch-yoyo entirely and doubles as a trim replacement — the pilot leaves the yoke where the aircraft flies level. Roll and yaw keep the spring-back slew behavior.

Persistent pitch applies to digital (key) input only. Analog devices — gamepad and joystick axes, or a mouse axis the player binds to pitch — keep the normal spring-back behavior even with the flag enabled: stick deflection maps to yoke position through the usual slew rates, and centering the stick recenters the yoke. The controller classifies the active input each frame via GetActionInputType("PFC_Pitch") (DIGITAL vs the analog types) and latches the mode of the last nonzero input, so releasing a key holds the yoke while releasing a stick recenters it — and the split follows user rebinding automatically.

In digital mode the pitch slew rates and any GetPitchSlewRate subclass override are bypassed. Attitude-hold style assists should be disabled alongside it: they detect "hands-off" from the raw action value and would integrate trim against the held yoke.

Mouse aircraft control

When the vanilla Settings → Gameplay → Mouse aircraft control option is on (and the player is using mouse & keyboard), the mouse flies the plane instead of free-looking — the same split the setting gives vanilla helicopters:

  • Mouse movement drives a persistent virtual stick: the deflection stays where you put it (helicopter cyclic behavior), clamped to ±1 roll and ±m_fPitchInputScale pitch. W/S/A/D nudge the same stick instead of springing back.
  • Freelook (default Alt): hold to look around (the stick holds its deflection), tap to toggle the mouse back to freelook until tapped again.
  • The camera returns to the nose at m_fMouseLookReturnRate deg/s while the mouse is flying (0 = leave the view where freelook left it).
  • Yaw and throttle are unaffected; with the setting off (or on gamepad/joystick) nothing changes.

No extra setup beyond the standard PFC_FreeLookController + ForcedFreeLook 1 pilot slot — the freelook controller drops forced freelook while the mouse is flying. Mouse deltas come from two PFC-defined AnalogRelative actions in CarContext, PFC_MousePitch / PFC_MouseRoll (mouse:y_rel/x_rel halves — the ManualCameraRotateYaw pattern; the vanilla context-free MouseXRel/MouseYRel Motion actions are running totals, not deltas, and are not used). Like all input-config additions they merge at cold engine start only. Mouse flight pauses automatically while a menu, dialog, or the map is open, and while the Jet Flight Core autopilot is engaged.

Attribute Default Meaning
m_fMouseFlightPitchSens 0.04 Pitch stick deflection per PFC_MousePitch unit (negative inverts)
m_fMouseFlightRollSens 0.04 Roll stick deflection per PFC_MouseRoll unit (negative inverts)

The mouse positions the virtual stick instantly, but the published input slews toward it at m_fMouseStickSlewRate (default 2.5/s, same for pitch and roll so the pilot hand moves uniformly; the variant high-IAS pitch falloff still caps pitch on top). Control surfaces and the hand animation therefore always move at an animatable rate no matter how fast the mouse flicks. The keyboard slew rates (m_fPitchControlRate / m_fControlRate) are not used in mouse mode. | m_fMouseLookReturnRate | 120 | Head-aim return-to-center rate (deg/s) while the mouse flies |

Ground steering & key de-conflicting

Because the airframe rides on Wheeled_Base.et, its native car controls collide with the flight keys. PFC_FlightController.ApplyGroundSteering() runs in EOnFrame (the wheel sim consumes CarSteering before the simulate phase, so writing it later is ignored) and:

  • Zeroes CarThrust - otherwise W revs the car engine and you hear the leftover turbine spin up.
  • Zeroes CarBrake - otherwise S (pitch back) grabs the wheel brake.
  • Zeroes CarShift - otherwise Q/E (yaw) shift the gearbox.
  • Injects nose-wheel steering - writes the smoothed PFC_Yaw value into CarSteering (scaled by m_fGroundSteerScale, default -1.0), so Q/E steer the nose wheel on the ground while A/D stay roll-only. Set m_fGroundSteerScale to 0 to disable (then A/D steer as vanilla).

Free look

PFC_FreeLookController gives car-based aircraft the helicopter-style camera:

  • Mouse & keyboard - the mouse free-looks, no modifier needed (unless the Mouse aircraft control gameplay setting is on — then the mouse flies the plane and Freelook works as on gamepad, see above).
  • Gamepad - the camera stays locked to the nose. Hold the vanilla Freelook modifier (right bumper) and the right stick pans the camera instead of flying; release and the camera stays where you left it; tap the modifier to recenter. While the modifier is held the flight controller ignores right-stick pitch/roll (yaw and throttle on the left stick stay live).

Setup needs two pieces, both required:

  1. Add the PFC_FreeLookController component to the vehicle prefab.
  2. Set ForcedFreeLook 1 on the pilot compartment slot.

The slot's ForcedFreeLook 1 keeps the camera following the head aim, so a pan is never auto-recentered. The controller then drives the character's freelook state per device every frame: forced free look for mouse & keyboard, cleared for gamepad unless the Freelook modifier is held (which is what keeps the right stick from panning without the modifier).

A static slot value alone is not enough

On a car-based aircraft no single ForcedFreeLook value gives the heli feel: 1 alone frees the camera for both devices (gamepad pans without any modifier), while 0 locks mouse look and auto-recenters gamepad pans the moment the modifier is released. The per-device controller plus ForcedFreeLook 1 is the working combination.