A Waccamaw-themed strategy game built in Godot 4
"Happy Hunting… or Place of Great Weeping?"
Wachesaw is a chess-like strategy game on a 5×5 board with unique pieces, a swap mechanic, and two ways to win — capture the opponent's Chief, or cross a piece to their back row. Play through a single-player story campaign, or jump into a match against the AI.
The fastest way to get playing on a Mac. Requires Homebrew and just (brew install just).
git clone https://github.com/doughatcher/wachesaw.git
cd wachesaw
just mac-setupThis installs Godot 4.4, GTK4 Python bindings, and creates two app shortcuts in ~/Applications/ that you can launch from Spotlight (⌘Space):
| App | What it does |
|---|---|
| Wachesaw | Launches the game |
| Wachesaw Level Editor | Opens the visual puzzle/story editor |
You can also launch from the terminal:
# Play the game
just mac-level-editor data/story/chapter_1.json # then hit ▶ Play
# Or launch Godot directly
/Applications/Godot_v4.4.app/Contents/MacOS/Godot --path .If you're on Linux/Windows, or prefer a containerized setup, open the repo in VS Code with the Dev Containers extension. Everything is pre-installed in the container (Godot 4.4, Python, GTK4, export templates).
git clone https://github.com/doughatcher/wachesaw.git
code wachesaw/ # VS Code → "Reopen in Container" when promptedThe container auto-builds the web export and serves it on port 8000 — open http://localhost:8000 in your browser to play.
The level editor is a native GTK4 desktop app. To run it from inside the dev container, you need X11 forwarding so the container can draw windows on your host display.
Linux host — works out of the box. The container mounts /tmp/.X11-unix and passes your $DISPLAY variable automatically:
# Inside the container terminal:
just level-editor # opens file chooser
just edit-chapter 1 # opens chapter 1macOS host — install XQuartz first:
brew install --cask xquartzThen open XQuartz → Preferences → Security → check "Allow connections from network clients". Log out and back in (or reboot) for the setting to take effect. After that, the level editor will render on your Mac desktop through XQuartz.
Windows host — install VcXsrv or X410. Launch it with "Disable access control" checked, then set DISPLAY=host.docker.internal:0 in the container environment.
If X11 isn't available, you can still edit chapter JSON files directly — they're human-readable. Or use the web workflow: just watch-story 1 builds a debug web export with hot-reload.
The level editor (tools/level_editor.py) is a GTK4 visual tool for authoring story chapters — the JSON files under data/story/ that define the single-player campaign.
Each chapter is a sequence of steps — dialog scenes (story text with speaker portraits) and puzzle scenes (a board position the player must solve). The editor lets you:
- Add, reorder, and delete steps in the left sidebar
- Edit puzzle boards visually — click any cell to place or change a piece
- Set puzzle metadata — win condition, max moves, opponent scripted responses, hints
- Edit dialog lines — speaker, portrait, and text for each line
- Play-test instantly — hit ▶ Play to launch the puzzle in Godot (macOS native mode) or in a browser (dev container / web mode). Edits are hot-reloaded on save.
| Mode | How Play works | Setup |
|---|---|---|
| Native (macOS) | Launches Godot directly. Subsequent saves hot-reload via file polling — no restart needed. Godot grabs focus automatically. | just mac-level-editor |
| Web (container) | Builds a web debug export, starts a dev server, opens your browser. File changes are served live. | just level-editor (needs X11) or just watch-story N (no GUI) |
Chapters live in data/story/chapter_N.json. Each file has a title and a steps array:
{
"title": "The Gathering Storm",
"steps": [
{
"type": "dialog",
"lines": [
{ "speaker": "Elder", "portrait": "elder_neutral", "text": "The Waccamaw lands have known peace…" }
]
},
{
"type": "puzzle",
"id": "ch1_p01",
"title": "The First Lesson",
"description": "Capture the enemy Chief to win.",
"player": "white",
"board": [ [null, null, ...], ... ],
"win_condition": { "type": "capture_chief", "max_moves": 1 },
"opponent_moves": ["Kd4"],
"hint": "The Keeper can reach the Chief in one move."
}
]
}The game's MapWatcher autoload watches for file changes and hot-reloads the current puzzle, so you get a tight edit → save → see loop.
All commands use just (brew install just or included in the dev container).
| Command | Description |
|---|---|
just mac-setup |
Install Godot 4.4, GTK4 deps, create Spotlight shortcuts |
just mac-level-editor |
Open the level editor (native Godot playback) |
just mac-edit-chapter N |
Open chapter N in the level editor |
| Command | Description |
|---|---|
just level-editor |
Open the GTK4 level editor (needs X11 display) |
just edit-chapter N |
Open chapter N in the level editor |
just watch-story N |
Build web debug + serve chapter N with hot-reload |
just watch-story N puzzle_id |
Same, jumping to a specific puzzle |
just serve |
Serve the web build on port 8000 |
| Command | Description |
|---|---|
just build-web |
Release web export → builds/web/ |
just build-web-debug |
Debug web export (for dev server) |
just build-linux |
Linux x86_64 binary |
just build-macos |
macOS export |
just build-windows |
Windows .exe |
just build-all |
All desktop + web |
| Command | Description |
|---|---|
just editor |
Open the Godot editor |
just clean |
Remove all build artifacts |
just clean-all |
Remove builds + Godot import cache |
just release |
Tag a release and push to GitHub |
These commands operate on the companion repos cloned into apps/. See multi-repo-arch.md for the full architecture.
| Command | Description |
|---|---|
just clone-apps |
Clone or update wachesaw-api and wachesaw-express into apps/ |
just api-dev |
Start Cloudflare Workers API locally (port 8787) |
just api-deploy |
Deploy API to production |
just api-deploy-staging |
Deploy API to staging |
just api-migrate |
Apply D1 database migrations |
just api-backup |
Manual D1 backup to R2 |
just express-dev |
Start Expo web dev server (port 8081) |
just express-build |
Build Expo PWA static export |
just setup-cloudflare |
Interactive Cloudflare login (wrangler login) |
just setup-gh |
Interactive GitHub CLI login |
Wachesaw is a three-repo system:
| Repo | Role | URL |
|---|---|---|
| wachesaw (this repo) | Godot game engine — story mode, AI, desktop/console/web builds | play.wachesaw.app |
| wachesaw-api | Cloudflare Workers API — auth, progress sync, community puzzles, leaderboards | api.wachesaw.app |
| wachesaw-express | Expo PWA — level editor, daily puzzles, community browser | wachesaw.app |
This repo's devcontainer is the hub — it includes Godot, Node.js, Wrangler, Expo CLI, and gh CLI. Run just clone-apps to pull the other repos into apps/. See multi-repo-arch.md for the full architecture, data contracts, auth flow, and CI/CD plan.
Everything below is the detailed design spec — rules, AI, architecture, platform targets, and roadmap.
Name: Wachesaw Tagline: "Happy Hunting… or Place of Great Weeping?" Genre: Abstract strategy / digital board game Theme: Waccamaw Indian heritage (initially chess-styled for mechanics validation; Native American theme applied later) Business model: Freemium Engine: Godot 4.4+ (GDScript primary, C# optional for performance-critical systems)
- 5×5 grid
- Center column (c-file) is thematically "The River" — no gameplay effect in v1, reserved for future map variants
- Coordinate system: columns a–e (left to right), rows 1–5 (bottom to top from White's perspective)
a b c d e
5 [B♞] [B♛] [B♚] [B♝] [B♜] ← Black home row
4 . . . . .
3 . . . . .
2 . . . . .
1 [W♖] [W♗] [W♔] [W♕] [W♘] ← White home row
White is always at the bottom (rows 1–2), Black at the top (rows 4–5). The layout is mirrored so identical piece types face each other diagonally, not directly.
| Piece | Chess Symbol (W/B) | Movement | Special Rules |
|---|---|---|---|
| Chief | ♔ / ♚ | 1 square in any direction (king) | Lose this = lose the game. Cannot win by crossing. |
| Keeper | ♕ / ♛ | 1 square in any direction (queen, range-limited) | Most versatile piece. Bodyguard role. |
| Hunter | ♖ / ♜ | 1 square orthogonal only (rook, range-limited) | Controls files and ranks. |
| River Runner | ♗ / ♝ | 1 square diagonal only (bishop, range-limited) | Controls diagonals. |
| Trader | ♘ / ♞ | L-shape jump, can leap over pieces (knight) | Cannot win by crossing to back row. Can only win by capturing. |
A player must do exactly one of the following on their turn:
- Move — Move one of your pieces to an empty square following its movement pattern.
- Capture — Move one of your pieces onto a square occupied by an opponent's piece. The opponent's piece is removed from the board. Follows normal movement pattern.
- Swap — Choose any two of your own pieces that are adjacent (orthogonally or diagonally). They exchange positions. This counts as your entire turn. A swap is always legal if two friendly pieces are adjacent.
The game ends immediately when either condition is met:
- Chief Capture — If you capture the opponent's Chief (♔/♚), you win.
- Back Row Crossing — If you move one of your pieces onto the opponent's home row (row 5 for White, row 1 for Black), you win. Exception: The Chief and the Trader cannot trigger this win condition. Only the Keeper, Hunter, and River Runner can win by crossing.
- Three-fold repetition: If the same board position occurs 3 times, the player with more total piece value remaining wins. If equal, the player who most recently made a capture wins.
- No stalemate: The swap mechanic ensures a legal move is virtually always available. In the extremely rare case a player has no legal move (isolated single piece with no movement squares), that player loses.
- No draw offers: There is no draw. Every game produces a winner.
- Trader back-row exclusion: Without this rule, the Trader can reach the opponent's home row in exactly 2 moves from its starting position, creating an unstoppable rush. Excluding it forces the Trader into an assassin/disruptor role instead.
- Chief back-row exclusion: The Chief is meant to be protected, not used as an offensive runner. This also prevents a degenerate strategy of just marching the Chief forward.
- Swap mechanic: Borrowed from Monsiv. Ensures pieces are never "stuck" and creates a layer of repositioning tactics unique to this game.
- First-move advantage: Not yet mitigated. Requires extensive playtesting. Potential future solutions include a pie rule (second player may choose to swap sides after the first move) or a bid system. Decision deferred.
Minimax search with alpha-beta pruning. Pure game tree search — no neural networks or ML required for a 5×5 board.
The static board evaluation scores from Black's perspective (positive = good for Black):
score = Σ (for each piece on board):
sign × material_value
+ sign × advancement_bonus
+ sign × center_control_bonus
where sign = +1 if piece is Black, -1 if piece is White
Material values:
| Piece | Value |
|---|---|
| Chief | 0 (infinite implicit value — losing it loses the game) |
| Keeper | 900 |
| Trader | 700 |
| Hunter | 500 |
| River Runner | 400 |
Advancement bonus: For pieces that can win by crossing (Keeper, Hunter, River Runner): advancement = distance_toward_opponent_back_row × 18. Rewards pushing pieces forward.
Center control bonus: (4 - manhattan_distance_from_center) × 6. Rewards occupying the center of the board.
Terminal states:
- White Chief captured → +100,000
- Black Chief captured → −100,000
- Depth bonus added to terminal scores to prefer faster wins
| Level | Name | Search Depth (plies) | Random Move % | Description |
|---|---|---|---|---|
| 1 | Beginner | 1 | 40% | Makes random legal moves frequently. Safe for children/new players. |
| 2 | Easy | 2 | 20% | Sees 1 move ahead. Occasionally blunders. |
| 3 | Medium | 3 | 8% | Default. Sees threats and basic tactics. Beatable with thought. |
| 4 | Hard | 4 | 2% | Strong tactical play. Rarely blunders. |
| 5 | Expert | 5 | 0% | Full-depth search. No random moves. Very difficult to beat. |
Random move chance: At each AI turn, roll against the random threshold. If triggered, the AI plays a uniformly random legal move instead of the minimax result. This creates natural-feeling mistakes at lower difficulties.
On a 5×5 board with 10 pieces and an average branching factor of ~25–35 (moves + swaps), depth 5 search examines roughly 15–50 million nodes worst case before pruning. Alpha-beta pruning typically reduces this by 90%+. On modern hardware, depth 5 should complete in under 1 second. If performance is an issue at depth 5, add iterative deepening with a time cutoff (e.g., 800ms).
Standard chess piece symbols on a classic brown/tan chessboard. This is intentional — the goal is to validate mechanics before investing in custom art.
- Board: Alternating light (#f0d9b5) and dark (#b58863) squares
- Pieces: Unicode chess symbols at large size for readability
- UI: Dark panel theme (#312e2b background), minimal chrome
- Selected piece: Blue highlight
- Valid moves: Green dots (empty squares), red border (captures), blue highlight (swaps)
- Last move: Yellow highlight on from/to squares
- Move notation: Chess-style in sidebar (piece symbol + destination, × for captures, ⇄ for swaps)
When mechanics are validated, transition to:
- Stylized 3D low-poly board (carved wood/stone slab)
- Totem-style 3D piece models with distinct silhouettes
- Particle effects system (embers, water, light trails) — "Tetris Forever" aesthetic
- Warm earth-tone palette with river blue accents
- Southeastern Woodlands visual identity (avoid stereotypes — focus on landscape and geometric patterns)
- Camera: Isometric with subtle orbit, zoom
- Sound: Wood/stone placement, water ambient, drum-based stings
| Event | Effect | Priority |
|---|---|---|
| Piece selected | Soft glow pulse, rising ember particles | P0 |
| Valid moves | Gentle shimmer/ripple on target squares | P0 |
| Piece moved | Light trail along movement path | P0 |
| Capture | Burst scatter from captured piece position | P0 |
| Swap | Swirling exchange particles between pieces | P1 |
| Win (back row) | River of particles flowing across board | P1 |
| Win (Chief captured) | Radial burst, screen flash, falling embers | P1 |
| Game start | Pieces materialize with particle flourish | P2 |
All game rules must be data-driven. No rule should be hardcoded such that changing it requires modifying game logic source code.
Rules are defined in a JSON or Godot Resource file. The game logic layer reads this config at startup and uses it for all validation.
{
"board": {
"width": 5,
"height": 5,
"terrain": [
[0,0,1,0,0],
[0,0,1,0,0],
[0,0,1,0,0],
[0,0,1,0,0],
[0,0,1,0,0]
]
},
"terrain_types": {
"0": { "name": "normal", "effect": "none" },
"1": { "name": "river", "effect": "none", "visual": "water" }
},
"pieces": {
"CHIEF": {
"name": "Chief",
"moves": [[1,0],[-1,0],[0,1],[0,-1],[1,1],[1,-1],[-1,1],[-1,-1]],
"can_jump": false,
"can_cross_win": false,
"material_value": 0,
"is_leader": true
},
"KEEPER": {
"name": "Keeper",
"moves": [[1,0],[-1,0],[0,1],[0,-1],[1,1],[1,-1],[-1,1],[-1,-1]],
"can_jump": false,
"can_cross_win": true,
"material_value": 900,
"is_leader": false
},
"HUNTER": {
"name": "Hunter",
"moves": [[1,0],[-1,0],[0,1],[0,-1]],
"can_jump": false,
"can_cross_win": true,
"material_value": 500,
"is_leader": false
},
"RIVER_RUNNER": {
"name": "River Runner",
"moves": [[1,1],[1,-1],[-1,1],[-1,-1]],
"can_jump": false,
"can_cross_win": true,
"material_value": 400,
"is_leader": false
},
"TRADER": {
"name": "Trader",
"moves": [[2,1],[2,-1],[-2,1],[-2,-1],[1,2],[1,-2],[-1,2],[-1,-2]],
"can_jump": true,
"can_cross_win": false,
"material_value": 700,
"is_leader": false
}
},
"layout": {
"white": {
"row": 0,
"pieces": ["HUNTER","RIVER_RUNNER","CHIEF","KEEPER","TRADER"]
},
"black": {
"row": 4,
"pieces": ["TRADER","KEEPER","CHIEF","RIVER_RUNNER","HUNTER"]
}
},
"rules": {
"swap_enabled": true,
"swap_range": 1,
"swap_directions": "all_adjacent",
"win_conditions": ["capture_leader", "cross_back_row"],
"repetition_limit": 3,
"turn_timer_seconds": 0
}
}- Change board size without code changes
- Add/remove/modify piece types and their movement
- Create asymmetric piece sets
- Add terrain types with gameplay effects
- Modify win conditions
- Toggle or extend the swap mechanic
- Support the map editor (maps are just rule configs)
- A/B test balance changes by swapping config files
project/
├── core/ # Pure game logic — NO engine dependencies
│ ├── board.gd # Board state representation
│ ├── rules.gd # Rule config loader and validator
│ ├── move_generator.gd # Legal move generation
│ ├── win_checker.gd # Win condition evaluation
│ ├── ai/
│ │ ├── evaluator.gd # Board evaluation function
│ │ └── minimax.gd # Search with alpha-beta pruning
│ └── types.gd # Enums, data structures
│
├── presentation/ # Godot-specific rendering
│ ├── board_view.gd # 3D/2D board rendering
│ ├── piece_view.gd # Piece rendering and animation
│ ├── particles/ # Particle effect scenes
│ ├── ui/ # Menus, HUD, move log
│ │ ├── main_menu.tscn
│ │ ├── game_hud.tscn
│ │ ├── difficulty_selector.tscn
│ │ └── settings.tscn
│ ├── audio/ # Sound effects and music
│ └── themes/ # Visual theme resources
│ ├── chess_classic/ # Phase 1 chess style
│ └── waccamaw/ # Phase 2 native theme
│
├── network/ # Future multiplayer layer
│ ├── matchmaker.gd
│ ├── state_sync.gd
│ └── lobby.gd
│
├── data/ # Configuration and content
│ ├── rules/
│ │ ├── classic.json # Default 5x5 ruleset
│ │ └── variants/ # Alternate rule configs
│ ├── maps/
│ │ ├── builtin/ # Shipped maps
│ │ └── custom/ # User-created maps
│ └── saves/
│
├── platform/ # Platform-specific code
│ ├── mobile_input.gd # Touch controls
│ ├── desktop_input.gd # Mouse/keyboard
│ ├── console_input.gd # Gamepad
│ └── web_bridge.gd # Web-specific APIs
│
├── project.godot # Godot project file
├── export_presets.cfg # Export configurations
└── addons/ # Third-party Godot plugins
The core/ directory has zero imports from Godot engine APIs. It uses only GDScript language features (or C# if preferred). This means:
- Game logic is unit-testable without running the engine
- Rules can be validated in headless mode
- Future server-side validation (for multiplayer anti-cheat) can reuse the same code
- Porting to a different engine (unlikely but possible) only requires replacing
presentation/
MainMenu
→ select mode (AI / Local / Online*)
→ select difficulty (if AI)
→ load rule config
→ instantiate Board (core)
→ instantiate BoardView (presentation)
→ game loop:
1. BoardView renders current state
2. Wait for input (human) or compute (AI)
3. Validate move via core/move_generator
4. Apply move to Board state
5. Check win via core/win_checker
6. Animate move in BoardView
7. Switch turn, goto 1
→ game over → show result → return to menu or rematch
Install the following:
# 1. Godot 4.4+ (standard or .NET build if using C#)
# Download from https://godotengine.org/download
# Or via package manager:
# macOS:
brew install godot
# Linux (Flatpak):
flatpak install flathub org.godotengine.Godot
# Or download the binary and add to PATH
# 2. Export templates (required for building)
# In Godot: Editor → Manage Export Templates → Download
# 3. For web builds: No additional dependencies
# 4. For Android builds:
# - Android SDK (API 33+)
# - Android NDK r25+
# - OpenJDK 17
# - Set paths in Editor → Editor Settings → Export → Android
# 5. For iOS builds:
# - macOS with Xcode 15+
# - Apple Developer account
# - Set up signing in export preset
# 6. For console builds:
# - Register with platform holders (Nintendo, Microsoft, Sony)
# - Purchase W4 Consoles subscription (https://www.w4games.com/w4consoles)
# - Follow W4 integration docs# Create project
mkdir wachesaw && cd wachesaw
# Initialize Godot project (or create via Godot editor: Project → New Project)
# Project settings to configure:
# Display → Window → Size → 1280×720 (landscape)
# Display → Window → Stretch → Mode: canvas_items
# Display → Window → Stretch → Aspect: expand
# Rendering → Renderer → Forward+ (desktop/console) or Compatibility (web/mobile)
# Application → Config → Name: "Wachesaw"
# Directory structure
mkdir -p core core/ai presentation presentation/ui presentation/particles presentation/themes
mkdir -p presentation/themes/chess_classic presentation/themes/waccamaw
mkdir -p network data/rules data/rules/variants data/maps/builtin data/maps/custom
mkdir -p data/saves platform addons
# Place the classic.json rule config in data/rules/classic.jsonGodot supports command-line exports. After configuring export presets in the editor (Project → Export), you can build from CLI:
# =====================
# WEB (HTML5) — P0
# =====================
# Export preset name: "Web"
# Renderer: Compatibility (OpenGL ES 3.0 / WebGL 2)
godot --headless --export-release "Web" builds/web/wachesaw.html
# Serve locally for testing:
cd builds/web
python3 -m http.server 8000
# Open http://localhost:8000/wachesaw.html
# NOTE: Godot web exports require being served over HTTP (not file://),
# and need the correct MIME types for .wasm and .pck files.
# For production, deploy to any static hosting (Netlify, Vercel, S3, itch.io).
# =====================
# ANDROID — P0
# =====================
# Export preset name: "Android"
# Requires: Android SDK, NDK, JDK configured in Editor Settings
# Renderer: Compatibility (for broad device support) or Forward+
# Debug APK (for testing):
godot --headless --export-debug "Android" builds/android/wachesaw.apk
# Release AAB (for Google Play):
godot --headless --export-release "Android" builds/android/wachesaw.aab
# Install debug APK on connected device:
adb install builds/android/wachesaw.apk
# =====================
# iOS — P0
# =====================
# Export preset name: "iOS"
# Requires: macOS, Xcode 15+, Apple Developer account
# Renderer: Forward+ or Compatibility
godot --headless --export-release "iOS" builds/ios/wachesaw.xcodeproj
# Then open in Xcode, configure signing, and build/archive:
open builds/ios/wachesaw.xcodeproj
# In Xcode: Product → Archive → Distribute App
# =====================
# WINDOWS (Steam) — P1
# =====================
# Export preset name: "Windows Desktop"
godot --headless --export-release "Windows Desktop" builds/windows/wachesaw.exe
# For Steam, use Steamworks SDK integration:
# - Create app on Steamworks partner site
# - Use GodotSteam addon (https://github.com/GodotSteam/GodotSteam)
# - Configure depot and build in Steamworks
# =====================
# macOS — P1
# =====================
# Export preset name: "macOS"
godot --headless --export-release "macOS" builds/macos/wachesaw.dmg
# For notarization:
# xcrun notarytool submit builds/macos/wachesaw.dmg --apple-id $APPLE_ID --team-id $TEAM_ID
# =====================
# LINUX — P1
# =====================
# Export preset name: "Linux/X11"
godot --headless --export-release "Linux/X11" builds/linux/wachesaw.x86_64
# =====================
# NINTENDO SWITCH — P2
# =====================
# Requires: Nintendo Developer account + W4 Consoles subscription
# W4 provides Godot export templates for Switch
# Follow W4 Consoles documentation for setup
# Build with W4's custom export preset after integration
# =====================
# XBOX SERIES X|S — P2
# =====================
# Requires: ID@Xbox developer account + W4 Consoles subscription
# W4 provides Godot export templates for Xbox
# Follow W4 Consoles documentation for setup
# =====================
# PLAYSTATION 5 — P3
# =====================
# Requires: PlayStation Partners account + W4 Consoles subscription
# W4 provides Godot export templates for PS5
# Evaluate after Xbox launch| Platform | Renderer | Why |
|---|---|---|
| Web | Compatibility | WebGL 2 required; Forward+ not supported in browsers |
| Android | Compatibility | Broad device support; Forward+ only for high-end |
| iOS | Forward+ or Compatibility | Forward+ for newer iPads/iPhones, Compatibility for broader support |
| Windows/macOS/Linux | Forward+ | Full visual quality on desktop |
| Consoles | Forward+ | Console hardware supports it well |
The fastest path to a playable POC on web and phone:
# 1. Install Godot 4.4
# 2. Create new project in Godot Editor
# 3. Build core/ game logic first (board state, moves, win check)
# 4. Build a simple 2D board view using Godot's Control nodes or Sprite2D
# (3D comes later — 2D is faster for POC)
# 5. Export to Web:
# - Project → Export → Add Preset → Web
# - Set Renderer to Compatibility
# - Export
# - Serve with local HTTP server and open on phone browser
# 6. Export to Android:
# - Project → Export → Add Preset → Android
# - Configure SDK paths
# - Export debug APK
# - adb install on phone
# For the absolute fastest iteration loop:
# - Use Godot's built-in "Remote Debug" to run on phone via WiFi
# - Editor → Run → Deploy → Remote Debug → enable
# - Set your phone's IP in Project Settings → Network → Remote Debug# .github/workflows/build.yml (GitHub Actions example)
name: Build Wachesaw
on: [push, pull_request]
jobs:
build-web:
runs-on: ubuntu-latest
container: barichello/godot-ci:4.4
steps:
- uses: actions/checkout@v4
- run: mkdir -p builds/web
- run: godot --headless --export-release "Web" builds/web/index.html
- uses: actions/upload-artifact@v4
with:
name: web-build
path: builds/web/
build-android:
runs-on: ubuntu-latest
container: barichello/godot-ci:4.4
steps:
- uses: actions/checkout@v4
- run: mkdir -p builds/android
- run: godot --headless --export-debug "Android" builds/android/wachesaw.apk
- uses: actions/upload-artifact@v4
with:
name: android-build
path: builds/android/
build-windows:
runs-on: ubuntu-latest
container: barichello/godot-ci:4.4
steps:
- uses: actions/checkout@v4
- run: mkdir -p builds/windows
- run: godot --headless --export-release "Windows Desktop" builds/windows/wachesaw.exe
- uses: actions/upload-artifact@v4
with:
name: windows-build
path: builds/windows/- Online 1v1 matchmaking (ranked + casual)
- Friend list and match invites
- Match history
- Player profiles (name, avatar, W/L record, rank)
- Spectator mode
- In-game emotes (pre-set, not free text)
- Leaderboards (global and regional)
- Daily/weekly puzzle challenges
- Clans/tribes
- Tournaments (bracket-style)
- Replay sharing
- Community maps (share and rate)
- Nakama (open source, self-hostable) — best for indie with full control
- PlayFab (Microsoft) — free tier, good for Xbox integration
- Firebase (Google) — fastest to prototype, good for mobile
A map is a complete game configuration file that overrides the default rules:
- Board dimensions
- Terrain tiles (normal, river, bluff, marsh, fire)
- Starting positions
- Piece set per side (can be asymmetric)
- Rule overrides (custom win conditions, etc.)
- Visual theme
| Terrain | Effect |
|---|---|
| Normal | None |
| River | Only River Runner can stop here (others must cross in one move) |
| Bluff | Piece on bluff immune to non-jumping captures |
| Marsh | Piece entering marsh skips next turn |
| Fire | Piece on fire is destroyed after 2 turns if not moved |
- Visual drag-and-drop in-game editor
- Set board size, place terrain, position starting pieces
- Custom rules per map
- Save/load as JSON
- Share via community system
| Name | Size | Notes |
|---|---|---|
| Wachesaw Classic | 5×5 | Base game, no terrain |
| River Crossing | 5×5 | Center column is River terrain |
| The Bluffs | 7×7 | Larger board with elevation |
| Marshlands | 6×6 | Marsh chokepoints |
| The Great Hunt | 5×7 | Rectangular, asymmetric starts |
- Full base game (Wachesaw Classic)
- Online multiplayer (casual)
- 2–3 default maps
- Basic piece skins
- Cosmetic piece sets (carved wood, river stone, shell, bone)
- Board skins (different environments)
- Particle effect packs
- Map packs (5–10 curated maps with terrain)
- Campaign mode (single-player puzzles/tactics)
- Battle pass (seasonal cosmetics)
No pay-to-win. Gameplay rules are identical regardless of purchases.
- Godot project setup with directory structure above
-
core/— Board state, move generation, win checking, rule config loading -
core/ai/— Minimax with alpha-beta, evaluation function, difficulty levels -
presentation/— 2D board view with chess piece sprites - Menu screen (Play vs AI, Local 2P, difficulty selection)
- Basic game HUD (turn indicator, move log, captured pieces)
- Input handling (mouse + touch)
- Web export working and playable
- Android APK working and playable
- iOS build working (if on macOS)
- Move animations (piece slides, capture effects)
- Sound effects (placement, capture, win/loss)
- Settings screen (volume, difficulty, rules display)
- Touch UX polish (drag vs tap, confirmation, undo)
- Desktop builds (Windows, macOS, Linux)
- Steam integration (GodotSteam addon)
- Backend selection and setup
- Account system
- Online matchmaking
- Server-authoritative game validation
- Friend system, profiles
- Ranked mode
- Map system + terrain effects
- Map editor
- Campaign mode (puzzle challenges)
- Cosmetics system
- Native American visual theme (3D pieces, board, particles)
- W4 Consoles integration
- Switch submission
- Xbox submission
- Tournament system
- Community features
- PlayStation evaluation
| Decision | Status | Notes |
|---|---|---|
| First-move advantage mitigation | Deferred | Needs playtesting. Pie rule is leading candidate. |
| River column gameplay effect | Deferred | No effect in v1. May add in map variants. |
| Game name trademark | TODO | Search "Wachesaw" for conflicts with Wachesaw Plantation. |
| Cultural consultation | After POC | Bring a working game to the Waccamaw tribal council. |
| Exact piece 3D models | Phase 4 | Chess symbols for now. |
| Backend provider | Phase 3 | Nakama, PlayFab, or Firebase. Evaluate when needed. |
The React prototype built during design (wachesaw.jsx) contains a working implementation of:
- Board state management
- Move generation for all 5 piece types
- Swap mechanic
- Win condition checking (Chief capture + back-row crossing with exclusions)
- AI with minimax + alpha-beta + difficulty levels 1–5
- Chess-style UI and move notation
This prototype validates the rules and AI. The Godot implementation should replicate this logic in core/ and build the presentation layer on top.
End of specification.