# AGENTS.md

Minecraft modpack "Aeroslop" (MC 1.21.1, NeoForge 21.1.248), managed with packwiz. There is no application code; the repo is pack metadata plus verification tooling.

## Environment

- Dev shell is nix/devenv (2.x): enter with `devenv shell`. Provides `packwiz`, `temurin-bin-21`, docker test helpers.
- `devenv.nix` defines the test scripts (`test-quick`, `test-server`, `test-client`, `test`, `test-status`) and the headless-client GL/audio env.
- Scripts run as `devenv shell <script>`; the bare `devenv <script>` form is not a subcommand and errors.

## Pack structure (packwiz)

- `pack.toml` — pack name, MC/NeoForge versions, index hash. Keep `version` in sync with the exported `.mrpack` filename (`Aeroslop-<version>.mrpack`).
- `mods/*.pw.toml` — one metafile per mod (name, filename, `side`, download url+hash, modrinth update info).
- `index.toml` — generated; never hand-edit. Run `packwiz refresh` from the repo root after any change to `mods/` or `pack.toml` to update hashes.
- Every `mods/*.pw.toml` must contain a `side` entry (`both`/`client`/`server`); `test-quick` fails on missing ones.
- Add mods with `packwiz modrinth add <mod>` so the metafile stays consistent.
- `config/*` — shipped modpack config defaults (installed into `<instance>/config/`). Currently `ftbultimine-server.snbt`.
- `moonlight-global-datapacks/<name>/` — datapacks applied to every world by Moonlight Lib (`pack.mcmeta` + `data/`). Used for pack-wide tag overrides.
- `.packwizignore` excludes devenv/scripts/.git from packwiz operations; keep it that way.
- `*.mrpack` exports are gitignored; generate with `packwiz modrinth export -o Aeroslop-1.0.0.mrpack`.

## Balance tweaks

- FTB Ultimine is gated to Create: Power Grid's electric tools (`powergrid:portable_drill`, `powergrid:portable_saw`). Three layers, primary first:
  - `kubejs/startup_scripts/ultimine_electric_tools.js` — registers an FTB Ultimine `RestrictionHandler` (mainhand must be one of the two tools). Airtight and the only layer that needs editing when tools change. FTB Ultimine allows this via `kubejs.classfilter.txt` (`+dev.ftb.mods.ftbultimine`); the event fires at common setup, after startup scripts.
  - `moonlight-global-datapacks/aeroslop-ultimine/` — fills `ftbultimine:excluded_tools` with every other tool tag/item (deny is checked before everything else). Backstop if the script fails to load; a new mod's untagged mining tool can slip past this layer.
  - `config/ftbultimine-server.snbt` — `require_tool` + `require_valid_tool_for_block`.
- `kubejs/*` is shipped by the pack; KubeJS + Rhino are pack mods, added for the Ultimine gate.

## Verification

Fast check after any pack edit:
- `devenv shell test-quick` — refresh + side lint + mrpack export. Always run this.

Full boot tests (slow, run in background; watch via `devenv shell test-status`):
- `devenv shell test-server` — serves pack via `packwiz serve --port 8080`, boots an `itzg/minecraft-server` docker container against it. Requires docker.
- `devenv shell test-client` — headless client boot via `scripts/launch-client.py` (custom launcher: resolves vanilla client, installs NeoForge, runs packwiz-installer-bootstrap, launches with `--quickPlaySingleplayer`). Requires Minecraft assets (`MC_ASSETS_DIR`, else auto-detects `~/.local/share/PrismLauncher/assets` or `~/.minecraft/assets`) and a display (default `xwayland`; `DISPLAY_MODE=xvfb` for headless).
- `devenv shell test` — quick checks, then starts both boot tests in background.

## Gotchas

- Test logs/caches live in `${XDG_CACHE_HOME:-~/.cache}/aeroslop-pack-test`; `devenv shell test-status` tails the last server/client run logs.
- Server test uses host networking on port 8080 and verifies the served `pack.toml` matches the local one — a stale `packwiz serve` on 8080 fails the test.
- Server test greps for `Done (` as the boot marker; client test for `Loaded.*entity animations`. Boot timeouts are 600s (server) / 1800s (client).
- Don't bump MC/NeoForge versions casually: they're consumed by both test scripts, the itzg image tag, and `launch-client.py` (`--mc-version`/`--neoforge-version`).
