CombatChess

β™žπŸ₯Š Combat Chess

Chess where captures don’t go quietly. Every capture can be challenged into a real-time, Street Fighter-style pixel brawl β€” and the piece that wins the fight keeps the square. Checkmate isn’t the end either: the king always gets one last stand in the ring.

License: GPL v3 Platform: iOS 17+ Swift 5.9 Engine: Stockfish 17

A native iOS game in SwiftUI + SpriteKit. Free software under the GPLv3 β€” clone it, build it, mod it, learn from it.


Features

How it plays

You command the White army. Standard chess until a capture is contested β€” then both pieces enter a side-view arena. Fight stats scale with chess value (HP = 50 + 25Γ—points, pawns are scrappy underdogs, queens are monsters, kings are 300 HP tanks). Blocking the correct side absorbs 80% of a hit, perfect dodges negate everything and charge your super, and every action drains stamina β€” a fully drained fighter is helpless and takes 1.5Γ— damage. Spam loses; reads win.

Getting started

Requirements: Xcode 16+, iOS 17+ target. No account needed for offline play; online play needs an Apple Developer account (see below).

  1. Clone the repo and open CombatChess.xcodeproj. Xcode resolves the single package dependency (ChessKitEngine, MIT).
  2. Stockfish networks (one manual step): download nn-1111cefa1111.nnue (~75 MB) and nn-37f18f62d772.nnue (~5 MB) from https://tests.stockfishchess.org/nns and drop both into CombatChess/CombatChess/. They’re gitignored as large binary data. Without them the app still runs β€” the built-in Swift minimax engine takes over transparently.
  3. Set your team under Signing & Capabilities and run.
  4. Online play (optional): requires the Game Center capability on your App ID and an App Store Connect app record with Game Center enabled, plus sandbox Game Center accounts on test devices.

Architecture

CombatChess/
β”œβ”€β”€ Models/          Chess rules engine (ChessBoard), match state machine
β”‚                    (MatchController: turns, cards, fights, king rule)
β”œβ”€β”€ Engine/          Stockfish adapter (EngineManager) + native minimax
β”‚                    fallback + AI card policies (ChessAI)
β”œβ”€β”€ Fight/           SpriteKit fight scene: deterministic seeded sim,
β”‚                    stamina system, multi-frame sprite animation
β”œβ”€β”€ Net/             Game Center: auth/matchmaking (GameKitManager),
β”‚                    turn-based bridge (OnlineMatchCoordinator), wire protocol
β”œβ”€β”€ Views/           SwiftUI: landing, board, fight wrapper, history, settings
β”œβ”€β”€ Persistence/     SwiftData match history
β”œβ”€β”€ PixelAssets/     194 generated PNGs (do not hand-edit β€” see pixelgen.py)
└── Support/         Pixel rendering helpers, seeded RNG, haptics
docs/                Online multiplayer technical design
pixelgen.py          The entire art pipeline (Python 3 + Pillow)

Key design decisions worth knowing before you dig in: the fight simulation routes all game-affecting randomness through a seeded SplitMix64 (deterministic replays / future lockstep netcode); MatchState is fully Codable and is the single source of truth shipped in online turn data; Stockfish strength comes from UCI_Elo/Skill Level with a hard movetime cap so moves stay fast.

The asset pipeline

Run python3 pixelgen.py from the repo root (needs pip install pillow) to regenerate all 194 assets: 168 fighter sprites (6 pieces Γ— 2 armies Γ— 14 animation frames), 3 stages, board tiles, piece icons, action cards, pixel logos, and the app icon. Palettes, poses, and body proportions are all data at the top of the script β€” a full visual re-theme is an afternoon, not a rewrite.

Roadmap / where help is wanted

Contributing

Issues and PRs welcome. Keep PRs focused (one system per PR), match the existing code style (plain Swift, no additional dependencies without discussion), and note that all contributions are accepted under GPLv3. For gameplay-balance changes, include your reasoning β€” tuning constants live at the top of FightScene.swift and in Difficulty.swift and are deliberately easy to experiment with. Art contributions should modify pixelgen.py, not the PNGs.

Privacy

Combat Chess collects nothing. No analytics, no advertising, no tracking, no accounts, and no server of ours for anything to be sent to. Because the whole codebase is public, you can verify that rather than take our word for it.

Full policy: PRIVACY.md β€” also published at https://punchmandev.github.io/CombatChess/#privacy and shown in-app under Settings β†’ Privacy Policy (App Store Review Guideline 5.1.1(i) requires the policy to be reachable from inside the app, not just the store listing).

The bundled PrivacyInfo.xcprivacy manifest declares no tracking and no collected data, with required-reason API disclosures for UserDefaults (CA92.1) and file timestamps (C617.1).

License

Combat Chess is licensed under the GNU General Public License v3 β€” see LICENSE. It bundles Stockfish (GPLv3, Β© the Stockfish developers) and uses ChessKitEngine (MIT). The app displays these notices in Settings β†’ Open Source & Licenses, which also links back to this repository as the Corresponding Source.

You may sell builds of this software; you may not close its source. If you ship a modified version, GPLv3 Β§5 requires prominent notice of your changes and this same license.

Maintainer release checklist (App Store)

Privacy manifest (PrivacyInfo.xcprivacy) and encryption-exemption flag are in the project; iPhone-only targeting is set. The public site (served from docs/ via GitHub Pages) supplies the URLs App Store Connect asks for:

App Store Connect field URL
Support URL (required) https://punchmandev.github.io/CombatChess/#support
Marketing URL https://punchmandev.github.io/CombatChess/
Privacy Policy URL (required) https://punchmandev.github.io/CombatChess/#privacy

Before each submission: sync this repo with the shipped source (that’s the GPL compliance), answer the App Privacy questionnaire as Data Not Collected, set the age rating (mild cartoon violence), confirm the NNUE networks are present in the copy you archive from, and run the device QA pass (all fight triggers, force-quit resume, online matches between two accounts). See docs/PRELAUNCH_AUDIT.md for the full pre-launch findings.