# Per-Cell Architecture Deep-Dives

V4 is not one game with five skins; it is six genuinely different games that
happen to share a roster, a perception model, and an online backbone. A
Rainbow-Six breach, a Hitman crowd assassination, a Commandos squad
infiltration, a Black-Myth-Wukong boss duel, an Age-of-Empires ladder match, and
a two-player Contra couch run each demand mechanics the others never touch —
sub-frame recoil curves, lux-based shadow detection, time-dilated command
queues, posture-break counters, fixed-point lockstep pathfinding, screen-edge
co-op tethering. The architecture answers that by giving each genre its own C++
**cell-mechanic module** under `V4/ue/Source/`, then layering ruleset
`GameFeature` plugins on top of it (the hosting model — how a plugin activates a
cell at runtime — is the subject of
[./high-level-architecture.md](./high-level-architecture.md)).

The unifying seam underneath all six is the Gameplay Ability System: every cell
module's `Build.cs` links `GameplayAbilities` and the shared `V4Gameplay` spine,
so attributes, abilities, and gameplay tags are common currency while the
genre-specific _feel_ lives in the cell's own components. What follows opens
each of those six modules in turn — what the cell is, the systems unique to it,
and how mature it is on disk, ending each with the dependency or state diagram
that the code actually encodes. It is the genre-by-genre companion to the
catalogue index in [../V4_ARCHITECTURE.md](../V4_ARCHITECTURE.md).

## What ships, honestly

**All six cell modules are real and compiled.** Each exists as a directory with
a `Public/`/`Private/` split and a `*.Build.cs`, and each has a compiled
`Binaries/Linux/libUnrealEditor-*.so` sitting next to its source — `V4Tactical`,
`V4Stealth`, `V4Tactics`, `V4ActionRPG`, `V4RTS`, and `V4Arcade` have all been
through the linker on this box, as have roughly thirty of the `V4Mode_*` ruleset
plugins on top of them. The genre cores are substantial, not skeletal:
`V4Tactical` carries 12 `.cpp`/12 `.h`, `V4ActionRPG` and `V4RTS` 11 each,
`V4Arcade` 9, `V4Stealth` and `V4Tactics` 8 each. The mechanics are
domain-specific — a 6-frame parry window, a 0.125× Showdown time-dilation, a
32.32 fixed-point A\* — not renamed CRUD, and most are pinned by dedicated
automation specs under `V4Tests` (`WukongSpec`, `ParrySpec`, `RecoilSpec`,
`ContraSpec`, `LockstepSpec`, `FogSpec`, `LightGaugeSpec`, `DisguiseSpec`,
`CommandosSpec`, `DesperadosSpec`, `ShowdownSpec`).

Two honest qualifications. **First**, "cell" means the _mechanic module_, not a
one-to-one game: a single ruleset plugin can compose several cells. `Commandos`
pulls `V4Tactical` **and** `V4Stealth` **and** `V4Tactics`; `Desperados` pulls
`V4Perception` + `V4Stealth` + `V4Tactics`; `Hitman` pulls `V4Stealth` +
`V4Perception` + `V4Schedules`. The genre families the monolith markets ("five
cells") and the six engine modules are both true descriptions at different
layers. **Second**, the _logic_ of every cell is in-tree C++ but the
hand-authored art is not: V4's content is JSON sidecars (`*.v4asset.json`), not
cooked `.uasset` binaries (see
[./high-level-architecture.md](./high-level-architecture.md) for the
0-binary-asset accounting). So a recoil _curve sampler_ is real code; the
specific recoil _curve assets_, MetaHuman meshes, and Paper2D flipbooks are
described, not baked. Where a claim leans on art, this page says so.

## The Tactical FPS cell — `V4Tactical`

This is the Rainbow-Six / Call-of-Duty surface: aim-down-sights, recoil, stance,
lean, cover, weapon attachments, grenades, and downed-teammate revives. It is
the fattest cell module (12 `.cpp`/12 `.h`) and the one whose plugins
(`R6Modern`, `CoDMultiplayer`, `CoDWarzone`, `RavenShield`, `CoDCampaign`) carry
the server-authoritative netcode.

The cell's signature subsystems are sub-frame, not stat-sheet. `UV4AimComponent`
is a state machine (`EV4AimState::Hipfire` ↔ `ADS`) that drives an `ADSAlpha`
interpolation with asymmetric timings — `HipToADSSeconds = 0.18`,
`ADSToHipSeconds = 0.12` — and a `1×–8×` zoom band, so the _exact_ time-to-ADS
that competitive shooters tune is a first-class, designer-editable property.
Recoil is a sampled curve, not a random kick: `UV4WeaponRecoilCurveAsset` holds
a `TArray<FV4WeaponRecoilSample>` of `{TimeSeconds, Offset}` keys, and
`SampleRecoil()` lerps between them, then scales the result by a stance
multiplier (`Standing 1.0`, `Crouch 0.8`, `Prone 0.6`) and a
`MovingMultiplier = 1.3`. That is a learnable, memorizable recoil pattern — the
property that separates a tactical shooter from a spray simulator — implemented
as real interpolation math. Around those sit `UV4CoverComponent`,
`UV4StanceComponent`, `UV4WeaponAttachmentComponent`,
`UV4WeaponSwitchComponent`, `UV4GrenadeComponent`, and `UV4ReviveComponent`,
with `UV4WeaponBase`/`UV4WeaponLibrary` as the weapon data layer.

```mermaid
flowchart LR
    subgraph Tac["V4Tactical — FPS cell"]
        Aim["UV4AimComponent<br/><sub>ADS 0.18s / hip 0.12s · 1–8× zoom</sub>"]
        Recoil["UV4WeaponRecoilCurveAsset<br/><sub>sampled curve × stance × move</sub>"]
        Cover[UV4CoverComponent]
        Stance[UV4StanceComponent]
        Wpn["UV4WeaponBase / Library / Attachments"]
        Revive[UV4ReviveComponent]
    end
    GAS["V4Gameplay · GAS"] --> Tac
    Tac --> Net["V4Netcode<br/><sub>server-authoritative hit-reg</sub>"]
```

**Maturity:** high. Real interpolation/curve math, compiled module, `RecoilSpec`
coverage. Authority and lag-compensation live one layer down in `V4Netcode`
(cross-referenced in
[./high-level-architecture.md](./high-level-architecture.md)); weapon _balance_
values live in JSON sidecars.

## The Stealth cell — `V4Stealth`

This is the Splinter Cell / Hitman surface, and its defining trait is that it
reads the _world's lighting_ as a gameplay input. `UV4LightGaugeComponent`
implements a lux-based shadow model: `CalculateLuxAtCapsule()` sums the
contribution of every `FV4StealthLuxSample` light against the player capsule and
classifies the result through `DarkLuxThreshold = 0.3` and
`LitLuxThreshold = 0.65` (over an `AmbientLux = 0.02` floor) into an
`EV4LightExposureState`. Detection is then gated by exposure:
`CanSplinterCellSightDetect()` is a distinct, stricter path from the generic
`CanBeSightDetected()`, and in true darkness a guard must close to
`DarkCloseDetectionDistanceCentimeters = 150` to spot you. The companion
`ApplyLightOut()` / `RestoreLight()` pair makes "shoot out the light" a real
state change to the gauge, not a cosmetic.

The Hitman face of the cell is `UV4DisguiseComponent`, a full disguise economy:
`BeginDisguisePickupSwap()` takes a downed-target body (knocked-out, dragged, or
hidden in a container) and times a swap; `HasZoneAccess()` enforces per-disguise
allowed zones; and `ComputeSuspicionMultiplier()` blends three tuned scalars —
`AllowedZoneSuspicionMultiplier = 0.3`,
`RestrictedZoneSuspicionMultiplier = 1.75`, `EnforcerSuspicionMultiplier = 2.0`
— against suspicious actions and visible weapons.
`ComputeEnforcerDetectionTimeSeconds()` models the Hitman "enforcer" NPC who can
see through your specific disguise faster. Rounding out the module are
`UV4SoundFootprintComponent` (movement noise), `UV4BodyDragComponent` (move and
hide bodies), `UV4StealthGadgetComponent`, and `UV4MarkAndExecuteComponent` (the
Conviction-style tag-then-execute chain). Critically, `V4Stealth.Build.cs`
depends on `V4Perception` — the gauges feed the _shared_ suspicion model that
every NPC reads, detailed in
[./ai-perception-stealth.md](./ai-perception-stealth.md).

```mermaid
flowchart TB
    Lights["world lights"] --> Lux["UV4LightGaugeComponent<br/><sub>lux → Dark 0.3 / Lit 0.65</sub>"]
    Disg["UV4DisguiseComponent<br/><sub>zone × enforcer suspicion</sub>"]
    Sound[UV4SoundFootprintComponent]
    Body[UV4BodyDragComponent]
    Lux --> Perc["V4Perception<br/><sub>shared suspicion state machine</sub>"]
    Disg --> Perc
    Sound --> Perc
    Body --> Disg
```

**Maturity:** high for the gauge/disguise math (real formulas,
`LightGaugeSpec` + `DisguiseSpec`); the perception substrate it feeds is its own
cell-shared system.

## The RTST cell — `V4Tactics` (Commandos / Desperados)

Real-time tactics is the squad-of-specialists genre: you pause-and-queue precise
actions for six characters, watch enemy vision cones, and trigger them in
unison. `V4Tactics` is the smallest headline cell by file count (8/8) but the
densest in distinctive subsystems. `UV4CommandQueueComponent` caps each
specialist at `MaxCommandsPerSpecialist = 2` queued orders.
`UV4VisionConeComponent` is the genre's iconic UI-and-logic primitive: a cone
with `HalfAngleDegrees = 60` (a 120° field), `RangeCentimeters = 1200`, a
`LowLightFalloff = 0.5`, and Calm/Alert/Hostile colors (green/yellow/red);
`ContainsPoint()` and `GetDetectionWeight()` are the detection math, and
`BuildGroundConeVertices()` generates the floor decal.

The defining mechanic is `UV4ShowdownModeSubsystem` — Desperados' "Showdown
Mode." `SetShowdownActive()` drops `ShowdownWorldTimeDilation = 0.125`
(one-eighth speed — the code is explicit that the world _slows_, it does not
stop), accepts up to `MaxShowdownCommands = 4` queued cross-specialist actions,
and `ResolveCommandOrder()` returns a dependency-resolved firing order **plus a
list of blocked command GUIDs** when a queued action's preconditions fail.
Releasing the queue fires the plan in that resolved order. With
`UV4PartyComponent`, `UV4SpecialistAbilitiesComponent`, and
`UV4BodyDisposalComponent` rounding it out, the cell is a genuine
simultaneous-turn planner, not a slow-mo toggle. Honest composition note: the
Commandos plugin links `V4Tactical` + `V4Stealth` + `V4Tactics` together,
because a WW2 squad mission _is_ stealth + gunplay + tactics fused — the
clearest demonstration that a ruleset plugin composes cells.

```mermaid
stateDiagram-v2
    [*] --> RealTime
    RealTime --> Showdown: SetShowdownActive(true)<br/>world × 0.125
    Showdown --> Showdown: QueueShowdownCommand()<br/>(≤ 4)
    Showdown --> Resolve: TriggerShowdown()
    Resolve --> RealTime: ResolveCommandOrder()<br/>fire ordered · drop blocked GUIDs
```

**Maturity:** high for the time-dilation/queue/cone logic (`ShowdownSpec`,
`CommandosSpec`, `DesperadosSpec`); see
[./ai-perception-stealth.md](./ai-perception-stealth.md) for how the cones tie
into the shared perception model.

## The Action-RPG cell — `V4ActionRPG` (Wukong)

This is the souls-like / Black-Myth-Wukong combat cell, and it is the most
combat-theoretic of the six — closest in spirit to V2's frame-deterministic
fighting core (see V2's
[combat-system-gas-frame-data-and-determinism](../../V2/architecture/combat-system-gas-frame-data-and-determinism.md)).
Its backbone is an explicit 8-state machine,
`EV4ARPGCombatState { Neutral, Attacking, Dodging, Parrying, Stunned, Transformed, Casting, Damaged }`,
with attacks classified `Light/Heavy/SuperHeavy` and timed by
`FV4ARPGFrameWindow { StartupFrames, ActiveFrames = 6, RecoveryFrames = 12 }` —
integer-frame data, the kind a fighting game exposes publicly.

The frame constants are precise and match the design intent: `UV4ParryComponent`
ships a `ParryWindowFrames = 6` window with `IsFrameInsideParryWindow()` and a
perfect-parry counter prompt; `UV4DodgeComponent` grants
`InvincibilityFrames = 9` of roll i-frames via `IsInvincibleAtFrame()`. Health
is split from poise: `UV4PostureComponent` carries `MaxPosture = 200` with a
`DecaySeconds = 3.0` regen and an `OnPostureBroken` delegate that fires the
cinematic counter. `UV4TransformationComponent` implements Wukong's form changes
— `FV4TransformationForm { HitPoints = 300, DurationSeconds = 12, WillCost }`
with a `CurrentWillCharges = 3` budget refilled by parries and posture breaks.
`UV4HeroComboComponent` (`LightComboLength = 4`, `HeavyComboLength = 3`),
`UV4SpellCraftComponent` (the
`Pillar Stance / Cloud Step / Body Double / Hair-Splitting` verbs),
`UV4StaminaComponent`, and `UV4CharmComponent` (`FV4CharmSpec` granting
`+ParryWindowFrameBonus`, stamina-regen, and posture-damage multipliers)
complete the kit. The cell even hosts a P3 duel sub-mode:
`UV4SpecialtyCombatModeCatalog` validates a UFC-style `BoxingSimulator` (uses
stamina/posture/parry, `KnockoutPostureThreshold = 100`, `RoundSeconds = 180`,
`PerfectGuardWindowFrames = 6`) and a `OneHitSwordDuel` (`bOneHitKill`,
`bWeaponNormalized`, `bRequiresMutualConsent`) by reusing the same backbone
components.

```mermaid
stateDiagram-v2
    Neutral --> Attacking: Light/Heavy combo
    Attacking --> Neutral: recovery (12f)
    Neutral --> Dodging: roll (9 i-frames)
    Neutral --> Parrying: parry (6f window)
    Parrying --> Attacking: counter prompt
    Neutral --> Transformed: Will charge (cost ≤ 3)
    Transformed --> Neutral: form HP/duration end
    Attacking --> Stunned: posture break (200)
    Neutral --> Casting: spell-craft verb
```

**Maturity:** high. Real integer-frame logic with `ParrySpec` + `WukongSpec`;
the souls-like math is in-tree, while move _montages_ and form meshes are
JSON-described art.

## The RTS cell — `V4RTS`

This is the Age-of-Empires / StarCraft cell, and it is the one whose
_determinism_ is load-bearing, because RTS networking is deterministic lockstep
— every client re-simulates the same inputs and any float divergence desyncs the
match. `V4RTS` takes that seriously at the type level: `FV4RTSFixed32` is a
32.32 fixed-point number (`FractionalBits = 32`, `OneRaw = 1 << 32`) with
integer add/subtract and ordering operators, used wherever the simulation must
be bit-identical across machines. `UV4PathfindingSubsystem::FindPath()` is a
real A\* over an `FV4RTSGrid` using **fixed-point** G/F scores and a
Manhattan-distance heuristic, with a seed-hashed tiebreak (`V4CellSortKey`
combines the cell hash with the match seed) so the open-set ordering is
reproducible rather than pointer-dependent. `AuditDeterministicPathfinding()` is
a built-in self-test: it runs the same query twice under seed 314 and asserts
the paths match step-for-step, and checks the heuristic for `(0,0)→(3,4)` equals
exactly 7 cells — determinism verified in code, not asserted in prose.

On top of that deterministic floor sits a complete economy: `FV4RTSResourceCost`
(`Ore` + `Crystal`), `UV4ResourceComponent` over `FV4RTSResourcePatch`
(`GatherPerSecond = 8`), `UV4BuildComponent` (`FV4RTSBuildOrder`,
`BuildSeconds = 10`, grid footprints), `UV4TrainComponent`
(`FV4RTSProductionOrder`, `TrainSeconds = 5`), `UV4TechTreeComponent`
(`FV4RTSTechNode` with prerequisite tags), `UV4AgeUpComponent`
(`EV4RTSAge { Dark, Feudal, Castle, Imperial }`), `UV4FogOfWarComponent`
(`EV4RTSFogState { Unexplored, Explored, Visible }`), `UV4UnitGroupComponent`,
and `UV4WonderComponent`. The lockstep _transport_ (`V4RTSLockstepSubsystem`, 25
Hz, replay) lives in `V4Netcode`; `V4RTS` provides the deterministic
_simulation_ it drives.

```mermaid
flowchart TB
    Fixed["FV4RTSFixed32<br/><sub>32.32 fixed-point</sub>"] --> Path["UV4PathfindingSubsystem<br/><sub>seeded A* · self-audited</sub>"]
    Econ["Resource → Build → Train<br/><sub>Ore/Crystal · 10s/5s</sub>"]
    Tech["TechTree → AgeUp<br/><sub>Dark→Feudal→Castle→Imperial</sub>"]
    Fog[FogOfWar · UnitGroups · Wonder]
    Path --> Sim["deterministic sim"]
    Econ --> Sim
    Tech --> Sim
    Fog --> Sim
    Sim --> Lockstep["V4Netcode · 25 Hz lockstep"]
```

**Maturity:** high. The fixed-point determinism, A\*, and economy are real and
covered by `LockstepSpec` + `FogSpec` + `AsymmetricRTSSpec`/`HistoricalRTSSpec`.

## The 2D run-and-gun & arcade cell — `V4Arcade`

The arcade cell wears two faces from one module. The first is **Contra**: a 2D
side-scrolling run-and-gun. `UV4SideScrollComponent` is the camera brain —
`CalculateCameraLocation()` follows a single player or the _midpoint_ of two for
couch co-op, applies a `CameraOffset = (-900, 0, 250)`, and
`ClampPlayerToScreen()` keeps both players inside a `HalfScreenWidth = 650`
frame with a `CoOpSeparationCap = 900` tether — the exact "you can't run off and
leave player two behind" constraint the genre lives on.
`UV4WeaponPickupComponent` swaps the held `FV4ArcadeWeaponSpec` and drops the
previous one, and the weapon roster is unmistakably Contra:
`EV4ArcadeWeaponType { Spread, Laser, MachineGun, Fire, Crush, Homing, Barrier }`
— the literal S/L/M/F/C/H/B power-up letters, each with its own
`FireRatePerSecond`, `ProjectileCount`, and `Damage`. `UV4LivesComponent`
enforces true arcade economy (`StartingLives = 3`, `StartingContinues = 2`,
`IsGameOver()`), alongside `UV4LadderClimbComponent`,
`UV4DropPlatformComponent`, and `UV4PowerUpComponent`.

The second face is the **Battle-Hub arcade cabinets**:
`UV4ArcadeMiniGameCatalog` defines `FV4ArcadeMiniGameDefinition` rows for
`Pinball, AirHockey, MiniGolf, Darts, Pool, Cooking` with score targets and
player caps — the social-space minigames. `V4Arcade.Build.cs` honestly links
`Paper2D` (plus `GameplayAbilities` and `V4Animation`), so the 2D pipeline the
monolith promises is wired at the dependency level; the flipbook sprites,
tilemaps, parallax materials, and Niagara 2D projectiles it references are
JSON-described content, not cooked binaries in-tree.

```mermaid
flowchart LR
    subgraph Arc["V4Arcade — two faces"]
        Scroll["UV4SideScrollComponent<br/><sub>midpoint cam · 900 co-op tether</sub>"]
        Wpn["UV4WeaponPickupComponent<br/><sub>S/L/M/F/C/H/B</sub>"]
        Lives["UV4LivesComponent<br/><sub>3 lives · 2 continues</sub>"]
        Mini["UV4ArcadeMiniGameCatalog<br/><sub>Pinball · Pool · Darts …</sub>"]
    end
    Paper["Paper2D"] --> Arc
    GAS["V4Gameplay · GAS"] --> Arc
```

**Maturity:** high for the run-and-gun and lives/weapon logic (`ContraSpec`);
the 2D _art_ (flipbooks, parallax, Niagara sprites) is described, not baked.

## Where the cells meet

Three things keep six genres from fragmenting into six engines. They all sit on
the **same GAS spine** (`V4Gameplay`), so an operator's attributes carry across
cells. The stealth and RTST cells both feed the **same perception model**
(`V4Perception`, with the Mass-based `V4Crowd` and `V4Schedules` above it) — a
Hitman guard, a Commandos patrol, and a Splinter Cell mercenary read stimuli
through one suspicion state machine, dissected in
[./ai-perception-stealth.md](./ai-perception-stealth.md). And they are all
activated, gated, and live-serviced by the **same mode machinery** — quick-play
playlists, per-cell ruleset gating, seasons, and cross-cell crossovers — covered
in [./game-modes-live-service.md](./game-modes-live-service.md). The cell
modules are where each genre earns its feel; those three shared layers are why
it is one game. For the full catalogue, return to
[../V4_ARCHITECTURE.md](../V4_ARCHITECTURE.md).
