Game Scene Split up
This commit is contained in:
@@ -0,0 +1,64 @@
|
||||
---
|
||||
date: 2026-06-04
|
||||
type: session
|
||||
tags: [session, core-loop, pacing, netcode, dev-tools, scenes, m8]
|
||||
---
|
||||
|
||||
# Session 2026-06-04 — M8: Persistent base & player-driven pacing
|
||||
|
||||
## Goal
|
||||
|
||||
Operator: *"I don't like the current pacing — the home base should feel persistent and like you aren't in a rush... when you are ready and have the inventory and prep you need for an expedition, you go. Attacks on the base will be triggered based on various events and timelines (possibly after an expedition). Built out properly — also make a separate scene and various dev tools to test/debug/validate (spawn waves, control game state, grant things). The main gameplay scene should feel like an actual game."*
|
||||
|
||||
Replaces the M6 **forced-timer treadmill** (Expedition 60s → Defend → Build 20s → repeat) with a **player-driven loop**: persistent **Calm** base by default → deploy when ready → **event-triggered Siege** (post-expedition retaliation) → defend → Calm. Decisions chosen by operator: **composite ThreatDirector**, **full staged build**, **new Game scene + DevSandbox**. Full rationale + the de-risked architecture: [[DR-017_Persistent_Base_Player_Driven_Pacing]].
|
||||
|
||||
## Process
|
||||
|
||||
- Phase-1 exploration (3 Explore agents: run-state/wave blast radius · scene/subscene/bootstrap wiring · dev-tools/RPC/test precedents).
|
||||
- Phase-2 **adversarial design review** (Workflow: 3 critics — netcode/determinism · reuse/scope · dev-tooling/scene/build-gotchas → synthesis). Caught the **co-op-breaking global-Expedition-phase flaw** (one byte can't represent player-A-out/player-B-home) and steered: reuse-symbols-re-mean-bytes, atomic WaveState siege seed, server-only ThreatConfig/State, duplicate-scenes-not-scratch, unconditional RPC type.
|
||||
- Plan approved → 5 staged steps, each `compile → read_console → EditMode → (Play where relevant)`.
|
||||
|
||||
## Done
|
||||
|
||||
### Stage 1 — Calm/Siege run-state + presence + boot-Calm + goal decouple
|
||||
- `CycleComponents.cs`: re-meaned `CyclePhase` → `Calm=0`/`Siege=1` (+ deprecated `Expedition`/`Defend`/`Build` aliases; byte values unchanged → **no serializer re-bake**); `CycleRuntime` → `ExpeditionEpoch`/`LastSpawnedEpoch`/`PrevExpeditionOccupied`.
|
||||
- `CyclePhaseSystem` rewritten to the **Calm↔Siege machine** (consume `ThreatState.PendingSiegeSize` → atomic `WaveState{Spawning, RemainingToSpawn=size, WaveNumber+1}` seed → Siege; exit on `DefendCleared` → Calm + goal `+1`). Boot = Calm (`CycleDirectorAuthoring` default + `CycleDirectorSpawnSystem` stamp `Phase=Calm, PhaseEndTick=0`, adds `ThreatState`). `ExpeditionFieldSystem` re-keyed off expedition-region presence + epoch. `ExpeditionGateSystem` hack deleted → increments `ThreatState.PendingReturns` on return. `WaveSystem` gate `!= Siege`.
|
||||
- Tests: rewrote `CyclePhaseSystemTests` (Calm holds; PendingSiege→Siege exact size; Siege→Calm + goal once; **co-op split-presence keeps global phase Calm**); `ExpeditionGateSystemTests` → return-signals-once. **137 baseline preserved.**
|
||||
|
||||
### Stage 2 — Composite ThreatDirector
|
||||
- `ThreatComponents.cs` (`ThreatConfig` + `ThreatState` + `ThreatStartCondition`, server-only, Heat/Schedule inert). `ThreatDirectorSystem` (Gate→ThreatDirector→CyclePhase order): post-expedition source arms a `SizeBase` siege after a telegraph; bounded-timeout collapse (no soft-lock). `ThreatConfig` baked via `CycleDirectorAuthoring` (inspector-tunable flat fields).
|
||||
- Tests: `ThreatDirectorSystemTests` ×5 (return→pending; multi-return de-dup; size=config-not-curve; Immediate arms via ArmTick; empty-base auto-resolves bounded).
|
||||
|
||||
### Stage 3 — Dev tools over RPC + god-mode
|
||||
- Unconditional `DebugCommandRequest`/`DebugOp` (Simulation); `DebugGodMode` enableable. `DebugCommandReceiveSystem` (server `#if UNITY_EDITOR` switch, reuses StorageMath/StatModifier/RegionMath/wave+cycle singletons, sender resolve). `DebugCommandSendSystem` (client static-queue → RPC, headless-friendly) + `DebugOverlay` MonoBehaviour (IMGUI). `HealthApplyDamageSystem` god-mode guard; `PlayerAuthoring` bakes `DebugGodMode` present+disabled; `AimPresentation.ForceCursorVisible` (overlay clickability); `[RuntimeInitializeOnLoadMethod]` resets.
|
||||
- Tests: `DebugCommandReceiveSystemTests` ×4 + god-mode skip-damage. **137/137.**
|
||||
|
||||
### Stage 4 — Scenes
|
||||
- Duplicated SampleScene → **`Game.unity`** (clean main, boots Calm) + **`DevSandbox.unity`** (Synty world disabled, `~DevTools`+overlay). Verified the SubScene `_SceneAsset` guid `9dc8ce2e…` + `_SceneGUID.x=3807153369` survived. `Game.unity` added to `EditorBuildSettings` index 0.
|
||||
|
||||
### Stage 5 — Feel pass
|
||||
- `HudSystem`: Calm/Siege labels + colors, "AT BASE — deploy through the gate when you're ready" prompt, "INCURSION IN Ns" telegraph (reuses `PhaseEndTick=ArmTick` countdown), dropped vestigial "CYCLE N". `AmbientAudioSystem`: Calm/Siege stinger + drone swell mapping.
|
||||
|
||||
### Validation
|
||||
- **EditMode 137/137** (was 127; rewrote/added per stage, no regressions), console clean.
|
||||
- **Focused-editor Play (server+client), SampleScene + Game.unity:** boot **Calm** (`Phase=0, PhaseEndTick=0`); re-bakes confirmed (`ThreatConfig{SizeBase=5,Delay=300,Timeout=3600}`, player `DebugGodMode` present+disabled); armed siege → **Siege**, **exactly 4 Husks** spawned, `WaveState{Spawning,Remaining=0}`, pending consumed; **server==client** (Phase + husk ghosts replicated). `Game.unity` screenshot: calm base + "AT BASE — deploy…" HUD. (`Assets/Screenshots/M8_Game_Calm_Boot.png`.)
|
||||
|
||||
## Decisions
|
||||
|
||||
- **Created [[DR-017_Persistent_Base_Player_Driven_Pacing]]** (supersedes the M6 forced-timer rhythm of [[DR-013_M6_Aether_Cycle_Region_Split]]/[[DR-014_M6_Build_Structures_Automation_Foundation]]; reuses their netcode infra).
|
||||
|
||||
## Build gotchas (→ [[CLAUDE]] addendum)
|
||||
|
||||
- A **system-ordering cycle is invisible to plain-Entities EditMode tests** (systems registered individually); only `ComponentSystemSorter` throws at Play/world-creation. Re-audit *existing* `[Update*]` attributes when reordering — caught the gate's stale `[UpdateAfter(CyclePhaseSystem)]` vs the new ThreatDirector chain.
|
||||
- **MCP `apply_text_edits` multi-edit-in-one-call can misalign** (a paired replace+delete hit the wrong line). One edit per call (or strict bottom-first), `precondition_sha256` always. `create_script` won't overwrite; `script_apply_edits replace_method` still can't target struct ISystems.
|
||||
- **Re-mean bytes, don't rename**: unchanged byte values keep the `[GhostField]` serializer identical → a global-loop reframe stayed re-bake-free (only authoring default-value edits re-bake the subscene).
|
||||
|
||||
## Open / deferred
|
||||
|
||||
- Base-integrity / visible fail-state (siege currently just collapses on timeout); haul-scaled retaliation (`SizePerExpeditionResource=0`); Heat/Schedule trigger sources (baked-but-inert); dev overlay in dev *player* builds; deploy-gate 3D marker. All defaulted/tunable — see [[DR-017_Persistent_Base_Player_Driven_Pacing]].
|
||||
|
||||
## Next
|
||||
|
||||
- **Build/automation/customization expansion** on the now-persistent base (the operator's stated next direction) — the ThreatDirector inert sources + the DR-014 structure tick fields are the additive hooks.
|
||||
- Multi-client (MPPM) run of the co-op split-presence + dev-tools-over-a-real-connection (the unconditional RPC type is the enabler).
|
||||
- Optional: base-integrity fail-state if losing a siege should have visible teeth.
|
||||
Reference in New Issue
Block a user