Decode headers, optional fields, fragments, and single-fragment messages directly over pooled datagrams. Copy only fragment state that crosses a datagram lifetime, preserve synchronous dispatch and ACK ordering, and lock the path to the owned decoder with differential and zero-allocation tests.
204 lines
9.3 KiB
Markdown
204 lines
9.3 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 — PENDING.** Write packet and fragment
|
||
framing into caller storage and remove intermediate payload arrays.
|
||
|
||
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.
|