Skip to content

08 — Camera, input, movement

  • FS §4 Camera, §5 Input, §6 Movement, §7 Loadout (hotkeys)
  • GDD: Hybrid Perspective, Input Infrastructure, Character Movement
  • Demo Space / stance detail: 22-demo.md
  • MASTER key state matrix: § Keymapping bible below (FS-INP-004)

Keymapping bible — Press / Hold / Release (MASTER)

Section titled “Keymapping bible — Press / Hold / Release (MASTER)”

Language: GDD paper-doll catalog says Physical Shield; HUD / FS / this bible use short form Phys Shield (same slot). Wall Run is current (was Wall Walk). Parkour DA fields: WallRunMaxDuration / MaxWallDashDistance / MaxWallTurnDegrees / WallRunLookaheadDistance / WallRunLookaheadSamples (mock UI may show …Sec / …M suffixes — same values). Curve / end-of-wall: docs/superpowers/specs/2026-11-02-wall-run-curve-end-design.md. Wall Run presentation: L/R authored cycle while attached; ground Pose Search at enter/exit edges only (docs/superpowers/specs/2026-11-07-wall-run-motion-matching-design.md) — CMC still owns peel/path. Demo + Full + Cinematic Benchmark locomotion: Motion Matching / Pose Search (FS-FX-002 · docs/superpowers/specs/2026-11-02-motion-matching-full-design.md). Full tutorial (Demo + Full, Lyra upper/lower): tutorials/motion-matching-demo-and-full.md. MM mesh motion never owns Look.

Contract: Every bound control is defined for Press (Started), Hold (ongoing past hold threshold 200 ms, or continuous while down), and Release (Completed / Canceled). Context (stance, wall-run, air, chat, map) may change the verb — never leave a state “undefined.”

EI mapping: On-foot IMC_TFA_Default · UI IMC_TFA_UI · Map IMC_TFA_Map · Chat IMC_TFA_Chat (FS-INP-002). Additive TF IMCs only — do not rip Lyra crouch/move/look (02b).

Hold threshold: 200 ms on UTFAInputConfig (was TBD-006, locked 2026-10-30). Fast combat default — under ~150 ms false-holds on taps; over ~300 ms feels sluggish for stance / radial. Same value for loadout 2·4·6·7, Tab, pad LB radial, pad RB wheel. Demo Mod may expose a dial; playtest can nudge ±50 ms without a redesign.

Context priority (high → low): Chat compose → Map UI → Character I / Esc overlays → On-foot default.

Legend: — = no gameplay change for that edge · no-op = input ignored · TBD-* = do not invent in C++

State Behavior
Press Begin axis contribution toward move vector. Ground / air: camera-yaw relative. Wall Running: wall-locked (along tangent — see below)
Hold Sustain move. Double-tap same axis within the window (250 ms, provisional, dial DoubleTapWindowSeconds on UTFAInputConfig; fires on the second press) → Dodge that way (FS-MOV-001). If Crouch also down → Roll. While Wall Running: double-tap opposite side → opposite-wall dash jump if in MaxWallDashDistance (FS-MOV-004); on success continue Wall Run + reset Wall Run timer to full; same-side double-tap = no transfer (not ground Dodge)
Release Drop that axis from move vector. Does not cancel an in-flight Dodge/Roll/dash montage

Wall Run move space (≠ ground): While stuck, W / forward = along wall tangent; A/D = along-wall lateral / lean — not remapped by camera yaw. Look does not steer the path (spin mouse 180° + hold W → keep running along the wall). No soft camera assist. Spec: docs/superpowers/specs/2026-11-02-wall-run-camera-move-design.md · FS-MOV-004.

State Behavior
Press N/A (axis) — first delta applies look
Hold Continuous look. Look never follows mesh flip / jump anim / Wall Run mesh re-stick (look-vs-body · 22-demo). During Wall Run look stays free; does not peel or redirect run
Release Stop look deltas

Left Shift / LS click (L3) — Sprint (toggle default)

Section titled “Left Shift / LS click (L3) — Sprint (toggle default)”

Default sprint binds: PC Toggle Sprint on Left Shift; pad LS click (L3) Toggle Sprint. Hold Sprint is a separate remappable bind — unbound by default. No full-tilt stick sprint. Remappable (FS-INP-001 · FS-INP-006).

State Behavior
Press Toggle Sprint: if not sprinting and grounded / legal → enter sprint; if already sprinting → exit sprint. Same for Shift and L3
Hold Only when Hold Sprint is bound: maintain sprint while held (needed with Crouch → Slide, with Space → Wall Run enter gate). Under Toggle default, Hold is —
Release Toggle: no-op (sprint stays until cancel or second Press). Hold Sprint layout: exit sprint. Does not cancel Slide already started · does not cancel Wall Run (Wall Run is not hold-to-stick)

Sprint cancel (any engage path): stop move · ADS · Fire start · plain Crouch (not Slide) · illegal stance. Cancel clears sprint; does not peel Wall Run already attached.

Built (2026-11-04): UTFAGameplayAbility_Sprint (ADDON), input tag InputTag.TFA.Sprint, IA_TFA_Sprint with Pressed triggers in IMC_TFA_Default (Left Shift · pad LS click). Toggle is a designer lock. Sprint ends on a second Press, on stopping (speed below SprintStopSpeed for SprintStopGraceSeconds), on crouch, or when a Slide starts; status tag Status.Sprinting. Speeds were tuned by feel and approved 2026-11-04 (1 unit = 1 cm, 100 cm/s = 2.24 mph). A 1100 cm/s sprint (25 mph) was rejected as too fast, and 300 cm/s normal run as too slow.

Speed cm/s mph Where it lives
Normal run 600 13.4 BP_Hero_TerraFirma → Max Walk Speed (same as stock Lyra)
Crouch walk 300 6.7 BP_Hero_TerraFirma → Max Walk Speed Crouched
Sprint 900 20.1 SprintSpeed
Slide threshold (min speed to slide) 750 16.8 SlideMinSpeed
Sprint stop speed 150 3.4 SprintStopSpeed

Other dials: SprintStopGraceSeconds 0.25 s, SlideMaxDuration 1.25 s. All movement dials are in Project Settings → Game → TFA Movement (UTFAMovementConfig, ADDON; defaults in DefaultGame.ini, no rebuild to change). Normal run and crouch walk are set on the hero Blueprint, not in that panel.

Auto Sprint (Options → Controls): boolean, OFF by default (FS-INP-006). When ON, forward move past threshold while grounded / legal auto-enters sprint (no Shift / L3 required). Toggle Sprint still cancels / re-engages. Hold Sprint (if bound) still works. Slide and Wall Run enter gates still require the sprinting state — Auto Sprint can supply it.

B. Shared Space / Jump family — Space · Cross / A

Section titled “B. Shared Space / Jump family — Space · Cross / A”

Same physical key. Context picks the verb (AC-INP-001). Never Dodge or Slide.

State Ground / air (no wall) Near low ledge (ex-Vaultable) Sprint + near WallRunnable Already Wall Running Air after wall jump-off (air-jump charge still available) Chat / map / I open
Press Jump (or air double-jump if charge) Jump only — WILL NOT USE Vault (FS-MOV-003) Enter Wall Run (FS-MOV-004) Wall jump-off Double jump along wall-exit vector — not a left/right dash Usually swallowed by UI; intro skip uses Space (FE)
Hold No extra verb — jump impulse already fired — No hold-to-stick — Wall Run continues without Space held Hold does not stick to wall — —
Release — (does not cancel jump arc) — Does not cancel Wall Run — — —

Not a L/R dash on Space: After wall jump-off, Space’s air jump follows the exit vector of that peel-off (carry leave direction — not free aim/stick redirect, not “dash left/right”).

Opposite-wall dash jump (L/R): while Wall Running, double-tap move toward the opposite side (Wall Run Left → double-tap Right, and vice versa) → dash jump across if in MaxWallDashDistance (FS-MOV-004; lab default 6.0 m, DEX/affix scaled). Success → continue Wall Run on the new wall and reset WallRunMaxDuration to full (lab default 3.0 s, DEX/affix scaled). Fail → no transfer; timer unchanged. Uses move keys / stick, not Space (Space = wall jump-off). Demo Mod Lab › Parkour exposes duration · dash · turn · lookahead dials.

Wall Run persist (geometry): continuous stick while tagged contact holds. Auto peel (same exit as wall jump-off) when lookahead finds no wall (WallRunLookaheadDistance 2.0 m / 4 samples) or normal delta > MaxWallTurnDegrees (45°). Gentle curves under the gate re-stick normals without resetting the timer (FS-MOV-004). Perspective during the stint still follows FS-CAM-001 (gun TrueFPP / melee WideTPP) — Wall Run does not force WideTPP.

WILL NOT USE: Parkour Vault / Carbon Vault* (FS-MOV-003). If WallRunnable is legal, Space enters Wall Run; else Jump — never a vault montage.

State Behavior
Press Hold-to-crouch (designer lock 2026-11-02), not a toggle. If moving at or above SlideMinSpeed (750 cm/s, 16.8 mph) → start Slide (FS-MOV-002) instead of plain crouch. The trigger is a speed threshold, not the Sprint button
Hold Stay crouched while held. After a Slide ends, still holding Ctrl means crouch. Held crouch during move double-tap → Roll not Dodge
Release Stand up. A Slide runs to its end (SlideMaxDuration 1.25 s, or the speed falling out) and releasing mid-Slide does not stand up early (designer lock 2026-11-03). Never starts/stops Wall Run

Built (2026-11-02…04): UTFAGameplayAbility_CrouchSlide and UTFAGameplayAbility_DodgeRoll (ADDON, standard movement so they live there for now), input tags InputTag.TFA.Crouch / InputTag.TFA.Dodge, status tags Status.Sliding / Status.Sprinting. IMC_TFA_Default (TFAInput plugin) maps Ctrl and pad B → Crouch at priority 2 with Consume Input on, so Lyra’s own IA_Crouch never fires. Dodge uses a custom trigger UTFAInputTrigger_DoubleTap on each of W/A/S/D (it fires on the second press; Epic’s built-in Repeated Tap fires on release and cancels on a held second tap, so it was rejected). Dodge and Roll dispatch one frame late, because an ability fired on the frame a key goes down runs before the character reads that frame’s move input and sees no direction. Dash is blocked while crouching, which is why crouch + double-tap = Roll. A Dodge that “does nothing” is usually GE_HeroDash_Cooldown (about 1.5 s, FS-MOV-001 “cannot chain”, TBD-007). LogTFADodge prints one line per double-tap.

LMB / RT · R2 — Weapon Discharge or right-hand shield bash/block

Section titled “LMB / RT · R2 — Weapon Discharge or right-hand shield bash/block”
State Firearm / partner on right (default) Phys Shield in-hand on right
Press Fire / start auto · Instant FPP if gun stance allows (FS-CAM) Shield bash (FS-LOD-009)
Hold Sustain auto / charge frames (Fusion etc.) Block / guard
Release Stop auto / release charge · melee-only: usually no-op End block

RMB / LT · L2 — Precision Aim (ADS) or left-hand shield bash/block

Section titled “RMB / LT · L2 — Precision Aim (ADS) or left-hand shield bash/block”
State Solo gun / solo 2H (ADS legal) Phys Shield in-hand on left (default) Dual / hybrid (no shield)
Press Enter ADS Shield bash — not ADS HARD LOCK no ADS
Hold Stay ADS / Shift-Out if melee follow-through legal (FS-CAM-004) Block / guard no-op
Release Exit ADS / end Shift-Out End block —

Hand rule (FS-LOD-009): bash/block always uses the button on the shield’s side. Default pair = 1H partner right + shield left → fire on LMB/RT, bash/block on RMB/LT.

State Behavior
Press Melee Strike GA (directional along stick/camera) (FS-CMB-002). If gun drawn → pull TPP for strike (FS-CAM). Not used for Phys Shield bash (bash = shield-hand side button). Airborne (regular jump / double jump / post wall-exit air): same directional slash set; no root motion / Motion Warp — keep jump arc (FS-CMB-002 air · spec 2026-11-02-air-melee-drive-design.md). Downward-slash art = later polish
Hold No separate hold-melee unless a charged skill binds later (not baseline)
Release — (does not cancel strike montage mid-window unless GA Cancel tag)

E. Loadout stance — Keys 1–7 · pad Hold RB / R1 stance wheel (FS-INP-005)

Section titled “E. Loadout stance — Keys 1–7 · pad Hold RB / R1 stance wheel (FS-INP-005)”

Hold threshold = 200 ms. Tap = Press+Release before threshold. Hold = Press sustained past threshold (action fires on threshold or on Release — implement as EI Tap/Hold chord; document both edges below).

Built (2026-11-14): keys 1–7 and the mouse wheel are live in IMC_TFA_Default at priority 2, so they win over Lyra’s own quickslot keys (One / Two / Three and the wheel in ShooterCore’s IMC_ShooterGame). One ability class, UTFAGameplayAbility_StanceKey (ADDON), is granted nine times in the hero ability set. It reads which key it is from the input tag it was granted with (InputTag.TFA.Stance1 … Stance7, InputTag.TFA.WheelUp, InputTag.TFA.WheelDown) and calls the stance owner through the TFACore contract ITFAStanceInput, so it never includes TFACombat. Keys 2, 4, 6, 7 use the hold threshold dial (200 ms, UTFAInputConfig): released before it is a Tap; still down at the threshold is a Hold, fired at the threshold, and the ability stays active until the key is released so a held key cannot repeat the Hold. Keys 1, 3, 5 have no Hold verb and Tap on press. The wheel sends one notch per press, wheel up = forward through the singles loop (the direction is an open question, see 09 loadout and stance). The stance itself is owned by UTFALoadoutComponent (TFACombat): rules in FTFAStanceMachine (covered by an automation test), server authoritative, replicated as TFA.Stance.* tags.

Temporary bridge: until a weapon plugin spawns weapons from the stance, a solo gun stance also sets Lyra’s quickbar slot (dials in Project Settings → Game → TFA Loadout: on/off, and which slot each gun uses). The hero starts with an empty quickbar, so weapons must be picked up before a swap shows. Remove the bridge when TFAWeapons drives equipment. Pad bindings for stance are not built: Lyra uses D-pad left / right for quickslot cycling, LB for grenade and RB for melee, which clash with the pad plan below.

State Behavior
Press Arm Wrist Razors/Claws stance (solo Wrist Melee slot only — not Weapon 1–4) (FS-LOD-004). Never pairs Phys Shield
Hold Same as tap — no alternate hold cycle
Release If tap path: commit Wrist on release-before-threshold · if already committed on press, —
State Behavior
Press Start tap/hold watch
Hold (past threshold) Cycle Dual guns ↔ Gun + Phys Shield (skip empty) (FS-LOD-004)
Release (before threshold) Tap 2 → Primary gun single (FS-LOD-003 resets family to single)
Release (after hold fired) — (stance already set on hold)
State Behavior
Press Start tap watch
Hold no-op (no Hold 3 cycle locked)
Release (tap) Secondary gun single
State Behavior
Press Start tap/hold watch
Hold Cycle Dual melee ↔ Melee + Phys Shield (skip empty)
Release (tap) Primary melee single
State Behavior
Press Start tap watch
Hold no-op
Release (tap) Secondary melee single
State Behavior
Press Start tap/hold watch
Hold Primary gun + Secondary melee
Release (tap) Primary gun + Primary melee. No-op if 2H / illegal (FS-LOD-006)
State Behavior
Press Start tap/hold watch
Hold Secondary gun + Secondary melee
Release (tap) Secondary gun + Primary melee

F. Mouse wheel — stance cycle (FS-INP-003 · FS-LOD-005)

Section titled “F. Mouse wheel — stance cycle (FS-INP-003 · FS-LOD-005)”
State Behavior
Press N/A (axis notch) — each notch = one step
Hold N/A (discrete notches); rapid notches = multiple steps
Release —

Singles loop (Wrist on the wheel — 2026-10-30). Skip empty. Wraps. Never enters Dual or Phys Shield:

Wrist → Primary gun → Secondary gun → Primary melee → Secondary melee

Current stance Wheel does
Wrist Singles loop
Single gun Singles loop (includes Wrist)
Single melee Singles loop (includes Wrist)
Gun + Phys Shield Which 1H gun paired (Wrist not in this loop)
Melee + Phys Shield Which 1H melee paired (Wrist not in this loop)
Dual guns / dual melee no-op
Hybrid Cycle four gun×melee combos

Dual / shield still need Hold 2 / Hold 4. Tap 1 still snaps to Wrist. Lock: do not merge Dual / Phys Shield into the singles mouse-wheel loop (playtest-confirmed design — Hold stays deliberate; pad Hold-RB wheel may show all stances).

State Behavior
Press Cycle vision mode (+1, wrap seven) (FS-INP-001)
Hold no-op (no hold-to-scroll locked)
Release —
State Behavior
Press Push Character screen I (IMC_TFA_UI). Closes chat compose without send if open
Hold —
Release — (close is Esc / I toggle — match FE: I or Esc closes)
State On-foot (chat closed) Chat compose focused Inside Map UI
Press Start tap/hold watch (IA_TFA_Map) Chat channel cycle (Fireteam→Clan→Match→General→Proximity; Whisper not Tab) — (see hold/release)
Hold (≥ threshold) Open Local Map (on planet) or World Map (orbit/station) no-op for map —
Release (before threshold) GUI locator ping 4 s Channel already advanced on press Map Toggle Local↔World (IA_TFA_MapToggle) on press/release per Map IMC — treat as Press toggle
State Behavior
Press Start tap watch (suppressed in chat)
Hold Open map same as Hold Tab if chorded on M (FS-INP-002 allows M on Map IA)
Release (tap) GUI locator ping 4 s

J. Chat & session — Enter · Shift · Esc

Section titled “J. Chat & session — Enter · Shift · Esc”
State Chat closed (Online, in play, no overlay) Compose focused
Press Open compose (IA_TFA_ChatOpen). Solo: no-op If no Shift: send (empty → close without send). If Shift held: newline
Hold — —
Release — —
State Behavior
Press Modifier only
Hold Shift+Enter → newline (IA_TFA_ChatNewline)
Release Clear modifier

(Same Left Shift is Toggle Sprint on-foot when chat closed — contexts mutually exclusive via IMC priority.)

State Compose open Else in play
Press Close chat without send — do not open session menu Open session / Esc menu (FE)
Hold — —
Release — —

K. Combat economy / world use (keyboard locked 2026-10-30)

Section titled “K. Combat economy / world use (keyboard locked 2026-10-30)”

Pipeline: Customizable 4×4 on Character I empowers Ultimates (drag Combat / Tentacle skills into cells). Then drag Ultimate seats and/or Combat-tree skills onto the combat hotbar (6 slots). Hotkeys = those slots. Tentacles never enter the hotbar — mount on Tentacles tab, toggle Active/Inactive with T. Grenades stay G.

Key verify (2026-10-30): F is free for hotbar (demo coach “F FPP/TPP” superseded — stance owns perspective, FS-CAM-001). V is not free — Vision cycle owns V / D-pad Up (FS-INP-001). Do not put Vision on the hotbar without relocating Vision first.

Combat hotbar — Q · E · Z · X · C · F (6 slots; was TBD-004 / TBD-013)

Section titled “Combat hotbar — Q · E · Z · X · C · F (6 slots; was TBD-004 / TBD-013)”
Slot Key Press Hold Release
1 Q Cast bound Ultimate (if charged) or Combat skill Aura toggle hold if authored —
2 E If Interact prompt legal → Interact (not hotbar). Else cast slot 2 Hold-to-complete Interact or aura hold Cancel hold-interact
3 Z Cast bound content Aura hold if authored —
4 X Cast bound content Aura hold if authored —
5 C Cast bound content Aura hold if authored —
6 F Cast bound content Aura hold if authored —

Legal hotbar contents: Ultimate 1–4 (Customizable rows) · Combat-tree offensive skills / auras. Illegal: tentacles · grenades · Vision · empty empowerment-cell widgets. Shared Shiv charge (FS-HUD-007).

State Behavior
Press Throw / start cook if authored
Hold Cook if applicable
Release Throw on release if cook
State Behavior
Press (tap RB) Start reload (mag ← reserve)
Hold RB Stance wheel (not reload) — see pad table
Release — for reload tap; commit stance if wheel was open

Interact — KB shares E · pad D-pad Down

Section titled “Interact — KB shares E · pad D-pad Down”
State KB Interact prompt legal KB else Pad
Press World use (wins over hotbar 2) Hotbar slot 2 cast D-pad Down = Interact when prompt legal; else no-op
Hold Hold-to-complete if authored Aura hold if slot has aura Hold-to-complete if authored
Release Cancel hold-interact — Cancel hold-interact

Pad keeps Interact off the ability radial (cleaner than KB E dual-use). No vault on Space / A / Cross (FS-MOV-003 WILL NOT USE).

Tentacles Active / Inactive — T · pad RS click / R3

Section titled “Tentacles Active / Inactive — T · pad RS click / R3”
State Behavior
Press Toggle mounted tentacles Active ↔ Inactive (FS-PRG-005)
Hold —
Release —
State Behavior
Press Tap = bash
Hold Block / guard
Release End block

Same-side button as shield hand (FS-LOD-009); default left → LT/L2 / RMB.

Special Takedown: no button — auto at 30 combo (FS-INP-001).

Pad defaults — Xbox / DualSense (FS-INP-005, playtest provisional)

Section titled “Pad defaults — Xbox / DualSense (FS-INP-005, playtest provisional)”

Names: Xbox · DualSense. Keyboard remains PC authority. Faces may change after playtest; update FS-INP-005 when they do.

Input Tap / Press Hold Release
LB / L1 no-op Open ability radial (hotbar 1–6) Cast highlighted wedge
RB / R1 Reload Open stance wheel (loadout 1–7) Commit highlighted stance
Y / Triangle Grenade / cook start Cook if authored Throw if cooking
RS click / R3 Tentacles Active ↔ Inactive — —
D-pad Up Vision cycle — —
D-pad Down Interact (prompt legal) Hold-to-complete Cancel hold-interact
D-pad Left / Right Reserved (playtest) — —
View / Create GUI locator ping Local / World map —
Menu / Options Session Esc Character I —
A / Cross Jump / Wall Run / wall jump-off / air jump (no Vault) — Does not cancel Wall Run
B / Circle Crouch · Sprint+Crouch=Slide Stay crouched End crouch per mode
X / Square Melee Strike — —
LT / L2 ADS or left-hand shield bash ADS / block End ADS / block
RT / R2 Fire or right-hand shield bash Auto / charge / block Stop fire / end block
LS Move; click (L3) = Toggle Sprint — (Hold Sprint only if remapped) Toggle: no-op · Hold layout: end sprint
RS Look; while LB/RB held = aim radial/wheel — —

Ability radial (Hold LB): six wedges clockwise from top = slots Q · E · Z · X · C · F. RS aims. Release LB casts. Cancel: stick deadzone + release, or B/Circle while LB held. Empty wedge = no cast.

Stance wheel (Hold RB): seven wedges = loadout keys 1–7 (same verbs as §E). RS aims. Release RB commits. Tap RB (no hold) = Reload only.

How to cast a skill / Ultimate on pad: put it on the hotbar in Character I → in play, hold LB → aim RS at that wedge → release LB.

Group Keys Count
Move WASD 4
Jump family Space 1
Crouch / Slide Ctrl 1
Sprint Left Shift (Toggle; Hold Sprint unbound default) 1
Fire / ADS / Melee LMB · RMB · Mouse4 3
Stance 1–7 · Mouse wheel 7 + wheel
Combat hotbar Q E Z X C F 6
Grenade / Reload / Tentacles / Vision G · R · T · V 4
Interact shares E 0 extra
UI / Online I · Tab · M · Enter · Esc 5
Dev only (not shipped) H (perspective flip) 1

Stance-driven camera and the dev flip on H (2026-11-14)

Section titled “Stance-driven camera and the dev flip on H (2026-11-14)”

Stance owns perspective (FS-CAM-001), and it is built. UTFACameraDirector (TFACombat, local player only) picks first person or third person from the current stance: a gun stance (solo gun, dual guns, gun + Phys Shield) is first person at about 105° FOV; a melee stance (solo melee, dual melee, melee + Phys Shield, Wrist) and no stance are third person (CM_ThirdPerson). Hybrid holds a gun and a melee weapon, which the spec does not settle, so it is a dial and an open question (09). There is no camera button in the shipped game.

How it works, with no Lyra code edited: Lyra picks a camera mode through ULyraCameraComponent::DetermineCameraModeDelegate (the hero component binds it: an ability’s mode such as ADS, otherwise the pawn data default). The director wraps that delegate. Whatever Lyra already chose is kept when it is not the plain default mode, so ADS always wins; when it is the default and the stance wants first person, the first-person mode is returned instead. The first-person mode is held as a class path in settings, so TFACombat never includes the plugin that owns it. The director is created by UTFALoadoutComponent on any machine that renders and waits (a short timer, no Tick) until it is the local player’s pawn.

H is a dev flip, not part of the shipped keymap. It flips whatever the stance chose: in a gun stance (first person) it shows third person so you can look at your own character, and in a melee stance (third person) it shows first person. Pressing it again flips back, and the flip clears by itself when the stance’s own perspective changes, so it never inverts the wrong way. H was chosen because it is unbound in every context attached to the hero (stock Lyra and ShooterExplorer already use P, B, G, I, M, Q, E, Tab) and the bible reserves none of the remaining letters.

State Behavior
Press Flip the perspective the stance chose (dev only)
Hold —
Release —

Built as UTFAGameplayAbility_ToggleCamera (ADDON, a one-shot, input tag InputTag.TFA.ToggleCamera, action IA_TFA_ToggleCamera with a Pressed trigger in IMC_TFA_Default). It finds the stance owner on the pawn through the TFACore contract ITFAPerspectiveOverride and never includes TFACombat; if TFACombat is not enabled it does nothing. It runs only on the owning client (LocalOnly): other players still see the full body with its head, nothing about the flip replicates. (Before 2026-11-14 H toggled first person on and off through ULyraHeroComponent::SetAbilityCameraMode; the head hiding moved into the camera mode when the director landed.)

This is a stop-gap in other ways too: the arms use the third-person animations and may look odd from the camera, and the long-term plan (not a bible requirement, our own direction) is a hidden third-person body plus separate first-person arms and weapon, which will replace it. Known gap: ADS while in a first-person stance still asks Lyra for its third-person ADS camera, until a first-person ADS camera mode exists.

Director dials (no rebuild): Project Settings → Game → TFA Camera Director (UTFACameraDirectorConfig, TFACombat):

Dial Value Meaning
bStanceDrivesCamera on master switch; off = default third person plus the H flip, takes effect immediately
bHybridIsFirstPerson on the Hybrid stance (gun + melee) is first person; off = third person (open question)
FirstPersonCameraMode /Script/ADDONRuntime.TFACameraMode_FirstPerson the first-person mode to request, as a class path

Camera position and look. The first-person view position follows the animated head bone plus a forward and an up offset, and its rotation is the controller’s, so lean, bob, crouch and slide carry the view while mesh flips, rolls and slides cannot rotate it (look-vs-body lock). Lyra’s own eye point is the capsule centre, which sits behind the mannequin’s head (you saw the shoulders and back from the back of the skull). Rolling was tried in play by the user on 2026-11-04 and looks fine. Known and accepted for now: the head sways with the third-person walk animation, and the hidden head casts no shadow (hiding the bone shrinks it; the dual-mesh rig will fix this with a hidden full body that casts the shadow).

Hiding the head. The first-person camera mode (UTFACameraMode_FirstPerson, ADDON) hides the head itself while it is the active mode, so it applies however first person was chosen, and it shows the head again the moment the camera is asked for a different mode, not when the blend out finishes (Lyra only reports a mode as finished after the blend, which showed the head at the end of the zoom-out). The head is hidden on the part meshes directly (each part has its own pose through ABP_Mannequin_CopyPose), not with “owner no see”. Lyra’s body parts are child-actor components, and Unreal only makes a child actor owned by its parent when the component’s bSetOwner flag is on (default off, and Lyra leaves it off), so owner-no-see never applied to them (found 2026-11-04 when the head stayed visible). Do not hide the hero’s own Mesh (SKM_Manny_Invis) with owner-no-see either: the part meshes copy its pose, and un-rendered it stops updating, which froze the whole body (found 2026-11-04).

Dials (no rebuild): Project Settings → Game → TFA Camera (UTFACameraConfig, ADDON):

Dial Value Meaning
FirstPersonFOV 105 FS-CAM-001 “~105°”
FirstPersonBlendSeconds 0.2 s blend into / out of first person
FirstPersonEyeBone head bone the view position follows
FirstPersonEyeForwardOffset 8 cm in front of the bone, along the look yaw only (tuned by eye in play)
FirstPersonEyeUpOffset 8 cm above the bone (tuned by eye in play)
FirstPersonHiddenBones neck_01 mannequin skeleton: neck_01 → neck_02 → head
FirstPersonHideWholeBody off hide everything instead of just the head
FirstPersonCrouchBlendSeconds 0.2 s fallback only (see below)

Crouch fallback: if the eye bone is not found, the camera uses Lyra’s capsule eye point, which deliberately stays at standing height while crouched (Lyra’s base mode cancels the capsule shrinking; only its third-person mode lowers it), so first person lowers it itself by CrouchedEyeHeight - BaseEyeHeight with an ease-in-out blend. With the head bone followed, crouch and slide height come from the animation instead.

Current state (2026-11-14). The TFAInput game feature plugin owns all Terra Firma input mapping: IMC_TFA_Default (built; priority 2), the input config DA_TFA_InputConfig (input tag → ability) and a game feature action that attaches them additively, so Lyra is never forked. Timing dials (DoubleTapWindowSeconds 0.25 s, HoldThresholdSeconds 0.20 s) are in Project Settings → Game → TFA Input (UTFAInputConfig). The name is TFAInput, not TFAIMC, because “IMC” already has a specific Enhanced Input meaning. IMC_TFA_UI, IMC_TFA_Map and IMC_TFA_Chat are not built yet. TFACore (contracts only: the TFA.* tag taxonomy of FS 2.3 and the ITFAStanceInput interface) and TFACombat (UTFALoadoutComponent and the stance rules) are built and live in the demo. The abilities behind the inputs (crouch / slide, dodge / roll, sprint, camera toggle, stance keys) currently live in ADDON. Plugins meet through TFACore contracts and never include each other’s headers (see the cookbook hard rules). The demo map ADDON/L_TestMap uses the experience B_TFA_Experience, which enables ADDON, ShooterCore, TFAInput and TFACombat. The hero is BP_Hero_TerraFirma (ADDON), parented straight to Lyra’s stock B_Hero_Default; its only real change is JumpMaxCount = 2 (double jump) and the speeds above. Rule: copy a Lyra asset only if we change it.

Domain IMC Owning GFP
Move / look / crouch / sprint (host) Lyra + additive TF Lyra HeroComponent; TF does not fork
Space parkour / dodge axis IMC_TFA_Default TFACombat (ADDON scratch OK)
Fire / ADS / melee strike IMC_TFA_Default TFAWeapons / TFAMelee + Combat spine
Stance 1–7 / wheel IMC_TFA_Default TFACombat loadout
Vision IMC_TFA_Default TFAVision (Demo may stub)
Map / ping IMC_TFA_Default + IMC_TFA_Map TFAWorld / Frontend map widgets
Chat IMC_TFA_Chat TFAOmniVisor / Online
I / Esc IMC_TFA_UI TFACharacterI / Frontend

The old host asset IMC_Default_TerraFirma (/Game/Input/Mappings) was not an orphan but redundant: ADDON’s game feature attached it, and all 18 of its mappings (move, look, fire, jump, crouch, reload, auto-run; keyboard and pad) also existed, key for key, in Lyra’s own IMC_Default. The Dash and C → IA_Slide mappings and IA_Slide were removed on 2026-11-04, ADDON’s attach action was emptied the same day, and the asset itself was deleted on 2026-11-14 after play-testing every key without it.


Done (design / doc locks only — not runtime on live host)

Section titled “Done (design / doc locks only — not runtime on live host)”
  • Keymapping bible Press / Hold / Release matrices (§ above) — FS-INP-004 (markdown)
  • Design locks: Space context stack, stance tap/hold, Tab/M/chat, ADS hard locks
  • Keyboard locks: hotbar Q/E/Z/X/C/F (6) · V=Vision · Grenade G · Reload R · Tentacles T · Interact-on-E-when-prompted (2026-10-30)
  • Pad defaults (FS-INP-005, playtest provisional): LB ability radial · RB tap reload / hold stance wheel · Y grenade · R3 tentacles · D-pad Down Interact · View ping/map · Menu Esc/I

Revert lock (2026-11-02): Prior TF keymapping runtime attempts are not shipped. Live 5.8_terra_demo has no IMC_TFA_*. Treat product EI as Need remake from this bible — do not mark keymapping Done in Have/Need for the host.

Update (2026-11-14): the project is now dev_ready4droid-game-demo (Lyra 5.8). IMC_TFA_Default is built in the TFAInput plugin and checked in play: Crouch / Slide, Dodge / Roll, Sprint toggle, the dev camera toggle, and stance keys 1–7 with the mouse wheel. IMC_TFA_UI / _Map / _Chat, stance on the gamepad and Wall Run to spec are still not built.

  • Lyra Enhanced Input hero configs (IMC_Default, ShooterCore IMCs)
  • TFAInput plugin: IMC_TFA_Default, DA_TFA_InputConfig, UTFAInputConfig / UTFAInputTrigger_DoubleTap; ADDON abilities for crouch / slide, dodge / roll, sprint toggle, the stance keys and the dev first / third-person toggle (H)
  • TFACore (tag taxonomy, ITFAStanceInput) and TFACombat (UTFALoadoutComponent, stance rules with an automation test, “TFA Loadout” settings, temporary Lyra quickbar bridge)
  • ADDON content GAs: Roll / Slide / WallRun (folder present; ADDON not in .uproject)
  • Wall-run backup variants under _WallRunBackup\ (if present)
  • Author + wire IMC_TFA_UI / IMC_TFA_Map / IMC_TFA_Chat (IMC_TFA_Default is built and IMC_Default_TerraFirma is deleted)
  • Tap/Hold chords for Tab/M · LB radial · RB stance wheel per this matrix (keys 2·4·6·7 and the mouse wheel are built)
  • Playtest finalize pad faces · pad chat TBD-033
  • Wire locked dials at runtime: Hold 200 ms · WallRunMaxDuration 3.0 s · MaxWallDashDistance 6.0 m · MaxWallTurnDegrees 45 · WallRunLookaheadDistance 2.0 m · WallRunLookaheadSamples 4 · DEX %/pt lab defaults 1.0 / 0.75 (Demo Mod Lab › Parkour; affixes may add on duration/dash only)
  • Persist ADDON in .uproject before relying on parkour GAs in PIE
  • Hybrid FPP/TPP (FS-CAM-001…005): the stance-driven perspective is built (UTFACameraDirector, 2026-11-14). Still to do: Shift-Out and the strike pull to third person (need melee), the first-person ADS camera, the dual-mesh first-person rig, FS-CAM-002 / 003 feel work
  • Wall Run FS completeness (FS-MOV-004); Vault remains WILL NOT USE (FS-MOV-003)
  • Custom movement modes server-simulated (FS-MOV-005)
  • AC-CAM-001, AC-INP-001, AC-MOV-001, AC-LOD-001
  • AC-INP-002 (bible): For each key in § Keymapping bible, Press/Hold/Release behave as tabled in on-foot PIE (chat/map/I contexts sampled)