Docs: DR-025 world redo (natural-frontier biomes) + session log; CLAUDE.md art pointer
Session log + DR-025 for the off-world natural-frontier world redo; mark PolygonNatureBiomes in-use in the Synty inventory; archive the long-form gotchas (PNB ring-mesh white-torus, edit-mode region-fog preview, EG-entity vs cosmetic, execute_code DeleteAsset block, shadow-cast hygiene). CLAUDE.md: net-zero art pointer to DR-025 (39882 B, under the 40KB budget). Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -98,10 +98,11 @@ Long-form originals + the milestone each came from: `Docs/Vault/_Meta/CLAUDE_Bui
|
|||||||
- **Asset-free presentation:** procedural `AudioClip.Create` SFX; runtime `ParticleSystem` pool (Sprites/Default + HDR start color); code-built **UI Toolkit** HUD/menus. Edit a prefab asset's component in code via `PrefabUtility.LoadPrefabContents` → modify → **`SaveAsPrefabAsset(root, path)`** → `UnloadPrefabContents`. Watch **shared-material bleed** when re-tinting. ACES tonemapping needs URP color grading mode = HDR (`m_ColorGradingMode=1`).
|
- **Asset-free presentation:** procedural `AudioClip.Create` SFX; runtime `ParticleSystem` pool (Sprites/Default + HDR start color); code-built **UI Toolkit** HUD/menus. Edit a prefab asset's component in code via `PrefabUtility.LoadPrefabContents` → modify → **`SaveAsPrefabAsset(root, path)`** → `UnloadPrefabContents`. Watch **shared-material bleed** when re-tinting. ACES tonemapping needs URP color grading mode = HDR (`m_ColorGradingMode=1`).
|
||||||
- **Prototype glue lives in `ProjectM.Client` as MonoBehaviours:** `PrototypeCameraRig` (player-following ARPG cam), `VFXConfig` (static `Instance` + prefab fields bridging authored VFX to `CombatFeedbackSystem`; keep a procedural fallback). A **static presentation bridge must reset on play-enter** via `[RuntimeInitializeOnLoadMethod(SubsystemRegistration)]` (statics survive fast-enter-playmode reloads → stale flash).
|
- **Prototype glue lives in `ProjectM.Client` as MonoBehaviours:** `PrototypeCameraRig` (player-following ARPG cam), `VFXConfig` (static `Instance` + prefab fields bridging authored VFX to `CombatFeedbackSystem`; keep a procedural fallback). A **static presentation bridge must reset on play-enter** via `[RuntimeInitializeOnLoadMethod(SubsystemRegistration)]` (statics survive fast-enter-playmode reloads → stale flash).
|
||||||
- **UITK HUD + menus ★:** `MenuUi` owns the shared palette + element factories + `PanelSettings`/`EventSystem` plumbing + the canonical `Round`/`Border` helpers; `HudUi` is a thin extension. `HudSystem` is a `PresentationSystemGroup` observe-only `SystemBase` owning a runtime `UIDocument` (`sortingOrder 50`, behind the pause overlay's 100); builds the tree on the first frame `rootVisualElement != null`, root `pickingMode = Ignore` so the HUD never eats world clicks (only palette buttons opt back in). **Runtime UITK needs a `PanelSettings` WITH a `themeStyleSheet` AND an `EventSystem` + `InputSystemUIInputModule`** or buttons are silently dead. The **build palette** (lazy-built from the client `StructureCatalog`) drives click-to-place: green/red ground-ghost preview (`BuildPreviewMath`, the client mirror of the server check), left-click → `BuildPlaceRequest` RPC, right-click/Esc cancel, `[`/`]`/R rotate, `Fire` suppressed in build mode. See [[DR-021_HUD_UITK_BuildPalette]].
|
- **UITK HUD + menus ★:** `MenuUi` owns the shared palette + element factories + `PanelSettings`/`EventSystem` plumbing + the canonical `Round`/`Border` helpers; `HudUi` is a thin extension. `HudSystem` is a `PresentationSystemGroup` observe-only `SystemBase` owning a runtime `UIDocument` (`sortingOrder 50`, behind the pause overlay's 100); builds the tree on the first frame `rootVisualElement != null`, root `pickingMode = Ignore` so the HUD never eats world clicks (only palette buttons opt back in). **Runtime UITK needs a `PanelSettings` WITH a `themeStyleSheet` AND an `EventSystem` + `InputSystemUIInputModule`** or buttons are silently dead. The **build palette** (lazy-built from the client `StructureCatalog`) drives click-to-place: green/red ground-ghost preview (`BuildPreviewMath`, the client mirror of the server check), left-click → `BuildPlaceRequest` RPC, right-click/Esc cancel, `[`/`]`/R rotate, `Fire` suppressed in build mode. See [[DR-021_HUD_UITK_BuildPalette]].
|
||||||
- **Synty HUD skin via a build-safe `HudTheme` ★ (DR-024):** Synty sprites/fonts live under `Assets/Synty/…` (NOT Resources) → a runtime name-string `Resources.Load` is **stripped from the build**; instead a curated `HudTheme : ScriptableObject` at `Assets/_Project/Resources/HudTheme.asset` holds **serialized** Sprite/Font refs (dependency-walked in), loaded null-safe via `HudTheme.Get()` with **every consumer falling back to the flat look on a null ref**. `unityBackgroundImageTintColor` MULTIPLIES (tint white skins, zero bleed); fonts = cached SDF `FontAsset`, reset on `SubsystemRegistration`. Don't set `unitySlice*` on Synty frame/bar sprites — they ship authored 9-slice borders and overriding logs a per-element ERROR (but DO set `unitySlice*` for border-0 sprites that ship no authored border). Some Synty sprites import as **Multiple** mode → `LoadAssetAtPath<Sprite>` returns null; verify import mode + each ref non-null. See [[DR-024_HUD_Synty_Skin_Theme]].
|
- **Synty HUD skin via a build-safe `HudTheme` ★ (DR-024):** Synty sprites/fonts under `Assets/Synty/…` (NOT Resources) → a runtime name-string `Resources.Load` is **build-stripped**; use a curated `HudTheme : ScriptableObject` (`Assets/_Project/Resources/HudTheme.asset`) holding **serialized** refs, loaded null-safe via `HudTheme.Get()` (every consumer falls back to flat on a null ref). `unityBackgroundImageTintColor` MULTIPLIES (tint white skins); fonts = cached SDF, reset on `SubsystemRegistration`. Don't set `unitySlice*` on Synty 9-slice frame/bar sprites (per-element ERROR; DO set it for border-0 sprites). Some Synty sprites import as **Multiple** → `LoadAssetAtPath<Sprite>` null; verify. See [[DR-024_HUD_Synty_Skin_Theme]].
|
||||||
|
|
||||||
### Art import (HDRP store packs → URP)
|
### Art import (HDRP store packs → URP)
|
||||||
- BefourStudios art is **HDRP-authored** → magenta under URP 17.4 + Entities Graphics. **Convert, don't switch pipelines** (HDRP breaks Entities Graphics). Re-author to stock URP/Lit via `EnvArtTools.cs` (menu `ProjectM/Art/1. Convert Curated Env Materials`). Synty art is **URP-native — no conversion**.
|
- BefourStudios art is **HDRP-authored** → magenta under URP 17.4 + Entities Graphics. **Convert, don't switch pipelines** (HDRP breaks Entities Graphics). Re-author to stock URP/Lit via `EnvArtTools.cs` (menu `ProjectM/Art/1. Convert Curated Env Materials`). Synty art is **URP-native — no conversion**.
|
||||||
|
- **World = cosmetic Synty nature biomes ★ (DR-025):** `Game.unity` roots `BaseBiome`(Meadow_Forest)@origin + `ExpeditionBiome`(Arid_Desert)@+1000 — classic-URP cosmetics, colliders stripped, **NEVER the subscene**; ground = stock URP/Lit `Mat_Grass_Textures_01`/`sand 1` (NOT prop-atlas `S_General` mats). Global `Skybox/Procedural` material (a Synty skydome MESH sits at origin → can't cover two regions); per-region fog/ambient cross-fade via client `WorldAtmosphereSystem` (camera X>500, mirrors `HudSystem`). **PNB fog/cloud-ring PREFABS render as a white torus — don't place them** (use `RenderSettings` fog). See [[DR-025_World_Environment_Redo_Natural_Frontier]].
|
||||||
- **A dark-lit screenshot MASKS material bugs — verify material *values*.** Always `shader.GetPropertyType(idx)`-guard before `GetColor`/`GetFloat`/`GetTexture` (`S_General`'s `_BaseColorMultiply` is a float; `GetColor` on it returns black). Gate source emission on the `_Emissive` flag AND a fixture name. Keep converted env metallic low (0.1–0.2).
|
- **A dark-lit screenshot MASKS material bugs — verify material *values*.** Always `shader.GetPropertyType(idx)`-guard before `GetColor`/`GetFloat`/`GetTexture` (`S_General`'s `_BaseColorMultiply` is a float; `GetColor` on it returns black). Gate source emission on the `_Emissive` flag AND a fixture name. Keep converted env metallic low (0.1–0.2).
|
||||||
- **`VolumeProfile.Add<T>()` does NOT persist** (serializes `{fileID:0}` on save) — use `AssetDatabase.AddObjectToAsset(component, profile)` + `SaveAssets`, verify on disk.
|
- **`VolumeProfile.Add<T>()` does NOT persist** (serializes `{fileID:0}` on save) — use `AssetDatabase.AddObjectToAsset(component, profile)` + `SaveAssets`, verify on disk.
|
||||||
- **A reverted engine/URP upgrade can stamp `UniversalRenderPipelineGlobalSettings.asset` `m_AssetVersion` AHEAD of the package's `k_LastVersion`** (here 11 > 10, from the reverted 6.6 alpha). URP migrates **forward only**, so `URPPreprocessBuild` rejects the "from-the-future" asset (*"not at last version"*) — **blocks player builds but NOT editor Play**. Fix: reflection-set `m_AssetVersion` back to `k_LastVersion`, `SetDirty` + `SaveAssets`.
|
- **A reverted engine/URP upgrade can stamp `UniversalRenderPipelineGlobalSettings.asset` `m_AssetVersion` AHEAD of the package's `k_LastVersion`** (here 11 > 10, from the reverted 6.6 alpha). URP migrates **forward only**, so `URPPreprocessBuild` rejects the "from-the-future" asset (*"not at last version"*) — **blocks player builds but NOT editor Play**. Fix: reflection-set `m_AssetVersion` back to `k_LastVersion`, `SetDirty` + `SaveAssets`.
|
||||||
|
|||||||
@@ -25,7 +25,7 @@ Catalog of the Synty Polygon packs under `Assets/Synty/`, produced by the [[DR-0
|
|||||||
|
|
||||||
## Environment / world (no characters — map + set-dressing)
|
## Environment / world (no characters — map + set-dressing)
|
||||||
|
|
||||||
- **PolygonNatureBiomes** (highest env value): **Arid_Desert** reads as an off-world expedition site out of the box (satellite, solar panels, turbines, beacons, artefacts, even a **Warpgate**) — perfect for the **+1000 expedition region** ([[DR-013_M6_Aether_Cycle_Region_Split]]). Meadow_Forest (ships a post-process volume) for the home base.
|
- **PolygonNatureBiomes** ✅ **IN USE** ([[DR-025_World_Environment_Redo_Natural_Frontier]]): **Arid_Desert** = the **+1000 expedition region** (off-world survey site: satellite, solar panels, turbines, beacons, artefact, alien bones, craters; cliff/rock perimeter ring) and **Meadow_Forest** = the **home base** (tree-ring bowl, Warpgate gateway, cabin/windmill/well/pond). Built as cosmetic classic-URP roots in `Game.unity` (no conversion; colliders stripped). Ground = `Mat_Grass_Textures_01` / `sand 1` (both stock URP/Lit — AVOID the prop-atlas `S_General` mats as a floor).
|
||||||
- **PolygonNature**: trees/rocks/foliage/water + skybox — terrain dressing, harvestable-node visuals.
|
- **PolygonNature**: trees/rocks/foliage/water + skybox — terrain dressing, harvestable-node visuals.
|
||||||
- **PNB_Core**: shared sky/weather/water/aurora atmosphere (rain/snow/fog FX, skydome, 9 ShaderGraphs — verify under URP 17.4; use the skydome in the classic-URP cosmetic root, not baked EG meshes).
|
- **PNB_Core**: shared sky/weather/water/aurora atmosphere (rain/snow/fog FX, skydome, 9 ShaderGraphs — verify under URP 17.4; use the skydome in the classic-URP cosmetic root, not baked EG meshes).
|
||||||
- **PolygonKaiju** (env half): 23 buildings incl. **pre-destroyed** highrises/blocks + 40 props (cars, boats, bridge+rubble, neon signs, powerlines, crane, jet, missile) — a ruined-city map + FX meshes (bullets/fire/stomp).
|
- **PolygonKaiju** (env half): 23 buildings incl. **pre-destroyed** highrises/blocks + 40 props (cars, boats, bridge+rubble, neon signs, powerlines, crane, jet, missile) — a ruined-city map + FX meshes (bullets/fire/stomp).
|
||||||
|
|||||||
@@ -0,0 +1,101 @@
|
|||||||
|
---
|
||||||
|
date: 2026-06-08
|
||||||
|
type: session
|
||||||
|
tags:
|
||||||
|
- session
|
||||||
|
- art
|
||||||
|
- synty
|
||||||
|
- environment
|
||||||
|
- world
|
||||||
|
- urp
|
||||||
|
- presentation
|
||||||
|
- biomes
|
||||||
|
permalink: gamevault/07-sessions/2026/2026-06-08-world-environment-redo
|
||||||
|
---
|
||||||
|
|
||||||
|
# Session 2026-06-08 — World environment redo (off-world natural frontier)
|
||||||
|
|
||||||
|
> Driven by `/dots-dev` (Feature track) under **ultracode**. Major world cleanup using newly-imported Synty
|
||||||
|
> nature packs (PolygonNature, PolygonNatureBiomes, PNB_Core).
|
||||||
|
|
||||||
|
## Goal
|
||||||
|
|
||||||
|
Operator: *"The world environment needs a major cleanup. I imported new assets — use them to redo the world.
|
||||||
|
Utilize materials, terrain, new models, foliage. Whatever makes the world look good."* Intake fork resolved:
|
||||||
|
**off-world natural frontier** (Meadow_Forest base + Arid_Desert expedition, sci-fi tech on top) · **both regions**.
|
||||||
|
|
||||||
|
## Process (ultracode)
|
||||||
|
|
||||||
|
- **Design fan-out Workflow** (3 read-only agents → verified build spec): Meadow base composition, Arid expedition
|
||||||
|
composition, atmosphere/lighting recipe extracted from Synty's own biome demo scenes. Every prefab/material path
|
||||||
|
verified by reading the `.prefab`/`.mat` YAML before listing.
|
||||||
|
- **Implementation sequential via `execute_code`** (single editor — mutation can't race; the blessed DR-011/DR-018
|
||||||
|
pattern), in batches with `read_console` between each.
|
||||||
|
- **4-lens adversarial review Workflow** (sim-isolation · performance · code-correctness · composition) over the
|
||||||
|
saved scene + new scripts + screenshots → confirmed findings fixed before sign-off.
|
||||||
|
|
||||||
|
## Done
|
||||||
|
|
||||||
|
- **Retired the old world** (`SyntyWorld` sci-fi colony + `BlightfieldDecor`/`ExpeditionGround`/`ExpedPillar*`/`Ground`,
|
||||||
|
8 roots) and built two cosmetic classic-URP roots in `Game.unity` (NOT the subscene; colliders stripped → inert to
|
||||||
|
the DOTS PhysicsWorld, per [[DR-011_Synty_World_VFX_Integration]]/[[DR-018_World_Space_Cohesion_Pass]]):
|
||||||
|
- **`BaseBiome`** (origin) — Meadow_Forest: grass ground plane, 195 deterministic foliage/tree/rock instances
|
||||||
|
(tree-ring bowl r20-30, wildflower band, bushes/rocks/ground-cover, flat interior cover only), 8 landmarks
|
||||||
|
(**Warpgate** hero gateway at (0,0,-20), stone cabin, windmill, well, pond + waterwheel + lilies, 2 sci-fi crates),
|
||||||
|
6 FX (butterflies/sunbeams/petals/glowing-dust/water), 4 cyan Aether point lights.
|
||||||
|
- **`ExpeditionBiome`** (+1000) — Arid_Desert: sand ground plane, 182+5 instances (cliff/spike ring r44-58, mid
|
||||||
|
rock/cactus/bramble bands, crater+alien-bone scatter, flat inner cover, background hills, **5 hero rock
|
||||||
|
silhouettes** added in review), 9 survey-outpost landmarks (satellite, solar array, 2 turbines, tent, survey
|
||||||
|
level, sign, alien artefact, rock arch), 6 FX (dust/ash/sunray/tumbleweed/vulture), 4 orange Aether point lights.
|
||||||
|
- **Atmosphere:** warm daylight directional sun (euler 50,330; `#FFF4E0`; 1.6), Trilight ambient, a new
|
||||||
|
`Skybox/Procedural` material (`Assets/_Project/Rendering/Sky_DaytimeProcedural.mat`, infinite → covers both regions
|
||||||
|
unlike a Synty skydome mesh at origin), exp-squared fog, and a cloned daylight post-FX profile
|
||||||
|
(`PostFX_Daylight.asset` — kept ACES, trimmed bloom/contrast/vignette + neutralised the dark-colony cool cast).
|
||||||
|
- **`WorldAtmosphereSystem`** (+ `WorldAtmosphereConfig`) — client-only presentation `SystemBase` that cross-fades
|
||||||
|
`RenderSettings` fog colour/density + ambient sky between the cool-green meadow and the warm-orange desert based on
|
||||||
|
camera world-X (mirrors `HudSystem`'s region split at X>500). Pure presentation, observe-only, zero sim impact;
|
||||||
|
live-tunable config mirroring the `WorldFeelConfig` idiom.
|
||||||
|
|
||||||
|
## Validation
|
||||||
|
|
||||||
|
- **EditMode 214/214** (unchanged; the new presentation code added no test but broke none). Console clean (only the
|
||||||
|
pre-existing benign Server-Tick-Batching/RPC-age warnings).
|
||||||
|
- **Value-introspected:** 832 renderers across both biomes, **0 colliders** (all stripped), **0 error/magenta
|
||||||
|
materials**, 8 point lights (shadows off), 13 particle systems. All Synty shaders URP-native.
|
||||||
|
- **Adversarial review (4 lenses):** isolation = *purely cosmetic confirmed* (no ghost/subscene/sim/PhysicsWorld
|
||||||
|
leak; system writes only `RenderSettings`); perf = Forward+ clustered lights + SRP batcher correct, **fixed**
|
||||||
|
realtime shadow-casting on 254 small props + ground planes (now off); code = correct vs sibling systems, **fixed**
|
||||||
|
fog-default drift; composition = **fixed** washed/flat desert (removed bad fog-ring meshes, saturated expedition
|
||||||
|
fog, added hero silhouettes). Hero shots: `Assets/Screenshots/redo_base_meadow3.png` (+ `redo_expedition_arid3.png`
|
||||||
|
previewed with expedition atmosphere baked).
|
||||||
|
|
||||||
|
## Decisions
|
||||||
|
|
||||||
|
- [[DR-025_World_Environment_Redo_Natural_Frontier]] — off-world natural-frontier biome world; cosmetic-GameObject
|
||||||
|
pattern reused; region-aware atmosphere cross-fade. Builds on [[DR-011_Synty_World_VFX_Integration]],
|
||||||
|
[[DR-018_World_Space_Cohesion_Pass]], [[DR-013_M6_Aether_Cycle_Region_Split]].
|
||||||
|
|
||||||
|
## Gotchas recorded (→ archive)
|
||||||
|
|
||||||
|
- **Synty PNB_Core fog-ring / cloud-ring MESHES render as a glaring white torus band** — don't place them; the
|
||||||
|
global `RenderSettings` fog gives the atmosphere. (Deleted all 4 in review.)
|
||||||
|
- **Edit-mode screenshots show the BASE region's baked fog over the expedition** because the runtime cross-fade
|
||||||
|
system only runs in Play — to preview a region's true look, temporarily bake that region's `RenderSettings` then
|
||||||
|
revert. (The desert looked washed until previewed with expedition fog.)
|
||||||
|
- **A cyan capsule at each region centre is a baked Gameplay-subscene ENTITY** (Entities-Graphics-rendered, Aether
|
||||||
|
material), NOT cosmetic dressing — `FindObjectsByType<MeshRenderer>` won't find EG entities; out of scope for an
|
||||||
|
art pass.
|
||||||
|
|
||||||
|
## Open / deferred
|
||||||
|
|
||||||
|
- **Live cross-fade Play-validation:** confirmed by-code + by a baked-atmosphere preview; a focused play-through to
|
||||||
|
eyeball the actual fog/ambient transition while walking base↔expedition is the remaining eyeball check.
|
||||||
|
- **Global quality knobs (deferred, low-risk perf):** shadow distance 50u/4-cascade and PC `lodBias=2` are generous
|
||||||
|
for a top-down cam; `RequireOpaqueTexture` likely unused. Left to a dedicated perf pass (they touch global RP/quality).
|
||||||
|
- **Polish opinions (optional):** stronger per-region brightness/contrast delta (hostile desert hotter), more visible
|
||||||
|
cyan at the base play area, procedural-skybox ground tint if the camera ever exposes the horizon.
|
||||||
|
|
||||||
|
## Next
|
||||||
|
|
||||||
|
A focused play-through to tune the atmosphere cross-fade + biome density/feel, then either the deferred global perf
|
||||||
|
pass or resume the milestone track. The biome-cosmetic pattern + `WorldAtmosphereConfig` generalise to future regions.
|
||||||
@@ -0,0 +1,92 @@
|
|||||||
|
---
|
||||||
|
id: DR-025
|
||||||
|
title: World environment redo — off-world natural frontier (Meadow_Forest base + Arid_Desert expedition) as cosmetic biomes + region-aware atmosphere cross-fade
|
||||||
|
status: accepted
|
||||||
|
date: 2026-06-08
|
||||||
|
tags:
|
||||||
|
- decision
|
||||||
|
- art
|
||||||
|
- synty
|
||||||
|
- environment
|
||||||
|
- world
|
||||||
|
- urp
|
||||||
|
- presentation
|
||||||
|
- biomes
|
||||||
|
permalink: gamevault/07-sessions/decisions/dr-025-world-environment-redo-natural-frontier
|
||||||
|
---
|
||||||
|
|
||||||
|
# DR-025 — World environment redo: off-world natural frontier
|
||||||
|
|
||||||
|
## Context
|
||||||
|
|
||||||
|
The world was a flat-shaded Synty **sci-fi colony** (`SyntyWorld` skyline ring + plaza + space skybox at origin,
|
||||||
|
[[DR-011_Synty_World_VFX_Integration]]) with a 21-piece rock-basin Blightfield at +1000 ([[DR-018_World_Space_Cohesion_Pass]]).
|
||||||
|
The operator imported the Synty **PolygonNatureBiomes** (Arid_Desert + Meadow_Forest), **PolygonNature**, and
|
||||||
|
**PNB_Core** packs and asked for a *major cleanup — redo the world with the new materials/terrain/models/foliage*.
|
||||||
|
The [[Synty_Asset_Inventory]] had already pre-scoped these: *Arid_Desert → the +1000 expedition region,
|
||||||
|
Meadow_Forest → the home base*. Intake fork (one `AskUserQuestion`): **off-world natural frontier** (nature ground
|
||||||
|
+ foliage as the world's truth, sci-fi tech layered on top — keeps the locked cyan-ordered ↔ orange-wild duality of
|
||||||
|
[[DR-015_The_Awakening_Engine_Fiction_Adoption]]) · **both regions** this pass.
|
||||||
|
|
||||||
|
## Decision
|
||||||
|
|
||||||
|
1. **Reuse the blessed cosmetic-GameObject pattern, full-replace the dressing.** All new world geometry is **cosmetic
|
||||||
|
classic-URP GameObjects in `Game.unity`** (two roots `BaseBiome`@origin, `ExpeditionBiome`@(1000,0,0)) — NOT the
|
||||||
|
`GameplaySubScene` (which owns collision/ghosts and is untouched). Every placed instance has its **colliders
|
||||||
|
stripped** (inert to the DOTS PhysicsWorld anyway; the player CC sweeps only the baked subscene). The 8 old
|
||||||
|
dressing roots were deleted. The 32×32 base buildable grid + the expedition walkable core stay **clear** — tall
|
||||||
|
props ring the perimeter (a natural "bowl"), only flat/low non-blocking cover goes inside. All Synty biome shaders
|
||||||
|
are **URP-native (`UniversalTarget` verified) → no conversion** (unlike the HDRP BefourStudios art).
|
||||||
|
|
||||||
|
2. **Two biomes, deterministically scattered.** `BaseBiome` = Meadow_Forest (grass ground plane, ~195 instances:
|
||||||
|
tree-ring r20-30, wildflower/bush/rock/ground-cover bands, flat interior grass/flowers; landmarks: **Warpgate**
|
||||||
|
hero gateway at the south edge facing center, cabin/windmill/well, a NE pond + waterwheel + lilies, 2 sci-fi
|
||||||
|
crates staging the gate; 4 cyan Aether point lights; butterflies/sunbeam/petal/glow FX). `ExpeditionBiome` =
|
||||||
|
Arid_Desert (sand ground plane, ~187 instances: cliff+spike perimeter ring r44-58, mid rock/cactus/bramble,
|
||||||
|
crater + **alien-bone** scatter telling the dead-survey story, flat inner cover, far background hills, 5 hero rock
|
||||||
|
silhouettes; landmarks: an abandoned **survey outpost** cluster NE — satellite/solar/turbines/tent/survey-level/
|
||||||
|
sign — + an alien artefact + a rock-arch vista; 4 orange Aether point lights; dust/ash/sunray/tumbleweed/vulture
|
||||||
|
FX). Bulk authoring via `execute_code` + `PrefabUtility` with a seeded LCG (deterministic), missing-path-safe
|
||||||
|
preload (skip+report; 0 missing in practice).
|
||||||
|
|
||||||
|
3. **One global daylight; per-region atmosphere cross-faded at runtime.** A single warm directional sun + Trilight
|
||||||
|
ambient + a `Skybox/Procedural` material (infinite → covers BOTH regions; a Synty skydome is a MESH at origin and
|
||||||
|
can't) + a cloned daylight post-FX profile (`PostFX_Daylight.asset`: keep ACES, halve bloom/contrast/vignette,
|
||||||
|
neutralise the dark-colony cool cast). Because the two regions share one scene/light/skybox, mood divergence is
|
||||||
|
carried by **`WorldAtmosphereSystem`** — a client-only presentation `SystemBase`
|
||||||
|
(`[WorldSystemFilter(ClientSimulation)]`, `PresentationSystemGroup`) that lerps `RenderSettings` fog colour/density
|
||||||
|
+ ambient-sky between the cool-green meadow and warm-orange desert by camera world-X (mirrors `HudSystem`'s X>500
|
||||||
|
region split). Pure presentation, observe-only, no ECS query, no sim/netcode impact; knobs live in a live-tunable
|
||||||
|
`WorldAtmosphereConfig` MonoBehaviour (the `WorldFeelConfig`/`VFXConfig` bridge idiom, `SubsystemRegistration`
|
||||||
|
static reset, null-safe fallbacks). Guarded to the `"Game"` scene so the menu is never restyled.
|
||||||
|
|
||||||
|
## Consequences
|
||||||
|
|
||||||
|
- **Validated.** EditMode **214/214** (new presentation code broke none). Value-introspection: 832 renderers,
|
||||||
|
**0 colliders**, **0 error/magenta materials**, 8 shadow-off point lights, 13 particle systems. Both biomes read
|
||||||
|
as intended (hero shots in the session log). A **4-lens adversarial-review Workflow** confirmed the redo is
|
||||||
|
*purely cosmetic* (no ghost/subscene/PhysicsWorld/sim leak; the system writes only `RenderSettings`) and drove
|
||||||
|
three fixes before sign-off: (a) **perf** — disabled realtime shadow-casting on 254 small foliage instances + the
|
||||||
|
2 ground planes (kept it on 149 trees/cliffs/landmarks); (b) **code** — aligned the no-config fallback fog
|
||||||
|
densities to the tuned values; (c) **composition** — the desert read washed/flat, fixed by deleting bad fog-ring
|
||||||
|
meshes, saturating the expedition fog, and adding 5 mid-ring hero rock silhouettes.
|
||||||
|
- **No new asmdefs.** New code: `…/Client/Presentation/WorldAtmosphereSystem.cs` + `WorldAtmosphereConfig.cs`. New
|
||||||
|
assets: `Sky_DaytimeProcedural.mat`, `PostFX_Daylight.asset`, and the two biome roots baked into `Game.unity`.
|
||||||
|
Orthogonal to + additive over all gameplay; the gameplay subscene, ghosts, region split, and save schema are
|
||||||
|
untouched.
|
||||||
|
|
||||||
|
## Gotchas (→ `_Meta/CLAUDE_Build_Gotchas_Archive.md`)
|
||||||
|
|
||||||
|
- **Synty PNB_Core fog-ring/cloud-ring MESHES render as a bright white torus** — don't place them; use
|
||||||
|
`RenderSettings` fog for atmosphere.
|
||||||
|
- **Edit-mode screenshots show the BASE region's baked fog over the +1000 expedition** (the runtime cross-fade only
|
||||||
|
runs in Play) — preview a region's true look by temporarily baking that region's `RenderSettings`, then revert.
|
||||||
|
- **A cyan capsule at each region centre is a baked Gameplay-subscene ENTITY** (Entities-Graphics-rendered, Aether
|
||||||
|
material) — `FindObjectsByType<MeshRenderer>` won't find EG entities; it is gameplay, not cosmetic dressing.
|
||||||
|
- **`AssetDatabase.DeleteAsset` is blocked by `execute_code` safety-checks** — rely on `CopyAsset` over an absent
|
||||||
|
destination for idempotent asset clones (or run with `safety_checks=false`).
|
||||||
|
|
||||||
|
Builds on + reuses [[DR-011_Synty_World_VFX_Integration]] (cosmetic-GameObject world, collider-strip, no-conversion
|
||||||
|
Synty), [[DR-018_World_Space_Cohesion_Pass]] (region dressing via `execute_code`/PrefabUtility, Aether palette),
|
||||||
|
[[DR-013_M6_Aether_Cycle_Region_Split]] (the +1000 region split + X>500 boundary), and the client-presentation
|
||||||
|
idiom of [[DR-009_GameFeel_Identity_FirstBlood]]. Serves the cohesive-world pillar in [[Pillars]].
|
||||||
@@ -321,3 +321,44 @@ Full rules: `~/.claude/skills/dots-dev/references/dots-conventions.md` (Windows:
|
|||||||
`.mcp.json` is committed + portable (`${CLAUDE_PROJECT_DIR}`); the **`dots-dev` skill travels with the repo** (`.claude/skills/dots-dev/`). Each machine still needs: (1) `uv`/`uvx` + Obsidian app + `obsidian-cli` (the `unity-mcp-skill` + native `memory/` are machine-local, don't sync); (2) basic-memory registration — `uvx basic-memory project add gamevault "<repo>/Docs/Vault" --default` then `uvx basic-memory reindex --full --search --embeddings --project gamevault`; (3) Unity 6.4 open + the Unity-MCP bridge connected (`mcpforunity://editor/state` → `ready_for_tools`).
|
`.mcp.json` is committed + portable (`${CLAUDE_PROJECT_DIR}`); the **`dots-dev` skill travels with the repo** (`.claude/skills/dots-dev/`). Each machine still needs: (1) `uv`/`uvx` + Obsidian app + `obsidian-cli` (the `unity-mcp-skill` + native `memory/` are machine-local, don't sync); (2) basic-memory registration — `uvx basic-memory project add gamevault "<repo>/Docs/Vault" --default` then `uvx basic-memory reindex --full --search --embeddings --project gamevault`; (3) Unity 6.4 open + the Unity-MCP bridge connected (`mcpforunity://editor/state` → `ready_for_tools`).
|
||||||
|
|
||||||
<!-- END snapshot -->
|
<!-- END snapshot -->
|
||||||
|
|
||||||
|
## 2026-06-08 — World environment redo to Synty nature biomes ([[DR-025_World_Environment_Redo_Natural_Frontier]])
|
||||||
|
|
||||||
|
Long-form lessons from the off-world-natural-frontier world redo (Meadow_Forest base + Arid_Desert expedition as
|
||||||
|
cosmetic classic-URP biomes in `Game.unity`; region-aware `WorldAtmosphereSystem` fog/ambient cross-fade).
|
||||||
|
|
||||||
|
- **Synty PNB_Core fog-ring / cloud-ring PREFABS are MESHES that render as a bright white torus band** at gameplay
|
||||||
|
scale — they do NOT read as soft haze. Do not place them for atmosphere; the global `RenderSettings` fog
|
||||||
|
(exp-squared, low density) gives the haze, and a `Skybox/Procedural` material gives the sky. (All 4 ring instances
|
||||||
|
were deleted in review.)
|
||||||
|
- **Two regions, one scene → use a `Skybox/Procedural` MATERIAL on `RenderSettings.skybox`, never a Synty skydome
|
||||||
|
MESH.** All Synty biome "sky" materials use one `SkyDome.shadergraph` authored for a dome MESH centred at origin —
|
||||||
|
a single dome can't cover the expedition at x=1000, and per-region domes double the cost. The procedural skybox is
|
||||||
|
infinite and region-agnostic; per-biome mood comes from the cross-faded fog/ambient instead.
|
||||||
|
- **Edit-mode screenshots show the BASE region's BAKED `RenderSettings` over the +1000 expedition**, because the
|
||||||
|
runtime cross-fade (`WorldAtmosphereSystem`, a `ClientSimulation` presentation `SystemBase`) only runs in Play.
|
||||||
|
The desert therefore looks washed/cool in an edit-mode capture. To preview a region's TRUE in-Play look without
|
||||||
|
entering Play: temporarily bake that region's `RenderSettings` (fog colour/density + ambientSkyColor) via
|
||||||
|
`execute_code`, screenshot, then revert. The desert read correctly the moment its warm-orange fog was baked.
|
||||||
|
- **A cyan capsule at each region centre is a baked Gameplay-SUBSCENE entity** (rendered by Entities Graphics with
|
||||||
|
the Aether material), NOT cosmetic dressing and NOT removable in an art pass. `Object.FindObjectsByType<MeshRenderer>`
|
||||||
|
returns nothing for it — EG entities use `BatchRendererGroup`, not `MeshRenderer`. Confirms the cosmetic/gameplay
|
||||||
|
split: an art pass touches only `Game.unity` GameObjects, never the subscene.
|
||||||
|
- **`execute_code` safety-checks BLOCK `AssetDatabase.DeleteAsset`** (and `File.Delete`, `Process.Start`, etc.) — the
|
||||||
|
whole snippet is rejected pre-execution (nothing runs, so no partial state). For idempotent asset clones, rely on
|
||||||
|
`AssetDatabase.CopyAsset` over an absent destination (it no-ops/false on an existing one and you load that), or
|
||||||
|
pass `safety_checks=false` deliberately.
|
||||||
|
- **Shadow-cast hygiene for hundreds of cosmetic props:** nothing in the project set `ShadowCastingMode.Off`, so all
|
||||||
|
~377 placed meshes + the 2 ground planes cast realtime soft directional shadows (4-cascade, soft-quality-3) — a
|
||||||
|
large depth-pass bill for sub-pixel foliage shadows that read as noise top-down. Fix: walk the biome roots and set
|
||||||
|
`Renderer.shadowCastingMode = Off` on small props (name heuristic + combined-AABB extent < ~1.6m) and the flat
|
||||||
|
ground planes, keeping it ON for trees/cliffs/landmarks (254 off / 149 kept here). Forward+ clustered lighting
|
||||||
|
makes 4 simultaneous additional point lights/region a non-issue (the per-object `AdditionalLightsPerObjectLimit`
|
||||||
|
is ignored under `RenderingMode: 2`); non-static cosmetics + SRP Batcher is the right batching choice (no static
|
||||||
|
combine, re-tint-friendly).
|
||||||
|
- **Region-aware presentation cross-fade pattern:** a client-only `SystemBase` in `PresentationSystemGroup` that
|
||||||
|
reads `Camera.main.transform.position.x` and lerps `RenderSettings` (fog/ambient) across the X>500 boundary
|
||||||
|
(mirrors `HudSystem.ExpeditionRegionXMin`). No ECS query, observe-only, `"Game"`-scene guarded so the menu isn't
|
||||||
|
restyled; knobs in a `WorldFeelConfig`-style MonoBehaviour with `SubsystemRegistration` static reset + null-safe
|
||||||
|
fallbacks. Zero sim/netcode impact (writes only global managed `RenderSettings`; `ClientSimulation` filter keeps
|
||||||
|
it off the server/headless world).
|
||||||
|
|||||||
Reference in New Issue
Block a user