# The Action-RPG (Wukong-Style) Cell

This is V4's duel. The Action-RPG cell is the soulslike / Black-Myth-Wukong
surface where the moment-to-moment loop is **read the tell, dodge or parry,
spend stamina, break posture, finish** — the genre that lives or dies on a
handful of integer frames: whether your parry window is six frames or five,
whether the roll grants enough invincibility to clip through a sweep, whether a
boss combo leaves a punish window or just rotates back at you. It is the most
combat-theoretic of V4's six genre modules, closest in spirit to V2's
frame-deterministic fighting core, because everything from a trash-mob crowd to
a chapter-end yaoguai runs on the same parry, posture, stamina, and
transformation math.

V4 markets this cell as the _Champion's Path_ — an eight-chapter Wukong
campaign, a boss-rush ladder, and two-player co-op — but on disk the genre is
one C++ **cell-mechanic module**, `V4ActionRPG`, with the campaign, bosses,
charms, and transformation rosters layered on top as `GameFeatures` plugins. The
promise is **soulslike feel from one combat engine**: a patient single-boss duel
and a frantic arena swarm read completely differently to the player, yet both
consume the same `UV4ParryComponent` window, the same `UV4PostureComponent`
break, and the same `UV4StaminaComponent` economy. The aim of this page is to
inventory what that core actually does, on the player's side of the screen, and
to point at the exact Unreal C++ that backs each verb. For the full mode
taxonomy, roster, and the scope this slots into, start at the hub:
[../V4_features.md](../V4_features.md).

## What ships, honestly

**The combat core is real, compiled, and tested.** The cell module
`V4/ue/Source/V4ActionRPG` carries 11 `.cpp` / 11 `.h` of domain logic — an
eight-state combat machine, integer-frame parry and dodge components, a posture
meter with a break delegate, a transformation/Will system, a spell-craft verb
set, a stamina economy, a charm aggregator, and a duel-mode catalogue — wired
into GAS through six cell-gated abilities in `V4ActionRPGAbilities`. A compiled
`libUnrealEditor-V4ActionRPG.so` sits next to the source, so the module has been
through the linker on this box. The signature numbers are frame-precise and
designer-editable, not stat-sheet placeholders: a `ParryWindowFrames = 6`
window, `InvincibilityFrames = 9` of roll i-frames, `MaxPosture = 200` with a
`DecaySeconds = 3.0` regen. They are pinned by dedicated automation specs under
`V4/ue/Source/V4Tests` — `ParrySpec`, `StaminaSpec`, `SpecialtyCombatSpec`, and
the integration-scale `WukongSpec`.

Three honest qualifications, in the spirit of the architecture companion.
**First**, "cell" here means the _mechanic module_ `V4ActionRPG`. The Wukong
_campaign_ — eight chapters, thirty bosses, five transformations, thirty charms,
the village hub — lives one layer up, in the `V4Mode_ARPG_Wukong` plugin (and
the `V4Mode_ARPG_BossRush` ladder plugin beside it), both of which compile to
their own `.so` and **configure the cell's components** through catalog objects
rather than reimplementing combat. The cell is the engine; the plugins are the
content roster that drives it. **Second**, the _logic_ is in-tree C++ but the
_content_ is not — V4 ships JSON sidecars (`DT_WukongBosses.json`,
`DT_WukongTransformations.json`, `*.umap.v4asset.json`), not cooked `.uasset`
binaries, so a posture **break formula** is real code while the specific boss
**movesets**, form meshes, and finisher montages are described, not baked.
**Third**, network authority is not in this module: `V4ActionRPG.Build.cs`
depends on `V4Core`, `V4Gameplay`, `V4Animation`, `GameplayAbilities`, and
`GameplayTags` — deliberately **not** `V4Netcode` — because the soulslike is a
solo/co-op PvE surface. What follows is the combat engine on its own terms.

## The action-RPG experience — what a duel feels like

Strip the campaign away and the shared verb set is small, tactile, and entirely
frame-timed: open a combo, cancel into a roll, time a parry against a
telegraphed heavy, drain the enemy's posture until it shatters, and cash the
break for a cinematic counter — all while watching a stamina bar that punishes
panic. Each verb is a component on the hero pawn, and each carries the exact
tuning a soulslike argues about.

### The frame-data combat core

The backbone is an explicit eight-state machine,
`EV4ARPGCombatState { Neutral, Attacking, Dodging, Parrying, Stunned, Transformed, Casting, Damaged }`
(`Public/V4ActionRPGTypes.h`), with attacks classified
`Light / Heavy / SuperHeavy` and timed by an
`FV4ARPGFrameWindow { StartupFrames, ActiveFrames = 6, RecoveryFrames = 12 }` —
integer-frame data, the kind a fighting game exposes publicly rather than hiding
behind a curve. `UV4HeroComboComponent` (`Private/V4HeroComboComponent.cpp`) is
the chain logic: `LightComboLength = 4`, `HeavyComboLength = 3`, and a
SuperHeavy that resolves to a single high-stagger hit. `AdvanceCombo` is a
genuine state machine — if you press the same attack while `Attacking` it steps
the chain, if you switch attack types mid-combo it **restarts at step one** (the
light-into-heavy branch), and once the chain reaches its length it resets to
`Neutral`. `WukongSpec` pins exactly that: two light steps land on step 2, then
a heavy press branches and restarts the counter at step 1.

### Parry, dodge, and the six-frame window

The property that separates a soulslike from a button-masher is a parry you can
_time_, and V4 implements it as a half-open integer interval, not a fuzzy
animation overlap. `UV4ParryComponent` (`Private/V4ParryComponent.cpp`) opens a
window with `BeginParry(StartFrame)` and answers `IsFrameInsideParryWindow(f)`
with `f >= StartFrame && f < StartFrame + ParryWindowFrames` —
`ParryWindowFrames = 6`. `ResolveIncomingAttack(frame, bParryable)` returns a
perfect parry only when the strike is parry-eligible **and** lands inside the
window, sets a one-shot counter prompt, and broadcasts `OnParryResolved`.
`ParrySpec` proves the arithmetic to the frame: with the window opened at 100,
frame 100 and frame 105 are inside, frame 106 is outside, a parryable strike at
103 succeeds and exposes a counter prompt, and an _unparryable_ strike inside
the window fails — a test that would collapse against a fuzzy or random parry.

Dodging is the same shape. `UV4DodgeComponent` grants `InvincibilityFrames = 9`
and answers `IsInvincibleAtFrame(f)` over the identical half-open interval, so a
roll started on frame 20 is invincible through frame 28 and vulnerable again on
29 — pinned in `WukongSpec`. The roll is the cell's core spacing verb, and at 18
stamina per dodge it cannot be spammed.

### Posture and the cinematic counter

Health and poise are split. `UV4PostureComponent`
(`Private/V4PostureComponent.cpp`) carries a `MaxPosture = 200` meter that
`ApplyPostureDamage` clamps upward and, the instant it reaches max, fires the
`OnPostureBroken` delegate that triggers the stagger-and-finisher. Posture is
not a one-way bar: `DecayPosture(dt)` bleeds it back at
`MaxPosture / DecaySeconds` per second (`DecaySeconds = 3.0`), so pressure has
to be _sustained_ to break a guard — let up and the meter recovers.
`ConfigurePosture(max, decay)` lets the content layer retune the pool per enemy,
which is exactly how the Wukong plugin gives a humanoid boss 600 posture and a
large beast 1200 without touching the component's code.

```mermaid
flowchart LR
    Input["V4Input · Enhanced Input"] --> Abilities
    subgraph Abilities["V4ActionRPGAbilities · GAS (cell-gated: ActionRPG)"]
        L[UGA_LightAttack]
        H[UGA_HeavyAttack]
        D[UGA_Dodge]
        P[UGA_Parry]
        T[UGA_Transform]
        C[UGA_CastCharm]
    end
    subgraph Cell["V4ActionRPG — combat components"]
        Combo["UV4HeroComboComponent<br/><sub>light 4 · heavy 3 · super 1</sub>"]
        Parry["UV4ParryComponent<br/><sub>6-frame window</sub>"]
        Dodge["UV4DodgeComponent<br/><sub>9 i-frames</sub>"]
        Posture["UV4PostureComponent<br/><sub>200 · 3s decay · OnPostureBroken</sub>"]
        Xform["UV4TransformationComponent<br/><sub>HP 300 · 12s · Will ≤ 3</sub>"]
        Spell["UV4SpellCraftComponent<br/><sub>Pillar/Cloud/Body/Hair</sub>"]
        Stam["UV4StaminaComponent<br/><sub>L5 · H12 · Dodge18 · 1.2s regen</sub>"]
        Charm["UV4CharmComponent<br/><sub>4 slots · folded buffs</sub>"]
    end
    L --> Combo
    H --> Combo
    D --> Dodge
    P --> Parry
    T --> Xform
    C --> Spell
    Combo --> Stam
    Parry --> Posture
    Cell --> Attr["UV4Attr_ARPG<br/><sub>Health · Stamina · Posture · Will · Mana</sub>"]
    Plugin["V4Mode_ARPG_Wukong<br/><sub>posture · transform · charm · boss catalogs</sub>"] -. configures .-> Cell
```

### The stamina economy

`UV4StaminaComponent` (`Private/V4StaminaComponent.cpp`) is the throttle on
every aggressive verb. It carries the genre's canonical costs —
`LightAttackCost = 5`, `HeavyAttackCost = 12`, `DodgeCost = 18`,
`ParryWhiffCost = 20` — over a `MaxStamina = 100` pool that refills fully in
`FullRegenSeconds = 1.2`. `SpendStamina` refuses any action it cannot pay for
(returning `false` rather than dipping negative), and `Regenerate(dt)` adds
`MaxStamina / FullRegenSeconds` per second, scaled by a `RegenMultiplier` the
charm system feeds. `StaminaSpec` pins the math: a dodge from 50 leaves exactly
32, 0.6 s of regen restores it to 82, and a further 2 s clamps cleanly at 100 —
and the component _cannot_ spend more than it holds. `SyncToAttributes` mirrors
the pool onto the replicated `UV4Attr_ARPG` GAS attribute set (`Health`,
`Stamina`, `Posture`, `Will`, `Mana`), so the bar the HUD reads is the same
number the ability system gates on.

## Signature systems — transformations, spell-craft, charms

The cell's identity above the parry/posture floor is its **power-move economy**:
the Wukong transformations, the stances-and-spells verbs, and the charm loadout
that ties them together. All three are real components; the _roster_ of forms,
spells, and charms is authored in the plugin layer.

### Transformations and the Will economy

`UV4TransformationComponent` (`Private/V4TransformationComponent.cpp`)
implements Wukong's form changes as a budgeted, time-and-HP-limited overlay. A
form is an
`FV4TransformationForm { FormTag, MovesetId, HitPoints = 300, DurationSeconds = 12, WillCost = 1 }`,
and the player holds `CurrentWillCharges = 3`. `ActivateForm` refuses unless a
matching form exists _and_ the Will budget covers its cost, then spends the
charge, seeds a separate `ActiveFormHP` pool, and starts a `DurationSeconds`
countdown. While transformed the form absorbs damage through `ApplyFormDamage`
against its own HP, and `TickForm(dt)` ends the form when either the timer or
the HP pool hits zero — `IsTransformed()` is true only while the tag is valid,
time remains, _and_ HP remains. That is the exact "powered-up for twelve seconds
or until you get bullied out of it" contract the genre runs on.

Will is _earned_, not regenerated on a clock: in the plugin layer a Will
component awards charges from parries and posture breaks (capping at three) and
syncs them into the cell component, which is why the aggressive, well-timed
player transforms more often than the turtling one.

```mermaid
stateDiagram-v2
    [*] --> Neutral
    Neutral --> Parrying: BeginParry (6f)
    Parrying --> Counter: perfect parry<br/>+1 Will (cap 3)
    Neutral --> Broken: ApplyPostureDamage ≥ 200<br/>OnPostureBroken · +1 Will
    Broken --> Counter: cinematic finisher prompt
    Counter --> Neutral: ConsumeCounterPrompt
    Neutral --> Transformed: ActivateForm · spend WillCost
    Transformed --> Neutral: TickForm 12s end<br/>or ApplyFormDamage → 0 HP
```

### Spell-craft verbs

`UV4SpellCraftComponent` (`Private/V4SpellCraftComponent.cpp`) is the "stances
and spells" branch, a four-verb enum
`EV4SpellCraftVerb { PillarStance, CloudStep, BodyDouble, HairSplitting }`.
`ActivateSpell` enforces a Will price that is verb-specific: **Pillar Stance is
free** (it is a defensive freeze-in-place hold, `PillarMaxHoldSeconds = 6.0`),
while Cloud Step (the short teleport behind a locked-on enemy), Body Double (a
decoy that draws aggro for `BodyDoubleDurationSeconds = 4.0`), and
Hair-Splitting (the multi-clone burst) each cost one Will, refusing the cast
when the budget is dry and broadcasting `OnSpellActivated` with the cast
location when it succeeds. `WukongSpec` confirms all four verbs cast with three
Will in the bank, and the plugin's spell catalog gives Hair-Splitting a
`SpawnedCloneCount > 1` so the multi-clone strike is data-true, not just a name.

### Charms — the progression economy

`UV4CharmComponent` (`Private/V4CharmComponent.cpp`) is the loadout layer. It
holds `CharmSlots = 4` and an equipped list, and `EquipCharm` enforces two real
rules: it rejects a charm once the slots are full, and it rejects a _duplicate_
tag, so you cannot stack the same buff twice. The payoff is in the aggregators —
`GetStaminaRegenMultiplier`, `GetParryWindowFrameBonus`, and
`GetPostureDamageMultiplier` fold every equipped `FV4CharmSpec` into a single
combined modifier (multiplicative for the float buffs, additive for the
parry-frame bonus). That is a genuine build-craft economy: a parry-frame charm
literally widens the six-frame window, a posture charm multiplies break damage,
and a stamina charm feeds the regen multiplier the stamina component already
reads. Progression is slot growth — the Wukong plugin grows the component from
four base slots to eight as boss kills are banked, verified in `WukongSpec`
(fifth base charm rejected; expands to eight after four earned slots).

## Traversal and spacing — honestly, it is the roll

A soulslike "traverses" combat space with its defensive verbs, and that is
exactly what the cell models. There is **no dedicated climbing or grapple
module** in `V4ActionRPG`, and this page will not invent one: mobility here is
the dodge-roll's nine i-frames for closing or evading, Cloud Step's one-Will
teleport behind a locked-on target, and (in the plugin roster) the Wind Form's
long evasive dashes. The over-shoulder, soft-locked combat camera the features
catalogue describes is presentation handled outside this module — the combat
components operate on integer frame indices, not on a camera — so the cell's
"traversal" is spacing and i-frame management, and it is real precisely because
it claims to be nothing more.

## The Wukong campaign and specialty modes — the plugin layer

Each ruleset that ships the cell is a `GameFeatures` plugin under
`V4/ue/Plugins/` that composes the combat core above with its own catalogs,
content root, and test spec. `V4Mode_ARPG_Wukong` is the headline. Its
`WukongSpec` is an integration-scale test that drives the _cell's_ components
through _plugin_ catalogs: four posture archetypes (Trash 60, Mid-Tier 200,
Humanoid 600, Large Beast 1200) pushed into `UV4PostureComponent` via
`ConfigurePosture`; five transformations (Tiger, Wolf, Bird, Stone, Wind), each
twelve seconds with a form-specific moveset and HP pool, configured into the
cell's transformation component; thirty launch charms across eight categories;
and thirty bosses, eight of them chapter-end, validated against a phase
contract.

That boss contract is the cell's most exacting design law, encoded in the
plugin's boss state machine. Every boss runs **three phases**, and the machine
accepts exactly three — `AdvancePhase` returns true twice and _rejects the
fourth_. Each phase carries a minimum attack tell of 18 frames
(`AttackTellFrames >= 18`) and a minimum punish window of 24 frames
(`RecoveryWindowFrames >= 24`), both enforced by `ClampMin` on the struct and
asserted in `WukongSpec`, with at least one parry-eligible attack and a
cinematic counter prompt on posture break.

```mermaid
stateDiagram-v2
    [*] --> Phase1: StartBoss()
    Phase1 --> Phase2: AdvancePhase() · HP ≤ 66%<br/>new attacks · posture reset
    Phase2 --> Phase3: AdvancePhase() · HP ≤ 33%<br/>desperation · super-armor
    Phase3 --> [*]: defeated
    note right of Phase1
      every phase: tell ≥ 18f ·
      recovery ≥ 24f · ≥ 1 parryable
    end note
```

The cell also hosts two duel sub-modes in its own catalogue,
`UV4SpecialtyCombatModeCatalog` (`Private/V4SpecialtyCombatModes.cpp`), each
reusing the same stamina/posture/parry backbone. The **Cage Boxing Simulator**
disables health chip and resolves five 300-second rounds through posture KOs
(`KnockoutPostureThreshold = 600`), judges' scorecards, and a standing-eight
count. The **One-Hit Sword Duel** normalizes weapons, confirms lethal hits, and
tightens the perfect-guard window to four frames, gated behind mutual consent
and locked ranked rules. `ValidateSpecialtyCombatModes` is a real linter — it
requires the `V4ActionRPG` backbone, the four base abilities, a two-player cap,
and mode-specific invariants (boxing must disable health damage and _not_ be
one-hit; the duel must be one-hit, weapon-normalized, guard window ≤ 4) — and
`SpecialtyCombatSpec` drives it end to end. Beside it, `V4Mode_ARPG_BossRush`
chains the same bosses into a timed ladder with limited heal-flask refills.

## How the cell ties to GAS and the shared engine

Every hero action routes through the Gameplay Ability System, and V4's abilities
are **cell-gated** so an action-RPG ability cannot fire on a non-ARPG pawn. The
six abilities in `V4ActionRPGAbilities.cpp` — `UGA_LightAttack`,
`UGA_HeavyAttack`, `UGA_Dodge`, `UGA_Parry`, `UGA_Transform`, `UGA_CastCharm` —
each set `RequiredCell = EV4RulesetCell::ActionRPG` and **delegate to the
components** rather than reimplementing them: the attack abilities call
`Combo->AdvanceCombo`, dodge and parry seed their windows from the triggering
event's frame magnitude, and transform resolves a default Tiger form
(`ARPG.Form.Tiger`, HP 300, 12 s, one Will) before activating it. Crucially,
they **fail loud** — a missing component yields `"missing-combo"`,
`"missing-dodge"`, or `"missing-transformation"`; a transform with no Will
yields `"transform-unavailable"`; a dry charm cast yields `"charm-unavailable"`.
The ability honestly reports what it could not do instead of faking success, the
fail-loud seam the project favours throughout.

The throughline is the architecture's unifying claim: six genres stay one game
because they sit on the same GAS spine and shared `V4Core`/`V4Gameplay`
libraries, while each cell earns its _feel_ in its own components. This cell's
contribution to that spine is `UV4Attr_ARPG` and the posture/Will currency the
other cells never touch. For the engine-side treatment — the eight-state combat
machine drawn as a diagram and the cross-cell seams — read the architecture
companion,
[../architecture/per-cell-deep-dives.md](../architecture/per-cell-deep-dives.md).

## Related

- The feature hub: [../V4_features.md](../V4_features.md)
- [Stealth & Real-Time Tactics cell](./cell-stealth-and-real-time-tactics.md) —
  the quiet, perception-driven cells (Splinter Cell, Hitman, Commandos,
  Desperados) whose patience is the inverse of the Wukong duel's aggression.
- [The 2D run-and-gun & arcade cell](./cell-2d-run-and-gun.md) — V4's Contra
  surface and Battle-Hub cabinets, the lightest of the six genre modules.
- Architecture companion:
  [../architecture/per-cell-deep-dives.md](../architecture/per-cell-deep-dives.md)
  — the genre-by-genre engine view, including `V4ActionRPG` maturity and the
  eight-state combat machine.
