Skip to main content
LingBot World 2 is a real-time navigable world model, and the next generation of LingBot. It takes a reference image plus a text prompt as visual and stylistic anchors, then generates an infinite video stream that you can explore in real time. Drive the camera with WASD, look around with the arrow keys, direct the camera with native pose moves, and restyle the world on the fly by hot-swapping the prompt. Coming from the first LingBot, three things are new:
  • Movement is now possible along two independent axes (longitudinal and lateral)
  • A native set_camera_pose layer drives directed camera moves to create new types of camera control
  • A broader prompt-steering surface handles mid-stream scene changes.
The LingBot World 2 reference is split across four pages: this overview, the complete command and event schema, the prompt guide for writing prompts that steer the world, and an end-to-end tutorial against the open-source reference frontend. The base wire protocol is the same as every other Reactor model: open a session with the Reactor class (model name reactor/lingbot-world-2), send named commands, receive events. LingBot World 2 also has a typed SDK, @reactor-models/lingbot-world-2, that wraps the base class with named methods (setImage, setPrompt, start, …) and React hooks; the tutorial uses it. See Typed Model SDKs.

At a glance

SpecValue
Model namereactor/lingbot-world-2
Pricing
Frame rate48 fps
Resolution1664 × 960
InputReference image + text prompt
The model name is the string you pass when you open a session, e.g. new Reactor({ modelName: "reactor/lingbot-world-2" }); the create-reactor-app CLI and the pricing catalog use the short slug lingbot-world-2. See Pricing & Billing for how billing works.

Key features

Two-axis WASD navigation

Drive the camera with independent longitudinal (W/S) and lateral (A/D) movement, plus arrow-key look. Commands apply at the next chunk boundary.

Image-anchored generation

A reference image fixes the visual identity of the world; the prompt steers atmosphere and content. An image is required before generation starts.

Directed camera moves

The native set_camera_pose layer drives arbitrary camera movements with per-frame motion deltas that can either augment or fully replace the look axes.
Beyond these, you can hot-swap the prompt mid-stream with set_prompt to change weather, lighting, or events without restarting the session or losing the reference image. The prompt guide covers how to write effective prompts.

Quick start

The fastest path to a working LingBot World 2 app is the create-reactor-app CLI, which scaffolds the reference frontend into a runnable project. You can also clone the open-source reference frontend itself, or follow the tutorial for a guided walkthrough.
npx create-reactor-app my-lingbot-world-2-app --model=lingbot-world-2
Working in Python instead? The CLI is JavaScript-only, so install the SDK with pip install reactor-sdk and follow the Python tab below (see the quickstart for the full walkthrough). A minimal connect-and-generate flow looks like:
import { Reactor } from "@reactor-team/js-sdk";

const video = document.querySelector("video")!;
const reactor = new Reactor({ modelName: "reactor/lingbot-world-2" });

// Render frames as soon as they arrive.
reactor.on("trackReceived", (name, track, stream) => {
  if (name !== "main_video") return;
  video.srcObject = stream;
  void video.play();
});

// Once the session is ready, set a reference image and prompt, then start.
reactor.on("statusChanged", async (status) => {
  if (status !== "ready") return;
  const ref = await reactor.uploadFile(seedImageFile);
  await reactor.sendCommand("set_image", { image: ref });
  await reactor.sendCommand("set_prompt", {
    prompt: "A reddish-brown ant on a dirt path between tall green grass blades, macro nature.",
  });
  await reactor.sendCommand("start", {});
});

const jwt = await getToken(); // token minted on your server
await reactor.connect(jwt);
import asyncio
import os
from reactor_sdk import Reactor, ReactorStatus

async def main():
    reactor = Reactor(model_name="reactor/lingbot-world-2", api_key=os.environ["REACTOR_API_KEY"])

    # Frames arrive as (H, W, 3) uint8 RGB NumPy arrays.
    @reactor.on_frame
    def on_frame(frame):
        print(f"Frame: {frame.shape}")

    # Once the session is ready, set a reference image and prompt, then start.
    @reactor.on_status(ReactorStatus.READY)
    async def on_ready(status):
        ref = await reactor.upload_file("seed.jpg")
        await reactor.send_command("set_image", {"image": ref})
        await reactor.send_command("set_prompt", {
            "prompt": "A reddish-brown ant on a dirt path between tall green grass blades, macro nature.",
        })
        await reactor.send_command("start", {})

    await reactor.connect()
    await asyncio.Event().wait()  # run until interrupted

asyncio.run(main())
That uses the base SDK. The typed SDK, @reactor-models/lingbot-world-2, gives you new LingbotWorld2Model() with named methods and React hooks (useLingbotWorld2, <LingbotWorld2MainVideoView />); the tutorial builds on it. See Typed Model SDKs.

How it works

On connect the model is live but idle; it won’t produce frames until it has both a reference image and a prompt and you call start. In order to get your first generated video stream, you must:
  1. Connect to the model.
  2. Upload and set a reference image with set_image; it anchors the visual identity of the world.
  3. Set a prompt with set_prompt to describe the scene and how the camera and subject may move.
  4. Start generation. start fails with a command_error until both an image and a prompt are set.
  5. Drive the camera with the two movement axes (W/S + A/D) and the look axes (arrow keys), or direct it with set_camera_pose.
  6. Restyle live by hot-swapping the prompt with set_prompt; the change lands on the next chunk.
  7. Pause / resume between chunks, or reset to clear state and re-stage with new conditions.
LingBot World 2 generates video one chunk at a time. Movement and look are persistent state, not pulses: set_move_longitudinal: "forward" keeps driving until you send "idle". Commands take effect at the next chunk boundary, so a quick key tap released before the boundary may never land on screen. When a run finishes, the server auto-restarts it with the same prompt and image until you reset. See the schema for the full surface.