Thank you for your interest in contributing to IronPhoenix, a C++20 engine for four-player Teams chess. Contributions that improve correctness, playing strength, performance, testing, documentation, tooling, or the localhost analysis GUI are welcome.
This guide explains how to propose changes that are easy to review and evaluate. For an overview of the engine and PhoenixNet, start with README.md and nnue/README.md.
- Review open issues and pull requests to avoid duplicating work. For a larger feature or a substantial search/evaluation redesign, open an issue to discuss the approach first.
- Keep changes focused: ideally, one feature, fix, or measurable optimization per pull request.
- Create a feature branch from the latest
main. Do not mix unrelated search changes, evaluation parameters, refactors, and formatting cleanups in one PR. - Describe the motivation, expected trade-offs, and a way to reproduce or measure the result.
- Do not commit generated build directories, large datasets, private credentials, or machine-specific configuration files. Add appropriate ignore rules when new tooling creates local artifacts.
IronPhoenix is not a standard two-player chess engine. All changes must respect:
- Teams: Red + Yellow versus Blue + Green.
- Turn order: Red → Blue → Yellow → Green, with appropriate handling of eliminated players.
- Board: 14 × 14 cross-shaped board with 160 playable squares.
- Scoring: Positive evaluations favor the side-to-move team, not necessarily the individual player or Red's team.
- Moves and state: Four-player check/king-capture and terminal rules, castling, promotion, en passant, and supported setup variations.
- Notation: IronPhoenix's four-player FEN4 and UCI-style coordinate moves. Ordinary 8 × 8 FEN and two-player SAN are not interchangeable with FEN4/PGN4.
Take particular care with teammate cooperation, the rotation of moves, positions where a king or player is eliminated, and scoring signs. Never assume a two-player chess algorithm or rule transfers unchanged.
You will need:
- CMake 3.24 or newer
- A C++20 compiler (MSVC, GCC, or Clang)
- A Git client
- Node.js 18+ only if working on the localhost web GUI
- Python and any required Python dependencies only for PhoenixNet training/export changes
From the repository root:
cmake -S . -B build -A x64 -DIRONPHOENIX_BUILD_TESTS=ON -DIRONPHOENIX_BUILD_BENCHMARK=ON
cmake --build build --config Release --parallel
ctest --test-dir build -C Release --output-on-failureIf using the repository's existing Visual Studio CMake out/build/x64-release configuration, you can build its ironphoenix target instead.
cmake -S . -B build -DCMAKE_BUILD_TYPE=Release \
-DIRONPHOENIX_BUILD_TESTS=ON -DIRONPHOENIX_BUILD_BENCHMARK=ON
cmake --build build --parallel
ctest --test-dir build -C Release --output-on-failureThese commands closely match the project's GitHub Actions build-and-test workflow. For generator work, keep IRONPHOENIX_BUILD_DATASET_GENERATOR=ON or configure the relevant target explicitly.
- Follow the surrounding project's C++20 naming, formatting, headers, and namespace conventions.
- Prefer focused changes with clear invariants over broad rewrites.
- Preserve search correctness: principal-variation handling, score and mate conventions, TT bounds, stop conditions, and four-player turn rotation.
- Do not introduce expensive calculations inside search or evaluation hot paths without measuring their cost. Consider bitboards, reuse of previously computed information, and avoiding redundant allocations.
- For evaluation changes, state which positions receive a bonus or penalty, whose team's score changes, and whether the term belongs to HCE, PhoenixNet NNUE, or both. An HCE change may have no effect when an NNUE network is loaded.
- For search heuristics such as LMR, RFP, NMP, SEE, and move pruning, document the guards that protect checks, tactical moves, mate scores, and unstable four-player positions. More pruning is not automatically better.
- Give new evaluation and search parameters understandable defaults and, where appropriate, tunable UCI options and a way to disable them for testing.
- Include explanatory comments where four-player semantics or non-obvious performance assumptions matter; avoid commenting every obvious line.
Every code PR should pass the existing tests and include a targeted regression test when changing behavior.
ctest --test-dir build -C Release --output-on-failureRelevant test areas include move generation and board correctness, search-stack behavior, mate stopping, pruning, evaluation, and UCI integration. Add new C++ test targets to CMakeLists.txt so CTest and CI execute them.
For a new evaluation term, test at least:
- Both teams and all relevant player orientations.
- Side-to-move team score signs.
- The condition that earns the bonus and conditions that must not earn it.
- Special cases such as missing or eliminated pieces, when applicable.
- Tuning boundaries, reset behavior, and disabling the feature.
- No unintended changes to the evaluation path when PhoenixNet NNUE is loaded.
For a bug fix, provide the smallest reproducible FEN4 position or command sequence you can. Tests should fail before the fix and pass afterward whenever practical.
The local web UI lives in web/. It uses Node.js to launch the native engine and supports FEN4, PGN4, and UCI analysis. See web/README.md.
Run the JavaScript test suite from the repository root:
node --test web/tests/*.test.jsAlso check JavaScript syntax if you modified client or server code:
node --check web/app.js
node --check web/server.js
node --check web/notation.jsFor protocol changes, test with the real compiled engine as well as mock fixtures. Keep the localhost server bound to loopback, validate inputs, and do not introduce arbitrary remote command execution.
If you change nnue/ training, features, export, or inference:
- Describe any feature layout, tensor-shape, output-scale, quantization, or model-format changes.
- Check that the C++ loader and Python exporter agree on serialization and score perspective.
- Clearly separate training/validation results from game-playing results.
- Preserve an HCE fallback and explain model compatibility when changing formats.
- Avoid committing large trained models or generated datasets unless specifically agreed upon.
A successful compile, deeper search, higher NPS, or a plausible evaluation term does not prove an Elo improvement. For strength-related PRs, include results when available and make clear when a change is still experimental.
For fair A/B testing:
- Compare against a known
maincommit with the same compiler, optimization settings, CPU allocation, hash size, time control, and engine options. - Use consistent four-player starting positions or an opening suite when available; balance teams/seats and repeat enough games to reduce random variation.
- Report the number of games, time control, concurrency, engine options, Elo estimate, and uncertainty/confidence interval when available.
- Use SPRT or another documented stopping rule for larger strength tests. Do not label a tiny or inconclusive sample as a confirmed win.
- Test NPS or elapsed time separately from playing strength, ideally on a fixed set of positions under comparable conditions.
- Report regressions as well as gains. If a heuristic loses Elo, consider disabling it or testing smaller weights before merging.
If you cannot run a meaningful match, say "strength not tested" rather than estimating an Elo improvement.
- Fork the repository or create a feature branch from the latest
mainif you have write access. - Make a focused change with tests and documentation as needed.
- Build and run the appropriate local checks.
- Open a PR targeting
main. Prefer a descriptive title such asEval: team bishop-pair bonusorSearch: reduce redundant check queries. - Address reviewer feedback and keep your branch reasonably current with
main. Do not rewrite shared history without coordinating with collaborators.
A useful PR description includes:
## Summary
What changed and why?
## Four-player considerations
How are teams, turn order, score signs, or special positions handled?
## Testing
- [ ] C++ build and CTest (Release)
- [ ] Relevant new regression tests
- [ ] Web / PhoenixNet checks, if applicable
## Performance / Elo
Baseline commit:
Test settings:
Results (or "not tested"):
## Risks / trade-offs
Known limitations, edge cases, or follow-up work:A PR can be reviewed before strength testing is complete; just label its status accurately. Do not claim a performance or Elo improvement without supporting measurements. The repository's GitHub Actions workflow builds and tests with Linux GCC and Windows MSVC for PRs targeting main.
For a bug, include the operating system, build configuration, relevant commit, exact UCI commands, FEN4 (or a minimal PGN4), expected behavior, actual behavior, and available logs or test output. For crashes, provide a reproducible case if possible.
For a feature request, describe the four-player problem it solves, the intended behavior, possible search/evaluation overhead, and how success could be measured. Benchmarks and representative positions are especially helpful.
Please keep issue discussions and code reviews respectful, technical, and constructive. Critique implementations and results, not contributors. Credit external ideas, datasets, and code appropriately, and check their licenses before incorporating them.
Thank you for helping make IronPhoenix stronger, faster, and more reliable.