A browser-based space game where you control a growing black hole consuming objects across procedurally generated galaxies.
Serve the game over HTTP (ES modules require it โ file:// won't work):
# With Node.js installed:
npx serve
# Or with Python:
python -m http.server 8080Then open http://localhost:8080 (or the port shown) in your browser.
- Size-Based Consumption: Eat objects smaller than you to grow larger
- Mass-Based Progression: Reach a mass threshold to advance โ galaxies are never empty
- Progressive Difficulty: Quadratic scaling (
10000 + 5000g + 1000gยฒ) makes each galaxy harder - Combo System: Chain rapid consumption for ascending audio feedback
- Smooth Physics: Momentum-based movement with boundary collision
- Gravity Well: Objects near the black hole curve toward you โ dust streams in, heavy objects barely budge
- Dynamic Spawning: New objects continuously fade in from galaxy edges, maintaining a living population
- Procedural Events: 6 event types triggered by game state metrics:
- Meteor Shower โ fast rocks from a single direction
- Comet Stream โ curved trails of ice and light
- Void Pulse โ expanding shockwave rings that push entities outward
- Derelict Flotilla โ formation of ancient craft drifting inward
- Stellar Birth โ gathering light โ flash โ explosion spawning a star
- Gravitational Wave โ sinusoidal displacement sweeping across the galaxy
- Ambient Background: Shooting stars, distant supernova flashes, and faint energy waves
- Debris Reef - Dense wreckage fields
- Comet Current - Fast-moving ice streams
- Ruined Armada - Ancient spacecraft graveyard
- Planet Nursery - Forming worlds
- Star Meadow - Brilliant burning suns
- Void Rift - Mysterious mixed space (Galaxy 3+)
- Neutron Forge - Dead star remnants (Galaxy 5+)
- Space Dust - Tiny, always eatable
- Debris - Common wreckage
- Meteors - Rocky objects with glow effects
- Comets - Fast-moving with particle trails
- Derelicts - Large spacecraft remains
- Planets - Massive worlds with color bands
- Stars - Huge burning suns
- Neutron Stars - Small but extremely dense (late game)
- Procedural Soundscape: WebAudio API generates all sounds - no audio files needed
- Adaptive Ambient Drone: Shifts based on biome color palette
- Dynamic Consumption Sounds: Pitch and tone adapt to object properties
- Combo Chimes: Ascending arpeggios for rapid consumption chains
- Event Audio Cues: Each living-world event has a distinct procedural sound signature
- Milestone Events: Satisfying chord progressions for galaxy completion
- ๐ฏ Zero Dependencies: Pure vanilla JavaScript with ES6 modules
- ๐ฑ PWA Ready: Installable with offline support
- ๐จ Canvas Rendering: Smooth 60 FPS gameplay
- ๐พ Auto-Save: LocalStorage persistence every 5 seconds
- ๐ฎ Multiple Controls: WASD, Arrow Keys, or Mouse movement
- ๐ WebAudio Engine: Fully procedural audio generation
| Input | Action |
|---|---|
| WASD / Arrow Keys | Move black hole |
| Mouse Movement | Direct control |
| P / Escape | Pause game |
| Volume Slider | Adjust audio level |
| Restart Button | Restart current galaxy |
| Reset All | Hard reset (clears progress) |
blackhole_game/
โโโ index.html # Main HTML structure with HUD
โโโ manifest.json # PWA manifest
โโโ sw.js # Service worker for offline support
โโโ css/
โ โโโ game.css # Styling and animations
โโโ js/
โ โโโ game.js # Main game loop and state management
โ โโโ entities.js # Object types, biomes, and spawning
โ โโโ living-world.js # Gravity, dynamic spawning, events, ambient effects
โ โโโ audio.js # Procedural audio engine
โ โโโ render.js # Canvas drawing functions
โ โโโ input.js # Keyboard and mouse input handling
โ โโโ save.js # LocalStorage save/load system
โโโ icons/
โโโ icon.svg # App icon (vector)
โโโ icon-192.png # PWA icon (192x192)
โโโ icon-512.png # PWA icon (512x512)
# ES modules require HTTP โ serve locally:
npx serve # Node.js (easiest)
# or
python -m http.server 8080 # Python- Modular ES6: Each system in its own file
- Clean Separation: Game logic, rendering, audio, and input are independent
- No Build Tools: Works directly in browsers with ES6 module support
- Comment Documentation: Each module has clear section headers
Game Loop (js/game.js)
- 60 FPS main loop with delta time
- State management with cached DOM references
- In-place array cleanup (reverse-splice, guarded by dirty flags)
- Galaxy transitions with starfield cache invalidation
- HUD synchronization
Entity System (js/entities.js)
- 8 object types with unique properties
- 7 biome configurations
- Procedural galaxy generation
- Cluster-based spawning for density variation
Living World (js/living-world.js)
- Gravity well with distance-based attraction and speed capping
- Depletion spawner + ambient trickle with population cap
- Hazard-function event probability with per-event and global cooldowns
- Screen-space ambient effects (shooting stars, flashes, energy waves)
Audio Engine (js/audio.js)
- 3-oscillator ambient drone
- Multi-layered consumption sounds with pre-generated noise buffer
- Combo chime system with event audio cues
- Dynamic compression and filtering
Rendering (js/render.js)
- Offscreen-cached starfield and nebula (only redrawn when camera exceeds buffer threshold)
- Pre-rendered entity sprites for planets and derelicts (baked at spawn time)
- Cached glow canvas shared across all glowing entities
- Black hole gradients cached and rebuilt only on radius change
- Alpha-segmented comet tails and speed trails (no per-frame gradient allocation)
- Mathematically computed edge indicator arrows (no save/translate/rotate/restore)
- Particle system, ripple effects, minimap
Edit js/entities.js and add to objectTypes array:
{
id: "newtype",
label: "New Object",
colors: ["#rrggbb"],
minR: 5, maxR: 10,
density: 1.5,
speed: 0.3,
tone: 200,
glow: 0.5,
sizeClass: 3,
minGalaxy: 1 // Optional: unlock at galaxy N
}Edit js/entities.js and add to biomeCatalog:
{
name: "Biome Name",
tint: "#rrggbb",
tintRGB: [r, g, b],
borderColor: "#rrggbb",
weights: { dust: 5, junk: 3, meteor: 2, ... },
description: "Flavor text",
minGalaxy: 1 // Optional
}In js/game.js:
// Mass threshold to complete a galaxy (quadratic scaling)
state.targetMass = 10000 + galaxyNum * 5000 + galaxyNum * galaxyNum * 1000;In js/entities.js:
// Object count per galaxy
export function galaxyObjectCount(galaxy) {
return Math.min(340, 30 + galaxy * 16); // Adjust multiplier
}
// Galaxy size
export function galaxyBounds(galaxy) {
return 800 + galaxy * 120; // Adjust growth rate
}In js/living-world.js โ tune the CFG object for gravity strength, spawn rates, event probabilities, and cooldowns.
- โ Chrome/Edge 90+
- โ Firefox 88+
- โ Safari 14+
- โ Mobile browsers (iOS Safari, Chrome Mobile)
Requires:
- ES6 Modules
- Canvas API
- WebAudio API
- LocalStorage
MIT License - Feel free to use, modify, and distribute!
Contributions welcome! Some ideas:
- New object types and behaviors
- Additional biomes and themes
- Power-up system
- Leaderboard/stats tracking
- Mobile-optimized controls
- Accessibility improvements
- Visual themes/skins
- Game Design & Development: Procedurally generated gameplay
- Audio: Fully procedural WebAudio synthesis
- Graphics: HTML5 Canvas rendering
Made with โค๏ธ using vanilla JavaScript, Canvas, and WebAudio