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

602 lines
37 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# 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.
- Owner approved: **Flerovium removed, spawn tuning reverted** (`217c346`). Server was
stopped while the three spawn files were deleted so it couldn't keep re-saved tuned
copies; restarted, Alex's Mobs regenerated defaults (gazelle weight 40). Bench
instance jar removed too. b14.py's `shipped` config now has nothing to ship.