@ignifx/core 0.0.0·Babylon Lite 1.27.0·WebGPU only
A game engine you write, on a frame you can measure.
ignifx is a code-first TypeScript engine for browsers and Electron. It renders exclusively through WebGPU via Babylon Lite, and it is built for indie 2D and 3D games — a Unity-style script lifecycle, Godot-style scenes and signals, and documentation written for the coding agent as well as for you.
Version 0.0.0. Nothing is published to npm yet, so the way in is a clone — not npm install.
Phase 0 – 5
One fixed loop, six phases, one budget
The engine owns the loop; Babylon Lite draws when it is told to. Every phase runs every frame, in this order, and a script's callbacks are dispatched from them by name.
- 0EndOfFrame
- Deferred signal deliveries, drained before the clock advances.
- 1PreUpdate
- Input polling and asset delivery, before any script callback.
- 2FixedUpdate
- The fixed-timestep loop: fixedUpdate, physics, collision dispatch.
- 3Update
- update on every enabled script, then coroutine resumption.
- 4PostUpdate
- Animation, state machines and tweens.
- 5PreRender
- Interpolation, sprite and camera sync, audio, diagnostics.
examples/recipes/
This is what a script looks like
No decorators and no reflection: Script.define declares the fields, which is what makes the component serializable, editable in the inspector, and patchable on hot reload. This one is lifted unedited from a recipe the documentation harness compiles and runs.
/** Spawns {@link Spawner.prefab} wherever the player clicks. */class Spawner extends Script.define({ camera: entityRef<Entity>(), lift: f32(0.4) }) implements ScriptCallbacks { static typeId = "recipes/Spawner"; /** An asset handle is not a schema field here: `asset()` needs an asset *class* as its token. */ prefab: AssetHandle<SceneAsset> | null = null; update(): void { const camera = this.camera?.getComponent(Camera) ?? null; const prefab = this.prefab; if (camera === null || prefab === null || !this.app.input.actions.get("spawn").wasPressedThisFrame) { return; } const pointer = this.app.input.actions.get("point").vector; const ray = camera.screenToRay(pointer.x, pointer.y); const hit = ray === null ? null : this.app.physics.raycast(ray.origin, ray.direction, 60); if (hit === null) { return; } // Along the surface normal, so a prop dropped on a wall does not start inside it. this.world.instantiate(prefab.value, { position: { x: hit.point.x + hit.normal.x * this.lift, y: hit.point.y + hit.normal.y * this.lift, z: hit.point.z + hit.normal.z * this.lift, }, }); }}@ignifx/*
What is in the box
Eleven subsystems, each an optional extension with its own skill page.
@ignifx/core
Kernel, scripts and scenes
An app, a world, entities, and scripts with schema-declared fields — no decorators.
@ignifx/core
Rendering on Babylon Lite
WebGPU only, through a pinned Babylon Lite. No WebGL fallback, by decision.
@ignifx/core
Assets
Addressed, typed, reference-counted, asynchronous — and delivered at one point in the frame.
@ignifx/input
Input
Devices become actions; actions come from a file, not from
keydown.@ignifx/physics
3D physics
Havok through Babylon Lite: bodies, colliders, triggers, a character controller, queries.
@ignifx/2d · @ignifx/physics-2d
2D toolkit and 2D physics
Sprites, atlases, tilemaps and sorting layers; Rapier for the bodies.
@ignifx/audio
Audio
A mixer tree, positional sources, and a browser that starts locked.
@ignifx/3d
3D toolkit
Character and camera rigs, an animation state machine, navigation.
@ignifx/ui
UI
Game UI is HTML: one overlay over the canvas, and your framework inside it.
@ignifx/electron
Electron
The same renderer bundle, in a window, with a sandboxed bridge and a file system.
@ignifx/devtools
Devtools and hot reload
Nine panels behind a backtick, and scripts that reload without losing state.
baselines.json
Numbers this repository actually recorded
Measured on macOS 25.5 arm64 (Apple Silicon), Node 25.2.1, Vitest 5.0.0, @babylonjs/lite 1.27.0. Frame times are reported, not asserted; the bundle ceilings are asserted by bundle-size.test.ts.
0.1624ms
whole-scheduler CPU time for 1,002 entities
frameTime.thousand-entities
397KB
entry chunk of the 3D third-person template, gzipped
bundles.templates/3d-third-person
264KB
entry chunk of hello-cube, gzipped — 20 KB over the plan's 250 KB target
bundles.examples/hello-cube
1.27.0
Babylon Lite, pinned exactly
pnpm-workspace.yaml
AGENTS.md
Where the project actually is
Phases 0–11 of docs/plan/engineering-plan.md were delivered on main between 2026-09-05 and 2026-09-06; Phase 12 (templates polish, examples gallery, website content, benchmarks) is next.
The engine is pre-1.0 and the public API is not frozen. There are no published packages, no migration path, and no compatibility promise yet — the constitution says what will change and what will not.