Concept: Ability Subclasses

Four shapes ship so you do not re-implement them. Each is a normal UCrimsonGameplayAbility subclass you can further subclass in Blueprint.

ClassShapeKey state tag
UCrimsonGameplayAbility_WithCastTimeWind-up, interruptible, configurable commit point.Ability.State.Casting
UCrimsonGameplayAbility_ToggleOn until pressed again.-
UCrimsonGameplayAbility_ChargesN uses that refill.Ability.ActivateFail.Charge.OutOfCharges
UCrimsonGameplayAbility_ChannelingTicks while held, optional movement break.Ability.State.Channeling
Abilities used as combo steps must derive from UCrimsonGameplayAbility
The combo controller cancels steps through Crimson-specific paths. A plain UGameplayAbility used as a step is silently skipped by cancellation, so the previous step never ends.

The shared networking contract

All four shapes are LocalPredicted, so each one runs on the server AND on the predicting client. They follow one rule: the server owns the ability's clock and lifetime; the client mirrors it for cosmetics and never replicates an end or a cancel.

RuleWhat it means for you
Only the authority ends the abilityThe client's instance is torn down when the server's end replicates back.
Client stop signals travel as replicated ability tasksInputPressed / InputReleased overrides only fire on the locally controlled client, so the shapes use UAbilityTask_WaitInputPress / UAbilityTask_WaitInputRelease.
Movement breaks and completion-time cost are server-sideA client cannot shorten, break, or discount its own cast.
Every lifecycle point fires twiceA (Cosmetic) event on both machines, an (Authority) event on the server only.
Put gameplay in the (Authority) events
The (Cosmetic) events run on both machines. Spawning an actor or mutating replicated state there yields two copies on a listen server and a client-only ghost on a remote client. Use them for VFX, sound, camera and UI; use the (Authority) events for everything else.
Why the split exists
Both machines run their own timer. When the client ended the ability itself, that ServerEndAbility RPC arrived at almost exactly the moment the server's own timer was due - so whichever won the race decided whether the server ran its completion logic at all, and authoritative work failed intermittently. Letting only the server end the ability removes the race.

See also

  • How-To: Make a Cast-Time Ability
  • How-To: Use Toggle, Charges and Channeling