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 ​

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

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 all compile errors.

State is facts, operations are verbs, and events are news, and each stays in its own channel. Writing a state field notifies nobody; there is no reactive state watching.

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, the generator's state, and every entity's ID, name, and state bag.

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 that package's business, not sage-core's.

What the packages hold ​

PackageHolds
@skewedaspect/sage-coreGameEntity, Behavior, the event map and EventBus, GameSimulation, 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.

On WebGPU, SAGE also sets enableAllFeatures, so the device is requested with every feature the adapter supports. WebGL ignores it.

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 ​

  • SAGE is not a general-purpose framework. It is for 3D games rendered with BabylonJS, and it does not abstract over multiple renderers or support 2D-only workflows.
  • SAGE is not production-stable yet. It is pre-1.0, breaking changes happen between minor versions, and 0.10 is a rewrite of the entity, input, and save systems.
  • SAGE is not a visual editor. Level geometry comes from Blender, or any tool that exports GLB, and game logic lives in TypeScript.
  • SAGE is not batteries-included for networking. sage-core runs on a server, but a game's own netcode, matchmaking, and prediction feed it; SAGE ships none of those.

Where to go next ​

Released under the MIT License.