Files
onion-mc/.pi/journal.md
T

37 KiB
Raw Blame History

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/<file> 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.<init>: before NeoForge constructs mods (ClientModLoader.begin is inside Minecraft.<init>), 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 <x> 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).
  • 2026-10-17 06:00 pause: matrix run 1 finished first (56/56 ok, 0 failures, B0–B12a incl. proxy B5). Timer pause-bench-start-server.sh started the server, but tmux was born inside the oneshot service's cgroup and systemd killed it (and the server, SIGKILL 1 s after Done, no players) when the unit exited. Restarted 06:05 in its own scope (systemd-run --user --scope tmux …, unit onion-mc-tmux.scope); script fixed the same way. Server is up (25565).
  • B4 GC verdict: J1 vs J0 S5 1%-low +1.3 fps < 6.6 spread → tie → J0.
  • Resume (stop the server first): cd analysis/client-perf/harness && python3 matrix.py run B4h,B7,B12b --param gc=J0 (20 sessions, ~3.5 h). Then B13 (manual spark), B14 (manual spawn counts), ship, owner report.

Session 2026-10-18 — run 2 + B14 done; server back

Overnight: 23:25 pause (owner) → 01:26 resume timer → matrix run 2 finished 03:18 (B4h, B7, B12b; all sessions ok after retries) → B7.noshader re-run on default JVM → B14 defaults + shipped (33 rows each, biome_ok, config check ok) → server up 04:31. 06:00 safety timer saw the server running and left it (its "not Done" warning was a scrolled-pane false alarm; readiness check now uses port 25565).

Results (full tables in analysis/client-perf/RESULTS-proxy.md §Run 2):

  • B4h: smallest heap within spread = 5 GB (4 GB loses S5) → PLAYER-TUNING note.
  • B7: shaders' big cost is S2 — Flywheel backends drop (974 → ~120 fps avg) for every profile; MakeUp shadowless near-free elsewhere, Complementary ~2× on S4.
  • B12b: Iris Flywheel Compat wins hugely under shaders (S2 p99 13.3 → 4.0); Flerovium wins S3 (entities; B12b's S3 baseline anomalous, so confirm once). Gnetum tie; BBE, Super Resolution, Ixeris (+1 crash), Cull Leaves rejected.
  • B14 (n=1): rule says back off, but driven by one goose/duck herd at the warm-ocean site; sea bunny never spawned in either config → inconclusive, needs ≥3 runs/config.
  • Super Resolution's first launch rewrote bench fml.toml (earlyWindowControl=false, unjournaled) → reset. Harness should snapshot/diff the whole config tree per session.

Remaining: B6 missing-texture check → ship modernfix-mixins; add Iris Flywheel Compat + Flerovium (visual check, then packwiz modrinth add, then re-run B0); DH low-quality visual check; B13 spark; B14 ×3 more; ship via build.py; owner report.

Session 2026-10-18 (b) — shipped, run 3, owner report

  • Shipped 7841361: ModernFix dynamic_resources (enforced config; owner waived texture check), Flerovium 1.1.2, Iris Flywheel Compat 2.4.0. Deck already had DH LOW.
  • Incident: 7841361 refreshed the index while alexsmobs/akashictome held boot re-saves → server packwiz install "Hash invalid" → server down 14:06–14:18. Fixed c5d25fa. Rule: git checkout -- config/ before packwiz refresh, not just before staging.
  • Run 3 (chain-0418): B0v2 noise p99 0.41 ms / 1%-low 1.6 fps. Flerovium did not hold up (S1 loss, S3 too noisy) → recommend removal (owner decision pending). B14 ×4: totals ~flat (jungle 130→128, river 208→212, warm ocean 145→136) → spawn tuning harmless but ineffective; keep/revert is the owner's call.
  • Docs: analysis/client-perf/OWNER-REPORT.md (new), RESULTS-proxy §Run 3, PLAYER-TUNING (5 GB heap; Iris Flywheel Compat under shaders).
  • Verified ModernFix honors the shipped override on the server boot log.
  • Open: owner decisions (Flerovium, spawn tuning); B13 spark (optional); fleet confirmation; push when the owner says so.