Docs: exploding-barrels Build Spec + session log Part J + roadmap tick

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
This commit is contained in:
2026-07-10 19:42:41 -07:00
parent cd607ae156
commit d8e724e40a
3 changed files with 96 additions and 8 deletions
@@ -0,0 +1,71 @@
---
title: Exploding_Barrels_Build_Spec
type: note
permalink: gamevault/03-design/exploding-barrels-build-spec
---
# Exploding Barrels — Build Spec (Phase 1.5 hazard v1, design-review-hardened)
Review: `wf_2cb10454-fdf` (3 lenses, 23 agents, 13 findings CONFIRMED / 3 refuted; the first run lost 8
verifiers to a session limit and was resumed from cache — the [[workflow-agent-quota-failures-look-clean]]
protocol held). This spec is the fold; it supersedes the pre-review draft.
## The core mechanism: the FUSE (one fix for both HIGHs)
On pop the barrel does NOT die. The server zeroes the barrel's REPLICATED `BlightClutter.Remaining` and adds
a server-only `BarrelFuse { uint ExplodeTick }` (`TickUtil.NonZero(now + Tuning.BarrelFuseTicks≈36)`). The
client therefore sees `Remaining==0` on a still-alive barrel across multiple snapshots → an unambiguous
"about to blow" cue, and the boom-vs-puff choice at despawn keys on the CACHED `Remaining<=0` — a room-
teardown despawn carries `Remaining>0`**no false booms** (HIGH #1: despawn-inference is cause-blind;
players stand in torn-down rooms through RouteSelect — RunDirectorSystem.cs:247-251, WorldFeedbackSystem
prune :96-119). Detonation is the AUTHORING moment → `DamageEvent.SourceTick = TickUtil.NonZero(detonation
tick)` honors the authored-tick contract dash i-frames negate against (HIGH #2; DamageEvent.cs:20-24).
The fuse also: dissolves the melee self-hit complaint (pop → step out), creates the bait loop (lure enemies
onto a lit barrel), and — because the fuse lives ON the RoomTag'd barrel — room teardown/Staging sweep
clean fused barrels for free (the orphaned-ExplosionEvent lifecycle findings dissolve).
## Server
- **Seeding** (RoomFieldSystem clutter loop): `bc.Variant = crng.NextFloat() < 0.25f ? (byte)3 : (byte)(i % 3)`
(seeded rng, deterministic; variants 0-2 stay cosmetic).
- **Pop sites** (BOTH: ResourceHarvestSystem projectile sweep; MeleeComboSystem isServer-gated harvest block):
gate on `isClutter && Variant==3` INSIDE the destroyed-bitset guard (nodes share the packed arrays with
Variant slot 0 — confirmed LOW). On rem<=0 for an explosive: mark destroyed[i] (unhittable this tick),
`SetComponent(BlightClutter{Remaining=0,...})` + `ecb.AddComponent(BarrelFuse{ExplodeTick})` — NO destroy.
Both target snapshots SKIP entries with `Remaining <= 0` (a fused barrel is not hittable → no double-pop).
- **`HazardExplosionSystem`** (new, ProjectM.Server, plain `SimulationSystemGroup`, NO ordering attributes,
NO lifecycle gating — a fused barrel must always drain (confirmed LOW: never RequireForUpdate-gate it);
`TryGetSingleton<NetworkTime>` invalid → skip tick, fuse persists): query `(BarrelFuse, LocalTransform)`;
when `ExplodeTick` elapses (NetworkTick.IsNewerThan semantics): radius scan (XZ, `Tuning.BarrelExplodeRadius
≈3.25`) — players via the BossAISystem:62-70 gather VERBATIM (`Health>0 && RegionTag==Expedition`; confirmed:
dead players persist at death pos for DelayTicks) + enemies (`EnemyTag && Health>0`, excludes Dying corpses)
`AppendToBuffer(DamageEvent{ Amount=Tuning.BarrelExplodeDamage≈26, SourceNetworkId=-1, SourceTick=
TickUtil.NonZero(now) })``ecb.DestroyEntity(barrel)` (single destroy site).
**SourceNetworkId = -1** (environment convention — confirmed: a player id would score+consume Charger
whiff-punish windows via HealthApplyDamageSystem:102, the sole reader).
- **No chain reactions** v1 (clutter has Remaining, not Health). Damage numbers as `Tuning` consts v1;
promote to TuningConfig knobs when the knob-table extension is worth it (confirmed-LOW tension, deferred
deliberately — noted here per [[ask-before-deferring-during-implementation]]: the overlay knob table is a
separate mechanical slice).
## Client (all new work — confirmed: NO existing per-variant path; Variant is read by zero client systems)
- **WorldFeedbackSystem**: add `Variant` to the Cache struct; at prune, `IsClutter && Variant==3 &&
Remaining<=0` → BIG boom (burst + `DynamicLightSystem.RequestFlash` large orange + low boom SFX); else the
existing small puff. Teardown despawns (Remaining>0) keep the puff.
- **DynamicLightSystem**: Variant==3 barrels get a red glow light (node-glow pattern); when the cached
`Remaining<=0` (fuse lit) the glow strobes hard — the flee cue. (Body tint via URPMaterialPropertyBaseColor
on LEG children = polish, deferred.)
## Tests
- ResourceHarvestSystemTests: explosive pop → BarrelFuse added, Remaining==0, entity ALIVE; fused barrel
not re-hittable.
- New HazardExplosionSystemTests: elapsed fuse → DamageEvent(Amount, SourceNetworkId=-1) on in-radius living
enemy AND living player, dead player skipped, out-of-radius skipped, barrel destroyed once; un-elapsed
fuse → nothing.
## Wire/bake classification
ZERO new [GhostField]s / ghost prefabs / RPCs; `BarrelFuse` is server-only; Variant==3 rides the existing
replicated byte. No new ordering edges. Re-bake: none (code + seeded-value only).
@@ -145,8 +145,11 @@ attacks/animations/effects**. Art direction deliberately UNDECIDED — lighting
### Long-term (server-sim; adversarial design-review REQUIRED per slice)
7. **Environmental hazards:** exploding barrels, Blight geysers, trap tiles — damage BOTH sides so enemies can be
baited into them. Real combat interplay; replication + predicted-damage surface needs the review.
7. **Environmental hazards — v1 SHIPPED (2026-07-10, `cd607ae15`, review-first `wf_2cb10454-fdf`):**
exploding barrels — ~25% of clutter seeds explosive; pop lights a ~0.6s FUSE (replicated Remaining=0 =
the client cue, strobing red glow) then radius-damages BOTH sides (bait mechanic; escapable). Zero new
replication. Geysers/trap tiles = later hazard variants on the same HazardExplosionSystem chassis.
See [[Exploding_Barrels_Build_Spec]].
8. **Destructible cover:** in-room cover rocks take damage and crumble (Charger smashes through, players carve LOS).
Structures already have Health; **re-validate the enemy stuck-fix backstop when cover can disappear mid-fight.**
@@ -214,14 +214,28 @@ Verified live: a 12 s combat histogram showed zones rendering K0+K1 materials ke
Client presentation file that only used Simulation types before). Remaining distinctness depth (per-kind
anim clips, creature locomotion) rides the parallel Blender workstream.
## Part J — exploding barrels SHIPPED (`cd607ae15`; 07-10, session continued past midnight)
The 1.5 long-term hazard v1, **review-first as mandated**: 3-lens adversarial workflow `wf_2cb10454-fdf`
(23 agents; the first run lost 8 verifiers to the session limit — resumed via `resumeFromRunId`, cache
replayed, 13 findings CONFIRMED / 3 refuted; Build Spec kept at [[Exploding_Barrels_Build_Spec]]).
**The fold: the FUSE** — one mechanism closed both HIGHs (despawn-inference false booms on room teardown ·
the SourceTick authored-tick contract): pop → replicated `Remaining=0` on a still-alive barrel + server-only
`BarrelFuse` (~36 ticks) → detonation damages LIVING enemies AND players (boss-slam filter verbatim,
`SourceNetworkId=-1`, SourceTick at detonation) → single destroy. Client: boom-vs-puff keys on cached
`Remaining<=0` (teardowns carry >0 → no false booms); Variant-3 barrels get a red glow that STROBES when
fused. ~25% seeding on the existing replicated Variant byte — **zero new GhostFields/prefabs/RPCs**.
Verified: 470/470 (4 new tests) · live smoke: client OBSERVED the fuse cue on the live ghost, pinned bait
enemy took exactly 26 (30→4), walk-out escape confirmed (fuse is escapable by design — first unpinned bait
simply left the radius) · console clean.
## Next-session intent
**Phase 1.5 short-term wins are COMPLETE** (collision ✓ lighting ✓ art-look ✓ ambient motion ✓ breakables ✓
attack distinctness ✓). Next: either the 1.5 long-term slices (**environmental hazards** / **destructible
cover** — BOTH adversarial design-review-first, and cover must re-validate the enemy backstop) or jump to
**Phase 1.7 boon overhaul** (~12 mechanic-changers; design review required — replicated ability swaps).
Operator gate: a feel-lap over the whole 1.5 package ("no longer static"?) decides. Queued taste items:
re-enable curated base flora · arid brightness · craters call · B5 split-panels smoke.
Phase 1.5 remaining: **destructible cover** (the last long-term item — design-review-first, MUST re-validate
the enemy stuck-fix backstop when cover can vanish mid-fight) → then the 1.5 gate lap → **Phase 1.7 boon
overhaul** (design review required — replicated ability swaps). Queued taste items: re-enable curated base
flora · arid brightness · craters call · B5 split-panels smoke · barrel VFX polish (authored explosion
prefab instead of the procedural burst).
Related: [[Iteration_2026-07_CoopHades]] · [[2026-07-07_Workflow_Consolidation]] ·
[[2026-07-07_Expedition_Enemy_Stuck_Harvest_Feedback]]