A retro space shooter built with vanilla JavaScript and HTML5 Canvas. Classic arcade-style gameplay with cinematic cutscenes.
Play Now: https://aijobwars.com
- Pure JavaScript canvas rendering (no frameworks)
- Cinematic engine with timeline-based scene playback
- Modal window system with responsive viewport scaling
- Particle system for explosions and effects
- Audio manager with Web Audio API
- Boss mode (Tab key hides game with fake spreadsheet)
- Virtual viewport (1920x1080) scales to any screen size
| Key | Action |
|---|---|
| Arrow Keys | Move ship (up/down/left/right) |
| W/A/S/D | Strafe |
| Space | Fire lasers |
| Enter | Fire missiles |
| Escape | Pause |
| Tab | Boss mode (fake spreadsheet) |
| M | Toggle sound |
| +/- | Volume |
| F12 | Toggle frame stepping (debug) |
| F11 | Step frame (when paused) |
ansible-playbook ansible/deploy.yml --tags bundle
cd html && python3 -m http.server 8000Open html/index.html in a browser, or visit https://aijobwars.com
- Window Manager - Modal window stack with event routing
- Graphics - Virtual 1920x1080 viewport with automatic scaling
- Sprites - Image cache with 9-slice scaling for UI
- Audio - Web Audio API with decoded buffer cache
- Cinematic - Timeline-based scene player with audio sync
- Input - Keyboard state tracking
html/static/js/
├── windows/ # Modal/window system
├── ui/ # UI components
├── logic/ # Game logic
├── cinematic/ # Scene player
└── lib/ # Utils
- Dual Loop Architecture - Input processing at 60 FPS, rendering at 24 FPS for responsive controls
- Double Buffering - Offscreen canvas eliminates flicker during resize
- Pixel-Perfect Rendering - Math.round() alignment prevents anti-aliasing artifacts
- Edge Gradient Sampling - Letterbox/pillarbox fills sample from inside viewport boundaries
- 9-Slice Scaling - Anti-aliasing gaps eliminated with +1 dimension offsets
- Independent Window System - Each modal/screen owns its own UI elements
- Title Screen Integration - Menu class now handles title rendering with animated glow
- Orientation Handling - Proper portrait/landscape transitions with background reloading
- Viewport Consistency - Uniform dark border color across all edges
- Input latency reduced from ~41ms (24fps) to ~16ms (60fps)
- Zero-blink resize via immediate render after canvas clear
- Efficient letterbox filling with single-pixel getImageData/putImageData
# Bundle JS
ansible-playbook ansible/deploy.yml --tags bundle
# Deploy
ansible-playbook ansible/deploy.yml- Music: Chiploop by iamoneabe
- SFX: 512 8-bit Sound Effects by SubspaceAudio
- Spells: Pixel Art Spells by DevWizard
- Explosions: Explosion Set 1 by Master484
Code is open source. Assets follow their respective licenses (see attribution links).




