chore(bench): add client bench harness and Phase 2 handoff

The client now boots cleanly on the bench machine (the CAC spawn-key
crash was fixed in 8e8483d). Add the harness used to drive bench scenes
and capture frametimes, the bench-world generation workflow, and a
self-contained handoff brief. All files live under analysis/ (packwizignored),
so nothing player-facing changes.

- harness/rcon.py: minimal RCON client for the temp worldgen server
- harness/run_scene.py: apply variant -> launch Prism under MangoHud ->
  xdotool scene commands -> p50/p95/p99/1%-low from the CSV
- HANDOFF.md: state, gotchas, next steps
- build.py: disable DH autoUpdater for bench variants (suppress modal)
This commit is contained in:
Onion Agent committed 2026-10-14 23:16:31 -04:00
1 parent 8e8483d072
commit e5e369a693
7 files changed
+611 -1

No files matched your search

+109
View File
@@ -0,0 +1,109 @@
# Onion MC client-perf — handoff (2026-10-15)
Self-contained brief for the next agent. Read `.pi/journal.md` (last sections) and
`BENCH-MATRIX.md` too, but this file is the live state on this machine.
## Goal
Finish the **Phase 2 client-performance loop**: measure the staged configs, decide by
`BENCH-MATRIX.md`'s rules, write winners into `proposed-configs/build.py`
(`DEFAULT` / `DECK` / `HIGH`), `build.py --ship`, `packwiz refresh`, commit (Conventional
Commits) and push. Pushes go live to players on their next Prism launch.
## Repo / pack state
- Pack: **217 mods**, MC 1.21.1, NeoForge 21.1.251. Git `HEAD == origin/main == 8e8483d`.
- `8e8483d` fixed the one real boot blocker: the Critters & Companions partial spawn config
used camelCase keys (`biomeSpec`) but YACL serialises with
`FieldNamingPolicy.LOWER_CASE_WITH_UNDERSCORES`; every entry loaded `biomeSpec = null` and
`CACSpawnConfig$SpawnEntry.isTag()` NPE'd in `FMLCommonSetupEvent`, leaving the client in a
"broken mod state" (119 refused events). Fixed to snake_case; **already pushed**.
- The Alex's Mobs (TOML) and Fowl Play (YACL camelCase) spawn files are correct and were
verified applied in-game. Do not commit the mod/server **full re-saves** of
`config/*` (the running server rewrites them): always `git checkout -- config/` before
staging.
- Nothing was shipped this session. Shipped `config/defaultoptions/**` is unchanged from
`a01bc3b`. `build.py` was only patched in the **BENCH** layer (below); the tiers are
untouched.
## Boot check (client, this machine) — essentially PASS
Reached main menu cleanly. `Sound engine started` 01:26:53; ModernFix "Game took 29.3 s to
start"; blocks atlas `4096x4096x2`; Default Options correctly seeded `options.txt`
(renderDistance 8, maxFps 120, vsync true). No missing deps, no mixin apply failures, no
`ftbteams` refs, no fishermans-haven biome errors, no YACL "Failed to deserialize". 22 ERROR
lines, all benign (pride access-transformer, Controlify @Shadow, FTB Library legacy
textures, 4 GeckoLib molang parses, icys-better-horses pack path, Xaero version expiry,
Veil failing to recompile 2 lodestone `nineslice` shaders).
**Open boot-adjacent issue (not yet fixed):** an intermittent crash on **world load**:
```
java.io.FileNotFoundException: minecraft:shaders/core/particle.json
at com.corosus.watut.ShaderInstanceBlur.<init>(ShaderInstanceBlur.java:27)
at GameRenderer.handler$jhl000$watut$onLoadShaders(...)
```
First world load succeeded and measured; the next crashed during "Rendering overlay". WATUT
is a LEVERS §5 removal candidate but the owner says **remove no mods** — look for a WATUT
config/patch or a reliable retry. Confirm whether real players hit it before shipping.
## Tooling installed on this machine (all user-local, no root)
- **Prism Launcher 11.0.3** (`/usr/bin/prismlauncher`). Data root `~/onion-bench/prism`,
instance id **`OnionBench`**, game dir
`~/onion-bench/prism/instances/OnionBench/.minecraft` (214 jars). A valid Microsoft
account is in `~/onion-bench/prism/accounts.json` (device-code login, owner-approved).
- **MangoHud 0.8.4** extracted to `~/.local/mangohud`; wrapper **`~/.local/bin/mangohud-local`**
(exports `MANGOHUD_CONFIG`, `LD_PRELOAD` shim, `vblank_mode=0`). CSVs land in
`~/onion-bench/mangologs/`. The instance has `WrapperCommand=mangohud-local`.
- **Bench world**: `~/onion-bench/prism/instances/OnionBench/.minecraft/saves/onionbench`
(seed `onionbench`, creative, cheats). S2 Create floor (2304 kinetic BEs) and S3 mob pen
(30 villagers/15 cows/15 sheep/10 allays) were placed via RCON and verified. S4 airships
NOT built. Datapack lives in the world's `datapacks/onion-bench`.
- **Temp server** for worldgen: `~/onion-bench/server-bench` (symlinks repo `mods`/
`libraries`, copies `config`), port 25566 / RCON 25576, currently **stopped**.
- **Harness** (this is new, untracked, packwizignored): `analysis/client-perf/harness/`
- `rcon.py` — minimal RCON client.
- `run_scene.py` — applies a variant, launches Prism into the bench world under MangoHud,
drives scenes with xdotool chat, slices the CSV into p50/p95/p99/1%-low. Verified working
end-to-end once (C1/S1).
## Measurements so far — NOT decision-grade
One run: **C1 / S1** p50 16.72 ms, p99 17.24 ms, peak 17.60 ms, avg 59.8 FPS, 1% low 57.5,
n=1889. It was **vsync-locked at ~60 FPS** (tight 16.7 ms floor). `vblank_mode=0` was added
afterwards but the next launch crashed on world load, so uncapped data is not collected yet.
Treat all of this as pipeline validation only.
## Next steps (in order)
1. Resolve the WATUT world-load crash; re-run one C1/S1 and confirm FPS > 60 (vblank off).
2. Run the matrix in order, per `BENCH-MATRIX.md`: **B0** noise floor (C0/S1 ×3) → **B1**
baseline (C0, S1–S6) → **B2** composite (C1, and C1-deck/C1-high) → **B3** DH radius
(`dh-r256`, `dh-r192`, `C1`, `dh-r64`, `dh-off` on S1/S5) → **B4** heap/GC (use `jcmd`/
`jstat`, or spark, at 5/6 G and J0–J3) → **B6** ModernFix → **B7** shaders → **B8**
entities → **B9** Flywheel → **B10** SPR → **B11** Sodium/blend → **B12a/b** ablation and
trials → **B13** spark profile → **B14** spawn counts.
3. Write winners into `build.py`, `python3 build.py --ship`, `~/go/bin/packwiz refresh`,
commit. Ship `config/modernfix-mixins.properties` only if B6 passes (see SHIP comment).
4. Update `PLAYER-TUNING.md` (tiers, heap/GC, shader profiles), `LEVERS.md`,
`BENCH-MATRIX.md`, and append a journal section.
## Fleet note
P0 (Steam Deck), P1 (7700K/1060) and P2 (6700K/1080 Ti) are **not reachable** from this box
(no routes / no SSH targets). Everything measured here is a **high-tier proxy** on a Ryzen 9
9900X + RX 7800 XT, 91 GB RAM. Label results as proxies; absolute FPS floors do not map to
tier decisions.
## Gotchas learned this session
- Prism 11 `--offline` fails a fresh instance with "Required libraries are missing"
(`EnsureOfflineLibraries`). Launch **online** once to download libs/assets; after that
offline works.
- `xdotool windowactivate --sync` **hangs** under kwin; use `windowactivate` + `windowfocus`.
- MangoHud needs `MANGOHUD_CONFIG` set explicitly and `LD_PRELOAD` **exported**.
- The owner's dedicated server runs from the repo root (`java @user_jvm_args.txt
@libraries/.../unix_args.txt`, port 25565). Never kill it; never touch `world/`. The temp
bench server used separate ports/paths and is stopped.
- `analysis/` is packwizignored (safe to commit); `config/` is server-rewritten (restore
before staging).