Skip to content

25 — How to program Terra Firma (Full game)

Audience: Engineers learning the Year-1 Full-game spine.
Engine: Unreal Engine 5.8 · Lyra host · Game Feature Plugins.
Authority: FS · Architecture Map · 02b-plugin-dependencies.md (MASTER deps) · 20-critical-path.md · 02-gfp-cookbook.md.
Sibling: Demo-only path → 26-howto-program-demo.md.

This chapter is a how you would program it walkthrough — not a calendar. Follow plugin order; keep Lyra mergeable.


  1. Lyra is the host, not your game. Experiences + GFPs load your systems. Do not turn LyraGame into Terra Firma.
  2. Never edit Epic-shipped Lyra .uassets. Duplicate IMC / PawnData / AbilitySet / widgets into your GFP, then edit the copy.
  3. C++ gameplay lives in GFPs (TFACore, TFACombat, TFAWeapons, …). Depend downward on Lyra modules; Lyra must not depend on you.
  4. Start play after OnExperienceLoaded. Async GFP activate — BeginPlay alone is a 5.8 footgun.
  5. Server owns power. Client predicts presentation (FS-ARCH-013).
  6. Tick off by default (Lyra 5.8 / FS-ARCH-014). Prefer timers, Anim Notifies, Gameplay Messages, GAS. No client Tick for HP / Flow / loot / Credits.
  7. TBD-* → data rows, never silent C++ defaults.
Lyra_5p8.uproject
└── LyraGame (host: Experience, CommonUI shell, EOS hooks)
└── GameFeatures ← PLUGIFY: each major surface = one GFP (Lyra-style)
├── ADDON SKG glue Boot Active
├── TFACore contracts only Boot Active
├── TFACombat spine (camera/stance/vitality)
├── TFAMelee Melee Drive ← pull/replace
├── TFASingularity Flow + climax ← pull/replace
├── TFAWeapons guns / Firehand ← pull/replace
├── TFAModular parts dials (opt)
├── TFAOmniVisor in-game GUI ← pull/replace
├── TFAFrontend boot / Deck GUI ← pull/replace
└── … Vision / CharacterI / Economy → MonetaryPlatform

Replace test: remove TFAOmniVisor (or Melee / Singularity / Weapons) from GameFeaturesToEnable → rest still loads. Cross-talk only via TFACore messages — see 02-gfp-cookbook.md Plugify lock.


1. What Lyra already gives you (do not rebuild)

Section titled “1. What Lyra already gives you (do not rebuild)”
System Use as-is Your job
Enhanced Input + ULyraHeroComponent binds Crouch / move / look path Do not patch HeroComponent for TF verbs
ALyraCharacter + ULyraCharacterMovementComponent Baseline locomotion + crouch replication Subclass character in ADDON; custom modes in GFP
GAS host (ULyraAbilitySystemComponent) Ability/GE pipeline Grant TF abilities from your AbilitySets; apply damage via GE
Experience Manager Async GFP load Own ULyraExperienceDefinition in TF content
CommonUI / UIExtension slots Layout host Inject OmniVisor / Frontend widgets via Game Feature Actions
EOS / CommonUser Identity hooks TFAOnline adapts — don’t fork Lyra login C++

2. What must live outside Lyra (custom plugins)

Section titled “2. What must live outside Lyra (custom plugins)”
Need GFP / plugin Why not Lyra
Hybrid FPP/TPP camera director · vitality · stance · Pose Search loco TFACombat (spine) Thin — Lyra camera modes stay; director + Full MM loco are ours. TrueFPP = same skeletal mesh / dual components + OwnerNoSee + bone-hide head/torso/legs/feet (arms+gun only) (FS-CAM-002) — no arms-only asset
Melee Drive · MM strike choosers TFAMelee Plugify — swap without touching guns/Singularity
Flow + Singularity climax TFASingularity Plugify — listens to kill messages
Wall Run (parkour) — Vault WILL NOT USE ADDON host → move lasting verbs toward Melee/Combat spine Lyra has crouch; not our parkour contract; Full MM loco into parkour entry; no Carbon Vault*
Firehand Bus / gun frames / Demo Mod host TFAWeapons (+ optional TFAModular) Plugify guns
OmniVisor HUD TFAOmniVisor Plugify GUI — UIExtension into Lyra HUD
SKG mesh / attachments ADDON glue only Vendor wrap; ASKGCharacter is not the Lyra pawn
Credits / BTUCOIN / LUMENAR MonetaryPlatform + TFAEconomy Portable product — not combat

Update rule: when Epic ships a new Lyra, you merge LyraGame / stock plugins with almost no TF diffs. Your GFP folders stay yours.


3. Program order (Full game critical spine)

Section titled “3. Program order (Full game critical spine)”

Walk 20-critical-path.md. Condensed:

Step Work Exit gate
0 Host Persist plugins in .uproject (ADDON, SKG, AimAssist, later TFA*) Clean clone boots
1 ADDON ATerraFirmaCharacter stub + SKG attach points; no inventory/HUD/economy/combat dump Playable glue pawn host
2 TFACore (REMAKE) Tags, message structs, interfaces; Boot Active with ADDON Other GFPs can depend
3 MonetaryPlatform Portable ledgers (can parallel after Core) Adapter can bind later
4 TFAFrontend Boot / Deck chrome Experience can show FE
5 TFAOmniVisor (Plugify HUD) HUD slots + messages Combat can push readouts
6 TFACombat spine (REMAKE) CameraDirector, loadout/stance, vitality, ASC host, hit auth, Pose Search loco Stance + vitality + MM loco playable
6b TFAMelee (Plugify) Melee Drive GAs + MM strike DBs/choosers Melee vs dummies (notifies still gate hits)
6c TFASingularity (Plugify) Flow meter + Singularity climax (message-driven) Flow → Singularity tiers
7 TFAWeapons (Plugify / REMAKE) Frames CSV → DA, Firehand Bus, SKG presentation Cadence lock FS-GUN-007
8+ Character I → Economy adapter → Progression → Crafting → Vision → World → Maps → Online Per-plugin A–E gates

Kanban: Full game board (Full game board).


4. Recipe — create a TFA GFP the 5.8 way

Section titled “4. Recipe — create a TFA GFP the 5.8 way”
  1. Editor / disk: Plugins/GameFeatures/TFACore/ (example) with TFACore.uplugin:
    • ExplicitlyLoaded: true (required — LyraGameTarget.ConfigureGameFeaturePlugins warns/disables otherwise)
    • Boot plugins: BuiltInInitialFeatureState: Active (Core + ADDON only)
    • Others: Registered — Experience enables them
  2. Module: TFACoreRuntime — PublicDeps: Core, Engine, GameplayTags, ModularGameplay, LyraGame (as needed), never reverse.
  3. Register plugin in Lyra_5p8.uproject (content/cook path). Do not invent a new *Target.cs for TFA — use Lyra’s shared targets.
  4. Experience: TF ULyraExperienceDefinition → GameFeaturesToEnable includes Plugify list (TFACombat, TFAMelee, TFASingularity, TFAWeapons, TFAOmniVisor, …).
  5. Actions: AddComponents / AddWidgets / AddInputContextMapping on Experience or Action Sets — inject into Lyra pawn/HUD without editing Lyra assets (UIExtension “harbour” ports).
  6. Pawn data: Duplicate Lyra EmptyPawn / Hero DAs into TF content → point Default Experience pawn at your DA_* / BP_Hero_*.
  7. Verify: PIE waits for Experience loaded; GFP modules appear in modules list; LyraGame.Build.cs still has no TFA refs; Tick off unless justified (FS-ARCH-014).

Repeat Plugify order: TFACombat spine → TFAMelee / TFASingularity → TFAWeapons (siblings: Core messages only; no sibling #include).


Lyra (leave alone) Your GFP
───────────────── ─────────────────────────────
Crouch bind + ToggleCrouch WallRun / Slide / Roll GAs (**no** Vault)
Move / Look IA Extra IMC (Game Feature Action)
Lyra CMC baseline Custom movement modes (server sim)
Lyra camera modes UTFACameraDirector (stance FPP/TPP)
Lyra AnimBP baseline Pose Search lower loco (keep Lyra upper Linked Layers)

Do:

Don’t:

  • Edit LyraHeroComponent.cpp to bind Vault (also: Vault is WILL NOT USE — do not add it anywhere).
  • Overwrite IMC_Default / IA_Crouch.
  • Put OmniVisor or economy in ADDON because “it’s already open.”
  • Use Pose Search as server damage authority — hit auth stays rewind + notify geometry (FS-ARCH-013).
  • Wipe Lyra Linked upper/lower with full-body MM.

  1. Hit auth: client claim → server validate → Gameplay Effect apply (no raw TakeDamage as authority) — Combat spine hosts pipeline; Melee/Weapons publish hits.
  2. Melee Full: Pose Search chooser picks strike clip → Anim Notify window → capsule / optional socket sweep (same hybrid auth as Demo montages).
  3. Flow / Singularity / Ultimate: separate meters per FS-CMB-004/005/006 — TFASingularity GFP (Ultimate stays separate). Melee/guns credit via Core kill messages.
  4. Guns: Frame cadence from data (FS-GUN-007); Firehand Bus in TFAWeapons; SKG for mesh/feel wrap only.
  5. Demo Mod (Full game still needs the contract): team tuner in TFAWeapons + CommonUI — not OmniVisor child; promote dials to cooked data (demo-mod-export.md).

  • Frontend / OmniVisor talk to gameplay via Gameplay Message Router + TFACore interfaces — no #include Combat headers from UI modules.
  • Online: TFAOnline owns EOS/Discord/social; Trust submits into MonetaryPlatform AntiCheat — combat never reads CF for power.

  1. Open kanban Full game → pick module whose dependencies’ Exit gates are green.
  2. Read that plugin’s A–E in ch. 20 + FS IDs.
  3. Implement in the correct GFP; run AC_* from FS acceptance pack.
  4. graphify update . after code lands; keep 02b honest if deps change.
  5. When Epic drops Lyra: merge host; your GFP diffs should be untouched.

Anti-pattern Fix
Gameplay C++ in Source/LyraGame Move to GFP; revert Lyra
“Just tweak” Lyra ShooterCore BP Duplicate into TFA content
Fat ADDON with Flow + HUD + bags Split to TFACombat / OmniVisor / Character I
Silent C++ for TBD-018 / AA floats Data asset / CSV row
Port old test-project TFAWeapons binaries as Done Remake on 5.8_terra_demo (gfp-status)
Ship Full loco without Pose Search Full shall MM (FS-FX-002); Demo has card demo-motion-matching (Lyra upper/lower) · CB standalone too
Treat MM chosen pose as server hit truth Notify + rewind geometry only