Skip to content

What is SAGE?

SAGE (SkewedAspect Game Engine) is a TypeScript game engine built on BabylonJS and Havok Physics. Its core, @skewedaspect/sage-core, holds the entity system and the simulation and depends on neither Babylon nor the DOM. The same entity classes run on a server, inside a client, and inside a client's prediction simulation. @skewedaspect/sage is the Babylon package on top of it: scene nodes, meshes, levels, physics, input devices, audio, pooling, saves, and debug tooling.

SAGE is code-first. There is no visual editor. You write entity classes, behaviors, levels, and input bindings in TypeScript, with YAML for level configuration, and the engine wires everything together.

Pillars

One simulation wherever it runs. sage-core is the entity system, the event bus, and the fixed-tick simulation manager. A server runs GameEntity classes with no renderer at all. A client runs the same simulation under Babylon, and the same behaviors run in both.

Composition the compiler checks. An entity class names its behaviors in TypeScript and the type checker proves the composition. An unknown operation, a behavior whose sibling requirements nothing meets, two behaviors exposing one operation name, an event name outside the vocabulary, and a shared state field with incompatible types are compile errors.

Three channels, each carrying one thing. State is facts, operations are verbs, and events are news. Writing a state field notifies nobody; there is no reactive state watching.

State is data. An entity's state bag is JSON-compatible and it is the only entity data that persists. A snapshot is the tick counter, the ID counter, and every entity's ID, name, and state bag.

A fixed tick the caller drives. The simulation takes elapsed time from whoever calls it and converts that into whole fixed steps. Replaying steps from a snapshot reaches the same state as running straight through.

Babylon lives in sage. Scene nodes, meshes, levels, physics, input devices, and audio are the Babylon package's business.

What the packages hold

PackageHolds
@skewedaspect/sage-coreGameEntity, Behavior, the event map and EventBus, GameSimulationManager, snapshot and restore, tags, NamedBehavior, StateMachineBehavior, the action declaration type
@skewedaspect/sagecreateGameEngine, NodeEntity, NodeSimulation, defineEntity and the standard mesh source, levels and the YAML config, physics, InputManager, audio and SoundBehavior, pooling, entity picking, the save manager, the debug console
@skewedaspect/sage-vueSageCanvas and the composables

A frame

render loop tick
  |
  |-- InputManager.routeCapturedInput      every live binding's fire, broadcast as action:<name>
  |
  |-- simulation.runStepsForElapsedTime    for each whole fixed step:
  |       every entity's update() in insertion order
  |       bus.drain()                      queued events delivered, FIFO
  |
  |-- frame callbacks                      registerFrameCallback, in registration order
  |
  '-- scene.render()

Rendering defaults

SAGE enables anti-aliasing and HiDPI scaling (adaptToDeviceRatio) by default. Without HiDPI scaling, rendering on Retina and 4K displays is blurry because the engine renders at CSS pixel resolution and upscales.

typescript
const engine = await createGameEngine(canvas, entityClasses, {
    renderOptions: {
        antialias: false,
        adaptToDeviceRatio: false,
        engine: 'webgpu',
    },
});

engine picks the rendering backend: 'webgl', 'webgpu', or 'auto' (default).

What SAGE is good for

  • 3D browser games built with BabylonJS and Havok physics
  • Code-first workflows where game logic lives in TypeScript
  • Composition-based designs where entities are assembled from reusable behaviors
  • Games whose simulation also runs on a server, from the same entity classes
  • Vue-based game UIs

What SAGE is not

  • Not a general-purpose framework. SAGE is 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. Breaking changes happen between minor versions, and 0.10 is a rewrite of the entity, input, and save systems.
  • Not a visual editor. Level geometry comes from Blender, or any tool that exports GLB. Game logic lives in TypeScript.
  • Not batteries-included for networking. sage-core runs on a server, and a game's netcode, matchmaking, and prediction feed it. SAGE ships none of those.

Where to go next

Released under the MIT License.