docs: client-perf analysis, bench harness and work journal

Everything the next agent needs to run the Phase 2 optimisation loop on a
machine that can launch the client:

- analysis/client-perf/: LEVERS (ranked levers + corrections), BENCH-MATRIX
  (world, scenes, config IDs, blocks B0-B14 with decision rules),
  PLAYER-TUNING, SPAWN-TUNING, research briefs, the jar scanner and its
  output, observed default configs, and proposed-configs/ (build.py
  generates tiers and bench variants and fails on unknown keys;
  apply_variant.py applies a variant and merges options.txt).
- analysis/client-perf/bench/onion-bench/: bench-world datapack (scene
  teleports, Create grid, mob pen, sound storm, 120 s teleport tour).
- analysis/audit/: the static recipe/dependency audit, including gen_fixes.py,
  which generates the shipped Paxi datapack and was never tracked.
- phase0/: per-machine measurement harness (Steam Deck, 7700K/1060,
  6700K/1080 Ti).
- .pi/journal.md: running work log; read it first.

All of it is packwizignored, so nothing here ships to players.
This commit is contained in:
logan committed 2026-10-14 18:15:32 -04:00
1 parent d80f85b3f6
commit 611a1a5952
102 files changed
+25853

No files matched your search

+249
View File
@@ -0,0 +1,249 @@
# Phase 0 — P0: Steam Deck
Setup and measurement procedure for the lowest-end test machine in the Onion MC client
tuning fleet.
---
## Profile
| | |
| --- | --- |
| CPU | AMD Zen 2, 4 cores / 8 threads, 2.4–3.5 GHz |
| GPU | AMD RDNA2 (Van Gogh), 8 CU, integrated |
| RAM | 16 GB LPDDR5, **shared with the GPU** |
| Display | 1280×800 — LCD is 60 Hz, OLED is 90 Hz |
| OS | SteamOS (Arch-based, read-only rootfs) |
| **Binding constraint** | GPU compute, memory bandwidth, shared memory pressure |
| **What this tier tests** | The floor. If the ladder holds here it holds anywhere. |
| **Expected DH answer** | Off, or the minimum viable preset |
### Determine your panel
The LCD panel is 60 Hz. **If this is an LCD Deck, targets of 120 and 144 are meaningless
on this machine** — it can only validate the 30 and 60 rows of the ladder. Record which
panel you have; it changes what this machine can prove.
---
## Shared measurement protocol
Applies to every machine in the fleet. Duplicated here so this document stands alone.
1. **Uncapped, vsync off** during measurement. Apply the FPS cap only *after* tuning.
With a cap or vsync active, every configuration "hits" the target and the ladder never
fires.
2. **Metric is p99 frametime and 1% low, not average FPS.**
3. **Discard 10–15 s of warmup** per scene — JIT, chunk load, initial GC.
4. **Settle after any render-distance or DH change.** Both trigger rebuilds; measuring
immediately measures the rebuild, not the steady state.
5. **Three runs per configuration, report the median and the spread.** A single run of
anything is noise.
6. **One variable per run.** If you change two things, you have learned nothing.
7. Guardrails: if the FPS limiter is active, the governor moved, or RAM headroom changed
materially, the run is invalid — discard rather than interpret.
---
## Step 1 — Preconditions
- [ ] Plugged into the charger. Battery vs. AC changes APU power behaviour.
- [ ] Switch to **Desktop Mode**. All measurement happens here, launching Prism from a
terminal. Gaming Mode routes the overlay through MangoApp, which cannot log.
- [ ] Instance installed on **internal storage**, not a microSD card. Card I/O affects
chunk loading and DH LOD reads.
- [ ] Confirm panel refresh rate and record it.
## Step 2 — Disable the competing overlay
SteamOS's built-in performance overlay is **MangoApp**, not MangoHud. It is an IPC bridge
and **cannot write CSV logs**. Running it alongside MangoHud produces two stacked overlays
and aborts logging.
- [ ] Quick Access Menu (`...`) → **Performance**
- [ ] **Performance Overlay Level → 0**
- [ ] **Framerate Limit → Off** (critical — otherwise every config "hits" the cap)
- [ ] **TDP Limit → Off**, or pin it to a fixed value (e.g. 15 W) and never change it
between sessions. Whichever you choose, record it and keep it constant.
- [ ] Check that no per-game profile is re-enabling any of the above.
- [ ] If Decky Loader is installed, disable any MangoHud/benchmark plugin that routes
through MangoApp.
## Step 3 — CPU governor and thermals
The Deck's governor is normally `schedutil`. Two options:
- **Recommended:** leave it as SteamOS sets it, but *record* it
(`cat /sys/devices/system/cpu/cpu0/cpufreq/scaling_governor`) and keep it identical
across every session.
- Pinning `performance` gives more consistent clocks but increases heat on a handheld,
which risks thermal throttling — usually a worse trade for repeatability.
**Thermal soak:** let the Deck play for ~5 minutes before the first measured run. A cold
Deck boosts then throttles; the first runs of a session are not representative. This is the
single biggest source of bogus deltas on this machine.
## Step 4 — Install MangoHud
SteamOS's rootfs is read-only, and anything installed via `pacman` can be removed by a
SteamOS update. Re-check this before every session.
```bash
sudo steamos-readonly disable
sudo pacman -S --needed mangohud
sudo steamos-readonly enable
```
Then find the actual paths — **do not assume them**:
```bash
pacman -Ql mangohud | grep -E 'mangohud$|libMangoHud'
```
This tells you the wrapper binary and the shared library path. Note them; you will need
them if the wrapper route fails.
> **Alternative if you don't want to touch the rootfs:** MangoHudPy is built for
> SteamOS/Bazzite and manages MangoHud configs and log uploads. Verify it can write CSV
> logs before relying on it — some SteamOS MangoHud tooling routes through the MangoApp
> IPC shim, which explicitly cannot write logs.
## Step 5 — MangoHud configuration
Generate the config from the packaged example rather than trusting a transcription:
```bash
mkdir -p ~/.config/MangoHud ~/mcbench/logs
cp /usr/share/doc/mangohud/MangoHud.conf ~/.config/MangoHud/MangoHud.conf # verify path with pacman -Ql
```
Then set these keys in `~/.config/MangoHud/MangoHud.conf`:
```ini
output_folder=/home/deck/mcbench/logs # required for logging
autostart_log=1 # start logging automatically
log_duration=30 # seconds; match your scene length
fps_limit=0 # uncapped
frametime=1
frame_timing=1
# percentiles: see the packaged example for the exact key/syntax — it defines a
# '+'-separated list of percentiles emitted in the benchmark summary
```
Confirm the exact percentile key name against the packaged example file. Logging can also
be toggled at runtime (`toggle_logging`, default `Shift_L+F2`).
## Step 6 — Launcher and JVM
Use **Prism Launcher** (or ATLauncher) with the pack imported, then launch it from a
terminal in Desktop Mode so the environment is under your control.
**Java:** 21 (Arch `jre21-openjdk` or Temurin 21). Use the **same JVM build across all
three machines** where possible — different JVM builds are a confound.
**Wrapper command** — Prism → *Edit Instance → Settings → Custom Commands → Wrapper
command*. This is the most reliable way to hook the Java process directly:
```
mangohud
```
If no overlay appears, or Minecraft fails to start, try:
```
mangohud --dlsym
```
**JVM arguments** (held identical across all three machines; only `-Xmx` differs):
```
-Xmx5G
-XX:+UseG1GC -XX:+ParallelRefProcEnabled -XX:MaxGCPauseMillis=200
-XX:+UnlockExperimentalVMOptions -XX:+DisableExplicitGC
-XX:G1NewSizePercent=30 -XX:G1MaxNewSizePercent=40 -XX:G1HeapRegionSize=8M
-XX:G1ReservePercent=20 -XX:G1HeapWastePercent=5 -XX:G1MixedGCCountTarget=4
-XX:InitiatingHeapOccupancyPercent=15 -XX:G1MixedGCLiveThresholdPercent=90
-XX:G1RSetUpdatingPauseTimePercent=5 -XX:SurvivorRatio=32
-XX:+PerfDisableSharedMem -XX:MaxTenuringThreshold=1
```
**On `-Xmx5G`:** the Deck's 16 GB is shared with the GPU, so heap is not free. Start at
5 G, never exceed 6 G, and treat the final value as a Phase 0 *output* derived from GC
data, not a guess. Omit `-XX:+AlwaysPreTouch` here — committing the whole heap up front
costs memory you may not have.
## Step 7 — Pin the in-game settings
These are **controlled variables**. Set them once, record them, and do not change them
between runs unless the run is specifically testing that setting.
- Graphics: Fancy
- Render distance: 8 (matches the server's `view-distance`)
- Particles: All
- Clouds: Fancy
- Entity shadows: On
- Biome blend: fixed value, recorded
- Mipmap levels: 4
- GUI scale: fixed number (not Auto)
- **Max framerate: Unlimited**
- **VSync: Off**
- FOV, resolution, fullscreen mode: fixed and recorded
## Step 8 — Verification run
Prove the harness works before collecting any real data.
- [ ] Launch the pack from Prism with the wrapper command set.
- [ ] Confirm the MangoHud overlay appears over Minecraft.
- [ ] Load the benchmark scene, play 30 s.
- [ ] Confirm a CSV file appeared in `~/mcbench/logs`.
- [ ] Open the CSV and confirm it contains a frametime column.
- [ ] Run the same configuration three times and check the spread. **If the spread is
large, nothing downstream is trustworthy** — fix that before continuing.
## Step 9 — Per-session checklist
- [ ] Charger connected
- [ ] Desktop Mode
- [ ] SteamOS overlay level 0, FPS limit off, TDP as recorded
- [ ] Governor matches previous sessions
- [ ] MangoHud still installed (SteamOS update may have removed it)
- [ ] 5-minute thermal soak completed
- [ ] CSV output folder writable
## Step 10 — Recording sheet
Log one row per run:
| Field | Example |
| --- | --- |
| Date / session | 2026-09-28-a |
| Machine | P0-SteamDeck-LCD |
| Config ID | baseline / dh-off / emf-off / … |
| Scene | A-base / B-terrain / C-gui |
| Run # | 1 / 2 / 3 |
| CSV file | `Minecraft_2026-09-28_14-22-01.csv` |
| p50 / p95 / p99 frametime (ms) | |
| 1% low FPS | |
| Avg FPS | |
| Peak measured frametime (ms) | |
| Notes | e.g. "thermals settled", "DH disabled" |
---
## Machine-specific caveats
- **The overlay trap.** SteamOS gives you MangoApp, which looks like MangoHud and cannot
write logs. Getting CSV requires launching through the MangoHud wrapper, in Desktop
Mode, not through Gaming Mode.
- **VRAM is not measurable here.** The GPU shares system memory, so there is no separate
VRAM number to track. Watch total system RAM and swap instead; memory pressure is what
you will actually see.
- **SteamOS updates remove `pacman`-installed packages.** Verify MangoHud exists at the
start of every session.
- **60 Hz panel (LCD) cannot validate 120/144 targets.** Document this rather than
pretending those rows are tested.
- **Smallest thermal envelope of the fleet.** The warm-up soak is not optional.
- **Per-core performance is much lower than the other two machines** despite the identical
4C/8T topology. Do not assume a CPU-side result from P1/P2 transfers here at the same
magnitude — only the direction should be expected to match.