Concept: Combo System
The combo system chains discrete abilities into designer-authored, branching sequences. It is structured the opposite way from most UE combo solutions: each step is its own ability, and a separate graph asset describes how steps chain.
Why one ability per step
The step owns its montage, its damage, its costs, its cooldown and its augment slots, because it is a normal ability and GAS already handles all of that. The graph owns only the topology: which step follows which, on what input, under what conditions.
The trade-off is real and worth stating: one activation per step means one ServerTryActivateAbility per step, plus the controller's own transition RPC. A four-hit string is more round trips than a single ability looping through montage sections would be. In exchange every step gets per-step gameplay data for free.
The three layers
| Layer | Lives in | Holds |
|---|---|---|
| Topology | The combo graph asset | Steps, transitions, entry handshake, end points. |
| Per-step numbers | The step node | Phase boundaries, transition window, buffer overrides, events. |
| Execution | The step ability | Montage, damage, cost, cooldown, augments. |
Runtime flow
rooting ability activates-> controller arms a root watcher for its cancel window-> player presses; the press is buffered and matched against the starting handshake-> StartCombo -> EnterNode: activate the step ability, open its transition window-> a matching press inside the window fires a transition -> EnterNode again-> an End node reaches ComboCompleted; a closed window with nothing queued resets
Step phases
A step node authors four boundaries in seconds at 1x play rate - Startup End, Active Start, Active End and Recovery End - and the controller turns them into one live phase: Startup, Active or Recovery. A phase is combo state and nothing more. It says where the active step is in its own timeline; it does not spawn a hitbox, apply damage, or read an AnimNotify. Hit frames stay wherever you author them.
Phases are opt-in per step. A node with Recovery End at 0 authored none: it reports None for its whole life, applies no tag and fires no phase hook. The tracker runs on the server and on the owning client, each from its own clock. Simulated proxies run no combo logic at all, so a phase never exists there.
While a phase is live the controller sets exactly one loose gameplay tag on the owner's ability system: Combo.Phase.Startup, Combo.Phase.Active or Combo.Phase.Recovery, all under the parent Combo.Phase. Loose and non-replicated is the design, not a shortcut. It makes the phase readable by every gate GAS already has - Activation Required Tags, Activation Blocked Tags, a tag query on a transition - with no combo-aware code anywhere, and it costs no bandwidth because both machines that care compute it from their own clock. The active node's Node Tags are applied the same way for as long as that node is the current step.
The ordering contract is StepEntered -> PhaseEntered ... PhaseExited -> StepExited: phases nest inside a step, and the last phase exits when the step does on every path - transition, completion, reset and prediction rollback. On PhaseEntered the tag is already set and Get Current Phase already reads the new phase. On PhaseExited the tag is already cleared and Get Current Phase already reads None, so the phase being left rides on Context.Phase instead.
A per-edge Cancel Open Override / Cancel Close Override is validated by the server but not by the client's own press gate, which reads the node-level window. An authority-driven transition follows the server rule.
Driving a combo without input
An authority can run the same graph with no press at all: Start Combo By Asset begins a granted combo at its first step and Request Transition To Node takes a chosen edge out of the active step. A driven request ignores everything that describes a human press - the input action, the kind, the fire mode, the direction and the chords - and respects everything that describes when the move may chain: the transition window and the edge's tag query. It is refused on a player-controlled pawn, because a server-initiated step is never predicted by that client and would roll it back. See How-To: Drive Combos from AI.
Where conditions fit
Each transition may carry conditional augments gated by a UCrimsonComboTransitionCondition. The condition observes the current step and decides at fire time whether the reward is granted - the difference between "you pressed in time" and "you actually connected". See How-To: Gate Combo Branches with Conditions.
What it does not do
- It does not play montages - the step ability does.
- It does not read AnimNotifies. Windows are authored numbers scaled by play rate, not notify-driven, so a missed notify on a dedicated server cannot desync the combo.
- It does not run on simulated proxies. Remote players see combos through the replicated ability montages only.
See also
- How-To: Wire Combo Input
- How-To: Author a Combo
- How-To: Drive Behavior from Step Phases
- How-To: Drive Combos from AI
- How-To: Tune Combo Input Feel
- Concept: Multiplayer and Prediction