Death Debris Spawn
When an enemy dies, the engine spawns a short, punchy burst of tumbling shard fragments at the death location via spawnDeathDebris(wx, wy, radius, count, behavior?) in engine/bridge-death-debris.ts. The burst is the primary at-a-glance signal that a kill landed — shards carry the dying archetype’s color so the kill stream stays readable in chaos.
Not to be confused with the ambient DebrisField cluster system in engine/world/debris.ts, which spawns floating metal-shard hazard clusters in the world (player-damaging contact obstacles). That is a separate, biome-driven destructible system — death debris is a one-shot visual on enemy kill.
Spawn pipeline
spawnDeathDebris is called on enemy death with the enemy’s world position, collision radius, a base shard count, and the enemy’s archetype behavior string. It then:
- Looks up tint in
ARCHETYPE_DEBRIS_TINT[behavior], falling back to a default red (_DEFAULT_DEBRIS_TINT: bright(1.00, 0.16, 0.16), dark(0.78, 0.10, 0.10)) when the archetype is unknown. - Looks up count multiplier in
ARCHETYPE_DEBRIS_COUNT_MULT[behavior], defaulting to1.0for unmapped archetypes. The scaled count isMath.max(1, Math.round(count * countMult))— at least one shard always spawns so a kill never reads as silent. - Spawns shards in a loop, gated by the global pool cap. Each shard gets a random ejection angle, a random speed in
[220, 400]px/s (DEBRIS_MIN_SPEED + DEBRIS_SPEED_RANGE), a random lifetime in[0.18, 0.32]s, a random rotation + spin, a size of4 + rand(0..4) + radius * 0.10, and a random sprite variant index in[0, 6).
Per-archetype tint map (16 archetypes)
Each entry is a 2-tone tint { rL, gL, bL, rD, gD, bD }. Per shard, bright vs dark is picked with 50/50 weight — matching the prior red-bright/red-dark jitter so kill bursts feel consistent across archetype. The map currently covers 16 archetypes:
| Archetype | Bright (rL, gL, bL) | Dark (rD, gD, bD) | Read |
|---|---|---|---|
orb | 1.00, 0.16, 0.16 | 0.78, 0.10, 0.10 | generic red (default) |
charger | 1.00, 0.40, 0.10 | 0.78, 0.25, 0.06 | aggressive orange-red |
racer | 1.00, 0.90, 0.20 | 0.78, 0.62, 0.10 | neon yellow-electric |
shooter | 0.30, 1.00, 0.30 | 0.18, 0.78, 0.18 | toxic green |
gunner | 0.60, 1.00, 0.20 | 0.40, 0.78, 0.10 | green-yellow |
mortar | 1.00, 0.55, 0.10 | 0.78, 0.35, 0.06 | explosive orange |
sniper | 0.75, 0.30, 1.00 | 0.50, 0.18, 0.78 | beam purple |
field | 0.30, 0.90, 1.00 | 0.18, 0.62, 0.78 | field cyan |
brute | 0.60, 0.45, 0.32 | 0.40, 0.28, 0.20 | dark grey-brown chunks |
wisp | 1.00, 0.50, 1.00 | 0.78, 0.32, 0.78 | ethereal magenta |
lurker | 0.55, 0.20, 0.80 | 0.35, 0.12, 0.55 | deep dark-purple |
bombardier | 1.00, 0.75, 0.20 | 0.78, 0.50, 0.10 | bright explosive amber |
sprinter | 0.78, 1.00, 1.00 | 0.50, 0.78, 0.78 | supersonic cyan-electric |
spitter | 0.70, 1.00, 0.20 | 0.50, 0.78, 0.10 | acid yellow-green |
burner | 1.00, 0.50, 0.15 | 0.78, 0.32, 0.08 | fire/lava red-orange |
suppressor | 0.55, 0.70, 0.30 | 0.35, 0.50, 0.18 | industrial olive-drab |
Per-archetype count multiplier (0.4x – 1.5x)
ARCHETYPE_DEBRIS_COUNT_MULT scales the caller-supplied base count so heavier archetypes throw more shards and lighter ones throw fewer — preserves the at-a-glance mass read that tint + audio already encode. Missing entries default to 1.0.
| Multiplier | Archetypes |
|---|---|
0.4 | wisp (tiny ethereal — almost no shards) |
0.5 | sprinter (fragile + supersonic) |
0.8 | gunner (small turret) |
1.0 (default) | orb, charger, racer, shooter, sniper |
1.1 | lurker |
1.2 | spitter |
1.3 | mortar, suppressor |
1.4 | field, burner |
1.5 | brute (heavy chassis), bombardier (big explosive payload) |
Floor of 1 shard is enforced regardless of multiplier, so tiny enemies still produce visual feedback.
Sprite variants (6)
Each shard picks one of SHARD_VARIANT_COUNT = 6 pre-baked red shard sprites from the texture atlas (baked once at startup by atlas-builder.ts). The atlas index is stored on the shard as variant: 0..5. The runtime never re-bakes — it just samples a different region of the same atlas per shard for visual variety in a single burst. Tint multiplies the sprite pixels at draw time, so all 6 variant shapes work for every archetype color.
Pool cap (60)
The active shard pool is capped at _MAX_DEBRIS = 60. The spawn loop checks deathDebris.length < _MAX_DEBRIS per shard and stops adding once the pool is full — late shards in a big kill chain (e.g. a screen full of brutes dying simultaneously) are simply dropped. There is no priority eviction; oldest shards fall out via lifetime expiry (life: 0.18–0.32 s), which clears budget quickly enough that the cap rarely starves a normal burst.
Position jitter
Each shard’s spawn position is offset from the death point by (rand-0.5) * radius * 0.4 on each axis, so shards emerge from a small box scaled to the enemy’s collision radius rather than all from a single point. Larger enemies → wider initial spread.
See also
engine/bridge-death-debris.ts— source moduleengine/world/debris.ts— separate ambient debris-cluster hazards- Sister T18/T19 dispatch-site override maps: tick-42 audio (per-archetype death SFX), tick-43 VFX burst, tick-56 count multiplier (this page)