Skip to content

Perf/optimization - #1

Merged
MrGreenCheezz merged 32 commits into
mainfrom
perf/optimization
Sep 29, 2026
Merged

MrGreenCheezz merged 32 commits into
mainfrom
perf/optimization

Conversation

@MrGreenCheezz

Copy link
Copy Markdown
Owner

No description provided.

MrGreenCheezz and others added 30 commits September 4, 2026 15:43
Integrate the accumulated browser UI, FrameXML/GlueXML, world rendering,
asset metadata, map and addon work. Add native mail, profession and socketing
windows, improve bags, portraits and nameplates, and preserve server-driven
state for item and crafting actions.

Batch the patched talent toggle so N and the microbutton publish the completed
window once instead of synchronizing the DOM after each Lua setter. Honor
tooltip line wrapping and colors and constrain the resulting tooltip to its
viewport. Show legacy gems with missing dataset properties and offer explicit
single-gem stack splitting without inventing properties or consuming items
optimistically.

Keep local browser profiles and generated map caches out of source control;
enable CI for master. TypeScript and Vite builds pass, as do the targeted UI
regressions and all nine TSWoW addon scenarios. The full local suite has
3176 passed, 27 failed and 19 skipped tests; remaining failures and the orphan
gem-1754 data issue are documented in UI_REPAIRS.ru.md.
Step 0: add harness only; shipping renderer algorithms unchanged.
Before: no npm run bench, no comparable automated baseline.
After (1280x720, DPR1, seed12340, 20 seconds, headless Chrome / RTX5070Ti):
movement: 138.41 FPS, 1% low 33.61, p99 20.10 ms, >30ms 3
crowd-10: 613.36 FPS, 1% low 327.74, p99 2.70 ms, >30ms 0
crowd-50: 101.58 FPS, 1% low 78.01, p99 12.40 ms, >30ms 0
crowd-200: 25.07 FPS, 1% low 18.73, p99 45.90 ms, >30ms 493

Validation: strict tsc --noEmit; 2 metric tests; all four real-asset browser scenarios; key screenshots reviewed.
Baseline measures the pre-existing dirty working tree; unrelated user changes are preserved and excluded from this commit.
Full result: bench/results/2026-09-20T09-43-31-511Z.json
Step 1: diagnostics only, shipping renderer unchanged.
Before (ordinary baseline): movement 138.41 FPS, p99 20.10 ms, >30ms 3;
crowd-200 25.07 FPS, CPU 39.44 ms, GPU 5.04 ms.
After (instrumented trace, not comparable performance): movement 129.96 FPS,
>30ms 2; crowd-200 33.13 FPS. Same renderer source SHA-256.

Long callbacks 133.2/83.0 ms correlate with +2 shader programs and blocking
GetProgramiv calls of 78.626/34.104 ms. Bone matrix traversal/multiplication
account for 54.12% self CPU profile. Ranked hypotheses and expected effects
recorded in PERF_STATUS.md; no speculative rendering changes applied.
Validation: 5/5 key screenshots are pixel-exact against baseline;
read-only trace/CPU-profile analysis and real-rig redundancy probe.
Before -> after, fixed 20s / 1280x720 / seed 12340:
movement: 138.41 -> 96.60 FPS; p99 20.10 -> 30.60 ms; >30ms 3 -> 24.
crowd-10: 613.36 -> 680.47 FPS; crowd-50: 101.58 -> 143.08 FPS.
crowd-200: 25.07 -> 37.71 FPS (+50.41%); CPU 39.44 -> 26.23 ms.
All 9 fixed views match baseline exactly; strict types and 71 focused tests pass.
Result: bench/results/2026-09-20T10-04-47-785Z.json.
Reject and revert because movement regressed; do not retry this candidate.
Only the task's integration delta is staged; pre-existing working changes remain unstaged.
This reverts commit ec88233.

Measured before -> rejected candidate:
movement 138.41 -> 96.60 FPS; >30ms 3 -> 24; p99 20.10 -> 30.60 ms.
crowd-200 25.07 -> 37.71 FPS, but route regression fails acceptance.
9/9 images unchanged. Restore exact pre-candidate rendering source; no second
benchmark or tuning attempt. Keep the measurements and rejection in PERF_STATUS.md.
Before -> after, fixed benchmark configuration:
movement 138.41 -> 82.82 FPS; p99 20.10 -> 31.80 ms; >30ms 3 -> 32.
crowd-10 613.36 -> 927.20 FPS; crowd-50 101.58 -> 143.32 FPS.
crowd-200 25.07 -> 25.34 FPS (+1.08%); CPU 39.44 -> 39.02 ms.
Under 5% improvement and movement regression: revert, do not retry.
9/9 fixed screenshots unchanged; strict types and 60 focused tests pass.
Result: bench/results/2026-09-20T10-12-53-150Z.json.
This reverts commit 390e5c6.

Before -> candidate: crowd-200 25.07 -> 25.34 FPS (<5%);
movement 138.41 -> 82.82 FPS, >30ms 3 -> 32.
Restore exact pre-candidate source and retain rejected measurements.
No repeated candidate benchmark or tuning attempt.
Identical source SHA before and after: 8135c443413b273e33d846251dcebac5e265351d2f5138058ea3533a6fad0759.
Baseline -> unchanged control, 20 seconds per scenario:
movement 138.41 -> 101.44 FPS; >30ms 3 -> 33; p99 20.10 -> 31.40 ms.
crowd-10 613.36 -> 541.08 FPS; crowd-50 101.58 -> 97.44 FPS.
crowd-200 25.07 -> 33.54 FPS; p99 45.90 -> 49.10 ms.
9/9 images identical. No renderer change; fix measurement repeatability before
further acceptance decisions. Rejected candidates stay reverted.
Result: bench/results/2026-09-20T10-16-49-498Z.json.
Windows CPU Set API reports logical 0-15 EfficiencyClass 1, 16-19 class 0.
Set and verify only benchmark Chrome process affinity before warmup.
Record topology/selection and include selection in config hash.

Unconstrained control -> P-core baseline (NOT a renderer speedup):
movement 101.44 -> 133.52 FPS; >30ms 33 -> 4; p99 31.40 -> 22.70 ms.
crowd-10 541.08 -> 1064.13 FPS; crowd-50 97.44 -> 125.37 FPS.
crowd-200 33.54 -> 32.57 FPS. Exact same renderer source SHA; 9/9 views identical.
Result: bench/results/2026-09-20T10-22-26-361Z.json.
Preserve original baseline; next control will check remaining variation.
Step 5 -> unchanged control:
movement 133.52 -> 131.58 FPS (-1.45%); p99 22.70 -> 24.50 ms; >30ms 4 -> 6.
crowd-10 1064.13 -> 1047.27 FPS; crowd-50 125.37 -> 129.29 FPS.
crowd-200 32.57 -> 31.93 FPS (-1.96%); CPU 30.36 -> 31.00 ms.
All four average-FPS deltas <5%; same source hash and 9/9 identical views.
Keep first fixed-profile baseline, never select the fastest run.
Result: bench/results/2026-09-20T10-27-28-963Z.json.
The pending shader registration candidate measured movement max CPU
123.8 -> 80.5 ms, but a concurrent game invalidated the crowd comparison:
crowd-200 32.57 -> 16.91 FPS while its code path was unchanged.
Do not accept or reject that candidate using these contested timings.

Before: resource-valid runs could report comparable=true under heavy host load.
After: independent preflight measured 8.85 externally occupied CPU cores;
the run stopped before samples with valid=false/comparable=false.
Result: bench/results/2026-09-20T10-48-02-039Z.json.

Collect load outside timed frames and exclude the runner and its Chrome children.
Never change unrelated processes or choose runs by FPS. Also retain all prepared
shader keys in diagnostic traces. No renderer optimization is committed here.
Before: 2.09s denominator excluded the slow process enumeration and reported
39.73 occupied cores on a 20-logical-CPU machine (invalid load estimate).
After: per-process monotonic intervals include enumeration; observed 9.86
external cores, including 8.61 for the game over its 10.68s sample interval.
The complete probe took 14.56s. The host still fails the 2-core load guard.
This corrects benchmark admission only; no measured render frames change.
Step 7 remains pending a comparable full run, with its render delta unstaged.
PERF_STATUS.md records the correction and supersedes old load magnitudes.
Comparable baseline: movement 133.52 FPS, 4 frames over 30ms, max CPU 123.8ms;
crowd-200 32.57 FPS. These remain the last accepted comparison values.
The candidate run observed movement 131.60 FPS / 5 long frames / max CPU 80.5ms,
and crowd-200 16.91 FPS, but external contention invalidates this comparison.
All nine screenshots match; 22 focused tests and strict types pass.
Do not claim these timings as an accepted before/after improvement.

After the host-load clock correction, the full command rejected the run before
measurement: 9.05 external CPU cores, zero measured scenarios, valid=false.
Result: bench/results/2026-09-20T11-14-30-428Z.json.
A 15-minute observation did not obtain a quiet host. No foreign process changed.

Step 7's two-line render candidate remains unstaged and unaccepted. Isolated
C3/C4/depth-context probes have correctness evidence but no FPS claim; details,
artifacts, restrictions and the exact resume command are in PERF_STATUS.md.
Step 8. Before: no real-world crowd case; only standalone 10/50/200 rigs.
After: world-crowd-50 and world-crowd-200 preserve the 64-unit admission limit.
Diagnostic reference 2026-09-20T12-43-07-995Z: 50 input -> 24.19 FPS,
CPU 40.58 ms, GPU 6.53 ms; 200 input -> 28.73 FPS, CPU 34.18 ms,
GPU 5.65 ms. Additional bone world updates: 13180 / 16848 per frame.
External load 9.46 / 5.22 CPU cores: valid=false/comparable=false.
These are diagnostic measurements, not an accepted performance improvement.

Keep ordinary load rejection and the four original scenarios unchanged.
Fix only the new scenario's admission clock and capture opposite viewpoints.
Validation: strict tsc, 2 metric tests, scene screenshots inspected.
Step 9, hypothesis C5. Preserve eager API behavior by default; only world
unit/mount posing defers the final hierarchy traversal to normal rendering.
Spell attachment queries explicitly refresh their ancestor chain.

Before -> after, diagnostic operation counts per frame:
50 rigs: updateWorldMatrix 13180.36 -> 1780.38; regular updates 11502 unchanged.
64 active / 200 input: 16848.35 -> 2254.97; regular updates 14694 unchanged.
Total bone updates fall 46.19% / 46.27%. This is NOT an FPS gain claim.
Diagnostic world FPS: 24.19 -> 33.33 and 28.73 -> 21.89, under varying
external load. Ordinary full benchmark 2026-09-20T12-49-22-784Z rejected
8.05 external CPU cores before timing. Performance acceptance is pending;
keep the 5% / regression revert rule for a comparable run.

Validation: strict tsc and 81 source tests; 9 original screenshots identical.
Fresh world scenes: 3/4 exact, fourth differs at 11 pixels by at most 1/255.
World screenshots now use fresh prepared scenes; an unchanged-source control
reproduced background variation after timed streaming. Timing is unchanged.

Preserve pre-existing user edits and the separate uncommitted F1a candidate.
See PERF_STATUS.md for JSON identifiers, evidence and remaining criteria.
…ding)"

Reverts the rendering optimization from 444bcb5; retains the independent
fresh-scene screenshot policy and the full measurement journal.

Before/after: user reports approximately 20 ->20 FPS in the same dense NPC
scene, no noticeable benefit. This is a user observation, not a controlled
measurement. No comparable >=5% FPS improvement was established.
The 46% reduction in bone traversal counts did not prove game speedup.

Baseline visuals had no visible change; this revert restores the earlier
render behavior. User's pre-existing source changes are preserved.

Validation: strict TypeScript check and 64 source tests passed.
The existing HumanMale harness is not representative of the recorded tavern
crowd: 488 vs 1160 median draws, 1280x720 vs 2560x1279, and 12 vs 24 shadow
casters. Keep the historical live capture explicitly separate from current
benchmarks and add capture-only world CPU attribution to the existing JSON.

Before: world submission was one aggregate (~31.36 ms in selected historical
slow live callbacks). After: seven exclusive intervals plus actual draw counts,
sampled at most every 500 ms. The validation fixture recorded 39 world samples
with zero accounting error; 21.44 ms mean splits into matrices 8.35, main
skeletons 4.96, main draws 4.15, shadow skeletons 1.07, shadow draws 0.45,
shadow other 0.66 and other 1.81 ms. These are different workloads, not a speedup.

FPS before in the historical live capture: 19.04. FPS after in the same live
scene: not yet captured; no FPS improvement claimed. The ordinary full bench
was rejected at 7.13 external CPU cores. Diagnostic-only FPS: movement 61.33,
10/50/200 rigs 333.60/68.34/18.83, world-200 25.85 (not comparable).

Validation: strict TypeScript, 20 source tests, Vite build; 11/11 benchmark PNGs
exactly match the proper baselines. Separate WebGL QA: 18 poses of 64 skinned
objects, identical pixels, palettes and draw counts; hooks always restored.
Disabled capture installs no hooks. User working changes remain unstaged.
Analyze the supplied 60-second capture with a reusable, data-only summary.
Main draws consume 14.35 of 30.53 ms sampled world CPU, with 1333 main
calls (639 skinned), 64 admitted units and 39 effects. Rank this path
ahead of further bone micro-optimizations; investigate additive double passes.

Before/after: rendering code unchanged; this step makes no FPS claim.
Current live result: 20.44 FPS, 8.25 1% low, RAF p99 111.10 ms,
1226/1226 intervals above 30 ms, full CPU average 46.66 ms.
The previous live result (19.04 FPS) has a different viewport and draw
count and is not an A/B baseline. World phase sum error is zero.

Validation: node --check, replayed analysis, git diff --check.
External load remains 7.98 CPU cores; no comparable optimization run
or production change was accepted. User changes remain unstaged.
Only MeshBasic One/One and SrcAlpha/One additive modes with AddEquation
and no separate alpha factors use forceSinglePass. Both faces remain
visible; ordered alpha, blend-add, lit materials and subtractive equations
keep their existing passes. Particle/ribbon and spell meshes use the same
material policy. Preserve all pre-existing user edits.

Before/after, isolated real effects (diagnostic, not full-world FPS):
  Draw calls: 644 -> 368 (-42.86%).
  Program parameter builds per frame: 600 -> 48 (-92%).
  CPU submission: 10.13 -> 3.88 ms; p50 9.90 -> 3.80 ms.
  36/36 views exactly identical; negative control changes >=11697 pixels.
  Source policy matches the tested prototype.

Reproduction: npm run bench -- --additive-probe.
Source result: 2026-09-20T14-32-18-371Z; compact reference is tracked.
Movement, crowd-10/50/200 and world-crowd-200 all ran in diagnostic mode:
11/11 baseline images match exactly, no page/resource errors or cache misses.
Strict types and Vite build pass; source tests: 101 pass, 9 legacy skips.

Performance acceptance PENDING: ordinary before/after runs were rejected
before measurement at 8.23/8.04 external CPU cores. Diagnostic FPS cannot
accept or reject this change. Plain crowd has no affected additive effects;
its draw counts stay 40/200/800. Live 60 FPS and movement zero hitches remain
unverified. Keep F1a and all other changes constant for the later A/B.
docs/ was not tracked. It holds WORK_PLAN.ru.md (247 items), IMPLEMENTATION_PLAN.ru.md with
the per-item specs under docs/implementation/ (lines A1-A10 and P), OPTIMIZATION_CATALOG.ru.md,
the parity audit, matrices and hand-offs, and the reports that used to sit in the repository
root (PERF_STATUS.md and others move here). AGENTS.md is added.

README.ru.md, CONTRIBUTING.md, SECURITY.md, the PR template and the per-directory READMEs are
deleted as in the working tree. NOTICE.md and tools/dbd/README.md are deleted here too and
restored by the commit that follows the series.

Part 1/9 of a restore point for the work left uncommitted since 3b09070 (2026-09-20),
committed by area before the work planned in docs/IMPLEMENTATION_PLAN.ru.md starts.
Intermediate commits of the series are not individually buildable; the tree after part 9
is the working tree as it was on 2026-09-29.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Part 2/9 of a restore point for the work left uncommitted since 3b09070 (2026-09-20),
committed by area before the work planned in docs/IMPLEMENTATION_PLAN.ru.md starts.
Intermediate commits of the series are not individually buildable; the tree after part 9
is the working tree as it was on 2026-09-29.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Part 3/9 of a restore point for the work left uncommitted since 3b09070 (2026-09-20),
committed by area before the work planned in docs/IMPLEMENTATION_PLAN.ru.md starts.
Intermediate commits of the series are not individually buildable; the tree after part 9
is the working tree as it was on 2026-09-29.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Part 4/9 of a restore point for the work left uncommitted since 3b09070 (2026-09-20),
committed by area before the work planned in docs/IMPLEMENTATION_PLAN.ru.md starts.
Intermediate commits of the series are not individually buildable; the tree after part 9
is the working tree as it was on 2026-09-29.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Part 5/9 of a restore point for the work left uncommitted since 3b09070 (2026-09-20),
committed by area before the work planned in docs/IMPLEMENTATION_PLAN.ru.md starts.
Intermediate commits of the series are not individually buildable; the tree after part 9
is the working tree as it was on 2026-09-29.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
public/textures/water/ carries four CC-BY 3.0 normal maps from OpenGameArt with their
LICENSE.md.

Part 6/9 of a restore point for the work left uncommitted since 3b09070 (2026-09-20),
committed by area before the work planned in docs/IMPLEMENTATION_PLAN.ru.md starts.
Intermediate commits of the series are not individually buildable; the tree after part 9
is the working tree as it was on 2026-09-29.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Part 7/9 of a restore point for the work left uncommitted since 3b09070 (2026-09-20),
committed by area before the work planned in docs/IMPLEMENTATION_PLAN.ru.md starts.
Intermediate commits of the series are not individually buildable; the tree after part 9
is the working tree as it was on 2026-09-29.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Part 8/9 of a restore point for the work left uncommitted since 3b09070 (2026-09-20),
committed by area before the work planned in docs/IMPLEMENTATION_PLAN.ru.md starts.
Intermediate commits of the series are not individually buildable; the tree after part 9
is the working tree as it was on 2026-09-29.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…nfig

Part 9/9 of a restore point for the work left uncommitted since 3b09070 (2026-09-20),
committed by area before the work planned in docs/IMPLEMENTATION_PLAN.ru.md starts.
Intermediate commits of the series are not individually buildable; the tree after part 9
is the working tree as it was on 2026-09-29.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Both files were deleted in the working tree, but package.json ("SEE LICENSE IN NOTICE.md"),
LICENSE and the LOCAL_ONLY text in vite.config.mjs point at NOTICE.md, and the CC BY-SA 4.0
definitions under tools/dbd/ stay tracked, so their attribution has to stay with them
(src/generated/dbcLayouts.ts and tools/generate-dbc-layouts.mjs link to it). Restored verbatim
from 3b09070. If the deletion was intended, revert this commit and fix the references instead
(WORK_PLAN 0.2 and 13.03).

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…ros, server questions

Closed in docs/WORK_PLAN.ru.md. Each item has a test that failed first, a mutation check and two reviews:
- 0.3: tests run through tools/run-tests.mjs, with a memory guard inside each test process.
- 1.02: world login over plain http without Web Crypto (HMAC-SHA1 fallback).
- 1.03: the gateway survives malformed upgrade requests (UpgradeGuard, ProcessGuard, orderly shutdown).
- 1.04: keys 1-= follow the bonus bar.
- 1.31: auction quality filter and guild-rank gold limit.
- 1.05, 3.20: HasFullControl, and issecure() scoped to the unit popup menu.
- 1.18, 1.20, 1.21, 1.25-1.27, 1.30: world protocol - miss reasons, cooldown holds, cast failure
  texts, GetNetStats bandwidth.
- 2.03, 2.04, 2.09: innkeeper, talent wipe and instance lock questions (ConfirmationProtocol).
- 3.10: macro conditionals shared by the stock UI and native, checked against Wow.exe.
- 3.28: bag gate.
- 5.31: movement resumes after a battleground ends.
- 9.01: TSWoW addon dialogs; world dialogs are modeless, as in the original.

Implemented but not closed (docs/parity/handoff-2026-09-29.ru.md, section 3):
- area triggers with the catalog routes (2.01, A3-0);
- skinning and gathering (2.06);
- glue error texts, queue and rename (10.06, 10.05, 2.07);
- runes and zone text files (3.03, 3.05, 3.09);
- MEM-1 build target (12.03) and bench/live-periods.mjs (12.01).

tsc --noEmit: 0 errors. The full test suite has not been run on this state.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
MrGreenCheezz and others added 2 commits September 29, 2026 16:05
docs/parity/handoff-2026-09-29.ru.md holds the hand-off:
- where work stopped;
- slices that are implemented but not closed;
- facts checked against Wow.exe;
- the owner's answers: recordings at 144 Hz, 4.16b migrates players' buttons, and TSWoW module
  compatibility, which adds plan item 9.09;
- the order to resume in.

Also updated:
- plan marks and the execution log;
- the perf numbers: the hidden callback cost H is 14.4 %;
- the Safari 16.4+ floor for the ES2022 build;
- the plan item count, which is 253.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Before the first push, the owner's public IP was removed from the unpushed commits: one line of
docs/implementation/line-A6.ru.md. That rewrite changed the hashes of the rollback point, which is
now 986a3da...6a0dc55 plus 78be281.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
@MrGreenCheezz
MrGreenCheezz merged commit 6b376b2 into main Sep 29, 2026
0 of 2 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant