Small World Engine is the "Preact of 3D Engines". It is an ultra-lightweight, high-performance, and strict TypeScript 3D game engine for the web. Built for the era of WebGPU and Playable Ads, it provides a modern Physically Based Rendering (PBR) pipeline and a robust Behavior Systemโdelivering the architectural elegance of a real game engine at a fraction of the bundle size of traditional frameworks.
Read our full Vision & Strategy (VISION.md).
OrbitController, FirstPersonController, ZoomController) are standard Behavior components attached via camera.addBehavior(). Features procedural effects like camera shake and flash.MathPool), BindGroup & Pipeline Caching (WebGPU), and zero-allocation hot paths to eliminate Garbage Collection pressure.FlickerBehavior, DeviceOrientationController, HoverBehavior, DraggableBehavior, etc.) directly to 3D objects, cameras, or materials. Includes a built-in, type-safe, zero-allocation Finite State Machine (FSM) framework to cleanly manage game actor lifecycles.InteractionManager allowing objects to instantly react to mouse/touch pointer events (onPointerEnter, onPointerClick, onPointerDown, onPointerMove, etc.). Pickable elements are queried via highly performant $O(\log n)$ Octrees and resolved to exact pixels via the Mรถller-Trumbore intersection algorithm.Object3D architecture.AudioSystem with 3D Spatial Audio (HRTF), a procedural Retro Synthesizer (footsteps, lasers, drones, fire), and a built-in Mixer with procedural Reverb.EventBus injected into all systems (this.events), separating Gameloop, Behaviors, and UI without relying on garbage-heavy DOM CustomEvent objects.PhysicsSystem. Supports RigidBodies with linear and angular dynamics (velocity, torque, inertia, damping), an Octree-broadphase, precise collision detection using the Separating Axis Theorem (SAT) for OBB vs. OBB and Spheres, realistic impulse resolution (bouncing/restitution) via Semi-Implicit Euler integration, fixed-timestep sub-stepping with render interpolation, Continuous Collision Detection (CCD) for fast-moving spheres, and FluidVolume zones for buoyancy/drag/current.GridLevelBuilder to instantly generate complete dungeon levels from simple ASCII maps (["###", "#P#", "###"]).Texture.fromUrl()).DeviceCaps provides robust detection of WebGPU/WebGL API support, hardware limits (Memory, Cores, Texture Sizes), and experimental browser features (Wasm, Async, Generic Sensors).engine.destroy() lifecycle hook that completely frees GPU memory and detaches global event listeners. The engine even auto-destroys if it detects its canvas has been unmounted from the DOM.glMatrix. Small World features a bespoke, highly-optimized mathematics library for vectors and matrices, tailored exactly for our right-handed coordinate system.OpenWaterMaterial with Gerstner Waves and Opaque Depth-Fade for soft shores).geometry.dispose() or material.dispose(). The engine utilizes rigorous internal reference counting across all renderers. When you remove an object from the scene, orphaned WebGL/WebGPU resources are safely and automatically garbage-collected.frustum.intersectsVolume(obj.bounds)), Scene Graph, and Resource Managementโentirely from scratch. This keeps the footprint tiny and performance at the absolute maximum.This package is private and not published to the NPM registry yet. Clone the repository and install dependencies locally:
git clone https://github.com/rottensteiner-stefan/small-world.git
cd small-world
npm install
The engine provides a SmallWorld base class that handles the render loop and hardware initialization automatically.
You can configure the engine by passing an options object to the constructor. In modern bundlers (like Vite), you can also import a JSON file directly.
import config from "./config/small-world.json";
class MyGame extends SmallWorld {
constructor() {
// Pass the configuration to the engine
super(config);
}
// ...
import { SmallWorld, Cube, Color, StandardMaterial, Object3D, OrbitController, Texture } from "small-world";
class MyGame extends SmallWorld {
constructor() {
super(); // Or pass config here
}
protected async setupScene(): Promise<void> {
// 1. Load a texture and create a PBR material
const albedoTex = await Texture.fromUrl("./assets/textures/diffuse.png");
const geometry = new Cube({ size: 2 }).getGeometryData();
const material = new StandardMaterial({
map: albedoTex,
color: Color.DODGERBLUE,
metallic: 0.7,
roughness: 0.2,
});
// 2. Wrap in an Object3D and add to scene
const cube = new Object3D("MyCube");
cube.geometry = geometry;
cube.material = material;
cube.position.set(0, 1, 0);
this.scene.add(cube);
// 3. Configure the camera and attach behaviors (controllers)
this.camera.position.set(5, 5, 5);
this.camera.target.set(0, 0, 0);
// Camera controllers are now behaviors!
this.camera.addBehavior(new OrbitController());
this.camera.addBehavior(new ZoomController());
}
protected override update(deltaTime: number): void {
// Logic executed every frame
}
}
// Start the application
const game = new MyGame();
game.start();
.nvmrc. If you use nvm, simply run nvm use in the root directory.npm install
npm run dev
npm run build:lib
For an isolated development environment, this project includes a Dev Container configuration for VS Code.
src/core: Core engine logic (SmallWorld, Object3D, Scene, Input, Color).src/core/behaviors: Modular runtime behavior components (e.g. Proximity Sensors, Oscillators).src/core/cameras: Camera strategies, projections, effects, and modular controllers.src/core/fsm: Type-safe, zero-allocation Finite State Machine utility.src/core/materials: Material definitions and PBR shader assets.src/core/lights: Light source implementations (Standard & PBR).src/geometry: Geometric primitives and terrain logic.src/math: Linear algebra, vectors, matrices, and object pooling.src/loaders: Asset loading pipeline (OBJ, MTL, Textures).src/renderers: Implementation of WebGL1, WebGL2, and WebGPU backends.
src/core/renderers/shaders/source: Core shader assets directly bundled with the engine.showcases: Interactive functional showcases demonstrating engine capabilities.public/assets, public/resources, public/tools: Static assets, shared resources, and the standalone browser-based generator tools (see below) used across showcases.The engine includes several browser-based tools to help generate assets directly on the client side without relying on external software:
~ or F12).
GridLevelBuilder.public/tools/pbr-gen.html): Generate Normal, Specular, AO, and Height maps from a single diffuse image.public/tools/splatter-gen.html): Generate procedural splatters and decals.public/tools/ibl-gen.html): Generate Image-Based Lighting (Irradiance and Radiance) environment maps.This project uses TypeDoc for automated API reference generation and VitePress for developer guides and tutorials.
Generate API Reference:
npm run docs:api
This automatically extracts all classes, interfaces, and methods from the TypeScript source and generates a static HTML site under docs/public/api.
Start the VitePress Dev Server:
npm run docs:dev
This serves the developer documentation locally. You can browse the guides and the newly generated API documentation.
This project is licensed under the MIT License.