# Onion MC — work journal ## Session 2026-10-06 — 60-mod expansion, integration review ### What this is **Onion MC**, a curated Minecraft modpack managed with **packwiz**. - Minecraft **1.21.1**, NeoForge **21.1.251** - **209 mods** (was 149 four commits ago) - packwiz lives at `~/go/bin/packwiz` — **not on PATH** - Remote: `ssh://git.ljones.me:2222/logan/onion-mc.git`, branch `main` - Commit style: Conventional Commits, imperative subject, body explains *why* - The repo **doubles as a server directory** (`.packwizignore` excludes `libraries/`, `world*/`, `logs/`, `crash-reports/`, `*.jar`, `run.sh`). Never blanket-un-ignore anything there — you will index runtime junk. ### Environment (checked 2026-10-06) - This machine is **NixOS**: no `java` on PATH; use `nix shell nixpkgs#jdk21` for anything server-side. No server is installed in the repo yet (no `libraries/`, `run.sh`, or NeoForge jar). - Client = Prism instance `~/.local/share/PrismLauncher/instances/Onion MC/`. Its pre-launch hook runs `packwiz-installer-bootstrap` against `https://git.ljones.me/logan/onion-mc/raw/branch/main/pack.toml`, so launching it pulls the pushed pack. Last launch (`logs/latest.log`) is **2026-09-24**, i.e. before all five commits below — confirms the expansion has never been booted. - `.pi/` is in `.packwizignore`, so this journal never ships. ### State Five commits, all pushed to `main`, HEAD = `e36bff8`: | Commit | Contents | | --- | --- | | `455e398` | 14 client-side mods + 12 libraries | | `b6ebdb8` | 11 Farmer's Delight addons + 4 decoration + 4 pet/mob | | `e371e51` | 15 gameplay/media/social | | `387ee1e` | config policy change + PetProtect default | | `e36bff8` | Akashic Tome whitelist config | Verified after each stage: mod set matches intent exactly (nothing auto-added by packwiz, nothing missing, nothing removed), `index.toml` hash matches `pack.toml`. **Two configs ship** (new capability — see policy in gotchas): - `config/petprotect.json` - `config/akashictome-common.toml` ### Goal A **working, well-integrated 209-mod pack**: 1. **Boots clean** on client and dedicated server — no mixin failures, no missing deps. 2. **No duplicate systems** — the pack has a history of removing them (FTB Chunks → Open Parties and Claims; FTB Quests/Teams/XMod Compat deleted). New mods must not reintroduce overlapping mechanics without a reason. 3. **No broken recipe chains** — every consumed item stays obtainable. 4. **Performance held** — Sodium, Iris, ImmediatelyFast, EntityCulling, ModernFix, FerriteCore, Distant Horizons mandatory, C2ME/Noisium server-side, Dynamic FPS. 5. **Tested, not assumed** — nothing has been booted yet. ### Decisions made — do not relitigate without cause **Excluded candidates:** - `sable_beyond` — every 1.21.1 build is alpha; wide Create/Aeronautics sublevel-mass mixin surface. Owner's call. - `expanded-delight` — beta-only, built against FD 1.2.4 (pack runs 1.3.4); sweet potato / cranberry / peanut / chili / cinnamon / salt duplicate kept mods. - `hearth-and-harvest` — no per-crop config, so corn/peanut/cotton/salt/blueberry dupes couldn't be trimmed. Dropping it also removed two cutting-board collisions (wheat, sunflower). - `display-delight` — zero risk but ~250 plate items incl. dishes from Delight mods we don't run. Could be added any time. **Rustic Delight dedupe declined.** Its flags are whole content-family switches: - `enable_cotton` — only dupe partner was hearth-and-harvest (not added). - `enable_coffee` — real dupe vs extradelight, but cascades into coffee-braised beef, Haste potions, cherry-blossom/syrup chains. - `squids_drop_calamari` — also strips calamari from creative tab and villager trades; `enable_fried_foods` depends on it. Remaining "duplicates" are tag-merged (`c:crops/coffee_beans` etc.) and benign. **Kept after being flagged:** - Grassier Grass — reported shader breakage is Rethinking Voxels-specific; issue lists Complementary Reimagined (what we ship) as working. BSL bug is separate. - Perception — OctoLib/ShatterLib is a maintained zero-dep lib; trails are particles, shake is camera; jar has no shader/post-process assets. ### Open questions for the owner 1. **Potato cutting-board collision → needs a datapack loader.** Only real unresolved defect. `c:crops/potato` + knife matches both `extradelight:cutting/sliced_potato` (4×) and `moredelight:cutting/diced_potatoes` (1×). Neither output is obtainable otherwise; they feed 4 and ~10 recipes. The losing chain breaks permanently. Fix: rewrite both recipes to emit the combined output via a datapack loader reading from `config/` (**Paxi** or **Global Packs**) — a new mod, awaiting approval. 2. **Keep PetProtect?** With both protection flags off it only stops pets being provoked into fights. Dropping it + config restores vanilla retaliation; Pet Cemetery works alone. 3. **Keep `mystical-oak-tree`?** Costs Moonlight (2.3 MB) for a 1-in-280-chunk feature — near-zero value on a pre-generated map. Offered to exclude. 4. **Rustic Delight coffee flag** — one line, if the second coffee should go. 5. **`display-delight`** — add later, or not. ### Known and potential conflicts | Area | State | | --- | --- | | **PetProtect ↔ Pet Cemetery** | Resolved *only* by the shipped config. `isInvulnerableTo` gates on `prevent_pet_damage` alone, so disabling `prevent_pet_death` alone leaves pets immortal. Both flags `false`. Delete the config and Pet Cemetery is dead weight. | | **extradelight recipe overrides** | 169 files under `data/farmersdelight/recipe/`, ~25 path-colliding with FD's own. Live, ungated. FD recipe book changes noticeably. | | **Twilight Forest stripping (16 pairs)** | `farmers-cutting-twilight-forest` and `twilight-delight` both cut TF logs into `stripped_X` + `tree_bark`. Identical outputs — harmless. Pre-existing. | | **Curios slot merging** | `artifacts`, `too-many-bows`, `tarotcards-remastered`, `mermod` define player slots, no `replace`. Should merge — **verify in game once**. | | **Sophisticated Core disc handlers** | Verified clean: first-supports-wins, predicates disjoint. | | **`dungeons_delight`** | **29 vanilla mixins** incl. `BlockBehaviourMixin`/`LevelRendererMixin`. Broadest surface added. Untested vs ModernFix/Sodium. | | **`fowlplay` spawning** | ~13 bird species via `NaturalSpawnerMixin` — spawns in already-generated chunks. Watch tick time. | | **`fishermans-haven`** | Lighthouse spacing 9/separation 6 (dense); several biome modifiers use **bare un-namespaced biome IDs** (may log errors / silently not spawn). Salt lakes in every biome via `neoforge:any`. | | **`extradelight` legacy `forge/` biome modifiers** | Inert on NeoForge (working `neoforge/` copies exist). Harmless. | | **`etched` ↔ `music-disc-maker`** | No code conflict (mixin points re-verified), but duplicate content: two blank discs, two boomboxes, two 9-disc albums, two recording pipelines. Design decision. | | **Tag merges** | Several mods write the same `c:` crop tags (3 garlics, 3 peanuts, 3 salts, 2 corns…). Benign. **Bell pepper and citrus NOT merged** (`crops/bellpepper` vs `crops/bell_pepper`, `crops/lemon` vs `foods/fruits/lemon`). | ### Not verified — nothing has been booted All findings are static analysis (jars, bytecode, data files, Modrinth API). Untested: - Whether the pack **boots at all**, client *and* server. - `dungeons_delight`'s 29 mixins vs the perf stack. - Grassier Grass vs **Complementary Reimagined** and **MakeUp Ultra Fast** (MakeUp untested by anyone). - Whether Terralith biomes carry `#c:is_*` / `#minecraft:is_overworld` tags that wild-crop/tree biome modifiers key off (generation density only). - Whether `fishermans-haven`'s bare-ID biome modifiers parse. - Whether `extradelight`'s inline-feature `neoforge:` biome modifiers place. - Whether `extradelight`'s cookbook opens (ships `patchouli_books/cookbook2/` dirs but **no `book.json`**). The item itself is real. - `room-for-two` (beta; compat untested by author) and `petprotect` (beta). - PetProtect edge case: logging out while downed may lose items (upstream #184, 1.19.2, never fixed). - Curios slot merge rendering all four mods' slots. ### Method notes and gotchas - **packwiz `side` quirk**: only client-only mods are special-cased; mods with `client_side: unsupported` still get `side = "both"`. `petprotect` manually set to `side = "server"` (as `c2me-neoforge` and `noisium` already were). **`packwiz update` rewrites metafiles and resets these.** - **Config policy is opt-in.** `.packwizignore` ignores `config/*` and `defaultconfigs/*`; shipping a file needs `!config/` at the **bottom** (last match wins), after the blanket `*.json` rule. - **Duplicate `version_number` traps**: `tarotcards-remastered`, `room-for-two`, `too-many-bows` reuse version strings across 1.21.1 / 1.21.11 / 26.x. Pin exact filenames by hand. - **Undeclared deps on Modrinth**: `perception` → `shatterbyte-lib` (OctoLib), `dungeons_delight` → `runiclib`. `mystical-oak-tree` → `moonlight` is declared in the jar but not the API. - **cdn.modrinth.com returns HTTP 501 to Range requests** — download whole jars. `unzip` is not installed; use `python3 -c "import zipfile..."`. - **`lodestonelib`** is the real slug; `lodestone` has no 1.21.1 build. - `FINDINGS.md`, `MODLIST-GROUPS.md`, `MODLIST-REVIEW.md` are untracked, packwizignored, and **~60 mods stale**. They hold the FTB-swap reasoning, OPAC config decisions and the original per-mod compat audit — refresh, don't re-derive. ### Next steps, in order 1. **Boot the pack.** Client first (launch the Prism instance — it self-updates from the pushed `pack.toml`), then the dedicated server. 2. Check logs for: missing deps, mixin apply failures, `fishermans-haven` biome-modifier parse errors, anything referencing `dev/ftb/mods/ftbteams` (soft-dep risk from the FTB removal). 3. Smoke-test: Grassier Grass + Complementary Reimagined, `dungeons_delight` mixins, curios slots, Pet Cemetery death→collar loop. 4. Watch tick time and entity counts (fowlplay, fishermans-haven, mooblooms). 5. Bring open questions to the owner, potato collision first. ## Static audit 2026-10-06 (all 209 jars + vanilla + NeoForge data) Scripts/output: `analysis/audit/` (jars cached in `/tmp/onion/jars`, ephemeral). Deps clean (no missing/out-of-range/incompatible; lambdynlights_runtime is a false positive — nested under META-INF/jars). No item-tag load failures. Corrections to the handoff: - Potato board collision is **3-way**: + `rusticdelight:potato_slices` (81 consuming recipes, board-only source). Vanilla `getRecipesFor` sorts by result translation key, so `extradelight:sliced_potato` likely wins; rustic + moredelight lose. moredelight diced potatoes/bread slices still reachable via Create saw. - New: bread + knife → extradelight vs moredelight bread slice. - rusticdelight tags `potato_slices` as `c:crops/potato` (re-cut/dupe loop); veggiesdelight tags sweet potato there too. rustic coffee beans sit in both `c:crops/coffee` and `c:crops/coffee/cooked`. - extradelight *disables* 14 FD recipes (relocated to oven/mixing bowl/feast/ chiller — all still obtainable); FD beef_stew is rustic-live vs extradelight-disabled → load order decides. Crafting-grid collisions (one output uncraftable): dungeonsdelight vs twilightdelight TF knives (×4); dungeonsdelight vs frightsdelight crates (×2); extradelight vs fruitsdelight apple crate, vs hamsterpets cucumber crate; coffee bag/sack/crate; comforts sleeping bag (vertical) vs handcrafted sheet; fishermans worms can → own worm vs aquaculture worm. Pre-existing: handcrafted wood plate vs 17 TF drying racks; create vs TF copper nugget (tag-unified, harmless). ## Fix pass 2026-10-06 — pushed as `fc649b4` (on top of `e7d6691`) - Added **Paxi** 5.1.3 (only dep YUNG's API, already present; injects packs at TOP). - Datapack `config/paxi/datapacks/onion-fixes/` (43 files), generated by `analysis/audit/gen_fixes.py` — edit the script, not the JSON. Shipped via a dir-by-dir re-include chain at the bottom of `.packwizignore` (packwiz's matcher needs negations *without* trailing slashes or it SkipDirs the parent). - Re-audit with the pack on top: all real collisions gone. Remaining flags are benign (dough shaping UI, mixing-bowl fluid variants, Aquaculture Delight neptunium tiering, Create/TF copper nugget). - Correction: rustic potato_slices has 3 direct consumers, not 81 (81 was via the polluted `c:crops/potato` tag). - `c:crops/potato` and `c:crops/coffee/cooked` now use `replace: true` — any future mod adding to them must be added to gen_fixes.py. - Orphaned on purpose (uncraftable, still uncraftable-from): dungeonsdelight TF knives + crates, hamster cucumber crate, fruitsdelight apple crate. Consider hiding them in JEI. - Needs in-game check: `/datapack list` shows onion-fixes (pink), recipes in JEI. - Rebased over upstream `0adfb6c` (Icy's Better Horses + Modonomicon, 212 mods); re-audit clean. Note: Better Horses' modId is `icys_better_horses` but it registers under `icys-better-horses` — the audit's absent-mod check flags it falsely. ## Session 2026-10-14 — client performance analysis, Phase 1 (static baseline) HEAD `aa1d273` (212 mods), unchanged. **Nothing committed, nothing changed in the pack.** All output is in `analysis/client-perf/` (untracked; `analysis/` is packwizignored). ### What exists now - `analysis/client-perf/LEVERS.md` — **the deliverable**: ranked levers (Tier 1–3), meta-levers, add/remove candidates, Phase 2 test order, corrections to the subagent research. Read this first. - `analysis/client-perf/README.md` — index and method. - `scripts/jarscan.py` + `scripts/report.py` → `data/jarscan.json`, `data/jarscan-report.md`. Parses class-file annotations for real `@Mixin` targets and injector kinds, per-frame/tick event refs, atlas px (one frame per animated texture), models, shaders, sounds and entities. It skips the Fabric-only nested jars of multi-loader jars (DH, LambDynamicLights). Runs in ~35 s over `/tmp/onion/jars` (ephemeral; refetch with `analysis/audit/fetch.py`; resource and shader packs were also dropped there). - `data/observed-default-configs/`: generated configs copied from the Prism instance's last launch (2026-09-24, the older 110-mod pack). They are the real-default reference (DH, Sodium, EMF, ModernFix, Flywheel, Sable, SPR…). - `research/r1..r9-*.md`: nine subagent briefs with confidence tags and URLs. ### Key facts established (verified) - 951 per-frame mixin classes (121 Overwrite/Redirect); top: Sable 127, Iris 114, Controlify 84 (GUI), Sodium 48, EMF 42. - Handcrafted + Chipped + Rechiseled = 58% of the block atlas and 62% of the 69k models. - Flywheel 1.0.x disables both GPU backends when *any* shaderpack is active (checked in `Backends.java`). The pack has no Iris Flywheel Compat. - DH defaults: LOD radius 256, SSAO and AA on, 2 worker threads. EMF `animationFrameSkipDuringIrisShadowPass` is already true. ModernFix `dynamic_resources` is off by default. Flywheel `lightSmoothness = SMOOTH`. - Sable renders each sub-level by re-driving Sodium's chunk renderer. `sub_level_skylight_shadows=false` by default; Iris #3164 (sub-level corruption with shadows) is open. - Chipped requires Athena and Rechiseled requires Fusion, so neither CTM engine is removable. Lodestone is required *only* by Miner's Delight. - Puzzles Lib 21.1.64 has an event-dispatch caching fix; the pack pins 21.1.62. - Shaders and resource packs are opt-in in practice (the last launch had none enabled). The pack ships no perf config, and JVM/heap is per-player Prism (old instance: 8 GB, stock G1). ### Decisions pending (owner) 1. Delivery mechanism for tuned defaults: **Default Options** mod (Balm is already present) vs packwiz `preserve = true` (semantics with `packwiz refresh` unverified). 2. Shader policy: default off / opt-in per machine? 3. Server-side spawn tuning (Alex's Mobs #62, Fowlplay #214, Critters & Companions datapack). 4. Removal candidates: Miner's Delight (drops Lodestone), Fowlplay, Charta, WATUT, Emojiful. 5. Add candidates: Default Options, Sodium Extra + Reese's Sodium Options, Particle Core, BadOptimizations; trials: Gnetum, Better Block Entities, Flerovium, Super Resolution (Deck), Ixeris (P1), Iris Flywheel Compat. ### Next steps - Phase 2 = benchmark per `LEVERS.md` §6 using the `phase0/` harness (P0 Deck, P1 7700K/1060, P2 6700K/1080 Ti with 8 GB RAM free). Capture the atlas size, heap and startup time at baseline. - Before benchmarking: the pack has never booted at this mod count (see the 2026-10-06 session), so do a boot/log check first. - Free change regardless of benchmarks: bump Puzzles Lib to 21.1.64. ## Session 2026-10-14 (b) — client perf Phase 1b: delivery, staged configs, bench matrix HEAD `aa1d273`, unchanged. **Nothing committed; zero tracked-file changes; no mods added/removed.** All output is under `analysis/client-perf/` (untracked, packwizignored). ### Produced - `proposed-configs/` — `build.py` generates player tiers (`out/T-default|deck|mid|high`) and 32 bench variants (`out/C0`, `C1`, `dh-*`, `fw-*`, …) from same-version observed defaults or source-verified templates. **The build fails if an override names a key that isn't in the base**, so key confirmation is enforced. README §1 = M1 decision, §2 = tier table, §3 = key provenance. - `BENCH-MATRIX.md` — replaces LEVERS §6: bench world recipe, scenes S1–S6, JVM sets J0–J3, blocks B0–B13 with decision rules and budget (~25 h machine time). - `bench/onion-bench/` — datapack (pack_format 48): scene teleports, `/fill` Create grid (2,304 kinetic BEs), mob pen, a 24-sounds/tick storm, and a 120 s teleport tour. **Never run in game**: syntax unverified, and the S2 `/fill`-placed kinetic network may need motors re-placed by hand (checklist in matrix §2). - `PLAYER-TUNING.md` — tiers, heap/GC, shader and RP guidance, Deck env vars. - `proposed-changes/puzzles-lib-21.1.64.patch` — `git apply --check` passes on HEAD. It touches only `puzzles-lib.pw.toml` + index/pack hashes. A single-mod `packwiz update puzzles-lib` does **not** reset the side fields on petprotect, c2me or noisium; only those three are at risk, from bulk updates. Its only dependent is HeldItemTooltips, range `[21.1.1,)`. ### Verified this session (don't re-derive) - **packwiz `preserve`** (packwiz `ef87d96` = the installed binary; installer v0.5.14 = the Prism jar): settable only by hand-editing `index.toml`. It survives refresh, content change and unrelated `update` (tested). It is **silently dropped** if a refresh runs while the file is absent or ignored. The installer writes the file only if it's absent. A skipped file re-logs "invalidated" every launch, and removing a file the installer wrote deletes the player's copy. Index files have no `side`, so they also land on the server (this repo *is* the server dir). - **Default Options 21.1.8**: copy-if-absent for `config/defaultoptions/options.txt` (`key_` lines stripped) and `config/defaultoptions/extra/**`. Runs at `GameConfig.`: before NeoForge constructs mods (`ClientModLoader.begin` is inside `Minecraft.`), but after mixin bootstrap, so too late for `modernfix-mixins.properties`. Balm `[21.0.39,)`; the pack has 21.0.66. - Observed defaults come from the **same jar versions as the current pins** (DH 3.3.2, Sodium 0.8.13, EMF 3.3.9, Create 6.0.10 / Flywheel 1.0.6, Sable 2.0.5, SPR 1.5.1). All 172 DH values match `Config.java` @ 3.3.2, except DH `numberOfThreads`: the true default is ceil(nproc/2) = **4** on the fleet (the observed 2 came from this 4-thread box). `serverId` is per-install random and is stripped from shipped files. - SSRD 1.8.7 config = `config/ssrd-common.toml` (COMMON; the server reads it too). `physicsRenderDistance` defaults to 128, slider floor 16. - LambDynamicLights 4.8.11 = `config/lambdynlights.toml`; `mode` is lowercase off/fastest/fast/fancy; `[light_sources] entities`. - SPR merges a partial `sound_rates.properties` over its generated defaults. Sounds over the cap play without physics; they are not dropped. - **Puzzles Lib 21.1.64 has no perf change on NeoForge**: `FabricEventFactory` isn't in the NeoForge jar. The 62→64 diff is access transformers plus one class. LEVERS #14 is corrected. - r6's `-XX:ShenandoahGCMode=iu` aborts JDK 21 without UnlockExperimentalVMOptions (tested). GenZGC and the brucethemoose G1 set parse cleanly. ### Owner decisions pending (presented 2026-10-14) 1. Approve **Default Options** as the delivery mechanism, plus enforced `modernfix-mixins.properties`. This is a mod add plus 3 `.packwizignore` lines (drafted in proposed-configs README §1). 2. Apply the Puzzles Lib patch (bugfix only). 3. Shader policy (B7 produces the data). 4. Server spawn tuning (Alex's Mobs / Fowlplay / Critters & Companions). 5. Removal candidates (Miner's Delight → Lodestone, Fowlplay, Charta, WATUT, Emojiful). 6. Add candidates (Sodium Extra + RSO, Particle Core, BadOptimizations; trials). These gate B12. ### Next steps 1. Boot check (matrix §0). Nothing else can proceed until the pack boots. 2. Build the bench world on P2 (matrix §2); fix any datapack parse errors on `/reload`. 3. Run B0 → B13; write the winners into `build.py`; regenerate; then ship via the approved mechanism. Existing players need the file-reset step in PLAYER-TUNING §1. ## Session 2026-10-14 (c) — owner decisions applied, pushed for the client machine The owner answered the pending list; this session acted on it, committed, and pushed. **The next agent works on a machine that can run the client.** This machine is NixOS with no `java`, no client and no `unzip`. Those notes are machine-specific; check what the new machine has. ### Owner decisions (2026-10-14), now settled 1. Delivery = **Default Options** (+ enforced `modernfix-mixins.properties` after B6). Done. 2. Puzzles Lib → 21.1.64. Done (bugfix only). 3. Shaders: **opt-in** (already the case: packwiz downloads them, nothing enables them). 4. Spawn tuning allowed if not detrimental to gameplay. Done, moderate (below). 5. **Remove no mods.** LEVERS §5 is reference only. 6. Add any helpful mods. Added the five "Add" verdicts. Trials are left to bench B12b, and the agent may add trial winners. ### Commits (all pushed to `main`; Prism instances self-update from it) - `a01bc3b` feat(perf): Default Options + `config/defaultoptions/` (8 provisional mid-tier files from `build.py --ship`); Sodium Extra 0.9.4, Reese's Sodium Options 2.2.4, BadOptimizations 2.4.1, Particle Core 0.3.3 (all `side = "client"`; deps already present); Puzzles Lib 21.1.64. **217 mods.** - `5919955` chore: stale reviews archived to `analysis/archive/` (README maps old paths); intermediates and API dumps deleted; `*.tar.gz` gitignored. - `d80f85b` feat(config): spawn tuning, enforced partial files `config/alexsmobs-common.toml`, `config/fowlplay.json5`, `config/crittersandcompanions-common.json5`. See `analysis/client-perf/SPAWN-TUNING.md`. - docs commit: `analysis/client-perf/` (minus the generated `out/`), `analysis/audit/` (incl. `gen_fixes.py`, which builds the shipped Paxi datapack and was never tracked before), `phase0/`, and this journal. ### Rules of the road for the iteration - Change tuned defaults **only** through `analysis/client-perf/proposed-configs/build.py` (`DEFAULT` / `DECK` / `HIGH`), then `build.py --ship`, then `~/go/bin/packwiz refresh` (wherever packwiz lives on that machine), then commit. - Shipped defaults are copy-if-absent. Changing them reaches **fresh installs only**; existing players use PLAYER-TUNING §1. - `modernfix-mixins.properties` ships only after B6 passes. Instructions are in the `SHIP` comment in `build.py`. - Any new mod: verify its NeoForge 1.21.1 build and its `neoforge.mods.toml` ranges against the pins, check `side`, rerun B0. **More Culling is unusable**: its NeoForge build declares `minecraft [1.21,1.21.1)`. - `packwiz update` (bulk) resets the hand-set `side = "server"` on petprotect, c2me-neoforge and noisium. A single-mod update is fine. - On first boot, the mods re-save the partial spawn files in full. Don't commit those expansions by accident (`git diff config/`). - `sp-world.tar.gz` (650 MB, untracked, gitignored) is a world save from the map-migration work. Leave it alone. ### Next steps 1. BENCH-MATRIX §0 boot check (now covers Default Options seeding, the RSO/SSRD video screen, YACL spawn-config loading, and the Iris↔Sodium report). 2. Build the bench world (§2), then run B0 → B14. Write the winners into `build.py`, ship, refresh, commit. 3. Report shader-policy data (B7) and any trial-mod verdicts (B12b) to the owner. ## Session 2026-10-15 — Phase 2 begins: client boots, bench harness built Machine: **Manjaro**, Java 21 (OpenJDK), Prism 11.0.3, RX 7800 XT / Ryzen 9 9900X / 91 GB. Unlike the previous machine this one runs the client. Full brief: `analysis/client-perf/HANDOFF.md`. ### Boot check (client) — essentially PASS Pack reaches the main menu cleanly (ModernFix "Game took 29.3 s"; atlas 4096x4096x2; Default Options seeds `options.txt` correctly). No missing deps, no mixin apply failures, no `ftbteams`, no fishermans-haven errors, no YACL "Failed to deserialize". 22 benign ERRORs. The one real blocker — **Critters & Companions spawn keys camelCase vs YACL's snake_case policy**, NPE in `CACSpawnConfig$SpawnEntry.isTag`, broken mod state — was fixed and pushed by the owner as **`8e8483d`** while this session ran. Alex's Mobs / Fowl Play spawn tuning verified applied in-game. **Open:** intermittent **world-load** crash in WATUT (`ShaderInstanceBlur` → `FileNotFoundException: minecraft:shaders/core/particle.json`). First load worked, next crashed. Needs repro; owner says remove no mods. ### Built this session (all under `analysis/client-perf/`, packwizignored) - `harness/rcon.py`, `harness/run_scene.py` — apply variant → launch Prism into the bench world under user-local MangoHud → drive scenes via xdotool → slice p99/1%-low from CSV. Verified end-to-end once (C1/S1, but vsync-locked; `vblank_mode=0` added after). - User-local MangoHud 0.8.4 (`~/.local/mangohud`, wrapper `~/.local/bin/mangohud-local`). - Bench world `saves/onionbench` generated by temp server `~/onion-bench/server-bench` (S2 Create floor, S3 mob pen placed+verified). S4 airships not built. - `build.py` BENCH layer: `enableAutoUpdater=false` (suppress DH update modal). Tiers unchanged; **nothing shipped**. ### Not done The matrix blocks B0–B14. Fleet P0/P1/P2 are unreachable → any data here is a high-tier proxy. Only one non-decision-grade run exists. Next agent: kill the WATUT crash, confirm uncapped frametimes, then run B0→B14 per `BENCH-MATRIX.md`. ### Pushed `8e8483d` (owner, CAC keys). This session's analysis/harness commit follows; it touches no shipped file. ## Session 2026-10-14 (d) — state capture for handoff (orchestrator) No pack changes; HEAD stayed `e5e369a`. Three read-only scouts inventoried the interrupted session's artifacts; findings folded into the new **`analysis/state/`** directory (6 markdown files: README, pack+environment, timeline, current-state, plan, artifact-map) — that directory is now the canonical onboarding point for a new agent. Facts established this session (all evidence-backed): - The 20:34 FML crash report is the **CAC spawn-key NPE** (fixed by `8e8483d`) — *not* the WATUT crash. No crash report exists for WATUT yet; it remains open and blocking. - The dedicated server from the boot check is **still running** (tmux `onion-mc`, PID 1699563, since 21:01) with an unidentified RCON keepalive polling every 30 s. Left alone per rules. - Working-tree diffs (`akashictome`, `alexsmobs` configs) are benign boot re-saves: whitelist intact; tuned spawn values retained. Per rule, restore before staging — not committed. - Bench instance `~/onion-bench/prism/instances/OnionBench` is fully provisioned (`.minecraft`, `saves/onionbench` 26 MB, Default Options seeded, bench pins, `BENCH_VARIANT.txt = C1`). One earlier scout misread it as unprovisioned — verified false by direct `ls`. - Jar cache `/tmp/onion/jars` is gone (ephemeral; `analysis/audit/fetch.py` rebuilds). State of the effort at capture: **Phase 2 begun, zero matrix blocks run.** Next agent: follow `analysis/state/04-plan.md` §"Next actions" (WATUT → verify uncapped frametimes → finish S4 → B0→B14 → ship → report). `analysis/state/` itself is uncommitted — fold it into the next commit. ## Session 2026-10-15 (b) — WATUT crash root-caused + fixed; harness v2 Commits: `a84319b` (fix(mods): MidnightLib 1.10.0 + `analysis/state/`), `e18bd3c` (feat(bench): harness v2). Not pushed. - **WATUT crash = victim, not cause.** Fright's Delight 1.4.8 jar-in-jars MidnightLib 1.9.2; its `MidnightConfig.init` races under NeoForge parallel mod construction → `ConcurrentModificationException` → broken mod state → `mod_resources` never loads → WATUT's unguarded `reloadShaders` mixin throws on `particle.json`. Fix: standalone `midnightlib` 1.10.0 (`side=both`; upstream fix 1fe69729, synchronizedMap). FML picks it over the JiJ copy (log: "Attempted to select a dependency jar ... Using Mod File"). Verified 10/10 cold launches to world join, 0 CME, all on 1.10.0. Frightsdelight doesn't touch `entries` (binary-compat risk checked). **Dedicated server still runs 1.9.2 until its next restart + jar install** — server-side exposure untested. - **Uncapped frametimes verified**: C1/S1 p50 2.9 ms, p99 9.5 ms, avg 297 fps (harness v2 smoke, `~/onion-bench/results/session.jsonl`, label `smoke`). The earlier 60 fps row in `harness-results.csv` is void. - **Harness v1 was silently broken**: KDE Plasma is Wayland; xdotool into Xwayland `:1` drops input when a native window has focus → no `/function`, no markers, ever. Also: partial `options.txt` re-triggered the accessibility onboarding screen (blocks `--world`), and FTB Backups fired ~7 s after every join (inside capture windows). - **Harness v2** (`analysis/client-perf/harness/bench.py`, `analyze.py`, `tests/`, README): `boot --n N --join` reliability loop; `session` drives scenes via a per-session generated datapack (armed only during the session, disarmed in `finally`), log markers with ms timestamps, CSV picked by birth time, validity flags, full metadata JSONL; `analyze.py` applies the BENCH-MATRIX win rule. 18 offline tests. - Bench-instance-only edits: FTB Backups `auto: false` (`config/ftbbackups3-server.snbt`); harness pins in `options.txt` (re-applied per run). - Observed noise: the idle dedicated server uses 23–78 % of a core; amdgpu DPM is `auto`; the bench window shares the owner's live desktop. Next: owner calls on noise controls (see harness README / session report), then S4 build → B0 (`bench.py session --variant C0 --plan s1 --reps 3 --label B0`, ×3 sessions) → matrix. ## Session 2026-10-16 — bench world finished, harness v3, matrix running Owner: stop the dedicated server while benching (done via console `stop`; tmux `onion-mc` is gone — restart with `./start.sh` in tmux when benching ends; packwiz will pull MidnightLib 1.10.0, jar also dropped in `mods/`). Gamescope integration approved. - **Harness**: `--display gamescope-headless` default @1920x1080 (~2 % cost vs desktop, isolates from the shared KDE Wayland desktop). Per-session `--shader/--shader-options/ --dh/--disable-mods/--add-mods/--world-zip` with a crash-safe restore journal (`bench.py restore`). Plan forces **spectator** — elevated scene cameras previously fell (S4 measured the sea floor at y=34). `shader_not_loaded` flag. `matrix.py` + `matrix.toml` = resumable B0–B14 runner; B7 profiles generated from pack `profile.*` lines (`gen_shader_profiles.py`); B12b trial jars in `~/onion-bench/trials/`. Post-join settle 45 s (rep 1 still warming at 10 s). Commits `c6341d0`, `4fa9a6a`. - **Bench world** built headlessly on `~/onion-bench/server-bench` via RCON: S4 = 4 Sable sub-levels (5×7×15 planks/glass, levitite floor + 2 interior layers — the 1-layer design sank ~14 blocks per physics wake), via `/sable assemble area`; stable at y≈169.24 across restarts and a 60 s client session. Removed 370 stray force-loaded chunks (S2/S3/S4 ticked in every scene). DH LODs pre-generated with `/dh pregen start minecraft:overworld 0 256` at x=0 and x=3680 (1.2 GB sqlite). S2 rotates (Speed 16 sampled), S3 = 30 villagers. Zips in `~/onion-bench/worlds/` (sha256): `bench-world-v1.zip` 144caf5fcdfea1a0eac0c787fdcded949e1a67df6ac112400f37be30ce7fb76e, `-s4-1.zip` 213b9b8871be527d0b5ac2e34615e8c2c1e3b206277fb37549a3014e2b895a38, `-s4-0.zip` 6b2a2bbd16f9f2e5aba34d53b09752d30fb7f9c3a97c24c46131b54d12bdc234. - **Matrix** run 1 (tmux `bench-matrix`, log `~/onion-bench/results/matrix-run1.log`): B0,B1,B2,B3,B4,B5,B6,B7(noshader),B8–B12a. B0 noise (settle 45): p99 spread 0.40 ms, 1%-low spread 6.6 fps. **B2: C1 beats C0 on every scene** (S1 p99 8.23 vs 9.33; S3 1%-low 186 vs 110) → no bisect stop. Early B3: dh-qlow wins S1, dh-ssao loses, dh-thr4 loses S5 (threads stay 2). Analyze with `--since 2026-10-16T22:24`. - Remaining after run 1: B4h (`--param gc=`), B7 shader rows, B12b, B13, B14, ship, owner report. Analysis proxy-only; noise floor gpu_dpm_auto (no root).