Everything below was implemented today on top of the postmortem baseline (2.5/10).
| # | Feature | Files Changed |
|---|---|---|
| 1 | Phase Announcements — FIGHT!, DOUBLE ELIXIR, OVERTIME, GAME OVER banners with fade-in/fade-out | components.rs, ui.rs, main.rs |
| 2 | Path Cache Fix — Clear PathCache on all 4 tower-death sites (was only cleared during tiebreaker) |
combat.rs |
| 3 | Game State Machine — MainMenu → DeckBuilder → Playing → GameOver with ESC pause, full restart support |
components.rs, input.rs, ui.rs, main.rs, sandbox/main.rs |
| 4 | Deck Builder — Clickable card grid, 8-card selection, sorted by cost, type-colored, live counter | components.rs, input.rs, ui.rs, main.rs, sandbox/main.rs |
| 5 | 8 New Cards — 6 troops + 2 spells that all work with existing engine | stats.json |
| 6 | Deck::new_from_cards() — Constructor that takes custom card lists instead of hardcoded 8 | components.rs |
| 7 | Multi-Tile Validation — Troops with footprints >1x1 (e.g. Golem) now correctly check all overlapping tiles for terrain/zone limits | spawning.rs |
| Card | Cost | Type | Key Feature |
|---|---|---|---|
| Knight | 3 | Troop | Balanced melee tank |
| Archer | 3 | Troop | Ranged, spawns ×2, hits air |
| Skeleton Army | 3 | Troop | Swarm ×15 |
| Minions | 3 | Troop | Flying ×3, hits air |
| Valkyrie | 4 | Troop | Self-centered splash |
| Baby Dragon | 4 | Troop | Flying, target-centered splash |
| Mini P.E.K.K.A | 4 | Troop | Fast, high single-target damage |
| Musketeer | 4 | Troop | Long-range, hits air |
| Hog Rider 🆕 | 4 | Troop | Very Fast, Buildings-only |
| Lumberjack 🆕 | 4 | Troop | Very Fast, 0.7s hit speed |
| Giant | 5 | Troop | Slow tank, Buildings-only |
| Wizard 🆕 | 5 | Troop | Ranged splash, hits air |
| Barbarians 🆕 | 5 | Troop | Swarm ×5 melee |
| Balloon 🆕 | 5 | Troop | Flying, Buildings-only, splash |
| P.E.K.K.A 🆕 | 7 | Troop | Slow ultra-tank, 816 damage |
| Golem | 8 | Troop | Massive tank, death-spawns Golemites |
| Zap 🆕 | 2 | Spell | Instant, small radius, cheap |
| Goblin Barrel | 3 | Spell | Spawner, drops 3 Goblins |
| Arrows | 3 | Spell | Large radius, 3 waves |
| Fireball | 4 | Spell | High damage, knockback |
| Poison 🆕 | 4 | Spell | Damage-over-time, 10 waves |
| Category | Postmortem | After Session 1 | Now | Change |
|---|---|---|---|---|
| Core Simulation | 7/10 | 9/10 | 9.5/10 | ⬆️ +0.5 (footprint checks) |
| Game Rules | 8/10 | 9/10 | 9/10 | ➡️ |
| Card Variety | 3/10 | 3/10 | 6/10 | ⬆️ +3 (23 cards, all engine-compatible) |
| Visuals | 1/10 | 2/10 | 2/10 | ➡️ (still colored squares) |
| Audio | 0/10 | 0/10 | 0/10 | ➡️ |
| UI/UX | 2/10 | 3/10 | 6/10 | ⬆️ +3 (menu, deck builder, pause, announcements, game over) |
| AI | 0/10 | 0/10 | 0/10 | ➡️ |
| Engine Quality | — | 8/10 | 9/10 | ⬆️ +1 (state machine, path cache fix) |
| Overall | 2.5/10 | ~3.5/10 | ~5.5/10 | ⬆️ Engine + UX solid, needs visuals/audio/AI |
| Source | What to Search | License |
|---|---|---|
| itch.io | "fantasy warriors pixel art", "tower defense sprites" | Varies (check each) |
| OpenGameArt.org | "top-down characters", "fantasy units" | CC0/CC-BY (free) |
| Kenney.nl | "tiny dungeon", "tower defense" | CC0 (100% free) |
| craftpix.net | "2D game characters" | Free tier available |
Tip
Best starter pack: Search itch.io for "16x16 fantasy characters" or "32x32 top-down RPG". You need ~20 unit sprites + towers + spell effects.
Use image generation tools to create consistent pixel art sprites. Prompt example:
"32x32 pixel art sprite sheet, knight character, top-down view, 4 directional walk cycle, transparent background, fantasy game style"
- Place sprites in
assets/sprites/(e.g.,assets/sprites/knight.png) - In
spawning.rs, replace theSpriteBundlecolor rectangles:
// Currently:
SpriteBundle {
sprite: Sprite { color: team_color, custom_size: Some(Vec2::splat(size)), ..default() },
..default()
}
// Replace with:
SpriteBundle {
texture: asset_server.load("sprites/knight.png"),
sprite: Sprite { custom_size: Some(Vec2::splat(size)), ..default() },
..default()
}- Add
asset_server: Res<AssetServer>to thespawn_entity_systemparameters - Map card keys to sprite paths:
format!("sprites/{}.png", card_key)
assets/sprites/
├── troops/
│ ├── knight.png
│ ├── archer.png
│ ├── valkyrie.png
│ ├── baby_dragon.png
│ ├── ...etc
├── towers/
│ ├── princess_tower.png
│ └── king_tower.png
├── spells/
│ ├── fireball.png
│ ├── zap.png
│ └── ...etc
└── projectiles/
├── arrow.png
└── fireball_projectile.png
| Source | What to Get | License |
|---|---|---|
| freesound.org | Sword hits, explosions, deploy sounds | CC0/CC-BY |
| OpenGameArt.org | Game sound effects packs | CC0 |
| Kenney.nl | Impact, UI, and RPG sounds | CC0 |
| jsfxr | Generate retro SFX procedurally | N/A (you make them) |
| pixabay.com/sound-effects | Battle music, ambient | Pixabay License (free) |
Tip
jsfxr (https://sfxr.me/) is the fastest way to get started — generate unique deploy, hit, explosion, and elixir sounds in seconds, download as .wav.
Bevy has built-in audio. No extra crate needed.
- Place sounds in
assets/audio/(.wavor.oggformat) - Add an audio system:
// In spawning.rs or combat.rs:
fn play_deploy_sound(
asset_server: Res<AssetServer>,
mut commands: Commands,
) {
commands.spawn(AudioBundle {
source: asset_server.load("audio/deploy.wav"),
settings: PlaybackSettings::DESPAWN, // auto-cleanup
});
}- For background music (looping):
fn setup_music(asset_server: Res<AssetServer>, mut commands: Commands) {
commands.spawn(AudioBundle {
source: asset_server.load("audio/battle_music.ogg"),
settings: PlaybackSettings::LOOP,
});
}assets/audio/
├── music/
│ ├── menu_theme.ogg
│ └── battle_music.ogg
├── sfx/
│ ├── deploy.wav (troop placement)
│ ├── sword_hit.wav (melee attack)
│ ├── arrow_fire.wav (projectile launch)
│ ├── explosion.wav (fireball/spell impact)
│ ├── tower_destroy.wav (tower death)
│ ├── elixir_full.wav (10/10 elixir warning)
│ ├── card_select.wav (UI click)
│ └── victory.wav (game over win)
| # | Item | Difficulty | Notes |
|---|---|---|---|
| 1 | AI Opponent | Hard | Both teams still human-controlled. Need at least reactive AI for solo play. |
| 2 | Visual Assets | Medium | assets/sprites/ is still empty. All entities are colored squares. |
| 3 | Sound Effects | Medium | No audio system. Complete silence. |
| # | Item | Difficulty | Notes |
|---|---|---|---|
| 4 | Building Cards (Tesla, Inferno, Bomb Tower) | Hard | Deployed structures with lifetime timers |
| 5 | Moving Spell Hitboxes (The Log) | Medium | Linear-travel AoE, needs new spell type |
| 6 | Speed Buffs (Rage) | Medium | Needs speed modifier component |
| 7 | Periodic Spawning (Witch, Night Witch) | Medium | Timer-based sub-unit spawning |
| 8 | Card Levels | Medium | Stat multipliers per level |
| # | Item | Difficulty |
|---|---|---|
| 10 | Troop animations (walk, attack, death) | Medium |
| 11 | Particle effects (deploy, death, trails) | Medium |
| 12 | Segmented tower health bars | Easy |
| 13 | Animated elixir bar (purple fill) | Easy |
| 14 | Crown star animations | Easy |
| 15 | Banner announcements for crown kills | Easy |
| 16 | Replay system | Hard |
| 17 | Multiplayer / netcode | Very Hard |
| # | Severity | Description |
|---|---|---|
| 1 | 🟢 Low | app/ and sandbox/ are still near-identical |
| 2 | 🟢 Low | No error handling — unwrap() on stats.json and tower lookups |
| 3 | 🟢 Low | No unit tests — tests/ has only .gitkeep |
- 🤖 Build a Basic AI — Random card placement on a timer makes the game playable solo immediately
- 🎨 Get sprite assets — Download a free pack from itch.io or generate with AI, wire into
spawn_entity_system - 🔊 Add basic SFX — Generate 5-6 sounds with jsfxr, wire into deploy/combat/game-over systems
Important
The engine and game flow are now complete. The remaining work is entirely about content and presentation: assets, AI, and polish. The architecture doesn't need further changes.