docs(performance): detail Slice H execution gates
This commit is contained in:
parent
51e184725f
commit
c0bec56dfe
2 changed files with 175 additions and 0 deletions
|
|
@ -883,6 +883,12 @@ proportional to resident content.
|
||||||
|
|
||||||
**Purpose:** Remove remaining work that scales with uncapped FPS.
|
**Purpose:** Remove remaining work that scales with uncapped FPS.
|
||||||
|
|
||||||
|
**Execution plan (active 2026-07-25):**
|
||||||
|
[`2026-07-25-modern-runtime-slice-h.md`](2026-07-25-modern-runtime-slice-h.md).
|
||||||
|
The plan separates H-a text/UI/attachment/frame work, H-b's exact light-set
|
||||||
|
optimization, and H-c's ordered network-I/O change into independently
|
||||||
|
revertible gates.
|
||||||
|
|
||||||
- Skip diagnostics with no consumer and reuse renderer visibility facts.
|
- Skip diagnostics with no consumer and reuse renderer visibility facts.
|
||||||
- Dirty-layout retained UI: apply anchors only after geometry changes.
|
- Dirty-layout retained UI: apply anchors only after geometry changes.
|
||||||
- Maintain an overlay-participant registry instead of a second full-tree walk.
|
- Maintain an overlay-participant registry instead of a second full-tree walk.
|
||||||
|
|
|
||||||
169
docs/plans/2026-07-25-modern-runtime-slice-h.md
Normal file
169
docs/plans/2026-07-25-modern-runtime-slice-h.md
Normal file
|
|
@ -0,0 +1,169 @@
|
||||||
|
# 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
|
||||||
|
|
||||||
|
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.
|
||||||
|
|
||||||
|
### H-a2 — visible cooldown participants
|
||||||
|
|
||||||
|
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.
|
||||||
|
|
||||||
|
### H-a3 — equipped-child transition work
|
||||||
|
|
||||||
|
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.
|
||||||
|
|
||||||
|
### H-a4 — diagnostics and frame scratch
|
||||||
|
|
||||||
|
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 diagnostic landblock visibility counting and shadow
|
||||||
|
enumeration. When no DebugVM/collision/probe consumer exists, publish a
|
||||||
|
neutral diagnostic outcome without scanning resident landblocks.
|
||||||
|
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,
|
||||||
|
and no diagnostic world traversal with all consumers disabled.
|
||||||
|
|
||||||
|
## 3. H-b — exact light top-k
|
||||||
|
|
||||||
|
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.
|
||||||
|
|
||||||
|
## 4. H-c — ordered, allocation-conscious network I/O
|
||||||
|
|
||||||
|
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.
|
||||||
Loading…
Add table
Add a link
Reference in a new issue