docs: client-perf analysis, bench harness and work journal

Everything the next agent needs to run the Phase 2 optimisation loop on a
machine that can launch the client:

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

All of it is packwizignored, so nothing here ships to players.
This commit is contained in:
logan committed 2026-10-14 18:15:32 -04:00
1 parent d80f85b3f6
commit 611a1a5952
102 files changed
+25853

No files matched your search

+63
View File
@@ -0,0 +1,63 @@
# Spawn tuning (server-side lever 3)
**Owner brief (2026-10-14):** tune spawns, but not in a way that hurts gameplay much. All
three files ship **enforced** from `config/` (this repo is the server directory, and clients
get them too, which only matters in singleplayer). Each file is **partial**: the mod fills
every other key with its default. Research came from three subagent briefs (2026-10-14);
every load-bearing fact below was re-checked against the pinned jar or the source at the
matching version. **Unmeasured:** bench block B14 (below) checks it.
## What shipped
### Alex's Mobs 1.22.17: `config/alexsmobs-common.toml`
- Format: NeoForge `ModConfigSpec` **COMMON** (`AlexsMobs.class`: `registerConfig(COMMON, …)`;
no custom filename). Keys are flat under `[spawning]` (`CommonConfig`: `push("spawning")`;
`buildInt` ignores its category argument). A partial file gets corrected and re-saved by
NeoForge.
- Changed (weight, 0–1000; group sizes are hard-coded in `AMWorldRegistry`): gazelle 40→20
(herds of 7), capuchinMonkey 28→14 (groups of 9–16), elephant 30→15, straddler 70→35,
rockyRoller 60→30, underminer 50→25, blobfish 30→15, mudskipper 28→14, caiman 29→15.
Everything rare is untouched.
- Issue #62 on Raguto/AlexsMobs-1.21.1 ("tons of monsters" / inflated *vanilla* spawns) is
open, unexplained, and no config addresses it. If it shows up, A/B test a world without
Alex's Mobs.
### Fowl Play 1.2.3: `config/fowlplay.json5`
- Format: YACL v3 JSON5 (`YACLIntegration`: `fowlplay.json5`). YACL 3.8.2
(`GsonConfigSerializer.loadSafely`) keeps defaults for missing fields and re-saves; a bad
value is logged and left at its default, not a crash.
- Changed (default → new): duck weight 4→2, max group 6→4 · goose 4→2, 4→3 · gull 5→3, 8→5 ·
sparrow 20→12, 6→4. Songbirds and raptors are untouched.
- Context: #214 (~400 ducks on rivers) is open. 1.2.1 added a 200-tick spawn gate. The
category caps (`fowlplay_birds` 20, `fowlplay_ambient_birds` 15) scale with loaded chunks
like vanilla, and only became configurable *after* 1.2.3. If counts are still high, the
next lever is a Paxi datapack that narrows `#fowlplay:spawns_ducks` (currently includes
forest tags), added through `analysis/audit/gen_fixes.py`.
### Critters and Companions 2.7.0: `config/crittersandcompanions-common.json5`
- It *does* have a spawn config (contrary to LEVERS' "no config"): YACL JSON5, nested
`spawning` object, one `List<SpawnEntry>` per mob. `SpawnEntry` is a record
`{biomeSpec, weight, min, max}` with no custom type adapter, so it serialises as plain Gson
record JSON. The jar has no biome-modifier JSON, so a datapack *cannot* reduce these spawns.
- A listed mob's list **replaces** its defaults, so each changed mob lists all its default
biomes. `"configVersion": 2` is required, otherwise the v1→v2 migration runs.
- Changed: sea bunny (the worst: warm ocean 32 × groups ≤4 → 20 × ≤3; other oceans 16 → 10,
max 4 → 3), leaf insect jungle 14→8 / forest 6→4, dragonfly lush 10→6, and the
ladybug / stag beetle / roly poly / snail / stick bug / weevil rules about −40 %. Unchanged:
jumping spider, red panda, ferret, dumbo octopus, otter, koi, shima enaga.
## Verify on first boot (part of BENCH-MATRIX §0)
- `latest.log` has no YACL "Failed to deserialize" lines for `fowlplay` or `crittersandcompanions`.
- After the first launch, each file has been re-saved in full with our values intact.
(In the repo working tree that shows up as a diff: **don't commit the expanded files**
unless you mean to.)
## B14: measure it (P2, singleplayer, Creative, `doMobSpawning true`)
Fresh world `onionspawn`, at a river/forest edge (ducks), a jungle (capuchins, leaf
insects) and a warm ocean (sea bunnies). Stand still 10 minutes at each, then count with
`/execute if entity @e[type=<id>,distance=..128]` for `fowlplay:duck`, `fowlplay:gull`,
`alexsmobs:capuchin_monkey`, `crittersandcompanions:sea_bunny`, and in total
(`@e[type=!player,distance=..128]`). Compare against the same world with these three
config files removed (defaults). **Keep the tuning** if totals drop and every species still
appears; **back it off** if a species effectively disappears. Spot-check that vanilla
passives (cows, sheep) still spawn normally.