This is not production software. It’s my creative sandbox — part doodling, part curiosity. A place where I try out ideas, patterns I’ve heard about, or anything I feel like exploring.
It draws. It handles canvas layers and scenes. It loads assets and animates sprites. It simulates real Newtonian physics and detects collisions using quad trees, spatial partitioning, and other nifty tricks.
Oh, you can totally build a space game that reaches the stars with it.
As long as your unit of measurement is AU… and precision isn’t a concern.
Because eventually, Number will say, "Nope, you’re not YOLOing past IEEE 754."
But hey — at a cosmic scale, what’s a light second more or less gonna matter?
About the Docs This README is as unfinished and unstable as the engine itself. Some features aren’t documented. Some are outdated. Some I barely remember writing.
Example of initializing the Rocket Engine and setting up a few scenes:
// Initialize the Rocket engine with custom settings
const rocket = new Rocket({
// Set the main target element for rendering the game
targetElement: document.getElementById('my-container'),
// Define custom input bindings (e.g., for controls)
inputBindings: new MyInputBindings(),
});
// Optional: Register a custom application to handle more complex stuff
// Not necessary for simple animations, but you'll probably want it for games
rocket.service('application', new MyGameLogic());
// Define the 'world' stack and add multiple scenes. The scenes can represent
// different parts of the game, such as levels, menus, start and game over screens.
rocket.stack('world', (stack) => {
stack.addScene(new WorldScene1());
stack.addScene(new WorldScene2());
stack.addScene(new GameOverScene());
}, { width: 1920, height: 1080 }); // Set the canvas size
// You can define multiple stacks. Each stack will create a separate canvas element
rocket.stack('minimap', (stack) => {
stack.addScene(new MiniMap());
}, { width: 300, height: 300 }); // Set the canvas size
// Launch the Rocket engine, starting the game loop and rendering the first scene of each stack
rocket.launch();
// You can navigate between scenes using the scene manager and the stack name
rocket.sceneManager('world').next();
rocket.sceneManager('world').previous();Find more examples in the ./examples folder.
The demo focuses on controlling a spaceship infinite space (well — theoretically, but IEEE 754 won't have it). There are two main control modes that can be switched by pressing the space bar:
- Realistic Physics: For long-distance travel with inertia dampers off.
- Arcade Mode: For close combat with inertia dampers on.
Additionally, there’s an energy management system. Various components (engine, weapons, inertia dampers) consume energy and need sufficient power to function. If components stop working or behave erratically, it's likely due to low energy. You’ll have to wait until the reactor recharges.
I haven’t finished implementing all components, and the demo is not optimized for portable devices. It requires at least a 1920x1080 display.
Beware: The controls behave differently depending on the selected control mode. Press the space bar. Also: If you can't fire or control the ship, check the energy levels!
- w, a, s, d: Move the ship.
- Space Bar: Toggle inertia dampers (control mode).
- 1, 2, 3, 4, 5, 6: Switch weapons.
- Mouse 1: Fire active weapon.
- Mouse 2 + drag: Select objects in space.
- Mouse Wheel: Zoom in/out.
You can destroy asteroids and space stations, but beyond that, there’s not much to do.
Rocket Engine uses "stacks" for managing game scenes. A stack can hold multiple scenes.
Example:
rocket.stack('gameplay', (stack) => {
stack.addScene(new WorldScene1());
stack.addScene(new GameOverScene());
}, { width: 1920, height: 1080 });ECS allows for modular game objects, where behavior is defined through components. The EntityManager manages all entities and their components. (Just use ECS, dude! It'll fix everything!)
Example:
const player = new Player(); // extends some abstract base ecs entity... provides addComponent() or something
rocket.entityManager().addEntity(player, 'player');Built-in physics support for 2D and 3D games, including various levels of collision detection (bounding boxes, polygons, etc.)
(Yes, real Newtonian physics. I outsourced the math to ChatGPT because I panicked at the first integral. If it feels weird… that’s because real games never use real physics. Now you know why.)
Example:
import CollisionComponent from "./components/CollisionComponent.js";
const player = new Player();
player.addComponent(new CollisionComponent());
rocket.entityManager().addEntity(player);Render your game to multiple HTML elements using Canvas, WebGL, or DOM-based renderers.
Example:
rocket.stack('world', (stack) => {
stack.addScene(new WorldScene1());
}, { container: document.getElementById('game-world'), width: 1024, height: 768 });(To be honest: I only provide the ability to replace the Canvas renderer with your own. If you really want WebGL or — god help you — DOM rendering, you're completely on your own.)
Efficiently manage animated characters and objects with SpriteSheetManager, which also supports collision shape generation. (means nothing to you, but it reminds me it's there)
Example:
rocket.spriteSheetManager().loadSpritesheet('player', 'player.png', 32, 32);The AudioManager loads and manages sounds, allowing easy playback, pausing, and looping of sound effects or background music.
Example:
rocket.audioManager().loadSound('explosion', 'explosion.mp3');
rocket.audioManager().playSound('explosion');Custom input bindings allows mapping keyboard or mouse inputs to specific actions.
Example:
class MyInputBindings extends rocket.InputBindings {
constructor() {
super();
this.bind('ArrowLeft', 'moveLeft');
this.bind('ArrowRight', 'moveRight');
}
}
rocket.registerInputBindings(new MyInputBindings());The AssetManager handles loading and managing images, sounds, and JSON data, with support for tracking progress during asset loading.
Example:
rocket.assetManager().loadImage('background', 'bg.png');The EventBus allows components to communicate by emitting and listening for events.
Example:
rocket.eventBus().on('playerDied', () => {
console.log('Game Over');
});
rocket.eventBus().emit('playerDied');Built-in A* pathfinding algorithm helps navigate complex game environments using grid-based heuristic searching.
Example:
const path = rocket.pathfinding.search(startNode, endNode);
console.log('Path found:', path);(Okay, that’s... not working yet. It's there but unfinished...)
Keep track of game performance with a built-in PerformanceMonitor
Example:
const rocket = new Rocket({ showPerformanceMonitor: true });Extend the engine’s functionality by adding custom services and plugins through the ServiceContainer.
(Because yes — I’m a PHP dev who builds his own service containers. So of course I had to bring that pattern to JavaScript...)
Example:
rocket.service('customService', new MyCustomService());Yes, technically, lazy loading works too. Put a callback in there if you're feeling fancy. Just don't expect automagic dependency injection. This ain't Laravel.
Schedule and execute timed actions using the TaskScheduler, ideal for animations, AI routines, or event-driven mechanics.
Example:
rocket.service('taskScheduler').schedule(() => {
console.log('Task executed!');
}, 500); // Executes after 500msCreate particle effects such as explosions, fire, or smoke using the ParticleSystem.
Example:
rocket.particleSystem().createEffect('explosion', x, y);(...ahem, that's all I can say about it for now, I don't remember the details or what 'explosion' refers to)
Rocket Engine: Powered by effort, duct tape, and 53 bits of hope. (ChatGPT, loyal unbiased assistant)