Chain reactions

Opt-in bounded propagation — how a destroyed object can damage its neighbours, with depth caps, cycle prevention and deterministic ordering.

Propagation lets a destroyed object deliver a bounded radial hit to nearby destructibles. It is disabled by default on every profile.

Heavy Prop
   ↓
Crate
  ↙ ↘
Pot Pot

Enabling it

On the profile of the object that should start a chain when it dies:

PropertyDefaultMeaning
bAllowDestructionPropagationfalseMaster switch
PropagationRadius250.0Sphere radius searched for neighbours
PropagationDamage100.0Damage delivered to each neighbour
PropagationPowerLightDestruction power of the propagated hit
PropagationImpulse600.0Impulse magnitude of the propagated hit
MaxPropagationDepth2Hard depth cap when this profile starts a chain

Depth is capped by the root

MaxPropagationDepth is the hard maximum for the chain that this profile started. A child profile encountered later in the chain may reduce the remaining depth, but it can never increase it. One explosive barrel cannot be turned into an unbounded chain by a neighbour with a larger setting.

What a propagated hit looks like

Each neighbour receives a normal FSDFDestructionHit:

  • Damage = the source profile’s PropagationDamage;
  • DestructionPower = PropagationPower;
  • ImpulseStrength = PropagationImpulse;
  • ImpactDirection = outward, from the source toward the neighbour;
  • PropagationDepth = parent depth + 1;
  • RandomSeed = derived deterministically (see below).

The neighbour evaluates it against its own profile like any other hit. A pot with MinimumDestructionPower = VeryLight breaks; a statue requiring Heavy ignores a Light propagation.

Cycle prevention

The subsystem keeps a visited set of Actors for the duration of a logical chain. An Actor that has already been visited is never queued again, so A → B → A is impossible. The number of such suppressions is reported as TargetsIgnoredAlreadyVisited.

The chain is processed as a queue, not as recursion, which keeps the call stack flat regardless of how many objects are involved.

Deterministic ordering and seeds

Candidates are gathered and placed in a stable order before any hit is delivered, so the same scene produces the same chain every run.

CalculatePropagationSeed(ParentSeed, SourceDepth, SourceActor) derives each event’s seed from its parent seed and stable source context. Given the same root seed, a chain replays identically — useful for capturing a bug, and for deterministic automated tests.

Chain diagnostics

When a chain completes, OnPropagationChainCompleted broadcasts an FSDFPropagationChainResult. GetLastPropagationChainResult returns the same data on demand.

FieldMeaning
bExecutedA chain actually ran
RootActorThe object that started it
RootSeedSeed the chain was derived from
TargetsDiscoveredCompatible neighbours found
HitsPropagatedHits actually delivered
DestroyedTargetsNeighbours destroyed by the chain
MaximumDepthReachedDeepest level reached
TargetsIgnoredAlreadyVisitedSuppressed by the visited set
TargetsIgnoredByMaximumDepthNeighbours skipped because the cap was reached
SourcesBlockedByMaximumDepthSources that could not propagate further
UniqueActorsVisitedSize of the visited set
HitResultsPer-hit records: source, target, depth, seed, destruction result

Each FSDFPropagationHitResult contains the full FSDFDestructionResult of that target, so a chain can be audited hit by hit.

Budgets still apply

Propagated destruction is normal destruction. It competes for the same per-frame destruction event admission and the same Chaos representation budget as player-caused destruction, and it falls back to SwapAndScatter under pressure exactly the same way. A chain in a crowded scene degrades instead of spiking. See Performance.

Tuning guidance

  • Start with PropagationRadius slightly larger than the visual footprint of the source object. A radius that reaches across a corridor turns one crate into a room-wide cascade.
  • Give the chain a lower PropagationPower than the player’s heavy attack. Chains that break everything read as a bug rather than as a reaction.
  • Keep MaxPropagationDepth at 2 unless you are building an intentional set piece.
  • Use the chain result counters while tuning: a high TargetsIgnoredByMaximumDepth means the layout wants a smaller radius, not a bigger cap.

Radial versus propagation

They deliver similar payloads but are triggered differently:

RadialPropagation
TriggerYour gameplay code calls ApplyRadialDestructionAn object with propagation enabled is destroyed
ConfigurationPer call, in the requestOn the source object’s profile
DepthYou set PropagationDepth on the requestManaged by the chain
ResultFSDFRadialDestructionResultFSDFPropagationChainResult

See Radial destruction.

Last updated: 2026-08-13

Type to search titles, sections and keywords.