Same code, same simulation, every screen.

oniq is a game engine written in Rust on WebGPU. One codebase runs on the desktop, Android, iPhone, iPad and Apple TV and in the browser, and the same inputs produce the same simulation on every machine. That is what makes lockstep multiplayer and exact replays work.

Get started

Runs on WebGPU in this page.

lantern playground · the engine itself, compiled to WebAssembly, on WebGPU in this page

controls Drag a body to throw it. Press and hold on empty space to gather the bodies around the pointer, then let go to scatter them.

controls Drag a body to throw it. Hold on empty space to gather the bodies, then lift your finger to scatter them.

Engine

A fairly complete 2D engine on a 3D-capable foundation, with a sizeable creative toolkit. Most of it sits behind Cargo features, so a game compiles only what it uses.

  • Simulation core

    An archetype ECS with deterministic iteration order, a staged scheduler, fixed-timestep time, and snapshot serialization with deltas and compression.

    always built

  • Rendering

    A WebGPU pipeline on wgpu: sprite batching, atlases, materials, a procedural sky with weather and lighting, bloom, and WGSL effects with a CPU fallback.

    rendering shaders

  • Text

    Font loading, MSDF glyphs, and full shaping and bidirectional layout through sigilbuzz: GSUB and GPOS, Arabic and Indic scripts, variable fonts, inline markup.

    text text-rich-markup

  • Animation

    State machines and keyframe tweening, plus Spine 4.3 skeletal animation through the pure-Rust chine runtime, with IK, path and physics constraints. Meet Qubit.

    spine

  • Physics

    Rapier 2D by default and Rapier 3D behind a feature, a fixed-point solver with sensors and continuous collision detection for bit-exact replicated simulation, and Salva fluids.

    2d 3d deterministic-physics 2d-fluids

  • Networking

    Lockstep and snapshot-interpolation netcode, a replay tap, compression, LAN discovery and session auth, over QUIC, WebTransport and WebSocket natively, and WebTransport and WebSocket from the browser.

    networking network-quic network-wtransport network-websocket network-wasm-bindgen

  • Audio and input

    A kira-backed audio context with panning and a streaming PCM sink, Web Audio in the browser, and keyboard, pointer, multitouch and gamepad input, including the Siri Remote and every Apple Pencil sample with its pressure and tilt.

    audio gamepad

  • Scripting and tools

    A sandboxed Rhai runtime, scriptable dockable panels with a native renderer and touch-sized controls, a debug console with a command registry, and an ECS inspector driven by a derive.

    scripting panel-scripting debug-tools

  • 2D content toolkit

    Brushes, tilemaps, atlas packing with 9-slice, palettes and dithering, image processing, selection masks, and bones with CCD and FABRIK IK.

    brush tilemap atlas color image-processing selection bones

Hosts

A game is a world and an update function. AppHost runs them at a fixed 60 Hz in whatever the platform offers: a desktop window, an iPhone, iPad or Apple TV app, an Android activity, or a canvas in a web page.

// The game: a world and a fixed-step update.
let (host, update) = makeshift::build()?;

// A desktop window, or an iPhone, iPad or Apple TV app.
host.run(update)

// An Android activity.
host.run_android(app, update)

// A canvas in a web page, on WebGPU.
host.run_web(canvas, update)

The scene at the top of this page is the engine itself, compiled to WebAssembly: its ECS, Rapier physics, point lights with soft shadows, bloom and the sprite renderer, drawing on WebGPU. Makeshift is built once by makeshift::build; its desktop example calls run, and this site calls run_web with the same host and the same update.

Determinism

The throughline of the engine. The same inputs give the same simulation on every machine, which turns multiplayer and replays into a matter of sharing inputs.

  • A fixed 60 Hz step

    The simulation advances in fixed ticks, decoupled from the display, so it runs the same at any frame rate.

  • Ordered by construction

    Deterministic ECS iteration and generation-checked handles: no hash-order surprises between runs.

  • Bit-exact when it counts

    A fixed-point Q32.32 math path with table-based trigonometry for physics that matches across platforms.

  • Netcode and replays

    Lockstep and snapshot-interpolation strategies, a state-hash canary that catches a desync within half a second, and a replay tap that records a match's inputs to play it back exactly.

Built on oniq

Three deliberately different products share the engine: a creative tool, a systems-level emulator frontend, and a networked game.

  • pixel-stroke

    A pixel and vector art editor with brushes, layers, bones and animation, on the web, with a native iPad app built for the Apple Pencil on the way.

    pixel-stroke.com

  • PolyConsole

    A libretro frontend for the TV, the desktop, Android and Apple TV, driven through oniq's runtime, input, text and audio.

    poly-console.com

  • Sqrly

    A networked lockstep game: the engine's reference multiplayer title, with its client, server and shared simulation in the oniq repository.

    in development

Start

A camera, a few entities and an update function are a running game, natively or in a browser tab.