# Contributing to PokeSim Everyone taking part is expected to follow the [code of conduct](CODE_OF_CONDUCT.md). For questions, see [getting help](SUPPORT.md). Original code is MIT licensed. Keep changes focused and describe the problem, resulting behavior, and validation in each pull request. Start with the [documentation index](docs/README.md) and [module boundaries](docs/architecture.md). ## Development setup Use Python 3.11 or newer, [uv](https://docs.astral.sh/uv/), Git, and Node.js 22 for browser checks. From the repository root: ```sh uv sync --locked --extra dev git clone https://github.com/pret/pokered .reference/pokered git -C .reference/pokered checkout a1a22aaf84d1675bcdbaeb194592379d586d838e uv run --locked python -m pokesim.prepare_data .reference/pokered ``` Reference preparation writes local game data for tests and native runs. It does not create a ROM. For an existing reference checkout, skip cloning and verify its revision. See [desktop development](docs/desktop.md#build-and-verify-the-python-package) for isolated package and native worker checks. ## Checks before a pull request ```sh uv run --locked pytest --ignore=tests/test_rom.py -q uv run --locked python tools/check_web.py uv run --locked python tools/check_docs.py uv build uv run --locked python tools/check_install.py package ``` Stylesheet changes also need `npm ci` once, then `npm run lint:css`. Stylelint enforces the shared breakpoints in `tools/stylelint/breakpoints.mjs`, and the pytest suite runs it when it is installed. These Node packages are development tools only and stay out of the wheel, the source archive and the image. `check_web.py` checks every packaged browser script and runs every `tests/*.test.cjs` file. `check_docs.py` checks local Markdown link destinations. CI runs the same checks. `main` and `feature/` branches take changes only through a pull request whose `ci gate` and `install gate` checks passed. Run focused tests while editing, then the full suite for changes to shared behavior. See [the validation guide](docs/testing.md) for real Chromium tests, copied-save comparisons, and embedded build identity. A failed push run on `main` reruns its failed jobs once by itself. A run that passes on that rerun is a flake. `python tools/flake_rate.py` with `GH_TOKEN` set counts them for the last 30 days. Policies decide once per emulator step, so code that runs on every step must not redo work that grows with the dex, the party, the PC, a map or the navigation graph. Cache such a result on a cheap change key, such as the snapshot fields it reads or a version counter bumped on every mutation, and recompute only when the key changes. Callers that change a result must get their own copy. `tests/test_step_budget.py` runs the per-step decision on large synthetic Gen I and Gen II states and fails when a step goes over its budget, about 5 ms median and 50 ms at most. Set `POKESIM_STEP_BUDGET_SCALE` to widen it on a slow machine. Optional ROM integration tests use your own supported ROM: ```sh uv run --locked pytest tests/test_rom.py -q ``` Never add ROMs, cartridge saves, portrait packs, private traces, or generated game data to source control, CI artifacts, or issues. Use synthetic states or private copied checkpoints for policy scenarios. ## Repository map | Path | Responsibility | | --- | --- | | `pokesim/` | Emulator, persistence, game data, and desktop entry points | | `pokesim/policies/` | Gameplay decisions and project planning | | `pokesim/web/` | HTTP routes, presentation helpers, and browser assets | | `pokesim/trade/`, `pokesim/broker/` | Checkpoint exchanges, coordination, and inventory matching | | `tests/` | Python scenarios and Node browser tests | | [`tools/`](tools/README.md) | Data preparation, validation, release, and operations commands | | `deploy/`, `compose*.yaml` | Server deployment examples | | `docs/` | Current guides, plans, and indexed historical evidence | `data/`, `roms/`, `.reference/`, `.release-local/`, `build/`, and `dist/` are local working artifacts excluded from Git. Some contain irreplaceable saves or private reproductions. Do not treat them all as disposable caches. ## Compatibility and documentation Save-format changes need a format version, upgrade and rollback notes, and a recovery test. The emulator comes from `pokecore` and `pyboy-rs`, which are bounded to compatible ranges deliberately. Test existing checkpoints, including loading them with the previous release, before widening a range. Use `uv lock --upgrade-package PACKAGE` for an intentional dependency update, then rerun affected checks and the container build. Generated data must retain its upstream revision and generator command. See the [feature guide](docs/guide.md#generated-game-data) and [third-party notices](THIRD_PARTY_NOTICES.md). Update the owning guide when behavior changes, and describe user-visible changes in the pull request. The release pull request writes [CHANGELOG.md](CHANGELOG.md) from those descriptions, so other pull requests leave it alone. Keep future work in the roadmap and deployment details in validation receipts. Review `docs/release-notes.md` for the exact tag before publishing. For publishing triggers, GHCR setup, and recovery after a failed release run, see the [release workflow guide](docs/publishing.md). Bug reports should include the release or commit, operating system and CPU architecture, ROM hash, sanitized settings and logs, and reproduction steps. Omit tokens and private save files. Use [private reporting](SECURITY.md) for security issues.