Map Updates
This commit is contained in:
@@ -0,0 +1,63 @@
|
||||
---
|
||||
date: 2026-06-04
|
||||
type: session
|
||||
tags:
|
||||
- session
|
||||
- world-architecture
|
||||
- economy
|
||||
- building
|
||||
- presentation
|
||||
- art
|
||||
- post-m8
|
||||
permalink: gamevault/07-sessions/2026/2026-06-04-world-space-cohesion-pass
|
||||
---
|
||||
|
||||
# Session 2026-06-04 — World-space cohesion pass
|
||||
|
||||
> Driven by `/dots-dev` (Feature track) under ultracode. Third log dated 2026-06-04 (after M8 + the Polish backlog pass).
|
||||
|
||||
## Goal
|
||||
|
||||
Make the flat-feeling world feel like **a more cohesive world** without editing the floor/terrain: non-flat feel
|
||||
via props, **build out a base** (more placeable structures), and **destructible resource gathering + clearing out
|
||||
areas**. Operator picked: balanced vertical slice · all-Synty recoloured Blight · clearing = juice + minor scrap ·
|
||||
buildables = Walls + structural variety.
|
||||
|
||||
## Done
|
||||
|
||||
- **Clearing mechanic (net-new):** `BlightClutter` ownerless-interpolated ghost (RegionTag{Expedition}, [GhostField]
|
||||
Remaining+Variant) + `ClutterFieldSpawner`. **Unified `ResourceHarvestSystem`** to sweep nodes + clutter in one
|
||||
best-target loop (the double-destroy fix). `ExpeditionFieldSystem` scatters/clears clutter alongside the node field
|
||||
(distinct seed). Client smash juice = new observe-only `WorldFeedbackSystem` + live-tunable `WorldFeelConfig`
|
||||
(chip on `Remaining` decrease, shatter + camera punch on despawn, proximity-gated so region-transit stays silent).
|
||||
- **Build out the base:** `StructureType.Wall=5`/`Pylon=6` (2–4 reserved for M7), generic `StructureAuthoring`, two
|
||||
additive `StructureCatalog` rows, V/N build keys + editor hooks. `Wall.prefab` blocks the player (BoxCollider →
|
||||
PhysicsCollider); `Pylon.prefab` cosmetic. `BuildPlaceSystem` untouched (already type-generic).
|
||||
- **Visual cohesion:** `M_Aether_Wild`(orange)/`M_Aether_Ordered`(cyan) HDR-emissive materials; the 3 new ghosts
|
||||
recoloured into the palette; the barren +1000 Blightfield became a 21-piece Synty rock/debris basin + 3 orange
|
||||
wild-lights (classic-URP cosmetics in `Game.unity`, no subscene re-bake; relief via props, no terrain).
|
||||
- **Validation:** EditMode **142/142** (5 harvest tests incl. overlap/fractional/same-tick-cleared). In-editor Play
|
||||
(server+client) introspected via `execute_code`: baking, ghost registration, buildables (Ore 50→44, R1 collider),
|
||||
clutter scatter (14+8 @ x≈1000), **0 errors**. A 4-lens adversarial-review Workflow (23 raised → 4 confirmed) caught
|
||||
an immortal-shot-sink (sub-1.0 `ScrapPerHit` truncates to 0) + a same-tick-cleared passthrough — both fixed +
|
||||
regression-tested before sign-off.
|
||||
|
||||
## Decisions
|
||||
|
||||
- [[DR-018_World_Space_Cohesion_Pass]] — clutter as a node-sibling on a unified sweep; byte-additive Wall/Pylon;
|
||||
classic-URP Blightfield dressing; Aether-palette recolour. Builds on [[DR-013_M6_Aether_Cycle_Region_Split]] /
|
||||
[[DR-014_M6_Build_Structures_Automation_Foundation]] / [[DR-015_The_Awakening_Engine_Fiction_Adoption]].
|
||||
|
||||
## Open / deferred
|
||||
|
||||
- Base-side cohesion accents (cyan lights / perimeter relief / re-enabled tiled ground) — deferred to avoid clashing
|
||||
with the tuned SSAO/ACES look.
|
||||
- Clearing as a spatial mechanic (gating / reveal nodes); build-palette HUD + ghost-preview; per-`Variant` clutter
|
||||
meshes — all additive follow-ups.
|
||||
- Eyeball the cohesion + Wall-blocks-player reads in a **focused** editor (mechanisms verified by value headless).
|
||||
|
||||
## Next
|
||||
|
||||
- A focused-editor play-through to tune the Blightfield basin density/lighting + the clutter/wall feel, then either
|
||||
the base-side cohesion accents or fold clearing into a spatial mechanic — or proceed to M7 automation (the reserved
|
||||
structure slots + tick fields are still the additive hook).
|
||||
@@ -0,0 +1,133 @@
|
||||
---
|
||||
id: DR-018
|
||||
title: World-space cohesion pass — destructible Blight clutter (clearing), buildable Wall/Pylon, Aether-palette Blightfield dressing
|
||||
status: accepted
|
||||
date: 2026-06-04
|
||||
tags:
|
||||
- decision
|
||||
- netcode
|
||||
- world-architecture
|
||||
- economy
|
||||
- building
|
||||
- presentation
|
||||
- art
|
||||
- post-m8
|
||||
permalink: gamevault/07-sessions/decisions/dr-018-world-space-cohesion-pass
|
||||
---
|
||||
|
||||
# DR-018 — World-space cohesion pass
|
||||
|
||||
## Context
|
||||
|
||||
The operator asked for a **world-space pass** so the world "feels like a more cohesive world" instead of flat:
|
||||
non-flat ground/foliage **without editing the terrain** (props on top only), **placing buildings / building out a
|
||||
base**, and **destructible resource gathering + clearing out areas**. Recon (read-only swarm) found this is mostly a
|
||||
**cohesion layer over the mature M8 foundation**, not greenfield: destructible `ResourceNode` harvesting already
|
||||
existed ([[DR-013_M6_Aether_Cycle_Region_Split]]); the full grid-placement build pipeline existed but shipped only the
|
||||
Turret ([[DR-014_M6_Build_Structures_Automation_Foundation]]); the world was a flat quad with ~60 clustered Synty
|
||||
city props at the base and **only 4 lone pillars** at the +1000 Blightfield. The fiction ([[DR-015_The_Awakening_Engine_Fiction_Adoption]])
|
||||
sets the duality: **cyan-ordered base sanctuary ↔ orange-red wild Blightfield**, Aether read by colour.
|
||||
|
||||
Four scope forks were resolved with the operator up front (intake `AskUserQuestion`): **balanced vertical slice**
|
||||
(touch all three, foundation now / expand later) · **all-Synty recoloured** Blight (URP-native; not the HDRP
|
||||
BefourStudios path) · **clearing = juice + minor scrap** (no hard gating) · **buildables = Walls + structural variety**
|
||||
(cosmetic / player-blocking, NOT Husk-pathing-defensive). Hard constraints honoured: region offset (1000,0,0) +
|
||||
GhostRelevancy, frozen 32×32 grid / save schema, byte ids (never enums) in Burst/RPC, static decor as collider-stripped
|
||||
classic-URP cosmetics, Aether palette, predicted-loop server authority, **no terrain edit**.
|
||||
|
||||
## Decision
|
||||
|
||||
1. **Clearing = `BlightClutter`, a `ResourceNode` SIBLING harvested by a UNIFIED sweep.** New ownerless interpolated
|
||||
ghost `BlightClutter { [GhostField] int Remaining; [GhostField] byte Variant; byte ScrapResourceId; float ScrapPerHit }`
|
||||
(RegionTag{Expedition}, prefab duplicated from `ResourceNode.prefab` so the GhostAuthoring comes free). It deposits a
|
||||
small Biomass "scrap" trickle and despawns at ≤0. **`ResourceHarvestSystem` was UNIFIED** to sweep nodes AND clutter
|
||||
in ONE best-target loop — **a correctness requirement, not a convenience**: two separate sweep systems would each
|
||||
`ecb.DestroyEntity` a projectile that overlaps a node AND a clutter piece → the documented "double DestroyEntity
|
||||
throws at playback". `ExpeditionFieldSystem` scatters clutter from an OPTIONAL `ClutterFieldSpawner` singleton on the
|
||||
same per-player-presence epoch edge as the node field (distinct seed `epoch*2+1`, round-robin Variant) and clears it
|
||||
on the occupied→empty edge. Client smash juice = new **`WorldFeedbackSystem`** (observe-only managed `SystemBase` in
|
||||
`PresentationSystemGroup`, mirrors `CombatFeedbackSystem`): edge-detects `Remaining` for a chip burst, despawn for a
|
||||
shatter burst + camera punch, with a **proximity gate** (last-pos within ~40u of the local player) so the
|
||||
region-transit relevancy-drop storm at +1000 stays silent off-camera. Knobs in live-tunable `WorldFeelConfig`.
|
||||
|
||||
2. **Buildables = byte-additive `Wall`(5)/`Pylon`(6).** `StructureType.Wall=5, Pylon=6` (2–4 stay RESERVED for M7
|
||||
automation). A generic `StructureAuthoring{ byte Kind }` bakes only `PlacedStructure{Type=Kind}` (no `Turret`
|
||||
component → `TurretFireSystem` ignores it). `StructureCatalogAuthoring` grew two additive rows; `BuildSendSystem`
|
||||
grew dedicated **V=Wall / N=Pylon** keys + editor `PlaceWall`/`PlacePylon` hooks. **`BuildPlaceSystem` was NOT
|
||||
touched** — it already resolves any catalog `Type` and stamps `PlacedStructure` + `RegionTag{Base}` generically.
|
||||
`Wall.prefab` carries a static `BoxCollider` (baked → `PhysicsCollider` → the CC sweeps it → blocks the player);
|
||||
`Pylon.prefab` has none (cosmetic beacon). Because `PlacedStructure.Type` is already a `[GhostField] byte`, adding
|
||||
values 5/6 keeps the serializer identical → **no re-bake of existing ghosts**.
|
||||
|
||||
3. **Visual cohesion = Aether material pair + Blightfield basin (classic-URP cosmetics, no subscene re-bake).**
|
||||
`M_Aether_Wild` (HDR orange emissive) + `M_Aether_Ordered` (HDR cyan emissive) URP/Lit assets; the three new ghosts
|
||||
recoloured into the palette (Clutter→wild, Wall+Pylon→ordered). The barren +1000 Blightfield became a **21-piece
|
||||
Synty rock/asteroid/debris basin + 3 orange wild-Aether point lights** under a `BlightfieldDecor` root in `Game.unity`
|
||||
— deterministic ring/scatter at varied scale/height (the "non-flat" relief via props, **no terrain**), colliders
|
||||
stripped (inert to the DOTS PhysicsWorld anyway, per the blessed `SyntyWorld` classic-URP pattern). Bulk authoring via
|
||||
`execute_code` (PrefabUtility) for determinism + speed.
|
||||
|
||||
## Consequences
|
||||
|
||||
- **Validated.** EditMode **142/142** green (rewrote/added 5 `ResourceHarvestSystem` tests incl. node+clutter overlap,
|
||||
fractional-yield, and same-tick-cleared consumption; existing 134 unaffected). **In-editor Play (server+client over
|
||||
IPC), driven via `execute_code` world-introspection:** baking clean (catalog = Turret/Wall/Pylon with valid prefab
|
||||
refs + correct costs; `ClutterFieldSpawner` baked); buildables end-to-end (built Wall@(16,16)+Pylon@(18,16), Ore 50→44,
|
||||
Type GhostField replicated, Cell stays server-only=0 on client); **R1** confirmed (client Wall entity has
|
||||
`PhysicsCollider`, Pylon doesn't); clutter scatter end-to-end (14 clutter + 8 nodes spawned + replicated at x≈1000,
|
||||
round-robin variants); **R2** clear (the edited Bursted `ExpeditionFieldSystem` ran; **0 errors** all session, only the
|
||||
pre-existing unfocused-editor Server-Tick-Batching warnings). Decor verified by VALUE (21 renderers, 0 broken shaders,
|
||||
x∈[977,1020], correct HDR emission) — not just a screenshot.
|
||||
- **Adversarial review** (4-lens Workflow → verify) raised 23, confirmed 4 (3 were one root issue). **Fixed before
|
||||
sign-off:** an **immortal-shot-sink** — `int amount = (int)YieldPerHit` truncates a sub-1.0 per-hit value to 0, so the
|
||||
projectile is consumed, nothing deposits, and the target never depletes; reachable only because
|
||||
`BlightClutterAuthoring.ScrapPerHit` was `[Min(0f)]` (the node sibling is `[Min(1f)]`). Hardened with `[Min(1f)]` +
|
||||
`math.max(1, (int)…)` in the system. Plus a low **same-tick-cleared passthrough** — a 2nd projectile whose only target
|
||||
a sibling already cleared this tick now still consumes (an `overlappedCleared` branch) so "a hit always spends the
|
||||
shot." Both regression-tested. The 19 refuted were correct-by-design (the `ghostId==0` relevancy skip, Temp-ECB
|
||||
no-dispose matching sibling spawn systems, the proximity gate vs. atomic-teleport transit, observe-only audit).
|
||||
- **No new asmdefs.** New code under `…/Economy/` (`BlightClutter`, `ClutterFieldSpawner` + authorings), `…/Building/`
|
||||
(`StructureType.Wall/Pylon`, `StructureAuthoring`, catalog rows), `…/Client/Presentation/` (`WorldFeedbackSystem`,
|
||||
`WorldFeelConfig`), `…/Client/Building/` (BuildSendSystem keys). New assets: `BlightClutter`/`Wall`/`Pylon` prefabs,
|
||||
`M_Aether_Wild`/`M_Aether_Ordered` materials, `Gameplay.unity` (clutter spawner + catalog rows), `Game.unity`
|
||||
(BlightfieldDecor). Reuses the runtime-ghost recipe / region split / GhostRelevancy / swept-hit / RPC-build /
|
||||
StatModifier-free-economy patterns verbatim. Orthogonal to + additive over M8; does not touch the M7 automation slots.
|
||||
|
||||
## Open / deferred (defaulted, tunable)
|
||||
|
||||
- **Base-side cohesion**: this layer dressed the Blightfield (the barren gap); the cyan-ordered base still reads via the
|
||||
existing city props + the new cyan-recoloured Wall/Pylon. A deliberate base accent (cyan lights, perimeter relief,
|
||||
re-enabled tiled ground) was deferred to avoid clashing with the tuned SSAO/ACES look.
|
||||
- **Clearing as a spatial mechanic**: shipped as juice + scrap only (no gating); making cleared cells buildable or
|
||||
reveal hidden nodes (the "functional gating" fork) is a follow-up.
|
||||
- **More buildables / build-palette HUD**: dedicated V/N keys for now (matches the B/U idiom); a selectable build palette
|
||||
+ ghost-preview is polish.
|
||||
- **Clutter visual variety**: `Variant` is replicated + round-robined but the prefab is single-mesh; per-variant meshes
|
||||
are a follow-up (additive, no schema change).
|
||||
- **Focused-editor Play confirmed (2026-06-04, same day):** the Wall **stops the player CC dead at the collider face**
|
||||
(drove +X, X 2.50→**3.257**, server==client, no tunnel); the **Blightfield reads as an orange-wild rock basin** vs the
|
||||
cyan base (real player-view game-camera screenshots); the **clutter-clear loop works end-to-end** (BIO 0→6→10, clutter
|
||||
14→13 shatter replicated to the client); node harvest AETHER 0→30 (R2 clear on the re-edited system). Console clean.
|
||||
Remaining is only **feel-tuning** (basin density/lighting) + the base-side accents — not correctness.
|
||||
|
||||
## Build gotchas recorded this session
|
||||
|
||||
- **A unified sweep is REQUIRED, not optional, when two target types share one projectile pass** — separate sweep
|
||||
systems each `DestroyEntity` an overlapping projectile → double-destroy at ECB playback. One best-target loop over the
|
||||
combined set + a shared destroyed-bitset is the correct shape.
|
||||
- **Float per-hit yield truncated to an int that ALSO gates despawn is an immortal-sink footgun**: a sub-1.0 value →
|
||||
`(int)`=0 → no deposit AND no decrement, yet the projectile is still consumed. Guard with `[Min(1f)]` on the authoring
|
||||
AND `math.max(1, (int)…)` in the consumer (the node path was already `[Min(1f)]`; the new clutter path wasn't).
|
||||
- **Unfocused-editor Play validation is feasible via `execute_code` world-introspection** even when the Play transition
|
||||
stalls: identify worlds by `world.Name`, query/instantiate/mutate via the live `EntityManager`, drive client editor
|
||||
hooks (`BuildSendSystem.PlaceWall`) + deposit into the ledger to exercise end-to-end paths, and read errors-only from
|
||||
the console (the tick-batching warning spam is benign). Keep the session short (unfocused can dispose netcode worlds).
|
||||
- **Editing a Bursted ISystem's BODY (not its query set) is low R2 risk** — the stale-binary hazard is tied to query-set
|
||||
changes on an unfocused editor; a `math.max`/loop-reorder edit that leaves the SystemAPI query set unchanged is safe.
|
||||
- **`manage_prefabs modify_contents component_properties` sets a `byte` field fine** (verified Pylon.Kind=6) — the
|
||||
silent-drop gotcha is enum/Vector3, not byte. Still verify via `execute_code`.
|
||||
|
||||
Builds on + reuses [[DR-013_M6_Aether_Cycle_Region_Split]] (region split, GhostRelevancy, swept-hit, runtime-ghost),
|
||||
[[DR-014_M6_Build_Structures_Automation_Foundation]] (build pipeline, structure ghost, frozen grid/schema),
|
||||
[[DR-015_The_Awakening_Engine_Fiction_Adoption]] (Aether palette), and the client-presentation pattern from
|
||||
[[DR-009_GameFeel_Identity_FirstBlood]]. Serves the cohesive-world + persistent-base pillars in [[Pillars]].
|
||||
Reference in New Issue
Block a user