Death, Downed & Respawn

Goal: turn "health reached zero" into a death that plays out, a bleed-out other players can reverse, and a respawn that puts the player back in the game.

Prerequisites
CrimsonCore integrated (Integration), a character with a UCrimsonHealthComponent and a granted UCrimsonHealthSet (Vitals: Shield, Barrier & Reservation), and a working interact ability if you want revives (Interaction Integration). Tick Show Plugin Content in the Content Browser's settings to see the shipped death montages.

UCrimsonHealthComponent already sends GameplayEvent.Death to the owner's ability system the moment health runs out. Nothing listens to it until you grant one of two abilities - and until something does, StartDeath and FinishDeath are never reached and the character simply stands there at zero health.

AbilityGrant it toWhat the death event means
UCrimsonCoreGameplayAbility_DeathNPCs, summons, anything that just diesCancel abilities -> StartDeath -> death montage -> FinishDeath -> destroyed or pooled; the owning client gets a respawn dialog
UCrimsonCoreGameplayAbility_DownedPlayersEnter a bleed-out first; only a finisher or an expired clock reaches the flow above
One or the other, never both
Both abilities trigger on the same GameplayEvent.Death. Granting both to one ability system activates both on the same death, and the generic one will destroy the pawn out from under the bleed-out. Pick one per ability set.

1. Create the death ability

Make a data-only asset from UCrimsonCoreGameplayAbility_Death and set its presentation. Everything about the ability's mechanics - the GameplayEvent.Death trigger, ServerInitiated execution, ReplicateYes, InstancedPerActor, the Ability.Behavior.SurvivesDeath asset tag that stops the pawn's own teardown from canceling it mid-death - is already set in the constructor. Do not change it.

PropertyDefaultWhat it does
DeathMontageNonePlayed through the ability's montage task on every machine. MM_Death_Front_01_Montage ships in /CrimsonCore/Characters/Mannequins/Anims/Death/.
FallbackDeathDurationSeconds2.0How long the death takes with no montage authored. Zero finishes on the next tick. Ignored while bRagdollOnDeath is on.
bRagdollOnDeathtrueHand the body to physics as it dies. On replaces DeathMontage / FallbackDeathDurationSeconds with the two timings below; off leaves the montage path exactly as it was.
RagdollDelaySeconds0.0How long the death montage plays before the physics takes over. Zero skips the montage entirely and ragdolls the instant the character dies.
RagdollDurationSeconds3.0How long the body lies there after it ragdolls, before FinishDeath.
RagdollGameplayCueTagGameplayCue.Crimson.Death.RagdollThe persistent cue that carries the ragdoll to every machine. Handled by the GCN_Crimson_Death_Ragdoll asset - see the step below.
RespawnHeader"You Died"Header of the respawn dialog.
RespawnBodyEmptyBody text. Empty is fine - the header alone reads perfectly well.
RespawnButtonText"Respawn"Label on the dialog's only button.
RespawnButtonDelaySeconds0.0Seconds before the button becomes pressable, so a mashed input cannot skip the death animation.

Right-click in the Content Browser -> Blueprint Class -> expand All Classes -> pick CrimsonCoreGameplayAbility_Death. Name it GA_Death. Open it, and in Class Defaults set DeathMontage and the four respawn texts under the Crimson|Death category. No graph is needed.

Then add GA_Death to a UCrimsonAbilitySet's Granted Gameplay Abilities list and reference that set from UCrimsonNPCData::AbilitySets (NPCs and summons) - see Character Pipeline for where ability sets are granted.

The ragdoll needs its cue asset
bRagdollOnDeath is on by default, and the ability only adds the cue - the thing that actually simulates each machine's mesh is a Blueprint of UCrimsonCoreGameplayCueNotify_Ragdoll named GCN_Crimson_Death_Ragdoll, sitting in /CrimsonCore/GameplayCues. The plugin registers that folder as a cue path through an Add Gameplay Cue Path action on its game feature, and the cue manager finds handlers by scanning registered paths, not C++ classes: without the asset the corpse simply never falls over. Author it once, by hand, in the Content Browser: navigate to /CrimsonCore/GameplayCues (tick Settings -> Show Plugin Content if the folder is hidden), right-click -> Blueprint Class -> expand All Classes -> search CrimsonCoreGameplayCueNotify_Ragdoll -> Select, and name the new asset exactly GCN_Crimson_Death_Ragdoll. Save it and you are done - it needs no graph and no properties, because the cue tag comes from the parent class.
Verify
Give a testing dummy an ability set containing GA_Death, then run VitalsDamage 9999 from the host window. With the ragdoll on, the dummy drops into physics on the host and on every client and is destroyed - or recycled into the pool when its UCrimsonNPCData has bCanBePooled - RagdollDurationSeconds later. With bRagdollOnDeath off it plays the montage on every machine and finishes when the montage ends.

2. Create the downed ability for players

UCrimsonCoreGameplayAbility_Downed inherits everything above and inserts a bleed-out in front of it. Author it exactly the same way, from the subclass.

PropertyDefaultWhat it does
DownedMontageNoneOne-shot knockdown, played on every machine. Not a loop: when it ends, the animation Blueprint holds the downed pose for as long as the ability system carries Status.Death.Downed.
GetUpMontageNoneOptional get-up animation. With none authored the downed pose is simply stopped.
DownedDurationSeconds30.0How long the character has before the bleed-out kills it.
DamageBleedOutPenaltySeconds5.0Seconds taken off the remaining bleed-out by each damaging hit. Zero disables the penalty.
ReviveHealthPercent0.3Fraction of effective maximum health (MaxHealth - HealthReserved) a revived character stands up with.
SelfReviveEventTagGameplayEvent.Downed.SelfReviveGameplay event that revives the character while it is down.
SelfReviveBuffTagsEmptyBuff tags that revive the character automatically; the effects granting them are removed when spent.
SelfReviveBuffDelaySeconds0.0Grace period before a buff revive fires, so the player still sees they went down.

Same recipe as step 1, with CrimsonCoreGameplayAbility_Downed as the parent. Name it GA_Death_Downed, set the montages and the four numbers under Crimson|Downed, then add it to the ability set referenced from your UCrimsonPawnData::AbilitySets.

The downed ability needs the component from step 3
With no UCrimsonCoreDownedComponent on the pawn there is no interaction surface, no replicated bleed-out and no HUD, so a downed state would be invisible and unrecoverable. The ability logs a warning and dies normally instead - look for has no Crimson Downed Component in the Output Log.

3. Add the Crimson Downed Component

The component is the interactable, replicated face of a bleeding-out character. Interaction discovery only inspects the primitive it overlapped, which is why this is a sphere on the character rather than something on the actor itself. It sits dark - NoCollision, no overlap events - until the pawn actually goes down.

PropertyDefaultWhat it does
ReviveText / FinishOffText"Revive" / "Finish Off"The two interaction prompts.
ReviveHoldSeconds / FinishOffHoldSeconds3.0 / 1.5Hold durations. Both options are Hold, never a quick press.
ReviveAllowedAttitudesFriendly & Neutral (Support)Who is offered Revive.
FinishOffAllowedAttitudesHostile OnlyWho is offered Finish Off.
ReviveAbilityClass / FinishOffAbilityClassUCrimsonCoreGameplayAbility_ReviveDowned / UCrimsonCoreGameplayAbility_FinishOffDownedHandler abilities granted to the interacting character. Two distinct classes because nearby-interaction grants are cached per class.
InteractionResponseECR_OverlapHow the sphere answers UCrimsonInteractionSettings::InteractionTraceChannel.
DownedStatusWidgetClassNoneBleed-out readout, shown to the downed player alone. Leave unset for no HUD.
DownedStatusSlotTagHUD.Slot.DownedUI extension slot the readout is registered at.
DownedStatusPriority0Higher displays first when the slot holds more than one widget.
Match the collision response to your scan strategy
With the TopDown scan the cursor trace hits the capsule and the sphere is found by the overlap around it, so the ECR_Overlap default is right. The SingleLineTrace scan only reports blocking hits: for that strategy set InteractionResponse to ECR_Block and point UCrimsonInteractionSettings::InteractionTraceChannel at the dedicated Crimson_TraceChannel_Interaction, or the sphere will block camera and visibility traces too. See Interaction Integration -> Collision channel + profiles.

Open your player character Blueprint -> Components panel -> Add -> search Crimson Downed Component -> drop it under the root (not under the mesh). Set DownedStatusWidgetClass, the hold times and the prompt texts in its Details panel.

For a character you do not own the Blueprint of, add it from an experience instead: an engine UGameFeatureAction_AddComponents entry targeting your pawn class, with UCrimsonCoreDownedComponent as the component class. It attaches to the actor rather than to a named socket, which is what the sphere needs anyway.

Verify
Kill the player with VitalsDamage 9999 from the host window. The pawn stops moving but stays solid, showdebug abilitysystem lists Status.Death.Downed on it, and the pawn is not destroyed. Every other client sees the same pose.

4. Put the bleed-out readout on the HUD

UCrimsonCoreDownedStatusWidget is registered by the component at HUD.Slot.Downed on the downed player's own client the moment the pawn goes down, and unregistered when the downed state ends. Nothing places it by hand and no other client ever sees it. All three bound widgets are optional, so a Blueprint that simply names them needs no graph at all.

Bound widgetTypeFilled with
Text_TitleUCommonTextBlockTitleText ("Downed"), once on construct.
Text_CountdownUCommonTextBlockCountdownFormat ("{0}") with whole seconds remaining, rounded up.
Bar_BleedOutUProgressBarRemaining over DownedDurationSeconds, clamped to 0..1.

Beyond those three, On Bleed Out Tick(RemainingSeconds, Fraction) fires on every update - and once immediately on construct - for anything else you want to drive (a pulsing vignette, a heartbeat sound), and On Downed Ended fires once as the state ends so you can play a closing animation before the component tears the widget down. The readout refreshes on a UpdateIntervalSeconds timer (default 0.1), never on tick, and refreshes immediately whenever the server moves the end time.

Create a Widget Blueprint whose parent class is CrimsonCoreDownedStatusWidget (User Interface -> Widget Blueprint -> All Classes), name it W_CrimsonDownedStatus, and add a CommonTextBlock named Text_Title, a CommonTextBlock named Text_Countdown and a ProgressBar named Bar_BleedOut. Set it as DownedStatusWidgetClass on the component from step 3.

Then place a CrimsonUIExtensionPoint in your HUD layout with ExtensionPointTag set to HUD.Slot.Downed. Without one the widget registers successfully and appears nowhere, with no error.

Verify
Go down on a client. The countdown appears on that client only and ticks toward zero; damaging the downed player from a hostile makes the number jump down by DamageBleedOutPenaltySeconds.

5. Block abilities while dead or downed

Nothing in C++ stops a dead or downed character from firing abilities - that is content's call, and it has to be made or a corpse can still cast. Status.Death.Downed is a child of Status.Death, so one rule covers both states.

Block on Status.Death either globally, through the UCrimsonAbilityTagRelationshipMapping named by your UCrimsonPawnData, or per ability through its Activation Blocked Tags. Two deliberate exceptions:

  • Leave the interact ability unblocked. A reviver is holding their interact ability while they are alive - but a downed player whose interact is blocked cannot be the one reviving anyone, and blocking it project-wide is the usual reason Revive prompts never appear.
  • Anything that must work while dead or downed carries `Ability.Behavior.SurvivesDeath`. That asset tag is what exempts an ability from the death gate and from the cancel sweep the death ability runs. Both death abilities already carry it.

HUD widgets built on UCrimsonTaggedWidget can hide themselves the same way with HiddenByTags = Status.Death.

Verify
While downed, your normal attack does nothing and the Output Log shows the Ability.ActivateFail.IsDead reason; the interact ability still activates.

6. Optional: give the player their own way back up

Two self-revive routes exist, both server-side, both ending in the same Revive. On Revived reports the instigator, and an instigator equal to the avatar identifies a self-revive.

  • Active - something sends SelfReviveEventTag (GameplayEvent.Downed.SelfRevive) to the downed character: a consumable's use ability, a Blueprint Send Gameplay Event to Actor, a cheat.
  • Passive - a gameplay effect grants a tag listed in SelfReviveBuffTags. The tag is checked on the way down and again whenever one arrives while down, so an ally can buff a downed friend from across the room. The effects granting it are removed when the revive is spent.
The sending ability must survive death
Status.Death.Downed blocks ability activation exactly like Status.Death. A consumable's use ability that does not carry the Ability.Behavior.SurvivesDeath asset tag can never activate while its owner is down, so the event is never sent and the item does nothing.

In the consumable's use ability (asset tags including Ability.Behavior.SurvivesDeath): Event ActivateAbility -> Get Avatar Actor From Actor Info -> Send Gameplay Event To Actor (Actor = the avatar, Event Tag = GameplayEvent.Downed.SelfRevive) -> End Ability.

For the passive route, author a gameplay effect granting a tag such as Status.Buff.SecondWind and list that tag in GA_Death_Downed's SelfReviveBuffTags. No graph is needed - applying the effect is enough.

7. Verify the whole loop in a networked session

Run Play As Client with two or three clients plus a listen host, and drive the cheats from the machine that owns the character - the vitals cheats on UCrimsonCheatManager are all BlueprintAuthorityOnly, so in a listen-server session run them from the host window.

Do thisServerThe downed clientAnother player nearby
VitalsDamage 9999 on an NPC with GA_DeathRuns the ability, calls FinishDeath-Sees the montage, then the NPC destroyed or pooled
DamageSelfDestruct on a player with GA_Death_DownedArms the bleed-out timer, replicates bDownedPose, no movement, countdown ticking, Status.Death.Downed in showdebug abilitysystemSees the pose; the capsule is still solid
Walk a party member up to the bodyRe-checks the attitude condition on the handler ability-Sees a Revive hold prompt and nothing else
Complete the Revive holdResetForRespawn, health set to ReviveHealthPercent, spawn-activated abilities re-activatedCountdown gone, movement back, abilities work againSees the get-up montage
Walk a hostile up insteadSame re-check-Sees Finish Off, never Revive
Let the clock run outBeginDying with no instigator to creditDeath montage, then the respawn dialogSees the death montage
Press the dialog's buttonServerRestartPlayer -> a fresh pawn at full healthNew pawn, full health, and dying again works immediatelySees the new pawn spawn
Verify
The last row is the one worth repeating: kill the freshly respawned player straight away. UCrimsonHealthComponent::InitializeWithAbilitySystem calls UCrimsonHealthSet::ResetForRespawn(), so bOutOfHealth is cleared on the PlayerState-owned set and the second death fires exactly like the first. If the second kill does nothing, the health set was not reset.

See also

  • Concept: Death, Downed & Respawn - the state machine, who runs where, and the API tables.
  • Vitals: Shield, Barrier & Reservation - where the health that reaches zero comes from.
  • Interaction Integration - the scan strategies, collision channel and prompt widget the Revive option rides on.
  • Character Pipeline - where ability sets are granted, and the NPC object pool a dead NPC returns to.
  • GameFeatureActions - adding the downed component to a pawn class you do not own.