What is SAGE?
SAGE (SkewedAspect Game Engine) is a TypeScript game engine built on BabylonJS and Havok Physics. It provides a structured, event-driven architecture for building 3D games in the browser without forcing you into a monolithic framework. You get entity composition, input abstraction, level management, and physics integration out of the box -- and full access to the underlying BabylonJS engine when you need to drop down a level.
SAGE is code-first. There is no visual editor. You define entities, behaviors, levels, and input bindings in TypeScript (or YAML for levels), and the engine wires everything together. If you prefer writing code over dragging widgets, this is the engine for you.
Key Features
Entity-Behavior Composition
Build game objects by composing reusable behaviors instead of deep inheritance hierarchies. Entities are defined as blueprints with a type, default state, and a list of behaviors. Create instances at runtime, attach them to scene nodes, query them by name, tag, or type.
Event-Driven Architecture
All communication flows through a central event bus with wildcard pattern matching. Behaviors subscribe to events, entities emit events, and systems stay decoupled. No direct references between components -- just publish and subscribe.
Havok Physics
Full rigid body physics with static and dynamic bodies, forces, impulses, and collision detection. Physics bodies are configured declaratively via scene node metadata or programmatically at runtime.
YAML Level System
Define levels in YAML with scene file references, entity placement, spawn points, lighting overrides, and post-processing configuration (bloom, SSAO, tone mapping). Load GLB scenes exported from Blender and let SAGE process node metadata automatically.
Input Abstraction
Map keyboard, mouse, and gamepad inputs to named actions organized into contexts. Supports analog and digital bindings, edge detection (pressed/released), toggle modes, and context switching for different game states (menu vs. gameplay).
Asset Management
Centralized asset loading with caching, reference counting, GLB fragment extraction, and mesh instancing. Load what you need, reuse what you can, and let the engine handle cleanup.
Vue 3 Integration
First-class Vue composables via @skewedaspect/sage-vue. The SageCanvas component handles engine lifecycle, canvas sizing, and provides the engine instance to child components through Vue's dependency injection.
Save and Serialize
Snapshot and restore full game state with a storage-agnostic serialization system. Supports ID remapping, custom serialization hooks, and versioned save data.
Additional Systems
- Scene Transitions -- orchestrated level-to-level transitions with preloading and lifecycle hooks
- Post-Processing -- declarative post-processing via level YAML
- Entity Hierarchy -- parent-child entity relationships with cascading lifecycle
- Entity Inheritance -- entity definitions can extend other definitions with deep merge
- Object Pooling -- opt-in per-entity-type pooling for high-frequency create/destroy patterns
- State Machine -- generic FSM utility plus entity behavior wrapper
- Game Timer -- pause-aware delay, interval, and cooldown primitives
- Raycasting -- entity-aware wrappers over BabylonJS scene picking
Architecture at a Glance
SAGE follows a layered architecture with strict separation of concerns:
+------------------------------------------------------------------+
| GameEngine (orchestrator) |
+----------------+-----------------+-------------------------------+
| Event Bus | Entity System | Scene Engine |
| (pub/sub) | (composition) | (BabylonJS wrapper) |
+----------------+-----------------+-------------------------------+
| Binding | Game Manager | Level Manager |
| Manager | (game loop) | (level lifecycle) |
+----------------+-----------------+-------------------------------+
| Asset Manager | Save Manager | Input Manager |
+----------------+-----------------+-------------------------------+The createGameEngine() factory wires everything together: it initializes BabylonJS, Havok physics, the event bus, all managers, and returns a GameEngine instance ready to use.
Data flows through events. A keypress becomes an input event, which triggers a binding action, which a behavior processes to update entity state, which the game loop picks up to render the next frame.
For a deeper dive, see the Architecture page.
Rendering Defaults
SAGE enables anti-aliasing and HiDPI scaling (adaptToDeviceRatio) by default. Without HiDPI scaling, rendering on Retina/4K displays looks blurry because the engine renders at CSS pixel resolution and upscales. These defaults produce crisp, clean output on all displays.
To override them (e.g. for performance on very high-DPI screens):
const engine = await createGameEngine(canvas, entities, {
renderOptions: {
antialias: false, // disable anti-aliasing
adaptToDeviceRatio: false, // render at CSS resolution, not native
},
});You can also force a specific rendering backend:
renderOptions: {
engine: 'webgpu', // 'webgl', 'webgpu', or 'auto' (default)
}What SAGE Is Good For
- 3D browser games built with BabylonJS and Havok physics
- Code-first workflows where you want full control over game logic in TypeScript
- Composition-based designs where entities are assembled from reusable behaviors
- Projects that need structure but not a heavyweight framework -- SAGE gives you patterns without locking you in
- Vue-based game UIs where you want reactive bindings to game state
What SAGE Is Not
- Not a general-purpose framework. SAGE is specifically for 3D games rendered with BabylonJS. It does not abstract over multiple renderers or support 2D-only workflows.
- Not production-stable yet. SAGE is pre-1.0 (currently v0.8.0). The API is solidifying but breaking changes can still happen between minor versions. Use it for new projects, prototypes, and game jams -- not for shipping a commercial title tomorrow.
- Not a visual editor. There is no drag-and-drop scene editor. You write code. Level geometry comes from Blender (or any tool that exports GLB), but game logic lives in TypeScript.
- Not batteries-included for networking. SAGE handles local game state. Multiplayer, matchmaking, and netcode are outside its scope.
Where to Go Next
- Installation -- get SAGE installed and a spinning cube on screen
- Architecture -- understand how the engine is structured
- Entities -- learn the entity-behavior composition model
- Events -- master the event bus
- Hello Cube Guide -- full walkthrough of the simplest SAGE application
