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.
4.2 KiB
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
ModConfigSpecCOMMON (AlexsMobs.class:registerConfig(COMMON, …); no custom filename). Keys are flat under[spawning](CommonConfig:push("spawning");buildIntignores 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_birds20,fowlplay_ambient_birds15) 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 throughanalysis/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
spawningobject, oneList<SpawnEntry>per mob.SpawnEntryis 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": 2is 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.loghas no YACL "Failed to deserialize" lines forfowlplayorcrittersandcompanions.- 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.