Compose Multiplatform chess app with full support for all standard chess rules and a 3D view mode, targeting:
- Android
- Desktop (JVM): Linux and macOS
- Web (Wasm)
- iOS
For the desktop target on Linux and macOS, JDK 26 is recommended. The desktop 3D renderer uses a native C++ Filament bridge; after a clean checkout run tools/fetch_filament_desktop.sh to fetch the gitignored Filament desktop payload before desktop builds.
For the desktop target on Linux, install stockfish first:
sudo apt install stockfish # For Ubuntu/Debian
sudo pacman -S stockfish # For Arch
sudo dnf install stockfish # For FedoraFor the desktop target on macOS:
brew install stockfishmacOS, Xcode 16+, and a working project JDK are required.
tools/fetch_filament_ios.shopen iosApp/iosApp.xcodeproj- Run the
iosAppscheme
The Stockfish engine is bundled automatically. The Filament iOS xcframeworks are fetched separately because they are large generated dependencies and are intentionally gitignored.
graph TD
subgraph commonMain ["commonMain (Shared)"]
GS["Game State (GameUiState)"] --> GameScreen["GameScreen (UI)"]
GS --> FC["FenConverter"]
FC --> FEN["FEN String"]
FEN --> BM["Board3DSceneMapper"]
BM --> B3S["Board3DScene (Renderer-Agnostic)"]
GameScreen -. "Toggles 3D view" .-> Renderer
Assets["Assets (chess.glb, IBL .ktx)"] --> Renderer
B3S --> Renderer
Renderer[["Chess3DBoardRenderer Contract"]]
end
subgraph Platforms ["Platform-Specific Renderers"]
Renderer --> Android["Android<br>AndroidSceneViewChessRenderer<br>(Filament / SceneView)"]
Renderer --> iOS["iOS<br>FilamentIosChessRenderer<br>(Filament / Metal)"]
Renderer --> Desktop["Desktop<br>DesktopFilamentChessRenderer<br>(Filament / native C++)"]
Renderer --> Web["Web (Wasm)<br>FilamentWasmChessRenderer<br>(Filament / WebGL)"]
end
%% Styling
classDef common fill:#e3f2fd,stroke:#1e88e5,stroke-width:2px,color:#000;
classDef state fill:#ffffff,stroke:#1e88e5,stroke-width:1px,color:#000;
classDef contract fill:#fff8e1,stroke:#ffb300,stroke-width:2px,color:#000;
classDef platform fill:#fafafa,stroke:#9e9e9e,stroke-width:2px,color:#000;
class commonMain common;
class GS,GameScreen,FC,FEN,BM,B3S,Assets state;
class Renderer contract;
class Android,iOS,Desktop,Web platform;
- Full Chess Rules: The application covers all standard chess rules and includes an explicit draw-by-agreement flow where the Stockfish engine evaluates whether to accept or decline draw offers.
- Game Lifecycle & Persistence: The in-progress game is auto-saved on every move and restored on next launch (board, turn, move list). On game end, the user can Save game (to a persisted Game History) and Share PGN (platform share sheet / file dialog / download). PGN export is full Standard Algebraic Notation with the Seven Tag Roster; paste a saved PGN into lichess.org "Import game" to validate. A History screen lists saved games with a detail view and delete.
- Engine Difficulty: A persisted Easy / Medium / Hard / Max setting (in Settings) weakens or strengthens Stockfish play via the UCI
Skill Leveloption and a per-move think-time budget. Applies to the Stockfish engine on every platform. - Settings & Navigation: A minimal multiplatform navigation host (
AppRoot) switches between the game, History, and Settings screens, with a persisted 3D-board toggle (default on) and the engine-difficulty selector in Settings. - 3D Board View: The app features a playable 3D board with shared camera, tap-to-move, ray picking, and move animation logic. Desktop, iOS, and web share
FilamentEncodedChessRendererfor FEN-to-scene, camera, selection, and transition state; their platform peers only own the Filament surface. Android uses Filament through SceneView (the visual reference); iOS uses Metal-native Filament through a Swift/Obj-C++CAMetalLayerbridge; desktop uses native C++ Filament with a headless swap chain and RGBA readback into Compose; web uses Filament (Wasm) loading the samechess.glbAndroid uses. Seedocs/plans/web-graphics-spike-result.mdanddocs/plans/ios-filament-spike-result.mdfor the spike verdicts. - Stockfish Engine Integrations:
- Android: Pinned to Stockfish 17, as the Stockfish 18 binary exceeds GitHub's 100 MB file limit.
- Desktop: Relies on system-installed binaries (e.g., via
aptorbrew). - Web (Wasm): Uses a lightweight
stockfish-18-lite-single.jsrunning in a Web Worker. - iOS: Wraps
ChessKitEngineusing an async-sync bridge and utilizes NNUE viaEvalFileSmall.
app/src/commonMainshared chess UI, game rules, and compose resourcesapp/src/androidMainAndroid-specific shared implementation and Stockfish integrationandroidApp/src/mainAndroid application manifest that depends on the shared KMP moduleapp/src/desktopMaindesktop launcherapp/src/wasmJsMainweb launcherapp/src/iosMainshared iOS implementationiosApp/Xcode project and Swift adapter
Third-party asset and dependency notices live in THIRD_PARTY_NOTICES.md.
./gradlew testruns shared unit tests./gradlew :androidApp:assembleDebug :androidApp:installDebugbuilds and installs the Android app./gradlew :app:runlaunches the desktop app./gradlew :app:wasmJsBrowserDevelopmentRunstarts the web target./gradlew :app:wasmJsBrowserDevelopmentWebpackbuilds the web development bundle without starting the dev server./gradlew :app:connectedAndroidDeviceTestruns Android UI tests./gradlew :app:iosSimulatorArm64Testruns iOS Compose UI tests./gradlew :app:desktopTest --tests "*board3d*"runs the 3D desktop tests (DesktopRendererSmokeTest writesbuild/chess3d-*.pngto eyeball the render)tools/ios_3d_screenshot.shcaptures the real iOS 3D board from a booted simulator