# Clear Code Zelda Top-down ARPG, y-sort, particles, state machines, upgrade UI. ```{raw} html ▶ Run in browser

Upstream: https://github.com/clear-code-projects/Zelda

``` **Tags:** `port` `tier-1` # Clear Code Zelda: SimVX port SimVX port of [Clear Code's "Zelda" Pygame ARPG](https://github.com/clear-code-projects/Zelda) (Tier 1 Port #8). Top-down ARPG with sword combat, magic, enemy AI, particles, y-sort, and a stat-upgrade screen. Source assets are CC0 (Ninja Adventure pack) and reused unchanged. ## Run From `/home/fezzik/dev/simvx`: ```bash # Windowed uv run python ../ported_games/clear_code_zelda/simvx_port/main.py # Headless smoke test (renders 12 frames then exits) uv run python ../ported_games/clear_code_zelda/simvx_port/main.py --test # Headless screenshots (frame 30/60/120) uv run python ../ported_games/clear_code_zelda/simvx_port/capture.py # Full scripted harness: 13 scripted stages, one screenshot each uv run python ../ported_games/clear_code_zelda/simvx_port/harness.py # Web export uv run simvx export web ../ported_games/clear_code_zelda/simvx_port/main.py \ -o ../ported_games/clear_code_zelda/simvx_port/web/index.html ``` ## Controls | Key | Action | |----------------------|------------------------------| | `WASD` / arrows | Walk (8-direction) | | `SPACE` | Sword attack (melee) | | `LEFT/RIGHT CTRL` | Cast magic (heal / flame) | | `Q` | Cycle weapon (sword/lance/axe/rapier/sai) | | `E` | Cycle spell (heal/flame) | | `M` | Open / close upgrade menu | | `LEFT` / `RIGHT` | Upgrade selection (in menu) | | `SPACE` / `ENTER` | Buy upgrade (in menu) | | `ESC` | Quit | ## What works - 57x50 tile map loaded from upstream CSV layouts (boundary, grass, objects, entities) - Player movement with 12-direction animation set (walk/idle/attack × 4 facings) - Sword attack with directional weapon sprite + cooldown - 5 weapon types with different damage/cooldown values, swappable on-the-fly - 2 spells (heal restores HP, flame is a projectile) - 4 enemy types (squid, raccoon, spirit, bamboo) with idle/move/attack states - Enemy AI: notice radius → chase via `AStarGrid2D` → attack radius - Y-sort drawing via `YSortContainer` so player and enemies depth-sort by y - Particle effects: leaves on grass slash, magic sparkles on heal/flame, monster-specific death puffs - HUD: HP bar, energy bar, kills counter, XP counter, weapon/magic indicators, help strip - Upgrade screen: 5 panels (health/energy/attack/magic/speed) with selection, buy via SPACE, cost scales 1.4x per buy - AABB collision against invisible boundary tiles + objects (grass is walkable but slashable) - Web export (~2.6 MB single-file HTML) ## What's intentionally simplified - **No procedural floor texture.** Upstream uses a 3648×3200 ground.png (~180 KB). The port draws a flat green rect under the world to keep the web bundle small and avoid the texture-cache for one giant repeating image. Visually matches at a glance. - **Flame projectile is a single trail of looping puffs**, not the upstream's chained particle anim with sparkle. - **No background music.** Upstream's `main.ogg` shipped but is not auto-played here (web autoplay policy + `feedback_app_quit_pattern`). - **Camera is unsmoothed.** Player stays exactly centred; upstream's port has no smoothing either. - **"Death" wraps to full-heal**, not a Game Over screen; the upstream has the same loop. ## Source ```{literalinclude} ../../examples/ports/clear_code_zelda/main.py :language: python :linenos: ```