Concept: Windows, Shapes and Filters

The model behind the plugin, and why it is split the way it is.

Geometry is a selection task, validity is a filter task

A UTargetingPreset holds both. A selection task contributes candidates; filter tasks remove them; a sort task orders what remains. That split is Epic's, and this plugin adopts it wholesale rather than inventing a parallel one.

Because of it, area attacks and hitscan need no geometry code here at all - the Targeting System's AOE and Trace tasks already cover them. This plugin contributes only the two shapes Epic does not ship: a multi-socket sweep for a swung weapon, and a path sweep for a moving actor.

Why filters cannot fix an empty selection
A preset made only of filters resolves nothing, because a filter can only remove candidates and there were none. This is why UCrimsonHitProfile reports a Data Validation error for a preset with no selection task - the failure is otherwise completely silent.

Why sweeps are interpolated

A weapon tip can travel several metres between two frames. A single overlap or trace at its new position simply misses everything it passed through, and the faster the swing or the lower the frame rate, the worse it gets. Both Crimson selection tasks sweep from where the shape was at the previous query to where it is now, sub-stepping when the distance exceeds the shape's radius.

That is also why lowering Query Hz on a profile is close to free: each sweep runs from the previous query, not the previous frame, so the swept volume still covers the whole gap. 30 Hz is a good default for melee and halves the trace cost.

Teleports are excluded
A possession change or a level transition can move a weapon across the map between queries. Sweeping that would rake every actor along the line, so travel beyond Teleport Distance Threshold is skipped and the history re-baselined.

Hit windows and dedup

A hit window is a period during which queries run. It is opened by an animation notify firing an armed profile, or by the Crimson Hit Window ability task, and it owns the state that makes a swing behave like one attack rather than a series of independent frames: the already-hit set, the target budget, and the previous positions the sweep interpolates from.

Dedup policyBehaviourUse for
Once Per WindowAn actor is reported at most once for the life of the windowAlmost every melee swing, and projectile pierces
Once Per IntervalAn actor becomes eligible again after Dedup Interval secondsLingering damage volumes, beams, burning ground
Every TickNo dedup at allWhen the consumer does its own accumulation
Windows always close themselves
An animation notify's end event is not guaranteed - an interrupted or blended-out montage can skip it. Every window therefore carries a safety timeout (Default Max Window Duration) and is force-closed with a warning if nothing else closes it.

For an attack that is routinely interrupted, prefer the Crimson Hit Window ability task: it is tied to the ability's lifetime and closes even when the ability is canceled.

Why the arc is measured from when the window opened

Crimson Filter: Angle measures against the facing captured at the moment the window opened, not the attacker's live rotation. An attack's arc is decided when it starts; sampling live rotation would let a player spin the camera mid-swing and retroactively sweep in targets who were behind them.

Report-only, and why

The plugin outputs a FCrimsonHitReport and stops. It never builds or applies a UGameplayEffect, and it never executes a GameplayCue - it carries the cue tag and lets you fire it.

This is deliberate. Effect specs are frequently modified between construction and application - by stat systems, augments, buffs - and applying them from inside a detection system would silently bypass all of it. It would also double-fire cues against any the caller's own effect already carries. Detection knows what was hit; your ability knows what that should mean.

Where each piece runs

PieceRuns on
Shape queries, filtering, dedup, target limitsServer only
On Hit Targets Resolved, On Hit Window State ChangedServer only
On Hit Impact CosmeticAll machines, via an unreliable multicast
Ability task completion pinsAll machines - empty report on clients, so a predicted graph continues
Projectile impact detection and pierce countingServer only
Projectile visual flightAll machines, simulated locally from the replicated launch state
There are no client-initiated RPCs
Nothing in the plugin is client-initiated, so there is no trust boundary to police and no _Validate surface. The cost is that hit feedback is delayed by roughly half a round trip; the cosmetic multicast exists so impact effects still land promptly on every machine that can see the fight.

The server has to be able to see the pose

Because queries run on the server, the sockets a swing sweeps between are read from the server's copy of the animation. That copy is only as current as the mesh's Visibility Based Anim Tick Option allows, and Always Tick Pose And Refresh Bones is the only value that refreshes bone transforms while a mesh is not being rendered. A server renders almost nothing, and on a listen server that includes every other player's character.

The failure looks like a replication bug and is not one
Montages keep ticking under every option, so the notify fires and the window opens exactly on schedule. Only the bones are stale. Every socket answers from the reference pose, so the attack sweeps a T-posed skeleton off to one side of the character and connects with nothing.

It is correct in standalone - one machine, mesh on screen - and wrong for everybody else, which is what makes it look like replication. It is not: the montage replicated fine and the window opened fine.

The plugin corrects this for you. Force Bone Refresh During Hit Windows (Project Settings > Crimson > Crimson Hit Detection, on by default) holds the attacker's mesh at Always Tick Pose And Refresh Bones while any window is open and restores the mesh's own setting the moment the last one closes, so the cost is paid only during the frames that need it.

See also

  • Quick Start
  • How-To: Projectiles
  • API Reference