FORERUNNER // CHARACTER ENGINE · API PREVIEW
AI CHARACTERSTHAT SEE YOUR GAME.
Stream the player's viewport to a character and it watches the game in real time — then speaks, reacts, and acts on what's actually happening. Memory and voice included, in one API.
IT SEES WHAT THE PLAYER SEES.
Open a perception stream and pipe the player's viewport to the character. It watches the game live — then speaks, reacts, and acts on what's actually in front of it. Not scripted triggers; a witness. Nothing else for games does this.
// stream the player's view → the character sees the gamevar eyes = fr.Characters.Perceive("char_8f2", fps: 4); // push the camera's render target each framevoid Update() => eyes.Send(playerCamera.Capture()); eyes.OnReaction += r => { // r.Sees "a dragon landing on the keep wall" // r.Says "Get down — to the wall, now!" npc.Perform(r); // r.Act "point", r.Emotion "alarm"};IN YOUR WORLD
A CHARACTER THAT LIVES IN THE GAME.
Drop one into your world and it remembers the player, talks back in its own voice, and stays in character — quest after quest.
BUILD VS BUY
ONE API VS. THE STACK YOU'D STITCH.
Every team prices the same DIY build: GPT for the brain, ElevenLabs for the voice, mem0 for the memory — plus the glue to make them feel like one character. Here's the math.
to first audio
GPT → ElevenLabs round-trips in ~1.2–2 s
not three vendors
replaces GPT + ElevenLabs + mem0 + glue
vector stores to run
memory is managed — it just works
GPT + ElevenLabs + mem0
the DIY stack- ✕Time to first audio — ~1.2–2 s
- ✕Real-time perception — No real path
- ✕Memory — You run a vector store + retrieval
- ✕Vendors to wire up — 3 + your glue code
- ✕Stays in character — Prompt-stitched across APIs
- ✕Voice consent — On you
Mirari
one API- Time to first audio — < 300 ms
- Real-time perception — Native — sees the game
- Memory — Managed — just works
- Vendors to wire up — 1
- Stays in character — One model, always
- Voice consent — Voice ID Registry, built in
Mirari first-audio is measured on our stack; the DIY figures are representative of a streamed GPT-class → ElevenLabs → mem0 round-trip. Full methodology on request.
GET RUNNING IN THREE CALLS.
An illustrative preview of the REST API. Shapes may change before general availability — you'll get the current spec with your key.
Authenticate
Drop in your API key and point at the base URL. Every call is one bearer token away.
// Unity — add the Forerunner UPM package, then:using Forerunner; var fr = new ForerunnerClient("fk_live_8f2a…");bool ok = await fr.HealthAsync();Debug.Log(ok); // TrueCreate a character
Give it a name, a persona, and a voice. It returns with persistent memory, ready to talk.
var rin = await fr.Characters.CreateAsync(new CharacterSpec { Name = "Rin", Persona = "Sharp-tongued, loyal, bilingual scout.", Voice = "mirari:rin", Memory = MemoryMode.Persistent,});Debug.Log(rin.Id); // "char_8f2"Send a message
Stream a reply in character — text and audio — while its memory updates itself. That's the whole loop.
// stream a reply, in character, with audioawait foreach (var ev in fr.Characters.Chat("char_8f2", new ChatRequest { Session = "player_42", Say = "I'm back.",})) { if (ev.Text != null) subtitle.Append(ev.Text); if (ev.Audio != null) audioSource.Stream(ev.Audio); // ~280ms first byte}Update memory & state
Write what just happened — a betrayal, a gift, a death — and patch game state or player facts. The character recalls it next session, unprompted.
// write what just happened — recalled next session, unpromptedawait fr.Characters.RememberAsync("char_8f2", new MemoryEvent { Event = "Player spared the bandit chief.", Weight = 0.8f, Tags = new[] { "mercy", "quest:bandits" },}); // patch game state + player factsawait fr.Characters.PatchStateAsync("char_8f2", new { trust = +2, location = "Riverwood", knows = new { player_name = "Dovah" },});LIVING WORLDS
DESCRIBE IT. THE NARRATOR KEEPS IT ALIVE.
Cast an ensemble and describe the world in plain English. An overseeing AI — the narrator — builds the social graph from your words, then reshapes every bond as events unfold. No relationship maps to wire, no branches to script.
// Describe the world in plain English — the narrator does the wiring.const world = await fr.worlds.create({ cast: ["Rin", "Tsuki", "Mochi", "Vex", "Kit", "Sable"], premise: `Rin trusts Kit, but both are rivals with Vex. Tsuki mentors Mochi, who owes Sable a life debt.`,}); // From here an overseeing AI runs the world: it reads each event and// reshapes every bond, mood, and stake on its own — no graph wiring,// no branch scripts.world.on("event", world.narrate);The narrator runs the whole graph live — you just say what the world is.
GET EARLY ACCESS.
We're onboarding studios and builders in waves. Tell us what you're making and we'll get you a key.
No credit card. Rolling invites. Full docs ship at api.forerunner.ai.


