Phase 9: reproducible builds, balance from the server, spark check, play feedback

Build: every tool pinned (JDK, packwiz, Gradle plugins, Python packages), exports
normalised, tools/check_reproducible.py proves two clean builds are byte-identical.

Server-side balance: a server can load config/cobblesurvival/datapack.zip in place of
the jar's data, /reload applies it, tools/server_update.py packages it and refuses
when a client change is needed. JEI drop pages are sent by the server. Code-held
balance numbers moved to tuning/server.json.

Performance: spark in the pack (server only), tools/perf_test.py with fake players
whose chunks really are active, docs/performance.md.

Adrian's feedback: default keys R, U, J, §; drop pages link to Cobblemon Info and show
real chances; bosses only hurt in battles; battle XP halved; channels between the
islands low level; temperature ×3 with insulation doubled; hazards start at once; no
item dots on the map; a wild attack starts a battle; the starter only faints; quest
book on join with a basics page and an HMs page; regional forms obtainable.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
claudeandClaude Opus 5.5 committed 2026-11-09 16:26:30 +01:00
1 parent 0741c84077
commit 4083791944
133 files changed
+8350 -3273

No files matched your search

+37 -5
View File
@@ -8,7 +8,7 @@ A free NeoForge 1.21.1 modpack on Cobblemon 1.8: one large island with soft-gate
- **Core:** Cobblemon 1.8.4, KubeJS, FTB Quests, WorldGen Editor, and the companion mod (`mod/`).
- **World:** a Poké Ball-shaped island (world type "Cobblemon Survival Island") with a fixed biome list, no natural ore and no Nether. See [world/README.md](world/README.md).
- **Quality of life:** JEI, Jade, Inventory Profiles Next, Mouse Tweaks, AppleSkin, Controlling, Xaero's Minimap and World Map; Default Options ships conflict-free default keybinds (`pack/config/defaultoptions/keybindings.txt`, check with `tools/check_keybinds.py`).
- **Quality of life:** JEI, Jade, Inventory Profiles Next, Mouse Tweaks, AppleSkin, Controlling, Xaero's Minimap and World Map; Default Options ships default keybinds (R recipes, U uses, J map, § quest book; JEI's R shares with Cobblemon's send-out, one works in screens, the other in the world) (`pack/config/defaultoptions/keybindings.txt`, check with `tools/check_keybinds.py`).
- **Rules:** no vanilla mobs (only Pokémon), Nether portals don't form.
- **Performance:** Sodium, FerriteCore, ModernFix, ImmediatelyFast, Entity Culling.
- **Shaders:** Iris with Complementary Reimagined, installed but off by default (Toggle Shaders key M, or Video Settings > Shader Packs).
@@ -29,9 +29,9 @@ tools/ build/export, cross-linking, Prism sync, server smoke test, i
## Requirements
- Java 21 to run Gradle and the server. `tools/` uses Prism's bundled Java 21 when present; Gradle downloads a JDK 21 for compiling if needed.
- [packwiz](https://github.com/packwiz/packwiz): `go install github.com/packwiz/packwiz@latest`
- Python 3.11+
- Java 21 to run the test server (`tools/` uses Prism's bundled Java 21 when present). The build downloads its own pinned JDK.
- [Go](https://go.dev/dl/) (the build compiles its pinned packwiz; no system packwiz needed)
- Python 3.14 (the build makes its own venv with exact packages)
## Everyday commands
@@ -131,7 +131,39 @@ Writes the Sigils' recipes and data and their fights (Phase 9) from `world/summo
```bash
python3 tools/jei_sources.py
```
Writes the data behind the pack's own JEI pages (Phase 8) into the companion mod (`mod/src/main/resources/assets/cobblesurvival/jei/drop_sources.json`): every Pokémon's drops and zones, guardians, the End boss, the altar, ore veins, pasture finds. Run it after changing species drops, spawns, guardians, machines, ores or Cobblebase tables, then rebuild; the self-test `drop_sources_match_the_server` fails while it's stale. Needs the Cobblemon jar in `build/server/mods` (any test-server run).
Writes the data behind the pack's own JEI pages (Phase 8) into the data pack (`datapacks/core/data/cobblesurvival/drop_sources/pages.json`), and the server sends it to players: every Pokémon's drops and zones, guardians, the End boss, the altar, ore veins, pasture finds. Run it after changing species drops, spawns, guardians, machines, ores or Cobblebase tables, then rebuild; the self-test `drop_sources_match_the_server` fails while it's stale. Needs the Cobblemon jar in `build/server/mods` (any test-server run).
## Balancing on a running server
Balance lives on the server, so playtesters keep the client they have. After changing the pack's data:
```bash
python3 tools/server_update.py --install /path/to/server
```
Or without `--install`, unzip `build/server-update-<ver>.zip` into the server's folder. Then `/reload` for the data pack and recipes, `/ftbquests reload` for the quest book; changed mod configs need a restart. `/cobblesurvival data` shows what is live. The JEI drop pages update for players by themselves.
This covers everything in `datapacks/core` (spawns, drops, machines, bosses, gates, hazards, recipes, `tuning/server.json`), `pack/config`, KubeJS server scripts and the quest book. It's refused when something players run or draw changed (mods, textures, lang, startup scripts, new items or blocks, client code), and names those files; hand out a new pack, then record it with `tools/server_update.py --mark-client-release`. Code that only the server runs can go along with `--with-jar`. Moving ores or reshaping the island needs a new world, not a new client.
`tools/check_server_update.py` proves on the test server that the data switches over and `/reload` picks up a change.
## Reproducible builds
The same commit builds the same bytes, wherever the repo is and whatever the machine has installed: `tools/build.py` compiles with a pinned JDK and runs a pinned packwiz (`tools/build-lock.toml`), with exact Python packages (`tools/requirements.txt`) and Gradle plugins, and every mod is pinned by hash. `build/SHA256SUMS` lists what it produced.
```bash
python3 tools/check_reproducible.py --fresh-gradle
```
Builds the working tree twice from clean copies in different folders, each with an empty Gradle home, and compares every output byte for byte. The island world template isn't covered: Minecraft's chunk generation is the same from one run to the next, the saved region files aren't.
## Performance
```bash
python3 tools/perf_test.py
```
Boots the island with fake players, full pastures and working machines at three sizes, profiles with spark (in the pack, server only) and writes [docs/performance.md](docs/performance.md). About 20 minutes.
## Adding a mod