# War Chess — Godot 4.4 iOS Port: Developer Handoff

**Prepared for:** Brandon (iOS Developer)
**Date:** April 28, 2026
**Project Owner:** Ashwin
**Live Web Version:** [warchess.co](https://warchess.co)

---

## 1. What This Project Is

War Chess is a tactical turn-based strategy game — think Advance Wars meets chess, wrapped in a Western military aesthetic. The web version is live and fully playable at warchess.co, built with Three.js. This Godot project is the **iOS port** of that game, targeting iPhone via Xcode export.

The game features:

- **Campaign Mode** — 10 historical battles (Gettysburg, Omaha Beach, Stalingrad, Verdun, Chosin Reservoir, Ia Drang, Mogadishu, 73 Easting, Tora Bora, Thermopylae) with unique terrain, enemy layouts, and assigned generals
- **Academy Mode** — 8 tutorial/training levels teaching mechanics progressively
- **War Games Mode** — Endless roguelike waves with buff selection between rounds
- **Codex** — Encyclopedia of units, generals, and game lore
- **7 Historical Generals** — Patton, Alexander, Sun Tzu, Zhuge Liang, Rommel, Napoleon, Clausewitz — each with portraits, board sprites, traits, and quotes
- **6 Piece Types** — King, Queen, Rook, Bishop, Knight, Pawn — each with unique stats and a special ability
- **Dynamic Terrain Events** — Earthquakes, floods, eruptions, rotating board sections
- **Full Original Soundtrack** — 12 battle tracks + menu + victory + anthem

---

## 2. Project Structure

```
war-chess-godot/
├── project.godot              ← Godot project config (480x270 viewport, integer scale)
├── default_bus_layout.tres    ← Audio bus layout (Master, Music, SFX, Ambient, UI)
│
├── assets/
│   ├── icon.svg               ← App icon
│   ├── backgrounds/           ← 21 level backgrounds (480x270 PNG) + cover art
│   ├── sprites/
│   │   ├── pieces/            ← 12 piece sprites (128x171 PNG, transparent)
│   │   ├── generals/          ← 7 board sprites + 7 portraits (256px / 512px)
│   │   └── vehicles/          ← 3 vehicle sprites (tank, helicopter, motorcycle)
│   ├── tiles/
│   │   └── terrain_tileset.tres
│   └── audio/
│       └── music/             ← 12 OGG tracks (menu, victory, anthem, 9 battle)
│
├── autoloads/                 ← Singletons (registered in project.godot)
│   ├── game_manager.gd       ← Session state, progress, XP, stars, buffs, save/load
│   ├── audio_manager.gd      ← Procedural SFX, music crossfade, ambient, 12-pool
│   ├── scene_manager.gd      ← Scene transitions with fade
│   └── settings_manager.gd   ← Volume, controls, persistence
│
├── data/                      ← Static data registries (all RefCounted, no instances)
│   ├── constants.gd           ← PIECE_STATS, TERRAIN_*, colors, timing, grid size
│   ├── levels.gd              ← All 18 level definitions (tiles, enemies, music)
│   ├── generals.gd            ← 7 generals with traits, quotes, level assignments
│   ├── buffs.gd               ← War Games buff definitions
│   └── music_tracks.gd        ← Track key → res:// path mapping
│
├── systems/                   ← Core game logic (stateless utilities + BoardSystem)
│   ├── board.gd               ← Grid state, terrain, piece positions, pathfinding
│   ├── combat.gd              ← Damage calculation, terrain modifiers
│   ├── movement.gd            ← Valid moves, range calculation, terrain costs
│   ├── isometric.gd           ← Grid ↔ world coordinate conversion
│   ├── fog_of_war.gd          ← Visibility system
│   └── terrain_events.gd      ← Dynamic hazards (earthquake, flood, eruption, rotate)
│
├── entities/
│   ├── piece/
│   │   ├── piece.gd           ← WarPiece class: stats, abilities, animation, drawing
│   │   └── piece.tscn         ← Scene: Node2D + HitArea + PieceSprite + Shadow
│   └── projectile/
│       ├── projectile.gd
│       └── projectile.tscn
│
├── scenes/
│   ├── main_menu/             ← Title screen with mode badges
│   ├── menus/                 ← Mode select, level select, settings, placeholder
│   ├── briefing/              ← Pre-battle briefing with general portrait
│   ├── battle/                ← Core gameplay scene
│   │   ├── battle.gd          ← Turn loop, deployment, AI, victory/defeat
│   │   ├── battle.tscn
│   │   ├── combat_choreographer.gd
│   │   ├── ground_effects.gd
│   │   ├── scorch_mark.gd
│   │   └── terrain_view.gd
│   ├── codex/                 ← Encyclopedia screen
│   └── wargames/              ← War Games menu + buff selection
│
├── ui/
│   ├── hud/                   ← Battle HUD (turn counter, piece info, end turn)
│   ├── components/            ← Toast, coach tooltip, war box style
│   ├── tutorial_overlay.gd    ← Step-by-step tutorial system
│   ├── tutorial_overlay.tscn
│   ├── victory_screen.gd/tscn
│   └── defeat_screen.gd/tscn
│
└── shaders/
    ├── flash_white.gdshader   ← Hit flash effect
    └── vignette.gdshader      ← Screen edge darkening
```

---

## 3. Architecture Overview

### Autoload Singletons

The project registers four autoloads in `project.godot`. These are globally accessible from any script:

| Singleton | Purpose |
|-----------|---------|
| **GameManager** | Tracks current_level_id, current_mode, is_wargames, player progress (stars, XP, unlocks), active buffs, battle results. Handles save/load via ConfigFile. |
| **AudioManager** | All sound is procedurally generated at startup (no SFX files needed). Music loads from OGG files. Provides crossfade_music(), play_sfx(), play_footstep(), play_terrain_event(), etc. |
| **SceneManager** | Wraps scene transitions with a fade-to-black tween. |
| **SettingsManager** | Persists volume levels and control preferences. |

### Data Flow: Level → Battle

1. Player selects a level in `level_select.gd`
2. `GameManager.current_level_id` is set (e.g., `"gettysburg"`)
3. Scene transitions to `battle.tscn`
4. `battle.gd._ready()` loads level data from `Levels.get_level(level_id)`
5. Board is built from `level_data.tiles` (2D array of terrain ints)
6. Enemy pieces are spawned from `level_data.enemy_pieces`
7. Player deploys their pieces via touch
8. Turn loop begins

### The Turn Loop (battle.gd)

```
DEPLOYMENT → PLAYER_TURN → ENEMY_TURN → (repeat)
                ↓                ↓
         terrain events    AI moves
         coach hints       combat resolution
         ability use       death checks
                ↓                ↓
         victory check ←── victory check
```

Each turn:
- All pieces call `begin_turn()` (resets has_acted, decrements stun)
- Terrain events may trigger (20% chance after turn 3)
- Coach tooltip may show tactical hints
- Player/AI selects and moves pieces, attacks, uses abilities
- Victory = all enemy kings dead. Defeat = all player kings dead.

### Piece Abilities (Chunk 4)

Each piece type has one unique ability, usable once per battle:

| Piece | Ability | Effect |
|-------|---------|--------|
| **King** | COMMAND PUSH | Knockback all adjacent enemies 2 tiles |
| **Queen** | ROYAL DECREE | Heal all friendly pieces for 5 HP |
| **Rook** | SUPPRESSIVE FIRE | 8 damage to all enemies in same row/column |
| **Bishop** | OVERWATCH | 6 damage to enemies on diagonals within range+1 |
| **Knight** | FLASHBANG | Stun all adjacent enemies for 1 turn |
| **Pawn** | PROMOTION | If 2+ kills, promote to Knight |

---

## 4. Art Assets — What's Included

### Piece Sprites (12 files)
Located in `assets/sprites/pieces/`. Each is 128x171 PNG with transparent background. NanoBanana "cardboard standee" style — military figures on circular base discs.

| File | Description |
|------|-------------|
| `king_blue.png` / `king_red.png` | General with officer cap, baton, gold stars |
| `queen_blue.png` / `queen_red.png` | Armored warrior with cape, sword, gold trim |
| `knight_blue.png` / `knight_red.png` | Dual-pistol soldier, horse emblem on chest |
| `bishop_blue.png` / `bishop_red.png` | Long-range specialist with scope |
| `rook_blue.png` / `rook_red.png` | Heavy armored unit, fortress silhouette |
| `pawn_blue.png` / `pawn_red.png` | Infantry with helmet, body armor, M4 rifle |

### General Portraits (14 files)
Located in `assets/sprites/generals/`. Board sprites are 191x256, portraits are 382x512.

Each general has: `{name}.png` (board sprite) and `{name}_portrait.png` (briefing portrait).
Names: patton, alexander, suntzu, zhuge_liang, rommel, napoleon, clausewitz.

### Vehicle Sprites (3 files)
Located in `assets/sprites/vehicles/`: tank.png, helicopter.png, motorcycle.png (256x191).

### Level Backgrounds (21 files)
Located in `assets/backgrounds/`. All 480x270 PNG. Every campaign and academy level has a unique background:

**Campaign:** gettysburg.png, omaha_beach.png, verdun.png, chosin_reservoir.png, ia_drang.png, fallujah.png, tora_bora.png, 73_easting.png, stalingrad.png, el_alamein.png, mogadishu.png, thermopylae.png
**Academy:** tutorial_sandbox.png, academy_basic.png, academy_urban.png, academy_terrain_mastery.png, academy_flanking.png, academy_fog_cover.png, academy_ability_training.png, academy_final_exam.png
**Other:** cover_art.png

### Music (12 OGG files)
Located in `assets/audio/music/`. All converted from the original MP3 soundtrack.

| File | Used For |
|------|----------|
| `menu.ogg` | Main menu |
| `victory.ogg` | Victory screen |
| `anthem.ogg` | War Chess anthem |
| `battle_pastoral.ogg` | Gettysburg |
| `battle_beach.ogg` | Omaha Beach |
| `battle_trench.ogg` | Verdun |
| `battle_arctic.ogg` | Stalingrad, Chosin |
| `battle_default.ogg` | Default fallback |
| `battle_jungle.ogg` | Ia Drang |
| `battle_urban.ogg` | Fallujah, Mogadishu |
| `battle_desert.ogg` | Tora Bora, 73 Easting |
| `battle_academy.ogg` | All Academy levels |

---

## 5. What's Done vs. What Needs Finishing

### DONE (Ready to Use)

- **Full game logic** — Board system, movement, combat, terrain modifiers, fog of war, pathfinding
- **All 18 levels** — 10 campaign + 8 academy, each with unique tile layouts and enemy placements
- **Turn-based battle loop** — Deployment phase, player turns, enemy AI, victory/defeat detection
- **Enemy AI** — Evaluates threats, prioritizes targets, uses terrain advantage
- **6 piece types with stats** — HP, ATK, DEF, move range, attack range all balanced
- **6 unique abilities** — One per piece type, fully implemented
- **Terrain events** — Earthquake, flood, eruption, rotating section — all functional
- **Coach tooltip system** — Context-aware tactical hints during battle
- **Tutorial overlay** — Step-by-step guided tutorial for new players
- **War Games mode** — Endless waves with buff selection between rounds
- **Buff system** — 12 buffs that modify piece stats during War Games
- **Star rating** — 1-3 stars based on performance, tracked per level
- **XP and progression** — Level unlocking, XP gain, save/load via ConfigFile
- **Procedural SFX** — All sound effects generated from sine/noise at startup (no files needed)
- **Music system** — Crossfade, ambient layers, per-level track selection
- **All NanoBanana art** — 12 piece sprites, 14 general images, 3 vehicles, 21 backgrounds
- **12 music tracks** — Converted to OGG, mapped to all 18 levels
- **Full Codex screen** — 4 tabs (Units, Terrain, Generals, Tactics) with real sprites, portraits, stats, and descriptions

### ALREADY WIRED (Done by Manus)

The following three integrations are **complete** — no action needed from Brandon:

- **Piece Sprites** — `piece.gd._load_sprite_art()` automatically loads the correct PNG (e.g., `king_blue.png`) based on piece_type and team. The PieceSprite AnimatedSprite2D gets a SpriteFrames with the texture, scaled to 24px wide to fit the tile grid. When `use_sprite_art = true`, the `_draw()` method still renders overlays (shadow, selection glow, health bar, stun indicator, ability glint) on top of the real sprite. Falls back to procedural shapes if the PNG is missing.

- **General Portraits** — `briefing_screen.gd` loads the real portrait PNG from `assets/sprites/generals/{id}_portrait.png` into a TextureRect. Handles the `sun_tzu` → `suntzu` filename mapping automatically via `gid.replace("_", "")`. Falls back to a colored rectangle if the portrait file is missing.

- **Level Backgrounds** — `battle.gd._load_level_background()` loads a background PNG from `assets/backgrounds/{level_id}.png` into a TextureRect node behind the game world. Rendered at 35% opacity so terrain tiles show through. Falls back gracefully for levels without art.

### NEEDS FINISHING (Brandon's Tasks)

#### Priority 1: iOS Export Configuration

1. Open project in Godot 4.4
2. Go to Project → Export → Add iOS preset
3. Configure:
   - Bundle Identifier: `com.warchess.app` (or whatever Ashwin wants)
   - App Name: War Chess
   - Version: 1.0.0
   - Minimum iOS: 15.0
   - Orientation: Landscape
   - Icon: Use `assets/icon.svg` or generate from cover_art.png
4. Set up signing with Apple Developer certificate
5. Export to Xcode project
6. Build and test on device via USB or TestFlight

#### Priority 2: Touch Input Polish

The game already handles touch via `InputEventScreenTouch` in `piece.gd` and camera pan/pinch-zoom in `battle.gd`. Tap forgiveness has been tuned for mobile (18px distance, 0.35s duration). Things to verify on a real device:
- Tap accuracy on the small 480x270 viewport (integer-scaled to device resolution)
- Pinch-to-zoom is implemented (two-finger distance tracking in `_handle_screen_drag`)
- Swipe gestures for camera pan feel natural (momentum + decay is implemented)
- State guards prevent input during animations (double-tap protection added)
- No accidental taps during piece selection

#### ALREADY DONE (No Action Needed)

The following were completed by Manus and are fully wired:
- **All 21 level backgrounds** — Every campaign and academy level has a unique background image
- **All music track mappings** — Every level maps to an existing OGG file in `music_tracks.gd`
- **Full Codex screen** — 4 tabs (Units, Terrain, Generals, Tactics) showing real piece sprites, general portraits, stats from constants.gd, ability descriptions, terrain data, and tactical tips

---

## 6. Key Technical Notes

### Viewport and Scaling
- Canvas size: **480 x 270** (16:9 at low res)
- Stretch mode: **viewport** (pixel-perfect scaling)
- Stretch aspect: **keep** (letterbox on non-16:9 screens)
- This means all art is designed for this tiny canvas and scales up cleanly

### Isometric Grid
- `isometric.gd` converts between grid coordinates (Vector2i) and world pixel positions (Vector2)
- Tile size is defined in `constants.gd` as `TILE_WIDTH = 32, TILE_HEIGHT = 16`
- Grid origin is top-left; pieces are positioned at tile centers

### Terrain System
- Terrain types are integers defined in `constants.gd` (TERRAIN_GRASS = 0, TERRAIN_FOREST = 1, etc.)
- Each terrain type has movement cost, defense bonus, and visual properties
- The board stores terrain as a 2D array: `board.tiles[y][x]`
- Terrain can be mutated at runtime by terrain events via `board.set_terrain(cell, type)`

### Save System
- Uses Godot's `ConfigFile` (writes to `user://save.cfg`)
- Saves: completed levels, star ratings, XP, unlocked levels, settings
- War Games progress is session-only (not persisted across app launches)

### Audio Architecture
- **SFX**: All procedurally generated from sine waves, noise, and sweeps at startup. Zero external SFX files. The `_generate_sound_cache()` method in `audio_manager.gd` creates ~20 sounds.
- **Music**: Loaded from OGG files in `assets/audio/music/`. Crossfade between tracks. Falls back to silence if file is missing.
- **Ambient**: Layered on top of music. Currently placeholder (no ambient OGG files included).
- **Bus Layout**: Master → Music, SFX, Ambient, UI (each with independent volume)

---

## 7. How to Build and Run

### Prerequisites
- macOS with Xcode 15+ installed
- Godot 4.4 (download from [godotengine.org](https://godotengine.org))
- Apple Developer account ($99/year) for device testing
- iPhone or iPad for testing

### Steps

1. **Unzip** the project to any directory
2. **Open Godot 4.4** → Import → navigate to the `project.godot` file
3. **Hit Play (F5)** to test in the editor — the game should run immediately
4. **Project → Export → Add Preset → iOS**
5. Configure bundle ID, signing, and icons
6. **Export** to an Xcode project folder
7. **Open in Xcode** → select your device → Build & Run
8. Or archive and upload to **TestFlight** for wireless testing

### Common Issues
- If music doesn't play: check that OGG files are in `assets/audio/music/` and the import settings are correct (Godot should auto-import them)
- If sprites don't show: check that the PNG files exist in `assets/sprites/pieces/` — the `_load_sprite_art()` function in `piece.gd` handles everything automatically
- If the game looks blurry: ensure the export template uses "viewport" stretch mode, not "canvas_items"

---

## 8. Web Version Reference

The web version at [warchess.co](https://warchess.co) is the definitive reference for how everything should look and feel. When in doubt about any visual, gameplay, or audio behavior, play the web version and match it.

Key differences between web and Godot versions:
- Web uses Three.js with 3D terrain + 2D billboard sprites; Godot uses pure 2D isometric
- Web has a full music player with 36+ tracks; Godot has 12 core tracks
- Web has multiplayer infrastructure; Godot is single-player only
- Web renders at any resolution; Godot uses fixed 480x270 with integer scaling

---

## 9. Contact

- **Ashwin** (Project Owner) — has full context on game design, art direction, and music
- **Web Version Codebase** — available at the space-chess project if you need to reference any game logic, level data, or asset URLs
- **Art Assets** — all original high-resolution sprites are stored in the web version's manus-storage. The Godot versions are resized copies optimized for the 480x270 canvas.

---

*This document was prepared by Manus AI on April 28, 2026.*
