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
+1
View File
@@ -105,6 +105,7 @@ Long-form originals + the milestone each came from: `Docs/Vault/_Meta/CLAUDE_Bui
- BefourStudios HDRP art: convert via `EnvArtTools.cs`, never switch pipelines (HDRP breaks EG); Synty = URP-native → archive 2026-07-06.
- **World = cosmetic Synty nature biomes ★ (DR-025):** `Game.unity` roots `BaseBiome`(Meadow_Forest)@origin + `ExpeditionBiome`(Arid_Desert)@+1000; ground = stock URP/Lit (NOT prop-atlas `S_General`). Per-region fog/ambient cross-fade via client `WorldAtmosphereSystem` (camera X>500). **PNB fog/cloud-ring prefabs = white torus — don't place.** See [[DR-025_World_Environment_Redo_Natural_Frontier]].
- **A dark-lit screenshot MASKS material bugs — verify material *values*.** `shader.GetPropertyType(idx)`-guard before `GetColor`/`GetFloat`/`GetTexture` (`S_General`'s `_BaseColorMultiply` is a float → `GetColor` returns black). Gate emission on the `_Emissive` flag + a fixture name; keep converted env metallic low (0.10.2).
- **An EG per-instance tint (`URPMaterialPropertyBaseColor`) darkens a ghost ONLY if the shader's `_BaseColor` is Hybrid-Per-Instance** (ShaderGraph `overrideHLSLDeclaration:true`+`hlslDeclarationOverride:2`). Enemies flash because `AnimatedLitShader` is DOTS-authored; a **stock Synty prop graph (`Generic_Basic`) is Unity-Per-Material → the override RENDERS but silently no-ops.** Check the graph before planning a per-instance tint on a baked/prop mesh; else use procedural decal quads (07-12 cover damage-cracks, Part P).
- **VolumeProfile.Add persistence + the URP `m_AssetVersion` build blocker** → archive 2026-07-06 (+ native memory `urp-global-settings-version-blocks-build`).
- **`LocalTransform.FromPosition()` resets Scale=1** — server spawners read the prefab's baked `LocalTransform`, override only Position (Scale is a `[GhostField]` → consistent-but-wrong).
- **Static decor → gameplay subscene** (EG renders only baked entities); **strip colliders from cosmetic props** + no `GhostAuthoring` on scenery (classic-URP colliders are inert to the DOTS PhysicsWorld). **World collision = subscene-only ★:** `Environment`-layer boundary ring + landmark colliders (player blocked via the layer matrix); enemies slide via a server `CollisionWorld.SphereCast` in `EnemyAISystem`. **★ enemy slide has NO pathfinding — a near-vertical wall normal or an embedded spawn FROZE Husks on cover rocks (soft-locks a room on one leftover); fixed 07-07 via `EnemyMoveUtil.Depenetrate` + tangent-slide + an `EnemyNavState` nudge backstop. Re-validate movers aren't frozen when adding Environment cover. 07-10: the nudge is COVER-AWARE — a live destructible-cover ghost (`BlightClutter` carrier) SUPPRESSES the phase-through (breakable ⇒ no soft-lock); static wedges still nudge.** Boundary = `SM_Env_Rock_Cliff` rim. See [[2026-06-08_World_Collision_HUD_Scaling]].
@@ -168,8 +168,14 @@ plain"** — expand 1.5 before 1.7. Locked bundles, sequenced ground-first:
per room inside the room's ACTUAL shape (hash stream 0xD2E55; 47 build-safe prefab refs), room-torn-down;
live-verified incl. teardown + exact Meadow tint convergence; (c) worn paths storage→warpgate/base-gate;
(d) 357 base flora re-enabled (buildings/pond/FX stay parked).
2. **Decals**: dynamic explosion scorch marks (fading quad pool at boom sites), static POI scorch/cracks,
cover damage-crack states (URPMaterialPropertyBaseColor darkening keyed on replicated Remaining).
2. **Decals** (SHIPPED, Part P — all procedural, client-only, zero netcode): explosion scorch pool
(fading disc pool via `ScorchDecalSystem.RequestScorch`, wired from the barrel boom; reusable by the
geyser) · cover damage-CRACKS keyed on replicated `BlightClutter.Remaining` (Variant 4) + proximity-gated
shatter-scorch · light room-arena crack/scorch scars (via `RoomDressingSystem`). ★ The specified
`URPMaterialPropertyBaseColor` darken would have **silently no-op'd** — cover's Synty `Generic_Basic`
shadergraph declares `_BaseColor` Unity-Per-Material, NOT Hybrid-Per-Instance (only the DOTS-authored
`AnimatedLitShader` honours the EG per-instance override); operator fork → decal quads instead. Base POIs
skipped (Part O baked their wear). Knobs in `DecalConfig`.
3. **Hazard variant**: Blight geyser (periodic both-sides AoE on the HazardExplosion + telegraph-disc
chassis) — mini design review first (new replicated erupt-phase surface).
4. **Critters + weather beats**: fleeing bugs/birds; cloud-shadow drifts; Blight lightning flicker.
@@ -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]]