Files
claudeandClaude Opus 5.5 d29e177f9d Phase 9: safe start island, better quest book, every useful item obtainable
- Button Isle is peaceful: wild Pokémon only fight a player who hit them first
  (tuning/server.json peaceful_zones); its apricorns and coal make Poké Balls
  (4 apricorns + coal or charcoal), and the world report checks it has enough.
- Quest book: no boilerplate; each zone page says what is particular to it, and
  every zone that needs gear or a field move to be safe has its own quest. New
  page on the bigger mods (Cold Sweat, Fight or Flight, Cobblebase, breeding,
  veins, shared loot, maps and info).
- The Mire's poison stops 10 blocks below the surface.
- Player battles never cost a Pokémon (CobbleHardcoreMon config, mixins, and the
  companion mod's own permadeath).
- tools/item_audit.py: every item with a use has a source on the island; new
  sources for the gaps it found (species additions, three recipes).

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-11-10 15:04:09 +01:00

191 lines
14 KiB
Markdown
Raw Permalink 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.
# Cobblemon Survival Pack
A free NeoForge 1.21.1 modpack on Cobblemon 1.8: one large island with soft-gated, Palworld/ARK-style progression, plus a companion mod for the mechanics no addon covers. The plan is in [docs/roadmap.md](docs/roadmap.md); decisions taken so far are in [docs/design.md](docs/design.md).
**Status:** Phases 0–8 approved (2026-11-09); Phase 9 (balancing and release) in progress. Checks per phase: `docs/checklists/`.
## What's in the pack
- **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 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).
Exact versions and each mod's Cobblemon 1.8 status are in [docs/addon-status.md](docs/addon-status.md).
## Layout
```
pack/ packwiz definition: mods/*.pw.toml (config/, kubejs/, defaultconfigs/ as phases add them)
datapacks/core/ data pack shipped inside the companion mod, always enabled
mod/ companion mod (Kotlin, Cobblemon NeoForge MDK)
world/ recipe for the island world template (the world itself is built into build/)
docs/ roadmap, design, balance, licenses, addon status
tools/ build/export, cross-linking, Prism sync, server smoke test, in-game self-tests,
dependency check, world builder and world report, zone map, field guide (tools/fieldguide/)
```
## Requirements
- 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
```bash
python3 tools/build.py
```
Builds the companion mod and writes `build/cobblemon-survival-pack-<ver>.mrpack`, `build/…-curseforge.zip` and `build/stage/full/` (every mod plus the companion jar). An export lists any mod it had to leave out because that platform doesn't host it, and fails if a third-party jar would end up in `overrides/`.
```bash
python3 tools/prism_instance.py
```
Creates or updates the Prism instance **Cobblemon Survival Pack (dev)** from `build/stage/full`. Run it after every build, with the instance closed. Worlds and options are kept.
```bash
python3 tools/quick_check.py
```
The everyday check after a change (about 5 minutes, two server boots): the smoke checks below, the in-game self-tests (next), `/locate` proof that ruined portals don't generate, and a sampled world (spawn plus a stronghold, mineshaft, trial chambers, ancient city, Gimmighoul towers and habitats) checked for ore outside regenerating veins or outside their zone, vanilla mobs and mob sources, unlisted biomes and gamerules, plus Lootr chests in a village. It then starts the server a second time for the self-tests that span a restart.
```bash
python3 tools/selftest.py
```
Only the companion mod's in-game tests, on a fresh flat world (faster while working on them), with a second server start for the tests that span a restart. They play real situations on the live server with every mod and config of the pack: for permadeath, Pokémon faint from a fall, lava, poison, in wild and trainer battles, with and without a Revival Charm, and in the PC. They use Minecraft's GameTest framework, started by `/cobblesurvival selftest run`; the command only exists when the server runs with `-Dcobblesurvival.selftest=true`. Tests live in `mod/src/main/kotlin/dev/cobblesurvival/selftest/`.
```bash
python3 tools/make_world.py
```
Builds the island world template (`build/world-template`, about 20 minutes: pregeneration, then a pass that waits until every chunk has its ore veins and nodes), runs the same world checks on the whole island plus border fit and End access, and renders `build/island-map.png`. Only needed when the island itself should change. Details in [world/README.md](world/README.md). Run `tools/prism_instance.py` afterwards to put it in Prism as the save "Cobblemon Survival Island".
```bash
python3 tools/make_machine_world.py --prism
```
Builds the machine test world (`build/machine-world`, a minute): superflat, creative, cheats on, every Phase 6 machine built three times (working with a Pokémon inside, empty, bare core). `--prism` copies it into the Prism instance as the save "Machine Test (Phase 6)", replacing an older copy.
```bash
python3 tools/zone_layout.py
```
Lays the zone plan in `world/zones.json` onto the island (from the seed's biome grid), draws `build/zone-map.png` with each zone's share of the land, and writes the zone grid the companion mod reads. Edit the JSON and rerun to try other zone shapes.
```bash
python3 tools/zone_spawns.py
```
Writes each zone's spawn pool from Cobblemon's spawn data (every evolution line on the island gets one home zone; levels follow the zone's band) and its Alpha guardian, and lists both in `docs/zone-species.md`. Run after `tools/zone_layout.py` and the field guide; pin a line to a zone in `world/zones.json` → `species`.
```bash
python3 tools/zone_bosses.py
```
Writes the boss fights (Phase 7): every guardian's area attacks by its level's tier, and the End boss. Run after `tools/zone_spawns.py`.
```bash
python3 tools/zone_ores.py
```
Writes Regenerating Ore Veins' config (`pack/config/regenerating_ore_veins/`) and the companion mod's ore node table from `world/zones.json` → `ores`: each ore tier's surface or cave-floor nodes and underground veins only in its zone, plus `world/vein-sources.json` for the field guide. Run after changing the ore tiers or the zone grid; the template must be rebuilt for new veins.
```bash
python3 tools/cobblebase_loot.py
```
Writes the pack's versions of Cobblebase's Mining, Ore Finder and Evolution-item Finder loot tables (`datapacks/core/data/cobblebase/loot_table/`): ores and evolution stones only from the pasture's zone, by `world/zones.json` → `ores`, and no type gems from Mining. Reads Cobblebase's own tables from its jar in `build/server/mods`; run after changing the ore tiers or updating Cobblebase.
```bash
python3 tools/drop_audit.py
```
Checks that every item a Pokémon or a vanilla mob drops and a recipe or brewing consumes has a source on the island (only Pokémon live there), and writes `docs/pokemon-drops.md`. Uses the field guide's model and its last KubeJS export, no server.
```bash
python3 tools/fieldguide/build.py
```
Writes the field guide to `build/field-guide/` (open `index.html`): where each Pokémon spawns on the island, how to get every mod item and what it's for, with items that have no source on the island flagged. Also generates FTB Quests chapters and a Pokédex text override under `build/field-guide/ingame/` (not installed). Details in [docs/field-guide.md](docs/field-guide.md).
```bash
python3 tools/item_audit.py
```
Every item in the pack that has a use can be had on the island (Adrian, 2026-11-10). Reads the field guide (run `tools/fieldguide/build.py` first) and fails on any item without a source, unless `NO_USE` in the script says why it needs none (decoration, creative-only, left over, or something Cobblemon can't make yet). Sources that only code knows go in `tools/fieldguide/manual_sources.json`.
```bash
python3 tools/smoke_test.py --load-only
```
Installs a NeoForge server under `build/server`, checks every mod's dependency ranges, and confirms the loader discovers all mods. It stops at the EULA check, so it needs no EULA.
```bash
python3 tools/smoke_test.py --accept-eula
```
The full smoke test: boots the server and runs `tools/smoke_checks.json` over RCON (companion mod live, core data pack enabled, key commands registered), then fails on unexpected errors in the log. Passing `--accept-eula` states that you accept the [Minecraft EULA](https://aka.ms/MinecraftEULA) for this test server. There is no CI: the Gitea server has no capacity for Actions runners, so the checks run locally (this, `tools/selftest.py`, `tools/quick_check.py`).
## Quest book
```bash
python3 tools/quests.py
```
Generates the quest book (Phase 8) from `docs/quests.yaml` into `pack/config/ftbquests/quests/`, and the hidden advancements quests check. `tools/build.py` runs it. `--pull <FTB Quests folder>` first copies node positions moved in the in-game editor back into `docs/quests.yaml` (`tools/prism_instance.py` does it from the instance before each sync); `--check` fails if the generated files are out of date.
## Legend summons
```bash
python3 tools/summons.py && python3 tools/zone_bosses.py
```
Writes the Sigils' recipes and data and their fights (Phase 9) from `world/summons.json`. Then run `tools/jei_sources.py` and rebuild.
## JEI drop sources
```bash
python3 tools/jei_sources.py
```
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).
## Handing out the pack
`tools/build.py` writes `build/cobblemon-survival-pack-<ver>-private.mrpack` (about 1 MB). Send that file to players: in Prism Launcher, Add Instance > Import, then pick the file. It lists all 43 mods and the shader pack by download link, so each player's launcher fetches them from Modrinth, CurseForge or the author's own host; no third-party jar is inside. It needs Prism: Modrinth's own app and site only accept links to their listed hosts, and four mods are only on CurseForge.
`tools/check_private_pack.py` downloads every link and checks it against the pinned hashes. After handing out a pack, run `python3 tools/server_update.py --mark-client-release`, so later balance updates know what players have.
For the server, install NeoForge from its installer (`--install-server`), then put the mods in with `python3 tools/packwiz_sync.py server <server folder>`, and copy `build/world-template` in as `world`. Balance updates then go through the section below.
## 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
1. Read its license and its Cobblemon 1.8 status; add both to `docs/licenses.md` and `docs/addon-status.md`.
2. `cd pack && packwiz modrinth add --project-id <id> --version-id <id>` (or `packwiz curseforge add --addon-id <id> --file-id <id>`). Always pin a version.
3. `python3 tools/crosslink.py`, which adds the other platform's source after checking that it's the same file. Overrides go in `tools/crosslink.json`.
4. `python3 tools/build.py`, then the smoke test.
## Disclaimer
Unofficial fan project, not affiliated with Nintendo, Game Freak, Creatures Inc., The Pokémon Company, the Cobblemon team, Mojang Studios or Microsoft. Free, with no monetization. Full credits: [docs/licenses.md](docs/licenses.md).