Files
onion-mc/analysis/client-perf/SPAWN-TUNING.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

64 lines
4.2 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.
# 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.