Files
onion-mc/.pi/journal.md
T
logan 611a1a5952 docs: client-perf analysis, bench harness and work journal
Everything the next agent needs to run the Phase 2 optimisation loop on a
machine that can launch the client:

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

All of it is packwizignored, so nothing here ships to players.
2026-10-14 18:15:32 -04:00

414 lines
24 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.