Write normal game-message and ACK packet framing directly into bounded stack spans, hash fragments without materialization, and send the populated slice to the socket. Preserve exact wire bytes and ISAAC failure ordering with differential and zero-allocation tests.
206 lines
9.4 KiB
Markdown
206 lines
9.4 KiB
Markdown
# Modern runtime Slice H execution plan
|
||
|
||
**Status:** ACTIVE
|
||
**Parent plan:** `2026-07-24-modern-runtime-architecture.md`, Slice H
|
||
**Prerequisite state:** Slice G4 production cutover is automated-gated; its
|
||
user visual gate remains pending.
|
||
|
||
## 1. Safety boundary
|
||
|
||
Slice H removes work which scales with presentation rate. It does not change
|
||
retail gameplay rules, visible-cell authority, light membership, packet
|
||
ordering, acknowledgement timing, heartbeat placement, or UI presentation.
|
||
|
||
The G4 old-route referee remains available until the user accepts the visual
|
||
gate. Slice H must not delete or alter that rollback boundary.
|
||
|
||
If the G4 visual result is wrong, revert only:
|
||
|
||
```text
|
||
git revert ef1d263337997bb030eadb7b8e71d73dc659907a
|
||
```
|
||
|
||
Do not reset history and do not revert G3. The portal-warmup corrections
|
||
`129dd77d` and `03b10183` are independent of the retained draw-source cutover.
|
||
|
||
## 2. H-a — retained UI, live attachments, diagnostics, and frame scratch
|
||
|
||
### H-a1 — cached shaped text — COMPLETE
|
||
|
||
1. Add a small retained text-layout cache keyed by source revision/value plus
|
||
width, padding, color, and font identity.
|
||
2. Convert appraisal item, inscription, spell, creature, character-info, and
|
||
active-effect detail providers so expensive report construction and
|
||
wrapping occur only after source or layout changes.
|
||
3. Preserve `UiText.LinesProvider` as the rendering seam. Dynamic one-line
|
||
widgets remain dynamic; this change is limited to report/wrapped content.
|
||
4. Ensure selection, appraisal response, component count, enchantment,
|
||
character-property, font, and resize changes invalidate the right cache.
|
||
5. Add tests proving stable draws return the same line collection while source
|
||
and geometry changes rebuild it.
|
||
|
||
Gate: the existing appraisal/character/effect behavior tests remain unchanged,
|
||
and repeated stable provider polls allocate no report/wrap objects.
|
||
|
||
Landed evidence:
|
||
[`../research/2026-07-25-slice-h-a1-ui-text-cache.md`](../research/2026-07-25-slice-h-a1-ui-text-cache.md).
|
||
|
||
### H-a2 — visible cooldown participants — COMPLETE
|
||
|
||
1. Keep the shared retail heartbeat and one cooldown result per represented
|
||
item.
|
||
2. Index mounted `UiItemList` participants once at bind time.
|
||
3. At heartbeat, visit only lists whose complete ancestor chain is visible.
|
||
Hidden panels keep no stale visual state: their slots query zero while
|
||
hidden and are refreshed on the first visible heartbeat.
|
||
4. Keep future-slot support and shared-group behavior.
|
||
|
||
Gate: hidden inventory, equipment, external-container, vendor, and spell-bar
|
||
lists are not scanned; reopening immediately displays the authoritative
|
||
cooldown step.
|
||
|
||
Landed evidence:
|
||
[`../research/2026-07-25-slice-h-a2-cooldown-scope.md`](../research/2026-07-25-slice-h-a2-cooldown-scope.md).
|
||
|
||
### H-a3 — equipped-child transition work — COMPLETE
|
||
|
||
1. Preserve both frame ordering points: pre-network presentation and
|
||
post-network spatial reconciliation have different authority boundaries.
|
||
2. Split transition retry from pose recomposition.
|
||
3. Run the complete parent-first pose walk once after animation.
|
||
4. In the post-network phase, recompose only attachments dirtied by accepted
|
||
root/relation/appearance changes.
|
||
5. Replace mutation-safe dictionary `ToArray` snapshots with retained key
|
||
scratch buffers. Callback reentrancy still observes the same transition
|
||
generation checks.
|
||
|
||
Gate: equip, unparent, reparent, pose loss, rollback, delete, GUID reuse, and
|
||
subtree-withdrawal suites preserve exact event and resource counts.
|
||
|
||
Landed evidence:
|
||
[`../research/2026-07-25-slice-h-a3-attached-pose-reconcile.md`](../research/2026-07-25-slice-h-a3-attached-pose-reconcile.md).
|
||
|
||
### H-a4 — diagnostics and frame scratch — COMPLETE
|
||
|
||
1. Reuse one synchronous `RetailPViewFrameInput` owned by
|
||
`WorldSceneRenderer`; reset every field before each draw.
|
||
2. Expose stable borrowed landblock entry/bounds views instead of creating
|
||
iterator state in each frame.
|
||
3. Consumer-gate optional shadow enumeration. Preserve landblock visibility
|
||
counting because the normal title and lifecycle checkpoints are active
|
||
consumers of `lb V/T`; neutralizing it would be a visible/automation
|
||
behavior change.
|
||
4. Do not rework `InteriorEntityPartition` while the G4 referee remains.
|
||
Issue #241 closes with G5 old-route deletion, not by editing the fallback.
|
||
5. Profile capped and uncapped production paths and retain evidence.
|
||
|
||
Gate: identical framebuffer/scene digest, no per-frame PView input allocation,
|
||
no iterator allocation for stable landblock views, and no shadow traversal
|
||
with all optional consumers disabled.
|
||
|
||
Landed evidence:
|
||
[`../research/2026-07-25-slice-h-a4-frame-scratch.md`](../research/2026-07-25-slice-h-a4-frame-scratch.md).
|
||
|
||
## 3. H-b — exact light top-k — COMPLETE
|
||
|
||
Retail anchors:
|
||
|
||
- `CEnvCell::add_dynamic_lights` at `0x0052D410`
|
||
- `Render::insert_light` at `0x0054D1B0`
|
||
- `Render::add_dynamic_light` at `0x0054D420`
|
||
- global caps at `0x0081EC94` / `0x0081EC98`
|
||
|
||
Execution:
|
||
|
||
1. Preserve the resident `_all` registry and existing visible-cell filter.
|
||
2. Preserve dynamics-first ordering and squared distance from the player.
|
||
3. Replace only the over-cap complete sort with a bounded exact top-k
|
||
selection.
|
||
4. Define tie-breaking from the existing comparator so the selected set and
|
||
final submission order are identical, including equal-distance fixtures.
|
||
5. Differential-test randomized candidate sets and the captured 463-light Town
|
||
Network fixture against the old full-sort oracle.
|
||
6. Run the fixed-camera screenshot comparison and connected light gate.
|
||
|
||
Gate: identical selected IDs and submission order for every fixture, identical
|
||
Town Network screenshot, reduced overflow CPU/allocation, and AP-85 retired
|
||
only after the visual evidence passes.
|
||
|
||
Landed evidence:
|
||
[`../research/2026-07-25-slice-h-b-light-top-k-report.md`](../research/2026-07-25-slice-h-b-light-top-k-report.md).
|
||
The deterministic differential fixtures preserve exact accepted output; the
|
||
463-light diagnostic microbenchmark reduced selection CPU time by 29.1% with
|
||
zero warmed allocations. AP-85 remains open because its retail dual-pool
|
||
behavior is outside this performance-only unit.
|
||
|
||
## 4. H-c — ordered, allocation-conscious network I/O
|
||
|
||
H-c is executed as three independently reversible units:
|
||
|
||
1. **H-c1 — pooled receive owner — COMPLETE.** One cancellable async socket
|
||
receive, a retained full-size edge buffer, right-sized pooled FIFO
|
||
datagrams, unchanged blocking handshake cadence, and direct span sends.
|
||
Evidence:
|
||
[`../research/2026-07-25-slice-h-c1-pooled-receive-owner.md`](../research/2026-07-25-slice-h-c1-pooled-receive-owner.md).
|
||
2. **H-c2 — borrowed decode — COMPLETE.** Parse and verify headers, optional
|
||
fields, and fragments as borrowed views. Copy only multi-fragment state
|
||
that must survive the current datagram. Evidence:
|
||
[`../research/2026-07-25-slice-h-c2-borrowed-packet-decode.md`](../research/2026-07-25-slice-h-c2-borrowed-packet-decode.md).
|
||
3. **H-c3 — direct outbound framing — COMPLETE.** Write packet and fragment
|
||
framing into caller storage and remove intermediate payload arrays.
|
||
Evidence:
|
||
[`../research/2026-07-25-slice-h-c3-direct-outbound-framing.md`](../research/2026-07-25-slice-h-c3-direct-outbound-framing.md).
|
||
|
||
Retail/transport invariants:
|
||
|
||
- one outstanding receive;
|
||
- kernel datagram arrival order remains inbound queue order;
|
||
- one acknowledgement decision per accepted packet;
|
||
- `LinkStatusHolder::OnHeartbeat` at `0x004113D0` remains at the same
|
||
last-heard point;
|
||
- `PumpOnce` handshake pacing remains unchanged;
|
||
- fragmented message assembly and sequence gates remain authoritative.
|
||
|
||
Execution:
|
||
|
||
1. Capture allocation and ordering baselines for login, idle, motion, portal,
|
||
appraisal, container, and combat traffic.
|
||
2. Introduce a single cancellable socket receive owner using reusable/pool
|
||
storage.
|
||
3. Decode packet headers and fragments from spans/borrowed storage.
|
||
4. Copy only payloads whose lifetime crosses the receive/dispatch boundary;
|
||
pooled receive memory is never returned while referenced.
|
||
5. Replace outbound temporary arrays with span/list segment writes where the
|
||
socket API permits.
|
||
6. Prove cancellation, remote close, malformed packet, receive fault, fragment
|
||
reassembly, queue backpressure, and reconnect cleanup.
|
||
7. Run connected lifecycle, reconnect, portal, interaction, and soak gates.
|
||
|
||
Gate: identical decoded event/ack traces, no receive-thread death, no pooled
|
||
buffer lifetime violation, and materially reduced bytes per packet.
|
||
|
||
## 5. Commit and evidence order
|
||
|
||
Each numbered unit lands as a bisectable commit after focused tests, App
|
||
Release, complete Release, and documentation reconciliation:
|
||
|
||
1. H-a1 cached shaped text.
|
||
2. H-a2 cooldown visibility.
|
||
3. H-a3 attachment retry/recomposition.
|
||
4. H-a4 diagnostics/frame scratch.
|
||
5. H-b exact light top-k.
|
||
6. H-c network receive/decode/send allocations.
|
||
7. Slice-H connected measurements and closeout.
|
||
|
||
Raw captures stay under `.test-out/` or `logs/`; reviewed summaries and compact
|
||
fixtures are committed under `docs/research/` or the matching test project.
|
||
|
||
## 6. Deferred boundaries
|
||
|
||
- Physics `Transition` pooling (#237) remains Slice I and requires reset-
|
||
completeness/identity tests first.
|
||
- G5 old-route/referee deletion waits for the user's G4 visual acceptance.
|
||
- Static publication indexing (#242) is not silently folded into H; it is
|
||
measured after H-a and scheduled only if still material.
|
||
- Slices I–L start only after Slice H is measured and documented, but no
|
||
additional authorization is required.
|