Execute approved sprint plans for Stapledons Voyage using AILANG. ALL game logic must be AILANG - engine is rendering only. Use when user says "execute sprint", "start implementation", or wants to begin an approved sprint plan.
Instalación
Instalar con Codex o Claude Copia este prompt, pégalo en Codex, Claude u otro asistente, y deja que revise la página de la skill y la instale por ti.
Execute approved sprint plans for Stapledons Voyage using AILANG. ALL game logic must be AILANG - engine is rendering only. Use when user says "execute sprint", "start implementation", or wants to begin an approved sprint plan.
Game Sprint Executor (AILANG-Only)
Execute an approved sprint plan with AILANG as the primary implementation language. All game logic, state machines, and gameplay code goes in sim/*.ail - the Go engine only renders DrawCmd output.
❌ Game-specific state types (DomeViewState, ArrivalState)
game_views/ for game-specific rendering:
DomeRenderer (solar system visualization)
DeckStackRenderer (5-deck ship structure)
DeckPreview (deck colors and names)
Any code that references sim_gen game types beyond DrawCmd
Example Violation (DO NOT DO):
// ❌ WRONG - in engine/render/draw.gofuncgetBridgeSpriteColor(id int64) color.RGBA {
case id == 1200: return ... // pilotcase id == 1201: return ... // comms <- GAME CONCEPTS IN ENGINE!
}
// ✅ RIGHT - move to game_views/sprite_colors.go// Or better: define colors in AILANG and pass via DrawCmd
Quick Start
Most common usage:
# User says: "Execute the arrival sequence sprint"# This skill will:# 1. Check AILANG modules compile# 2. Write new AILANG types and functions# 3. Run ailang check after every change# 4. Report AILANG issues immediately# 5. Compile to Go and test in engine
When to Use This Skill
Invoke this skill when:
User says "execute sprint", "start sprint", "begin implementation"
User has an approved sprint plan ready
Implementing ANY game feature (it MUST be AILANG)
Do NOT use this skill for:
Pure engine rendering changes (use dev-tools or direct edits)
Asset pipeline work (use asset-manager skill)
Core Principles
AILANG-First: ALL game logic in sim/*.ail - no exceptions
Test-Driven: Run ailang check after every change
Feedback-First: Report AILANG issues immediately
Track Progress: Use TodoWrite AND update sprint JSON
Document Workarounds: Record how you navigated limitations
Physics Accuracy First: Use exact formulas, document any approximations
No Wrapper Files: NEVER create Go wrapper files to work around AILANG codegen issues - report the bug and wait for a fix
JSON Progress Tracking (IMPORTANT)
Always update the sprint JSON file as you work. This enables session continuity.
Sprint JSON files can use either features-based (preferred for new sprints) or phases/tasks-based (legacy) structure.
Commands
# Location: sprints/sprint_<sprint-id>.json# For feature-based sprints (preferred):
.claude/skills/sprint-executor/scripts/update_progress.sh \
sprints/sprint_<sprint-id>.json feature <feature_id> in_progress
.claude/skills/sprint-executor/scripts/update_progress.sh \
sprints/sprint_<sprint-id>.json feature <feature_id> completed [actual_loc]
# For phase/task-based sprints (legacy):
.claude/skills/sprint-executor/scripts/update_progress.sh \
sprints/<sprint-id>.json task <task_id> completed
.claude/skills/sprint-executor/scripts/update_progress.sh \
sprints/<sprint-id>.json phase <phase_id> completed
# Update overall sprint status (both formats):
.claude/skills/sprint-executor/scripts/update_progress.sh \
<sprint-file>.json sprint in_progress
# Show current progress (auto-detects format):
.claude/skills/sprint-executor/scripts/update_progress.sh \
<sprint-file>.json show
Feature Command (for features-based sprints)
Command
Effect
feature <id> in_progress
Sets started timestamp
feature <id> completed
Sets completed timestamp, passes: true
feature <id> completed <loc>
Also sets actual_loc
feature <id> blocked
Sets passes: false
feature <id> pending
Resets to initial state
Status values:pending | in_progress | completed | blocked
When to Update JSON
Mark sprint as in_progress when starting
Mark each feature/task in_progress before starting work
Mark each feature/task completed immediately after finishing
Mark sprint completed at the end
Engine-Only Changes (Rare)
Most work should be AILANG. Engine changes are only needed for:
Adding new DrawCmd rendering (e.g., new DrawCmd variant)
Shader modifications (generic visual effects)
Asset loading (generic loaders)
STOP - Is this game-specific?
Game-specific rendering → game_views/*.go
Generic rendering → engine/*.go
For engine-only work:
make engine # Build engine only (skips sim_gen check)
make run # Test rendering
Remember: Engine code should be "dumb" - it only renders what AILANG tells it via DrawCmd. It should work unchanged for ANY AILANG game.
Game-Specific Views (game_views/)
For rendering helpers that reference game concepts:
DomeRenderer, DeckStackRenderer, DeckPreview
Any code using sim_gen types beyond DrawCmd/FrameInput/FrameOutput
Code that knows about decks, planets, crew, etc.
# game_views imports both engine/ and sim_gen/# engine/ should NOT import game_views/
Execution Flow
Phase 1: Initialize Sprint
Check Status
# For AILANG sprints:for f in sim/*.ail; do ailang check "$f"; done
ailang messages list --unread
# For mock-only sprints:
go test ./...
make game-mock
# After each file edit:
ailang check sim/<file>.ail
# If errors, fix immediately# If stuck, report to AILANG team
Test with ailang run
# Test entry function
ailang run --entry <function> sim/step.ail
Report Issues Encountered
# For bugs
~/.claude/skills/ailang-feedback/scripts/send_feedback.sh bug \
"Issue title""Description" --from stapledons_voyage
# For missing features
~/.claude/skills/ailang-feedback/scripts/send_feedback.sh feature \
"Feature needed""Why it would help" --from stapledons_voyage
Update Progress (IMPORTANT)
# After each task
.claude/skills/sprint-executor/scripts/update_progress.sh \
sprints/<sprint-id>.json task <task_id> completed
# After completing all tasks in a phase
.claude/skills/sprint-executor/scripts/update_progress.sh \
sprints/<sprint-id>.json phase <phase_id> completed
Note workarounds used
Update CLAUDE.md if new limitations found
Pause for Review
Show progress: .../update_progress.sh sprints/<id>.json show
Ask if ready to continue
Phase 3: Engine Integration (if needed)
Compile AILANG to Go
make sim # Generates sim_gen/*.go
Check Codegen Quality (MANDATORY)
# Run quality check on generated Go code
.claude/skills/sprint-executor/scripts/check_codegen_quality.sh
What it checks:
Excessive nesting (>20 chars indentation)
Too many closure wrappers (>10 consecutive)
Patterns that indicate AILANG codegen issues
If issues found:
Report to AILANG via ailang messages send user "..." --type bug --github
Consider refactoring AILANG source to reduce nesting (helper functions)
Document workarounds in sprint JSON
Test Game
make run # Run with Ebiten
Fix Integration Issues
Check generated Go code
Update engine/ if needed
Phase 4: Finalize Sprint
Final Testing
# All AILANG modulesfor f in sim/*.ail; do ailang check "$f"; done# Game build
make game
Skip this for mock-only sprints - the ailang-feedback skill is for AILANG language feedback, not general sprint completion.
For sprints that involve AILANG code, send a DX feedback message reflecting on the overall experience:
~/.claude/skills/ailang-feedback/scripts/send_feedback.sh dx \
"Sprint DX: <sprint-name>" \
"<honest reflection on working with AILANG this sprint>" \
--from stapledons_voyage
Include in your reflection:
Positives: What worked well? What felt natural?
Friction points: Where did you get stuck? What was confusing?
Productivity: Could you express your intent easily?
Error messages: Were they helpful or cryptic?
Documentation: Did ailang prompt have what you needed?
Overall sentiment: Would you want to use AILANG again?
Be honest - negative feedback is valuable. Examples:
"Pattern matching felt natural and expressive"
"Nested field access errors were frustrating to debug"
"The functional style made NPC updates clean"
"Had to fight the type system on record updates"
Sprint Report
Milestones completed
AILANG issues encountered (if any)
Workarounds used (if any)
DX rating (1-5 stars) - for AILANG sprints only
Error Handling
CRITICAL: Use make build - It Enforces Correct Behavior
Always use make build instead of go build!
make build automatically:
Detects if errors are in sim_gen/ (AILANG codegen bug)
Prints instructions for reporting the bug
Prevents workaround attempts
# CORRECT - use this
make build
# WRONG - don't use direct go build
go build ./... # Won't detect codegen bugs
If make build shows "ERROR IN sim_gen/":
Follow the printed instructions to report the bug
Mark the feature as BLOCKED in sprint tracking
STOP and wait for fix
DO NOT refactor AILANG to work around it
DO NOT edit sim_gen files
If make build shows a normal error (not in sim_gen/):
Fix it in engine/.go or cmd/.go as usual
AILANG Compilation Fails
Show error output
Check ailang prompt for correct syntax
If unclear error, report to AILANG team
Don't proceed until ailang check passes
Recursion Depth Exceeded
Reduce data size for testing
Consider iterative workaround (if possible)
Report as feature request (tail recursion optimization)
Module Import Fails
Duplicate type definitions locally
Document the duplication
Report import issue to AILANG team
Feature Not Available
Design workaround
Document the workaround
Report as feature request
Common AILANG Workarounds
Quick reference for known issues and their solutions:
Problem
Error Message
Workaround
Nested field access
"cannot unify open record with TVar2"
Break a.b.c into let b = a.b; b.c
Record update with derived value
"cannot unify open record" on {b | pos: newPos}
Use explicit construction: { field1: b.field1, pos: newPos }
Module-level let in function
"undefined variable"
Inline constant or pass as parameter (intentional design)
Tuple destructuring
Parse error on let (x, y) = pair
Use match pair { (x, y) => ... }
ADT in inline tests
Test harness crashes
Only use primitive types in test inputs
DrawCmd uses color index not RGBA
N/A (works but limited)
Use direct Ebiten drawing in engine/ for custom colors. Feature requested from AILANG.
Go codegen wrong return types
Exported func returns struct{} but impl returns typed value
DO NOT create wrapper files - report bug via ailang-feedback and wait for fix
Go codegen unexported converters
convertToDrawCmdSlice is lowercase
DO NOT create wrapper files - report bug via ailang-feedback and wait for fix
Editing sim_gen/*.go
Changes overwritten
NEVER edit sim_gen files. Request features via ailang-feedback.
Maintaining This List (IMPORTANT)
This project's purpose is to surface and fix AILANG issues. Keep this workarounds table current:
Scripts for tracking workarounds:
# Check inbox and verify workarounds still needed
.claude/skills/sprint-executor/scripts/check_workarounds.sh
# Add a new workaround (updates both SKILL.md and CLAUDE.md)
.claude/skills/sprint-executor/scripts/add_workaround.sh \
"Problem name""Error message""Workaround description"# Mark an issue as fixed (moves to Fixed section)
.claude/skills/sprint-executor/scripts/mark_fixed.sh \
"problem keyword""v0.5.0"
When you discover a new issue:
Run add_workaround.sh with problem, error, and workaround
Report via ailang-feedback with detailed repro steps
When AILANG fixes an issue:
Check inbox: ailang messages list --unread
Verify fix: ailang check sim/*.ail
Run mark_fixed.sh "<keyword>" "<version>"
Remove workarounds from code where practical
Acknowledge: ailang messages ack <msg-id>
At sprint start:
# Full status check
.claude/skills/sprint-executor/scripts/check_workarounds.sh
Record Update Pattern
When updating nested records, this pattern works:
-- WORKS: newPos comes from parameter or fresh construction
pure func moveBox(b: Box, newPos: Point) -> Box {
{b | pos: newPos}
}
-- FAILS: newPos derived from b.pos
pure func moveBoxBad(b: Box) -> Box {
let oldPos = b.pos;
let newPos = { x: oldPos.x + 1, y: oldPos.y };
{b | pos: newPos} -- ERROR!
}
-- WORKAROUND: explicit construction
pure func moveBoxFixed(b: Box) -> Box {
let oldPos = b.pos;
let newPos = { x: oldPos.x + 1, y: oldPos.y };
{ pos: newPos, size: b.size } -- Explicit fields
}
Quality Checkpoints
After each milestone:
# 1. All AILANG modules compilefor f in sim/*.ail; do ailang check "$f"; done# 2. Entry functions run
ailang run --entry init_world sim/step.ail
# 3. Game builds (if engine changes)
make game
Visual Verification (MANDATORY for Visual Features)
For any milestone involving visual output, YOU MUST take and verify screenshots.
CRITICAL: Use In-Game Screenshots, NOT macOS screencapture
NEVER use macOS screencapture command - it captures the entire desktop at native resolution (5K+ on Retina), producing huge files that crash Claude.
ALWAYS use the in-game screenshot functionality - it captures the game's internal render buffer at 1280x960, producing consistent, small PNG files.
Screenshot Helper Script (Recommended)
Use the dedicated screenshot helper for easy, reliable screenshots:
# Basic game screenshot at frame 30
.claude/skills/sprint-executor/scripts/take_screenshot.sh
# Bridge demo at frame 60
.claude/skills/sprint-executor/scripts/take_screenshot.sh -c demo-game-bridge -f 60
# Game with effects
.claude/skills/sprint-executor/scripts/take_screenshot.sh --effects bloom,sr_warp --velocity 0.5
# Arrival sequence at frame 120
.claude/skills/sprint-executor/scripts/take_screenshot.sh --arrival -f 120
# Custom output path
.claude/skills/sprint-executor/scripts/take_screenshot.sh -o out/screenshots/my-test.png
Direct Command Usage
You can also use the screenshot flags directly on any game command:
# Main game
go run ./cmd/game --screenshot 30 --output out/screenshots/game.png
# Demo commands
go run ./cmd/demo-game-bridge --screenshot 30 --output out/screenshots/bridge.png
go run ./cmd/demo-saturn --screenshot 60 --output out/screenshots/saturn.png
# With effects
go run ./cmd/game --screenshot 60 --output out/test.png --effects bloom,sr_warp --velocity 0.5
# Arrival sequence
go run ./cmd/game --screenshot 120 --output out/arrival.png --arrival
Why In-Game Screenshots?
Method
Resolution
File Size
Works?
--screenshot flag
1280x960
~50-200KB
YES
macOS screencapture
5120x2880+
5-20MB
NO (crashes)
Screenshot Workflow
Take Screenshots at Key States
# Initial state
.claude/skills/sprint-executor/scripts/take_screenshot.sh -f 30 -o out/screenshots/initial.png
# Mid-animation (if applicable)
.claude/skills/sprint-executor/scripts/take_screenshot.sh -f 60 -o out/screenshots/mid.png
# Final state
.claude/skills/sprint-executor/scripts/take_screenshot.sh -f 90 -o out/screenshots/final.png
View Screenshots Using Read Tool
# Claude Code can view PNG images directly# Use Read tool on screenshot path to verify visuals
Document What to Look For
Visual elements positioned correctly
No rendering artifacts
Effects applied properly (if enabled)
UI elements visible and readable
Screenshot Verification Checklist
For each visual feature:
Screenshot captured at initial state
Screenshot captured during any animations/transitions
Screenshot captured at final state
Screenshots viewed and verified correct
Issues found documented in sprint JSON
Visual artifacts investigated and fixed
Available Commands for Screenshots
Command
Description
game
Main game (bridge view, NPC, etc.)
demo-game-bridge
Bridge interior only
demo-saturn
Saturn with rings
demo-arrival
Black hole arrival sequence
demo-sr-flyby
SR effects flyby demo
demo-view
View system demo
Output File Organization (MANDATORY)
All generated output MUST go in the correct out/ subdirectory. See out/README.md for full details.
Directory Structure
out/
├── eval/ # Benchmarks, evaluation reports
├── generated/ # Final GIFs, videos, animations
├── scenarios/ # Scenario runner temp output
├── screenshots/ # Demo screenshots from sprints ← USE THIS
└── test/ # Visual test golden files
Where to Put Files
Output Type
Location
Example
Demo screenshots
out/screenshots/
out/screenshots/bridge-initial.png
Sprint verification
out/screenshots/<sprint>/
out/screenshots/arrival-v1/mid-transition.png
Evaluation output
out/eval/
out/eval/report.json
Generated videos/GIFs
out/generated/
out/generated/flyby-demo.gif
Test scenario output
out/test/<scenario>/
out/test/camera-pan/after-right.png
Rules
NEVER put files in out/ root - always use a subdirectory
Clean up intermediate files - frame sequences for video generation should be deleted after the final video is created
Use descriptive names - bridge-initial.png not test1.png
Organize by sprint - for multi-screenshot verification, use out/screenshots/<sprint-name>/
Debug, Rand, Clock, AI (with Claude/Gemini/stub backends)
Assets
Sprites (animated), Audio (OGG/WAV), Fonts (TTF with scaling)
Shaders
SR warp (Doppler, aberration), GR warp (lensing, redshift), bloom, vignette, CRT
Physics
Lorentz factor, time dilation, gravitational redshift, Schwarzschild radius
Project Commands
make sim - Compile AILANG to Go
make game - Build game executable
make run - Run game
make install - Install voyage CLI globally
Voyage CLI (Dev Tools)
The voyage CLI provides development tools. Install with make install.
# API documentation (always up-to-date via AST parsing)
voyage api # List all engine packages
voyage api tetra # List types in package
voyage api tetra.Scene # Show type details
voyage api tetra.Scene --methods # Show with method signatures
voyage api --search camera # Search across all packages# Demo runner (use instead of manual go run)
voyage demo # Interactive selection menu
voyage demo bridge # Run demo-game-bridge directly
voyage demo orbital # Partial name matching works# File watcher (auto-rebuild on changes)
voyage watch # Watch sim/*.ail, run make sim on changes
voyage watch --test# Also run ailang test after rebuild
voyage watch --run bridge # Rebuild and restart demo automatically# Screenshot capture (use for visual verification)
voyage screenshot # Capture main game (frame 60)
voyage screenshot bridge # Capture specific demo
voyage screenshot --all # Capture all demos to out/screenshots/
voyage screenshot bridge -f 120 -o out/ # Custom frames/output# Asset validation (run before sprints)
voyage manifest # Validate all asset manifests exist
voyage manifest -v # Verbose (show all files)
voyage manifest sprites # Check specific manifest# Other inspection tools
voyage world # Inspect world state
voyage bench # Run benchmarks
voyage ai # Test AI handlers
Use voyage commands for:
Engine API lookup (find correct signatures, constructors, methods)
Quick demo switching during development
Auto-rebuild while editing AILANG
Screenshot capture for visual verification
Asset validation before commits
AILANG Commands
ailang check <file> - Type-check
ailang run --entry <func> <file> - Run with entry point
ailang prompt - Syntax reference
Feedback Commands
ailang messages list --unread - Check unread messages