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:
1 parent
d80f85b3f6
commit
611a1a5952
102 files changed
+25853
No files matched your search
@@ -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.
|
||||
Reference in new issue
Block a user