perf(streaming): quiesce retired generations and budget teardown
Publish the retail blocking-for-cells edge before deferred recenter work, freeze old-world presentation/simulation/audio, and advance full-window retirement from exact metered entity and owner cursors. This removes synchronous portal teardown without allowing retained owners to remain observable.
This commit is contained in:
parent
b8f6317fe1
commit
bb16f74fd4
38 changed files with 1691 additions and 170 deletions
|
|
@ -44,9 +44,11 @@ What does NOT go here:
|
|||
smooth and physics, collision, and wire state remain correct.
|
||||
- **Build hygiene:** `#228` records 17 clean-Release test-project warnings;
|
||||
production compilation and all tests pass.
|
||||
- **Performance side track:** prepared-content Slices A–C and unified-residency
|
||||
Slice D are complete. Slice E cost-budgeted streaming/retirement is next.
|
||||
Evidence:
|
||||
- **Performance side track:** Slices A–D and Slice E0–E3 are complete. Typed
|
||||
completion admission, immediate generation-scoped old-world quiescence, and
|
||||
budgeted full-window/recenter retirement are live; E4 cursor-budgeted
|
||||
publication is next. Physical performance/visual evidence is paused while
|
||||
the desktop is RDP. Evidence:
|
||||
[`research/2026-07-24-slice-d-unified-residency-report.md`](research/2026-07-24-slice-d-unified-residency-report.md).
|
||||
|
||||
The [documentation map](README.md) defines how this tactical ledger relates to
|
||||
|
|
|
|||
|
|
@ -8,16 +8,20 @@ banner cannot silently override the current program state.
|
|||
|
||||
- **Milestone state:** M3, “Cast a spell,” landed 2026-07-21. M4, “Live in the
|
||||
world,” is active.
|
||||
- **Active gameplay program:** the pre-M4 world-interaction completion program
|
||||
- **M4 gameplay program (paused while the authorized performance program
|
||||
executes):** the pre-M4 world-interaction completion program
|
||||
in
|
||||
[`plans/2026-07-23-world-interaction-completion.md`](plans/2026-07-23-world-interaction-completion.md).
|
||||
The eight-slice `GameWindow` decomposition and its connected visual matrix
|
||||
are complete.
|
||||
- **Active performance side track:** Slices A–C of
|
||||
- **Current active engineering program:** Slices A–D and Slice E0–E3 of
|
||||
[`plans/2026-07-24-modern-runtime-architecture.md`](plans/2026-07-24-modern-runtime-architecture.md)
|
||||
are complete. Production world-mesh streaming consumes the validated
|
||||
prepared package; Slice D unified residency/accounting is next. See the
|
||||
[Slice C physical cutover report](research/2026-07-24-slice-c-prepared-asset-cutover-report.md).
|
||||
prepared package, typed residency is bounded/accounted, and streaming now
|
||||
has typed admission plus immediate old-generation quiescence and metered
|
||||
retirement cursors. E4 cursor-budgeted publication is next. Physical
|
||||
GPU/FPS gates wait for the physical console because the desktop is RDP. See
|
||||
the [Slice D residency report](research/2026-07-24-slice-d-unified-residency-report.md).
|
||||
- **Completed gates:** R6 locomotion/collision/projectile/teleport/radar and
|
||||
the final two-client portal-out/materialization observer comparison (`#218`).
|
||||
- **Separate visual verification:** the shared-alpha lifestone/particle result
|
||||
|
|
@ -28,7 +32,7 @@ banner cannot silently override the current program state.
|
|||
user decision gate; Linux/headless automation (Track LH) remains future work.
|
||||
- **Divergence audit:** 178 active rows — IA 17, AD 37, AP 85, TS 34,
|
||||
and UN 5 — plus the retained retired TS-37 history note.
|
||||
- **Latest automated baseline:** Release build succeeds; 8,076 tests pass and
|
||||
- **Latest automated baseline:** Release build succeeds; 8,148 tests pass and
|
||||
five are intentionally skipped. The capped, uncapped, and dense-Arwic
|
||||
physical prepared-asset routes all completed their portal/input/lifetime
|
||||
assertions and disconnected gracefully.
|
||||
|
|
|
|||
|
|
@ -720,8 +720,19 @@ exact reference identity and retry position, rejects stale generations, and
|
|||
executes every class through the same meter. Priority changes order, never the
|
||||
budget. Lifecycle artifacts publish worker and per-class backlog, retained
|
||||
bytes/age, yields, oversizes, overruns, and pending publication/retirement
|
||||
facts. Publication remains transaction-atomic until Slice E4; retirement
|
||||
quiesce/cursors belong to E3.
|
||||
facts.
|
||||
|
||||
At a hard login/portal reveal edge, `WorldGenerationQuiescence` makes the old
|
||||
generation unavailable through the same `WorldRevealCoordinator` lifetime.
|
||||
World rendering and spatial queries return no old content; object/effect clocks,
|
||||
liveness, and spatial reconciliation stop; world-space audio is silenced; UI,
|
||||
network/event/command delivery, portal presentation, destination streaming, and
|
||||
readiness continue. Canonical live records remain retained until physical
|
||||
teardown converges, so quiescence neither reconstructs server identity nor
|
||||
invents Hidden/UnHide transitions. Full-window and shared-origin retirement
|
||||
advance only from `StreamingController.Tick` through stable resident and
|
||||
per-owner entity/stage cursors on the frame's one meter. Publication remains
|
||||
transaction-atomic until Slice E4.
|
||||
|
||||
### World-reveal readiness ownership
|
||||
|
||||
|
|
|
|||
|
|
@ -68,7 +68,7 @@ accepted-divergence entries (#96, #49, #50).
|
|||
|---|---|---|---|---|---|
|
||||
| AD-38 | Outgoing teleport viewports retire when retail's quantized animation level exceeds the last captured visible level 1022 (index 96), suppressing levels 1023/1024 up to 20.2 ms before retail's literal `elapsed >= 1.0` state edge. Incoming fades retain the exact timer. | `src/AcDream.Core/World/TeleportAnimSequencer.cs` (`OutgoingViewportReachedTerminalProjection`) | An uncapped 2000 FPS pass can publish the finite tunnel at levels 1023/1024 even though the paired 2013 retail capture switches viewports after 1022. The table-level cutover preserves the captured visible viewport ordering without throttling the application. | Exit sound, viewport replacement, and logout tunnel entry can occur at most two easing-table quanta (about 20.2 ms) earlier than retail's logical timer. | `UIGlobals::GetAnimLevel @ 0x004EE540`; `gmSmartBoxUI::UseTime @ 0x004D6E30`; paired retail/acdream captures documented in `docs/research/2026-07-15-retail-portal-space-pseudocode.md` |
|
||||
| AD-1 | Lost-cell machinery replaced by recoverable outdoor demote (**#107** safety net) + outdoor-restore `max(terrainZ, z)` under-terrain lift; retail goes `GotoLostCell` | `src/AcDream.Core/Physics/PhysicsEngine.cs:553` (+ :808) | acdream has no lost-cell state machine; outdoor landcell is the recoverable equivalent; the #107 auto-entry hold should make the demote branch unreachable | Gap in the hold → player committed to outdoor terrain inside/under a building (fake-grounded spawn, fall-through); a legit below-heightmap server restore is silently lifted — upward warp vs server | `GotoLostCell` pc:283418; `SetPositionInternal` 0x00515bd0, pc:283892-283945 |
|
||||
| AD-2 | Async readiness gates replace retail's synchronous destination cell load. **#229 refinement (2026-07-20):** login and F751 portal-space exit now share `WorldRevealReadinessBarrier`, so neither path can expose the normal viewport until the same render-publication, composite-texture, and collision domains converge. A hydratable indoor claim requires its owning Near-tier static/EnvCell mesh set, destination composites, and exact EnvCell physics (`IsSpawnCellReady`); an outdoor claim requires those render domains plus terrain/collision residency for the priority near ring. Hard-recenter generations and tier-aware completion application prevent stale overlapping loads/unloads or Far/Near jobs from opening or erasing the gate; mesh upload remains separate from balanced landblock ownership. Claims beyond NumCells still take the loud forced-placement path. `WorldRevealCoordinator` owns this shared lifetime; diagnostic telemetry observes its generation without defining another readiness path. The portal hold→materialize→regain-control lifecycle remains owned by `TeleportAnimSequencer`. | `src/AcDream.App/Streaming/WorldRevealCoordinator.cs`; `src/AcDream.App/Streaming/WorldRevealReadinessBarrier.cs`; `src/AcDream.App/Streaming/StreamingOriginRecenterCoordinator.cs`; `src/AcDream.App/Streaming/LandblockPresentationPipeline.cs`; `src/AcDream.App/Rendering/GameWindow.cs` (owner wiring + draw eligibility); `src/AcDream.App/Streaming/StreamingController.cs` (`IsRenderNeighborhoodResident`); `src/AcDream.App/Streaming/GpuWorldState.cs` (`IsRenderReady`); `src/AcDream.App/Rendering/Wb/LandblockSpawnAdapter.cs`; `src/AcDream.Core/Physics/PhysicsEngine.cs` (`IsSpawnCellReady`, `IsNeighborhoodTerrainResident`) | This is the asynchronous equivalent of retail leaving `SmartBox::position_update_complete` false while `CellManager::blocking_for_cells` is set: neither initial login nor portal arrival may reveal an empty collision world, a terrain-only Far shell, or a published-but-not-drawable GPU landblock. Indoor does not require a terrain heightmap, only the owning render landblock and exact EnvCell. | Gate opens early → grey/untextured first login or portal reveal, free-fall, wrong-cell rooting, or missing scenery; predicate never satisfies (streamer/DAT/upload failure) → login remains behind the world render gate, while portal transit reaches its existing loud timeout/forced-placement diagnostic. | `SmartBox::UseTime` 0x00455410; `gmSmartBoxUI::EndTeleportAnimation` 0x004D65A0 |
|
||||
| AD-2 | Async readiness gates replace retail's synchronous destination cell load. **#229 refinement (2026-07-20):** login and F751 portal-space exit now share `WorldRevealReadinessBarrier`, so neither path can expose the normal viewport until the same render-publication, composite-texture, and collision domains converge. A hydratable indoor claim requires its owning Near-tier static/EnvCell mesh set, destination composites, and exact EnvCell physics (`IsSpawnCellReady`); an outdoor claim requires those render domains plus terrain/collision residency for the priority near ring. Hard-recenter generations and tier-aware completion application prevent stale overlapping loads/unloads or Far/Near jobs from opening or erasing the gate; mesh upload remains separate from balanced landblock ownership. Claims beyond NumCells still take the loud forced-placement path. `WorldRevealCoordinator` owns this shared lifetime; diagnostic telemetry observes its generation without defining another readiness path. **Slice E3 refinement (2026-07-24):** the same generation now publishes an immediate `WorldGenerationQuiescence` edge: old-world drawing/spatial queries, simulation/effect clocks, reconciliation, targeting, and 3-D audio stop while retained physical teardown advances through metered cursors and destination network/UI/streaming/readiness remain live. The portal hold→materialize→regain-control lifecycle remains owned by `TeleportAnimSequencer`. | `src/AcDream.App/Streaming/WorldRevealCoordinator.cs`; `src/AcDream.App/Streaming/WorldGenerationQuiescence.cs`; `src/AcDream.App/Streaming/WorldRevealReadinessBarrier.cs`; `src/AcDream.App/Streaming/StreamingOriginRecenterCoordinator.cs`; `src/AcDream.App/Streaming/LandblockPresentationPipeline.cs`; `src/AcDream.App/Rendering/GameWindow.cs` (owner wiring + draw eligibility); `src/AcDream.App/Streaming/StreamingController.cs` (`IsRenderNeighborhoodResident`); `src/AcDream.App/Streaming/GpuWorldState.cs` (`IsRenderReady`); `src/AcDream.App/Rendering/Wb/LandblockSpawnAdapter.cs`; `src/AcDream.Core/Physics/PhysicsEngine.cs` (`IsSpawnCellReady`, `IsNeighborhoodTerrainResident`) | This is the asynchronous equivalent of retail leaving `SmartBox::position_update_complete` false while `CellManager::blocking_for_cells` is set: neither initial login nor portal arrival may reveal or continue simulating an old/partial collision world, a terrain-only Far shell, or a published-but-not-drawable GPU landblock. Indoor does not require a terrain heightmap, only the owning render landblock and exact EnvCell. | Gate opens early → grey/untextured first login or portal reveal, free-fall, wrong-cell rooting, missing scenery, or a still-active old generation; predicate never satisfies (streamer/DAT/upload failure) → login remains behind the world render gate, while portal transit reaches its existing loud timeout/forced-placement diagnostic. | `SmartBox::UseTime` 0x00455410; `gmSmartBoxUI::EndTeleportAnimation` 0x004D65A0 |
|
||||
| AD-3 | Outdoor seeds always walk the transit array (retail skips the walk when the seed CLandCell is null/unloaded); per-cell lookups no-op on unhydrated data | `src/AcDream.Core/Physics/CellTransit.cs:503` | Equivalence argument: with nothing hydrated every lookup inside the walk no-ops, so the result matches retail's skipped walk | Near partially-streamed landblocks, building-transit promotion silently can't fire until structs hydrate — membership stays outdoor while the player is inside a building | `CObjCell::find_cell_list` 0052b535-0052b56c (null-CLandCell case) |
|
||||
| AD-4 | `point_in_cell` against an unhydrated CellBSP returns false (skip) rather than the null-node "inside" default; retail never queries unloaded cells | `src/AcDream.Core/Physics/CellTransit.cs:588` | The null-node default would make an unhydrated cell spuriously claim every point; skipping is the conservative streaming-safe choice | During hydration, a point genuinely inside a not-yet-loaded cell resolves outdoor/stale — transient membership misclassification driving wrong collision set and render root | `CEnvCell::find_visible_child_cell` :311397; cell-BSP vtable[0x84] |
|
||||
| AD-5 | Outdoor `point_in_cell` is an identity compare against the global XY-column cell from `LandDefs.AdjustToOutside` (no per-cell containment test) | `src/AcDream.Core/Physics/CellTransit.cs:865` | Landcells are disjoint 24 m columns — identity-compare against the column under the sphere centre is exactly equivalent to retail's per-candidate test | If block-origin/lcoord math is wrong at a landblock seam, the compare silently never matches — outdoor membership freezes at boundaries (the pre-#106 symptom) | `find_cell_list` pick pc:308788-308825; `CLandCell::point_in_cell` (get_block_offset pc:308804) |
|
||||
|
|
|
|||
|
|
@ -1605,13 +1605,16 @@ port in any phase — no separate listing here.
|
|||
> and dense-Arwic physical routes passed; third-visit cache residence was
|
||||
> non-growing and no checkpoint retained staged or retiring bytes. [Residency
|
||||
> report](../research/2026-07-24-slice-d-unified-residency-report.md). Slice E
|
||||
> cost-budgeted streaming/retirement is active. E2 has replaced the flat
|
||||
> cost-budgeted streaming/retirement is active. E2 replaced the flat
|
||||
> deferred list, count-only throttle, priority hunt, and unload bypass with one
|
||||
> typed-meter scheduler over explicit stable destination/control/unload/Near/
|
||||
> Far queues; production prices worker results before adoption and lifecycle
|
||||
> artifacts expose exact backlog/retained-byte facts. E3 next adds immediate
|
||||
> old-generation quiesce and cursored retirement. F/G and J retain their
|
||||
> explicit approval gates.
|
||||
> artifacts expose exact backlog/retained-byte facts. E3 now makes the old
|
||||
> generation unavailable at the hard reveal edge and freezes its world
|
||||
> simulation/audio while full-window and shared-origin teardown advance through
|
||||
> metered resident, entity, and owner-stage cursors with exact retry receipts.
|
||||
> E4 cursor-budgets publication next. F/G and J retain their explicit approval
|
||||
> gates.
|
||||
|
||||
**Spec:** `docs/superpowers/specs/2026-07-05-modern-pipeline-design.md` (the
|
||||
umbrella design — read it first). **Goal:** smoothness first (no frame over
|
||||
|
|
|
|||
|
|
@ -93,10 +93,12 @@ The separately authorized modern-runtime performance program has completed
|
|||
Slices A–D: corrected measurement, prepared-package bake/dedup, package-only
|
||||
production streaming, and typed unified residency. Its physical capped,
|
||||
uncapped, and dense connected gates pass without a visual-quality change.
|
||||
Slice E0–E2 now define and enforce typed completion admission through explicit
|
||||
stable priority queues; E3 adds immediate old-generation quiesce and cursored
|
||||
retirement next. Slices F/G remain behind their explicit ECS approval gate,
|
||||
and Slice J remains behind its gameplay-owner approval gate.
|
||||
Slice E0–E3 now define and enforce typed completion admission through explicit
|
||||
stable priority queues, publish an immediate generation-scoped old-world
|
||||
quiesce at login/portal boundaries, and advance full-window/recenter teardown
|
||||
through exact metered retirement cursors. E4 next makes publication itself
|
||||
cursor-budgeted. Slices F/G remain behind their explicit ECS approval gate, and
|
||||
Slice J remains behind its gameplay-owner approval gate.
|
||||
|
||||
Slice 1's 18-cell favorite-spell overflow bar is user-accepted. Slice 2's
|
||||
status hand selected-object availability and existing
|
||||
|
|
|
|||
|
|
@ -2,7 +2,7 @@
|
|||
|
||||
**Date:** 2026-07-24
|
||||
|
||||
**Status:** Slices A–D complete. Slice E is active (E0/E1 complete).
|
||||
**Status:** Slices A–D complete. Slice E is active (E0–E3 complete).
|
||||
|
||||
**Scope:** Reconcile and sequence the existing Modern Pipeline (`MP`) and
|
||||
Linux/headless (`LH`) tracks using the 2026-07-24 connected performance audit.
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
# Modern Runtime Slice E — Cost-budgeted streaming and retirement
|
||||
|
||||
**Status:** active — E0/E1/E2 complete; E3 quiesce and budgeted retirement next
|
||||
**Status:** active — E0/E1/E2/E3 complete; E4 cursor-budgeted publication next
|
||||
**Program:** `docs/plans/2026-07-24-modern-runtime-architecture.md`
|
||||
**Baseline:** Slice D closeout commit `66690805`
|
||||
**Behavior contract:** no visual-quality or retail-behavior reduction
|
||||
|
|
@ -288,6 +288,35 @@ E6; the active desktop was RDP and is not valid performance evidence.
|
|||
- Prove no old generation ticks, emits, collides, targets, or renders while its
|
||||
retained memory converges.
|
||||
|
||||
**Complete 2026-07-24.** `WorldGenerationQuiescence` now publishes the hard
|
||||
login/portal edge through one generation-scoped availability state owned by
|
||||
`WorldRevealCoordinator`. The edge withdraws world drawing, picking/radar
|
||||
spatial queries, target selection, object/static animation, PhysicsScript time,
|
||||
particle/effect progression, liveness, spatial reconciliation, and owner-tagged
|
||||
3-D audio while network/event/command, portal presentation, UI, streaming, and
|
||||
destination readiness continue. A superseding reveal remains continuously
|
||||
quiescent and only its exact generation can reopen the world; canonical live
|
||||
records and readiness state remain retained, so the mechanism does not
|
||||
synthesize Hidden/UnHide or rebuild server identity.
|
||||
|
||||
Full-window and shared-origin retirement are now retained frame transactions.
|
||||
Generation invalidation, worker-inbox clearing, accepted-payload release,
|
||||
region clearing, stable resident capture, and landblock detachment all resume
|
||||
from exact cursors through the frame's single `StreamingWorkMeter`.
|
||||
`LandblockRetirementCoordinator` preserves stable FIFO order and advances one
|
||||
entity or one owner stage per reservation across scripts, classifications,
|
||||
lighting, translucency, plugin projection, terrain, physics, cell visibility,
|
||||
building registries, and environment cells. Failures retry the exact unfinished
|
||||
entity/stage without replaying committed work. A landblock detach remains one
|
||||
named indivisible spatial boundary; its complete entity count is charged before
|
||||
the operation.
|
||||
|
||||
Validation: 51 focused reveal/quiescence/retirement tests passed; the complete
|
||||
App suite passed 3,666 / 3 skipped; the complete solution passed 8,148 / 5
|
||||
skipped; Release solution build green. The physical connected performance and
|
||||
visual gate remains deferred to E6 because the active desktop is RDP and is not
|
||||
valid GPU/FPS evidence.
|
||||
|
||||
### E4 — Cursor-budgeted publication
|
||||
|
||||
- Move stable ordered arrays/cost facts into retained receipts.
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue