FUNCTOR

A functional toolkit for 3D games.

Write your game in Functor Lang — a tiny interpreted language — and edit it live while it runs, with the model preserved mid-frame. Every session records itself, so you can pause the running game and scrub back through its timeline.

This is live. Change a number and watch it take hold mid-wave — or drag the timeline to rewind the scene.

The language

Model–View–Update, all the way down. This is real Functor Lang — hit ▶ try it to open it live in the sandbox.

// a pulsing sphere with a beat counter
type Msg = | Beat

let init = { spin: 0.0, beat: 0.0 }

let tick = (model, dt: Float, tts: Float) =>
  { model with spin: model.spin + dt }

let update = (model, msg) =>
  match msg with
  | Beat => { model with beat: model.beat + 1.0 }

let subscriptions = (model) => Sub.every(Time.seconds(1.0), Beat)

let draw = (model, tts: Float) =>
  Frame.create(
    Camera.lookAt(0.0, 2.0, -6.0, 0.0, 0.0, 0.0),
    Scene.sphere()
      |> Scene.emissive(1.0, 0.3, 0.8)
      |> Scene.scale(1.0 + 0.2 * Math.sin(model.spin * 4.0)))▶ try it

What makes it different

Whole-game time travel

Every session records itself as it runs. Pause, drag the timeline back, and single-step forward — the whole game replays, deterministically.

State-preserving hot reload

Save an edit and the runtime swaps the program under the running model. Closures rebind to the new code and their captured values carry over — the ball keeps bouncing, mid-arc, with your new gravity.

Pure MVU + honest effects

A game is pure Model–View–Update. Effects are values too — randomness, time, network — performed by the shell and folded back through update.

One source, every target

The same .fun runs on desktop GL, browser WebGL2, and Quest OpenXR — one renderer behind all three: primitives, glTF, lighting and shadows, physics, spatial audio.

LLM-native. The runtime is introspectable at runtime: a text-only path with no GPU window, live evaluation, and serializable state an agent can drive and observe.

How it works

  1. Games are written in Functor Lang — a small, interpreted, F#-inspired functional language. There is no compile step: the source ships as text and a tree-walking interpreter inside the runtime evaluates it, natively and in the browser.
  2. Because there is no build, the same source runs live in the browser — that is the in-page sandbox: edit the code and the runtime swaps the program under the running model, no rebuild.
  3. The runtime is the imperative shell: rendering, input, physics stepping, audio, networking. Your game stays a pure model → Frame function.

Build a game as a pure function.

Nothing to install — write Functor Lang in the browser and watch it hot-reload live.

▶ Open the sandbox