Asteroids++ — Player's Guide
Classic Asteroids reimagined with procedural polygon asteroids, wrap-around physics, pixel-perfect collision, infinite rounds, and an accuracy streak bonus. The ship rotates and thrusts in zero-gravity; each asteroid you shatter splits into smaller, faster fragments until nothing remains.
- Play now: /asteroids
- How it works (architecture): /docs/arcade/asteroids
- Build your own (tutorial): /docs/arcade/build_asteroids
Quick Start
| Key | Action |
|---|---|
| Arrow Up | Thrust |
| Arrow Left / Right | Rotate ship |
| Space | Fire bullet |
| Enter (game over) | Restart |
| P | Pause / resume |
| Escape | Open settings |
Your score appears below the canvas; the current accuracy streak sits alongside it. When you die, press Enter to start a new game.
Gameplay
Rounds and Multiplier
Each round spawns a fresh wave of asteroids. The round multiplier increases every wave, amplifying your score:
| Round | Asteroids | Multiplier |
|---|---|---|
| 1 | 5 | ×1.0 |
| 2 | 7 | ×1.5 |
| 3 | 9 | ×2.0 |
| 4 | 11 | ×2.5 |
| 5 | 13 | ×3.0 |
| N | 3 + 2N | 1 + (N-1) × 0.5 |
When all asteroids are cleared the next round begins immediately. Your ship respawns centre-screen with a brief invincibility period (indicated by flashing).
Asteroid Tiers
| Size | Radius | Base Score | Splits into |
|---|---|---|---|
| Large | 90 px | 20 | 2 Medium |
| Medium | 50 px | 50 | 2 Small |
| Small | 25 px | 100 | Nothing (destroyed) |
Each asteroid is a unique irregular polygon — no two look alike. Splits inherit the parent's velocity plus a small random offset, so fragments scatter unpredictably.
Accuracy Streak
Every consecutive asteroid hit builds your accuracy streak. The higher the streak, the more bonus points per hit:
- +10% bonus per streak level: streak 1 = +10%, streak 5 = +50%, streak 10 = +100%
- Streak resets to 0 when a bullet expires without hitting anything, or when your ship is destroyed
- Max streak is capped at 20
- Current streak is always visible next to your score:
Score: 1540 | Streak: x7
Strategy: fire deliberately. Spraying bullets into empty space resets your streak. Wait for a clear shot and aim carefully to keep the bonus climbing.
Lives and Death
You have a single life per game — no extra lives or continues. When the ship is destroyed the game is over, your high score is checked, and you can restart with Enter. The accuracy streak resets immediately on death.
Scoring Summary
| Source | Points |
|---|---|
| Large asteroid | 20 × round multiplier × streak bonus |
| Medium asteroid | 50 × round multiplier × streak bonus |
| Small asteroid | 100 × round multiplier × streak bonus |
| Streak bonus | +10% per streak level, multiplicative with round multiplier |
Example: destroying a large asteroid in round 3 (×2.0) with a streak of 5 (+50%):
base = 20 × 2.0 = 40
bonus = round(40 × 5 × 0.1) = 20
total = 60
Controls
Default Key Bindings
| Action | Default Key |
|---|---|
| Thrust | Arrow Up |
| Rotate left | Arrow Left |
| Rotate right | Arrow Right |
| Fire | Space |
| Pause | P (not rebindable) |
| Settings | Escape (not rebindable) |
| Restart | Enter |
Re-binding Keys
- Press Escape or click the cog icon to open Settings.
- Click the bind button next to the action you want to change (e.g. "Thrust").
- Press the desired key on your keyboard.
- The button updates to show the new key.
If you bind a key that is already in use, the old binding is reassigned back to its default. P and Escape are reserved and cannot be changed.
Settings Panel
Press Escape or the cog icon to open settings. All changes save automatically to your browser's localStorage and persist between sessions.
Key Mappings
As described above — rebind any action by clicking the bind button and pressing a key.
Colour Themes
The game supports two theme modes:
Default (Bootswatch) — inherits colours from the active Bootswatch CSS theme (light or dark). When the page theme changes, the game updates automatically. Not editable.
Custom themes — click + to create a named theme. Colour pickers become active for each element:
| Element | CSS variable (default) | What it colours |
|---|---|---|
| Ship | --bs-primary |
The player's ship polygon |
| Bullets | --bs-danger |
Bullet squares |
| Asteroids | --bs-body-color |
All asteroid polygons |
| Stars | — | The starfield dots |
| Background | --bs-body-bg |
The canvas fill colour |
Changes save in real time as you pick. Themes can be renamed (click the name) or deleted (click ✕). Switch between themes at any time, even mid-game.
Sidebar Toggles
Seven visual and audio toggles live in the left sidebar. Each can be changed mid-game without restarting:
| Toggle | Effect when OFF |
|---|---|
| Sound | Mutes all audio (fire, explosions, thrust hum) |
| Shake | Suppresses camera shake on hits and death |
| Stars | Hides the starfield background |
| Glow | Removes the neon glow (shadowBlur) from all polygons and floating text |
| Hit FX | Suppresses floating +N score popups and the hit sound |
| Thrust FX | Hides the warm-coloured thruster flame particles behind the ship |
| Particles | Stops explosion debris from spawning when asteroids or the ship are destroyed |
All toggles default to on and are persisted in localStorage.
Focus Mode
Click the eye icon next to the score to toggle focus mode. The sidebars dim (remaining visible but low-opacity), letting you concentrate on the canvas. Click again to restore full UI.
High Scores
How to Submit
When your ship is destroyed, the game checks if your score qualifies as a top-10 high score. If it does, a modal appears with a countdown timer:
- Enter your name (max 20 characters, or leave blank for "Unknown").
- Submit before the timer expires.
- The high score list in the right sidebar updates immediately.
Anti-tampering
Score submissions use a signed token that expires after 10 seconds. You must actually play the game to get a valid token — direct API calls are rejected. Each token is single-use and tied to the exact score it was issued for.
Visual Effects
- Thruster flame — four warm-coloured particles per frame emit from the ship's rear while thrusting, with a wider spread and shorter life than explosion particles
- Explosion particles — bursts of 12 particles (asteroid) or 25 (ship) scatter with randomised velocity, inheriting 50% of the destroyed object's momentum
- Screen shake — hits trigger a 3px shake, death triggers 10px; decays over time
- Score popups — floating
+Ntext rises from each destroyed asteroid and fades over 1 second - Starfield — 200 stars across three depth layers, with sine-based twinkle and slow downward parallax drift
- HiDPI canvas — automatically renders at your display's pixel ratio for crisp text and polygons on Retina screens
Tips and Strategy
- Build your streak early — the first wave has only large asteroids, which are slow and easy to hit. A streak of 5–10 from round 1 carries bonus momentum into harder waves.
- Don't spray — every bullet that misses costs you your streak. Fire when you have a clear line.
- Use the wrap — asteroids and bullets wrap around all four edges. A shot fired toward the right edge can hit an asteroid on the left edge of the screen.
- Large asteroids first — they're worth fewer base points but split into two medium asteroids, each worth 50 (before multiplier and streak). Clearing large asteroids quickly fills the screen with smaller, more valuable targets.
- Stay central — the centre of the screen gives you the most time to react to asteroids approaching from any direction.
- Kite — thrust in the opposite direction from the densest cluster of asteroids to buy space, then turn and fire.
File Reference
| File | Purpose |
|---|---|
/asteroids |
Play the game |
/docs/arcade/asteroids |
Architecture documentation |
/docs/arcade/build_asteroids |
Step-by-step rebuild tutorial |
static/js/asteroids.js |
Game engine (~1360 lines) |
templates/asteroids.html |
Page layout and UI |
src/routers/asteroids.py |
Server route |
src/routers/highscores.py |
High score API |
src/store.py |
Score storage |
tests/js/asteroids.test.js |
53 unit tests |