Docs: session log Part P + roadmap tick + CLAUDE.md gotcha — Phase 1.5b decals bundle shipped

Bundle 2 (decals): explosion scorch pool, cover damage-cracks, room-arena
scars — all procedural, client-only, zero netcode. Records the pivotal
finding that a stock Synty prop shadergraph's _BaseColor is Unity-Per-Material
(not Hybrid-Per-Instance), so URPMaterialPropertyBaseColor darkening silently
no-ops on cover — the fork to decal quads.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This commit is contained in:
2026-07-12 11:04:43 -07:00
parent 8da1402e25
commit b3ef846fb8
3 changed files with 51 additions and 8 deletions
@@ -319,14 +319,50 @@ normals untouched. Ground luminance now 0.30/0.33 in edit ambient (tints stay th
for the play lap). Recipe note: bake pattern = readback-blit sources to linear Color[] → composite →
LinearToGammaSpace → PNG sRGB; HP detail imports LINEAR.
## Part P — Phase 1.5b bundle 2 (DECALS) shipped
Three locked sub-features, all **client-only presentation, procedural, zero netcode surface** (they read
*existing* replicated state): (a) explosion scorch pool, (b) cover damage-cracks, (c) light room-arena scars.
- **Pivotal grounding finding (a fork the roadmap didn't foresee):** the roadmap specified cover cracks as
`URPMaterialPropertyBaseColor` darkening — but that would **silently no-op**. Cover's render child uses the
Synty `Generic_Basic.shadergraph`, whose `_BaseColor` is declared **Unity-Per-Material**
(`overrideHLSLDeclaration:false`, `hlslDeclarationOverride:0`), **NOT Hybrid-Per-Instance** — so the
Entities-Graphics per-instance override that `EnemyHitFlashSystem` drives (enemies use the DOTS-authored
`AnimatedLitShader`, which IS hybrid-per-instance) writes to a slot the shader never reads. Exactly the
"dark render masks a material bug" trap. **Operator fork → crack-decal QUADS** (guaranteed to render,
on-theme for a decals bundle, most legible as damage) + **light room-arena cracks** (skip base POIs — Part O
already baked their wear; the deleted-WornPath double-darken lesson).
- **Architecture — one procedural decal primitive:** `FeedbackFx` gained `MakeDecalMaterial` (Sprites/Default,
ZWrite off, transparent, vertex×MPB `_Color`), `BuildScorchMesh` (irregular soft radial disc, vertex α1→0
jittered rim — the feathered edge is what stops it ghosting over fog like the old rectangle quad) and
`BuildCrackMesh` (jagged radial spokes, feathered tips). `ScorchDecalSystem` = static `RequestScorch(pos,
radius)` queue → pooled fading discs under a `DontDestroyOnLoad` root, scene-gated "Game", per-decal
hold→fade via a reused MPB (mirrors `DynamicLightSystem.RequestFlash`); wired from `WorldFeedbackSystem`'s
barrel-boom branch; **reusable by the bundle-3 geyser**. `CoverDamageSystem` accretes cracks keyed on
replicated `BlightClutter.Remaining` (Variant 4, 8→0) + shatter-scorch on despawn. `RoomDressingSystem` lays
arena scars on a distinct hash sub-stream (0xD2E56), torn down with dressing. `DecalConfig` = live knobs.
- **Self-review caught + fixed (stood in for the diff-review — client-only, no netcode):** the shatter-scorch
is now **proximity-gated** (mirrors WorldFeedbackSystem) — else a room-teardown / region-transit despawn
storm (every cover ghost dropped at once, off-camera) would spray scorches and exhaust the 24-cap pool.
- **Verified:** 470/470 EditMode; console clean (only pre-existing `WorldAtmosphereSystem` CS0618 warnings —
not this bundle). L3 headless — all 3 systems exception-free in ClientWorld, `DecalConfig` reset correct,
and the flagship scorch path proven end-to-end via VALUE inspection (mesh 25 verts + feathered vColors,
y=0.05, scale 2.76 = 3.25×0.85 exact, Sprites/Default queue 3000, shadows off, `_Color` dark-char @ α0.85)
**plus** the full spawn→hold→fade→recycle→pooled-reuse lifecycle (no leak). Commit `<pending>`.
- **Deferred to the operator's gate lap (documented, per precedent):** the in-run VISUAL judgment — cover
cracks accreting during real carving, arena scars in a real room, and whether the dark scorch reads well
over the dark baked ground — needs a launched expedition + a focused editor (unfocused blocks live-frame
verify). Knobs to taste on the lap: `ScorchColor`/alpha, `CoverCrackMaxCount`, `RoomArenaDecalCount`.
## Next-session intent
**Phase 1.5b bundle 1 (ground) is SHIPPED**; remaining locked bundles in order: **2) decals** (explosion
scorch pool · POI grime · cover damage-cracks) → **3) Blight geyser** (mini design review first — new
replicated erupt-phase surface) → **4) critters + weather beats**. Then the operator's 1.5 gate lap ("no
longer static", ground judged explicitly) → Phase 1.7 boon overhaul (design-review-FIRST) → Phase 2
hub-ification. Taste queue: arid brightness · craters call · B5 split-panels smoke · barrel explosion VFX
polish · flower density judgment (base may read dense — operator call on the lap).
**Phase 1.5b bundles 1 (ground) + 2 (decals) are SHIPPED**; remaining locked bundles in order: **3) Blight
geyser** (mini design review FIRST — new replicated erupt-phase surface) → **4) critters + weather beats**.
Then the operator's 1.5 gate lap ("no longer static", ground + decals judged explicitly) → Phase 1.7 boon
overhaul (design-review-FIRST) → Phase 2 hub-ification. Taste queue: **decals feel lap (scorch/crack/scar
tuning)** · arid brightness · craters call · B5 split-panels smoke · barrel explosion VFX polish · flower
density judgment (base may read dense — operator call on the lap).
Related: [[Iteration_2026-07_CoopHades]] · [[2026-07-07_Workflow_Consolidation]] ·
[[2026-07-07_Expedition_Enemy_Stuck_Harvest_Feedback]]