488 lines
26 KiB
Markdown
488 lines
26 KiB
Markdown
# GameWindow Slice 6 — update-frame orchestration
|
|
|
|
**Status:** Active 2026-07-21.
|
|
**Parent program:** [`docs/architecture/code-structure.md`](../architecture/code-structure.md), Slice 6.
|
|
**Baseline:** `d4ecac1d`; `GameWindow.cs` is 8,811 raw lines, 247 fields, and
|
|
153 methods. Release baseline: 7,054 passed / 5 skipped. The connected
|
|
lifecycle gate and synchronized nine-stop resource soak both pass.
|
|
**Behavior rule:** This is an ownership extraction. Preserve the accepted
|
|
retail object/network order, asynchronous streaming-readiness adaptation,
|
|
portal transit, input semantics, and camera presentation. A defect exposed by
|
|
the boundary receives its own deterministic oracle and bisectable fix; it is
|
|
never hidden behind a retry, delay, suppression flag, or reordered callback.
|
|
|
|
## Progress ledger
|
|
|
|
- [x] A — freeze the complete production phase graph and introduce the typed
|
|
orchestration contract plus structural/order guards.
|
|
- [x] B — extract the pre-network live-object presentation phase and the
|
|
non-advancing post-network spatial reconciler; remove callbacks into
|
|
`GameWindow` from `RetailLiveFrameCoordinator`.
|
|
- [x] C — extract streaming-origin convergence, observer selection, dungeon
|
|
collapse, streaming tick, and rescued-entity rebucketing.
|
|
- [x] D — extract dispatcher/raw-mouse/combat input sampling without changing
|
|
movement-command or UI-capture semantics.
|
|
- [ ] E — extract the complete local-player teleport owner and wire it between
|
|
the existing post-network liveness and player-mode auto-entry phases.
|
|
- [ ] F — extract the shared player-mode lifecycle plus fly/chase/player
|
|
camera presentation and cut production over to one
|
|
`UpdateFrameOrchestrator`.
|
|
- [ ] G — delete the old `OnUpdate` bodies, callback facades, and obsolete
|
|
frame state; run focused corrected-diff reviews after each ownership edge.
|
|
- [ ] H — full Release suite, connected lifecycle/reconnect gate, synchronized
|
|
resource soak, documentation, durable memory, and line/field/method closeout.
|
|
|
|
Every checked checkpoint is committed as one bisectable architectural unit.
|
|
Documentation records the exact commit and accepted test count as work lands.
|
|
|
|
Checkpoint A introduced the internal `AcDream.App.Update` contract, one typed
|
|
`UpdateFrameClock`/`IPhysicsScriptTimeSource`, the twelve-phase outer-order
|
|
oracle, exact teardown and invalid-delta tests, and guards against a transitive
|
|
`GameWindow` clock capture. Production now publishes PES time once per update;
|
|
18 focused Release tests and the full 2,709-test App project pass, and all
|
|
three corrected-diff reviews are clean.
|
|
|
|
Checkpoint B moved the complete local/ordinary/static/effect body into
|
|
`LiveObjectFrameController`, made `RetailLiveFrameCoordinator`'s
|
|
object → inbound batch → command → spatial-reconcile barrier fully typed,
|
|
and removed animation/runtime/projectile back-references to `GameWindow`.
|
|
`GameWindow.cs` is now 8,716 raw lines. The corrected diff passes 239 focused
|
|
Release tests, the 2,732-test App suite, and the full 7,090-test Release suite
|
|
(5 fixture/environment skips); all three independent reviews are clean.
|
|
|
|
Checkpoint C moved retained origin convergence, readiness, observer selection,
|
|
sealed-dungeon collapse, streaming publication, and persistent live-projection
|
|
rescue into `StreamingFrameController`. Production keeps streaming publication
|
|
ahead of input and the live object/network barrier, so a same-frame
|
|
CreateObject can enter the newly resident bucket. The focused 146-test Release
|
|
selection, 2,754-test App suite, and complete 7,112-test Release suite (5
|
|
fixture/environment skips) pass. Login-before-position, portal hold, outdoor
|
|
and sealed/SeenOutside EnvCells, pending recenter, exact rescue rebucketing,
|
|
GUID deletion, and session reset are pinned; all three corrected-diff reviews
|
|
are clean. `GameWindow.cs` is now 8,569 raw lines.
|
|
|
|
Checkpoint D moved semantic hold delivery, movement sampling, autorun,
|
|
instant mouse-look, cursor capture, raw filtering/idle handling, and combat
|
|
intent into `GameplayInputFrameController` and focused typed owners. Devtools
|
|
keyboard capture pauses all gameplay movement without clearing the autorun
|
|
latch; retained chat suppresses held keys while autorun continues. Every
|
|
focus, teleport, camera/player-mode, reset, and shutdown boundary now releases
|
|
mouse-look through one lifecycle path and clears stale RMB orbit state.
|
|
Production combat requests, automatic hostile selection, UI-capture probes,
|
|
and movement-truth diagnostics no longer retain callbacks into `GameWindow`.
|
|
The 2,787-test App suite and complete 7,145-test Release suite pass (5
|
|
fixture/environment skips); all three corrected-diff reviews are clean.
|
|
`GameWindow.cs` is now 8,205 raw lines.
|
|
|
|
## 1. Outcome and non-goals
|
|
|
|
At slice exit, `GameWindow.OnUpdate` starts the profiler scope and delegates one
|
|
host delta to `UpdateFrameOrchestrator`. `GameWindow` composes concrete owners;
|
|
it no longer selects a streaming observer, advances animations/effects,
|
|
samples raw mouse input, sequences inbound network traffic, advances portal
|
|
transit, or updates gameplay cameras.
|
|
|
|
The owner graph is explicit rather than a list of anonymous callbacks:
|
|
|
|
```text
|
|
UpdateFrameOrchestrator
|
|
├── live teardown convergence retry retained tombstones
|
|
├── UpdateFrameClock normalized host time / PES clock
|
|
├── StreamingFrameController residence/readiness pre-pass
|
|
├── GameplayInputFrameController semantic input + mouse/combat intent
|
|
├── RetailLiveFrameCoordinator retail SmartBox object barrier
|
|
│ ├── LiveObjectFrameController local/ordinary/static/effect tails
|
|
│ ├── LiveSessionController inbound network drain
|
|
│ ├── RetailLocalPlayerFrame CommandInterpreter position tail
|
|
│ └── LiveSpatialReconciler non-advancing authoritative refresh
|
|
├── LiveEntityLivenessController expiry after accepted inbound state
|
|
├── LocalPlayerTeleportController local transit/reveal/tunnel state
|
|
├── PlayerModeAutoEntry one-shot ready-world entry
|
|
├── PlayerModeController enter/exit/current-player lifetime
|
|
└── CameraFrameController fly/chase/player presentation
|
|
```
|
|
|
|
Concrete names may be narrowed during checkpoint A's source audit, but the
|
|
ownership boundaries and order do not change. The orchestrator receives a
|
|
small immutable per-frame input and concrete phase owners. It does not receive
|
|
a hundred delegates, one mega `IUpdateFrameServices` context, or a service
|
|
locator, and no transitive update collaborator calls a substantial method back
|
|
on `GameWindow`.
|
|
|
|
This slice does not change simulation rate, object quantum rules, movement
|
|
speed, interpolation, streaming radii, reveal readiness, portal visuals,
|
|
particle range, combat cadence, key bindings, camera formulas, render order,
|
|
or shutdown order. It adds no GL work and does not move retained-UI timers out
|
|
of their render seam. Slice 7 owns the draw graph; Slice 8 owns final
|
|
composition and Silk callback cleanup.
|
|
|
|
## 2. Retail oracle and accepted adaptation
|
|
|
|
The object/network barrier is pinned by
|
|
[`2026-07-19-r6-update-object-order-pseudocode.md`](../research/2026-07-19-r6-update-object-order-pseudocode.md):
|
|
|
|
- `CPhysicsObj::update_object @ 0x00515D10` applies the strict object quantum;
|
|
- `CPhysicsObj::UpdatePositionInternal @ 0x00512C30` advances the PartArray,
|
|
position/physics candidate, then processes semantic hooks;
|
|
- `CPhysicsObj::UpdateObjectInternal @ 0x005156B0` runs Detection → Target →
|
|
Movement → `CPartArray::HandleMovement` → Position → Particle → Script;
|
|
- `SmartBox::UseTime @ 0x00455410` advances object/physics time before the
|
|
inbound queue and then calls `CommandInterpreter::UseTime`;
|
|
- `gmSmartBoxUI::UseTime @ 0x004D6E30` owns UI/viewport time outside that
|
|
object barrier.
|
|
|
|
At the retail host level, `Client::UseTime @ 0x00411C40` calls
|
|
`UIElementManager::UseTime` before `SmartBox::UseTime`; the UI time broadcast
|
|
reaches `gmSmartBoxUI::UseTime`. Retail also publishes player-camera work from
|
|
the physics/player callback rather than from one post-network camera tail.
|
|
acdream currently advances teleport/UI-camera presentation after its
|
|
object/network/command barrier. Slice 6 preserves that existing order as
|
|
registered TS-53; it does not cite `gmSmartBoxUI` as proof that the current
|
|
post-network placement is retail-exact.
|
|
|
|
acdream preserves two documented presentation adaptations:
|
|
|
|
1. only semantic `AnimationDone` executes at retail's in-object hook slot;
|
|
every other captured animation hook retains the current deferred path after
|
|
final root, part, and equipped-child poses are published, including
|
|
particles, audio, lights, translucency, `CallPES`, and default-script
|
|
chaining (TS-50);
|
|
2. shared particle simulation and PhysicsScript queues tick once per host
|
|
update after both worksets rather than once per object's admitted quantum.
|
|
This also means the current shared Particle → Script order does not reproduce
|
|
the static workset's retail Script → Particle → hooks order (TS-51).
|
|
|
|
Asynchronous landblock streaming has no one-call retail equivalent. Its
|
|
convergence pre-pass remains before inbound CreateObject dispatch so a newly
|
|
accepted projection can find a resident bucket in the same frame. This
|
|
pre-pass does not advance an object's retail clock. `WorldRevealCoordinator`
|
|
remains the single login/portal readiness owner.
|
|
|
|
## 3. Fixed production phase order
|
|
|
|
The complete host-update graph is frozen as follows:
|
|
|
|
1. retry canonical live-entity teardown tombstones; an `AggregateException` is
|
|
logged and later phases continue, while any other exception propagates;
|
|
2. normalize the host delta, advance the shared PES clock once, and publish it;
|
|
3. advance pending origin retirement/recenter, select the observer, tick
|
|
streaming, and rebucket rescued persistent entities;
|
|
4. tick `InputDispatcher`, consume one raw mouse sample, and advance combat
|
|
attack intent;
|
|
5. enter the non-reentrant inbound-event envelope and advance the pre-network
|
|
live-object phase:
|
|
- local object and pre-network movement/jump output;
|
|
- queued selection/use output after movement edges;
|
|
- ordinary live objects;
|
|
- the distinct static-animation workset;
|
|
- equipped children and static hook completion;
|
|
- fades, every deferred non-`AnimationDone` hook, and current effect/light
|
|
anchors;
|
|
- particle visibility and particle simulation;
|
|
- PhysicsScript queues;
|
|
6. drain inbound session traffic inside one `GpuWorldState.MutationBatch`;
|
|
7. run the local player's post-network `CommandInterpreter` position check;
|
|
8. perform the ordinary post-network non-advancing root/child/emitter/light
|
|
reconcile;
|
|
9. advance liveness expiry from the absolute client timer;
|
|
10. activate/tick local teleport transit. A Place edge commits the player and
|
|
live root, immediately performs its own non-advancing reconcile, then
|
|
notifies world reveal and continues tunnel state;
|
|
11. evaluate one-shot player-mode auto-entry;
|
|
12. update fly or chase/player camera presentation. If the local player was
|
|
first created by this frame's inbound pass, publish its non-advancing
|
|
projection, immediately reconcile a second time, then update the camera.
|
|
|
|
Those three reconcile edges—ordinary post-network, teleport Place, and
|
|
inbound-created-player projection—are separate accepted production edges. Any
|
|
future consolidation is a behavior change with its own oracle, not part of
|
|
this extraction.
|
|
|
|
An invalid/non-positive host delta becomes zero for the PES/object/particle/
|
|
tunnel delta but never blocks inbound traffic, absolute-time liveness,
|
|
recenter convergence, or camera-state publication. Raw mouse idle uses its
|
|
independent monotonic input clock. A missing gameplay camera/input owner never
|
|
suppresses outer phases; the streaming controller may skip observer-driven
|
|
streaming when it has no valid live or offline observer, while origin
|
|
retirement still advances. Devtools keyboard capture pauses player/camera
|
|
control including autorun; retained chat capture suppresses held WASD while
|
|
autorun continues; mouse capture ends mouse-look but does not suppress
|
|
keyboard, combat, network, streaming, teleport, or teardown.
|
|
|
|
## 4. Architecture and interfaces
|
|
|
|
### 4.1 Per-frame input
|
|
|
|
Use an immutable value equivalent to:
|
|
|
|
```csharp
|
|
public readonly record struct UpdateFrameInput(double HostDeltaSeconds);
|
|
```
|
|
|
|
Derived facts are read by their owning controller from stable runtime owners
|
|
or from a narrowly typed state source. Do not pass `GameWindow`, expose its
|
|
private fields wholesale, or create a service locator. Mutable player/session
|
|
owners that legitimately change during login are represented by one focused
|
|
state/source interface per domain, not anonymous closures into window methods.
|
|
|
|
`UpdateFrameClock` is constructed before any materializer/network owner that
|
|
needs the current PES time. It owns the normalized host/PES clock and exposes a
|
|
narrow `CurrentScriptTime` source; `_physicsScriptGameTime` does not remain a
|
|
`GameWindow` field captured by later owners. Absolute liveness time and raw
|
|
mouse idle time remain distinct monotonic sources and are not derived from the
|
|
normalized simulation delta.
|
|
|
|
### 4.2 Object phase
|
|
|
|
`LiveObjectFrameController` owns the body currently in
|
|
`AdvanceLiveObjectRuntimeCore`. It composes existing focused owners and keeps
|
|
their retail order; it does not absorb their algorithms or identity maps.
|
|
`LiveSpatialPresentationReconciler` owns the current no-time refresh body.
|
|
`RetailLiveFrameCoordinator` depends on those typed owners plus the existing
|
|
session and local-player owners. Its public `Tick` remains the one explicit
|
|
object → network → command → reconcile barrier.
|
|
|
|
`RetailInboundEventDispatcher` continues wrapping the complete object phase.
|
|
Reentrant packets queue until the current object's manager tail completes.
|
|
The hot path remains allocation-free after warmup.
|
|
|
|
The extraction inventory includes the complete transitive update graph, not
|
|
only `RetailLiveFrameCoordinator`: `RetailLocalPlayerFrameController` loses
|
|
substantial window captures in favor of a focused local-player slot, movement
|
|
input source, outbound owner, and projection owner;
|
|
`LiveEntityAnimationPresenter` receives a concrete animation-presentation
|
|
context instead of retaining `GameWindow` as
|
|
`ILiveAnimationPresentationContext`; scheduler clock/player/projectile sources
|
|
are similarly narrow. Existing small value/policy callbacks are acceptable
|
|
only when they do not call a substantial body back on the window or create a
|
|
second identity/state owner.
|
|
|
|
### 4.3 Streaming phase
|
|
|
|
`StreamingFrameController` owns observer selection and the sealed-dungeon
|
|
gate. It receives the existing `StreamingOriginRecenterCoordinator`,
|
|
`StreamingController`, `LiveWorldOriginState`/center state, camera/player
|
|
state, physics current cell, `GpuWorldState`, and `LiveEntityRuntime` through
|
|
typed seams. It never builds, publishes, or retires a landblock; those remain
|
|
Slice 5 owners.
|
|
|
|
The controller preserves:
|
|
|
|
- no pre-login hardcoded-Holtburg streaming;
|
|
- real-player-origin readiness before first streaming;
|
|
- destination-origin pinning while in portal space;
|
|
- authoritative player landblock during the login hold;
|
|
- offline fly-camera observation only outside live in-world mode;
|
|
- sealed EnvCell collapse using the cell's own landblock identity;
|
|
- teleport-hold suppression of the stale source-cell dungeon gate;
|
|
- rescued-entity rebucketing after the accepted streaming tick.
|
|
|
|
### 4.4 Input and camera phases
|
|
|
|
`GameplayInputFrameController` owns per-frame dispatcher hold delivery,
|
|
UI-capture transitions, raw mouse sample/filter/idle handling, combat attack
|
|
ticking, and the complete mouse-look/cursor-capture lifetime. It is the single
|
|
owner of mouse-look state, saved cursor mode, begin/end/hide/restore, and
|
|
movement teardown across press/release, capture change, focus loss, teleport,
|
|
session reset, player-mode exit, and shutdown. Action press/release callbacks
|
|
remain on `InputDispatcher` and movement stays owned by
|
|
`PlayerMovementController`.
|
|
|
|
`PlayerModeController` owns enter/exit/toggle construction and the current
|
|
player-controller, physics-host, chase-camera, and chase-mode slot. Manual
|
|
input, `PlayerModeAutoEntry`, and local teleport activation all enter through
|
|
that one owner. Streaming, camera, local-frame, and teleport owners receive
|
|
narrow read sources from it; no path calls the substantial current
|
|
`EnterPlayerModeNow`/exit bodies back on `GameWindow` or duplicates player-mode
|
|
state.
|
|
|
|
`CameraFrameController` owns held fly-camera controls, retail chase offsets,
|
|
post-network player presentation sampling, and both chase-camera updates. It
|
|
does not own physics, target selection, or camera formulas. The local player
|
|
created by the inbound pass gets a non-advancing projection before its first
|
|
draw exactly as today, followed by the current second spatial reconcile before
|
|
the camera samples that projection.
|
|
|
|
### 4.5 Teleport phase
|
|
|
|
`LocalPlayerTeleportController` owns only the current local-player transit
|
|
state machine and presentation edges. It composes
|
|
`TeleportTransitCoordinator`,
|
|
`TeleportViewPlaneController`, `PortalTunnelPresentation`,
|
|
`WorldRevealCoordinator`, streaming priority, and the session LoginComplete
|
|
send. Checkpoint E first extracts the currently window-owned local aim,
|
|
destination, hold/forced, activation, placement, reset, and session-clear
|
|
state into this owner plus a concrete local placement collaborator where
|
|
needed. It does not reuse `RemoteTeleportPlacement`, and network/session sinks
|
|
do not retain `AimTeleportDestination` or reset callbacks into `GameWindow`.
|
|
`LiveEntityLivenessController`, tombstone retry, and `PlayerModeAutoEntry`
|
|
remain separate focused phases; teleport does not absorb them.
|
|
|
|
### 4.6 Composition, thread, and lifetime
|
|
|
|
The clock and focused dynamic sources are constructed before their first
|
|
consumer. The final orchestrator is composed exactly once at the end of a
|
|
successful `OnLoad`; `OnUpdate` fails fast if that invariant is broken rather
|
|
than running a nullable partial graph. Every phase mutates state only on the
|
|
existing update/render thread. Streaming worker completion remains behind
|
|
`StreamingController.Tick`; the extraction adds no lock, task, or async entry.
|
|
|
|
Phase controllers borrow their input, session, streaming, portal, camera, and
|
|
render-presentation owners; they do not dispose shared dependencies. Any new
|
|
event subscription has explicit symmetric detach. During shutdown the update
|
|
collaborators remain alive through the first-stage `LiveSessionController`
|
|
reset, then retire before their underlying input/camera/portal/streaming
|
|
resources. Existing retryable shutdown ordering remains authoritative.
|
|
|
|
## 5. Checkpoints and acceptance
|
|
|
|
### A — contract and guards
|
|
|
|
- record the exact production phase graph and every mutable dependency;
|
|
- correct and pin the retail oracle for physics-hook retention/reentrant
|
|
append, inactive object behavior, and static Script → Particle → hooks; pin
|
|
the existing TS-50/TS-51 divergences without reordering runtime behavior in
|
|
this ownership-only slice;
|
|
- add an explicit orchestrator order test covering all twelve phases and the
|
|
three conditional reconcile edges;
|
|
- pin normalized simulation/PES/particle/tunnel time separately from absolute
|
|
liveness and raw-mouse idle clocks for NaN, both infinities, non-positive
|
|
values, and finite values above `float.MaxValue`;
|
|
- pin missing live/offline camera behavior and the separate devtools keyboard,
|
|
retained-chat keyboard, and mouse-capture contracts;
|
|
- pin teardown retry success, `AggregateException` log-and-continue, other
|
|
exception propagation, and next-frame retry;
|
|
- add source guards that prevent `OnUpdate` or the coordinator from regaining
|
|
substantial callback bodies, and prevent any transitive update owner from
|
|
retaining `GameWindow` or one mega service context;
|
|
- verify current production traces before cutover.
|
|
|
|
### B — object/network barrier
|
|
|
|
- move the pre-network animation/effect body into
|
|
`LiveObjectFrameController`;
|
|
- move no-time root/child/effect refresh into
|
|
`LiveSpatialPresentationReconciler`;
|
|
- replace coordinator callbacks with typed collaborators;
|
|
- preserve semantic/visual hook separation, owner-incarnation revalidation,
|
|
static-after-ordinary order, ordinary Particle-before-Script, the current
|
|
shared-tail TS-51 adaptation, and once-per-host tails;
|
|
- delete `AdvanceLiveObjectRuntimeCore` and
|
|
`ReconcileLiveObjectSpatialPresentation` from `GameWindow`.
|
|
|
|
Focused tests cover `RetailObjectActivityGate` and
|
|
`RetailObjectQuantumClock`: parented/cell-less/Frozen suspension, inactive
|
|
Particle/Script-only time, Hidden+Active adjustment/hooks/manager time, and
|
|
separate ordinary epsilon/Min/Max/Huge plus static epsilon/Huge boundaries.
|
|
They also cover incomplete physics-hook
|
|
retention, same-drain animation-hook append, deferred `CallPES`/default-script/
|
|
translucency routing, physics-hook append deferred until the next drain,
|
|
completed physics-hook removal preserving the snapshotted successor, static
|
|
hooks, callback GUID reuse, and reentrant inbound packets. Particle then Script
|
|
must run exactly once for an empty world,
|
|
multiple ordinary/static owners, invalid delta, and reentrant inbound work;
|
|
the one published PES clock remains visible from hook capture through the
|
|
script tick.
|
|
|
|
Checkpoint B removes the coordinator, animation presenter/scheduler, runtime
|
|
view, static-root, and projectile callbacks into `GameWindow`. The callback
|
|
composition still retained by `RetailLocalPlayerFrameController` is explicitly
|
|
deferred: checkpoint D owns its input/capture sources and checkpoint F owns its
|
|
mutable player-mode/controller/session sources. A structural test permits that
|
|
one named legacy owner only; D/F must remove the exception before final cutover.
|
|
|
|
### C — streaming frame
|
|
|
|
- extract readiness/recenter advancement, observer selection, dungeon gate,
|
|
streaming tick, and rescued projection rebucketing;
|
|
- test login-before-player-spawn, outdoor/dungeon/portal-hold/offline observer
|
|
cases, missing live/offline camera sources, and cell-landblock identity;
|
|
- prove same-frame streaming completion precedes CreateObject projection into
|
|
the resident bucket, unknown pre-login origin enqueues nothing, and recenter
|
|
retirement continues while ordinary streaming is gated;
|
|
- verify no build/publication/retirement ownership leaks back from Slice 5.
|
|
|
|
### D — input frame
|
|
|
|
- extract dispatcher tick, UI mouse-capture edge, raw sample/filter/idle path,
|
|
combat intent tick, and the one cross-lifetime mouse-look/cursor owner;
|
|
- test capture entry while mouse-look is active, zero-idle drift stop,
|
|
production action ordering, devtools-vs-chat autorun semantics, mouse-only
|
|
capture, and focus/teleport teardown;
|
|
- prove every non-input phase still runs under each capture mode;
|
|
- retain diagnostic semantic input as the unattended connected gate seam.
|
|
|
|
### E — local teleport and post-network world frame
|
|
|
|
- extract the currently window-owned local-player teleport state and every
|
|
aim/destination/activation/place/reset/session port before moving its tick;
|
|
- retain liveness and auto-entry as separate orchestrator calls around pending
|
|
transit activation, readiness/hold, tunnel events, materialization, and
|
|
reveal completion;
|
|
- test loaded and pending destinations, forced-readiness boundary, same-cell
|
|
respawn, LoginComplete ordering, delete/reset, and no second reveal owner;
|
|
- pin Place → immediate reconcile → reveal and old-GUID liveness candidate →
|
|
inbound delete/recreate generation safety;
|
|
- preserve the completed portal visuals and world-reveal barrier unchanged.
|
|
|
|
### F/G — camera, cutover, and deletion
|
|
|
|
- extract player-mode enter/exit/toggle and current-owner state before camera
|
|
or teleport cutover; retain `PlayerModeAutoEntry` only as its one-shot
|
|
readiness guard;
|
|
- extract fly camera, retail chase adjustment, local post-network projection,
|
|
combat target tracking, and chase-camera publication;
|
|
- pin inbound-created projection → immediate second reconcile → camera, with
|
|
exact root/child/emitter/light refresh counts and no duplicate time advance;
|
|
- compose `UpdateFrameOrchestrator` only after all dependencies exist;
|
|
- replace `OnUpdate` with profiler scope plus one `Tick` call;
|
|
- remove obsolete frame fields/facades and prove there is no back-reference to
|
|
`GameWindow` from an extracted owner;
|
|
- measure line/field/method count. The target is below 8,000 lines, but the
|
|
ownership/ordering exit criteria outrank the count.
|
|
|
|
### H — release and connected gates
|
|
|
|
After all three independent corrected-diff reviews are clean:
|
|
|
|
1. run every focused App/Core/Net/UI test project;
|
|
2. run `dotnet build AcDream.slnx -c Release`;
|
|
3. run the full Release suite;
|
|
4. run the connected lifecycle/reconnect gate;
|
|
5. run the synchronized nine-stop resource soak with movement, turn, jump,
|
|
combat, portal materialization waits, fatal-log scan, and graceful close;
|
|
6. compare lifecycle, outbound movement, materialization, entity/animation,
|
|
frame-profile, resource, and teardown traces with the Slice 5 baseline;
|
|
7. audit the divergence register, architecture, milestones, roadmap, issues,
|
|
`AGENTS.md`, `CLAUDE.md`, and durable memory.
|
|
|
|
The slice requires no new visual behavior. If connected screenshots or traces
|
|
change, return to the responsible checkpoint; do not defer the difference to
|
|
Slice 7.
|
|
|
|
## 6. Review gate for every checkpoint
|
|
|
|
After each implementation checkpoint:
|
|
|
|
1. run focused tests and inspect the complete diff;
|
|
2. retail-conformance review checks named functions, exact order, Hidden/
|
|
quantum semantics, and adaptation boundaries;
|
|
3. architecture review checks dependency direction, absence of a replacement
|
|
god object/service locator, same-thread mutation, and symmetric teardown;
|
|
4. adversarial review checks independent clocks, callback reentrancy,
|
|
owner/GUID reuse, login/portal transitions, capture modes, missing observer
|
|
sources, teardown failures, and early-return phase suppression;
|
|
5. fix every confirmed root cause and repeat review until clean;
|
|
6. build/test Release and commit the checkpoint before starting the next one.
|
|
|
|
## 7. Divergence and documentation bookkeeping
|
|
|
|
TS-50, TS-51, and the newly documented existing host-order TS-53 remain until
|
|
their exact adaptations are ported; this slice must not overclaim retail
|
|
parity. IA-14/AD-22 and the lifetime/resource rows are audited against the
|
|
final owner graph but changed only if their mechanism actually changes. Any
|
|
newly discovered unavoidable adaptation gets a register row in the same
|
|
commit. The Slice 6 closeout updates the code-structure table,
|
|
roadmap, milestones, session docs, and
|
|
`project_gamewindow_decomposition.md` with exact commits, test counts, gates,
|
|
and final metrics.
|