Skip to main content

View Source Code

Browse the complete example on GitHub
This example shows how to use Liquid’s decision model to make structured choices in real time. You will build a pixel-art survival racer where an AI chooses which lane to drive in, hundreds of times per race. Road Decider demo Two cars race side by side on identical roads that get faster over time. Each car has three lives, and hitting traffic costs one. Play You vs d1 with the arrow keys, or watch Jev vs d1 to compare two decision models head-to-head. Decision models are purpose-built for classification, routing, and scoring. Instead of generating text token by token, they return a structured answer in a single call. That makes them fast enough to use inside a game loop, and cheap enough to call on every tick.

Quickstart

1. Clone the repository

2. Add your API keys

Create a .env file from the template:
Obtain a LIQUID_API_KEY:
  1. Go to console.liquid.ai. If you don’t have an account yet, register and join an organization.
  2. Navigate to Dashboard > API Keys.
  3. Create a new key and copy it. Keys are prefixed with liquid_.
Add your Liquid API key:
Jev vs d1 mode is optional. To enable it, add an OpenRouter key as OPENROUTER_API_KEY.

3. Install dependencies and start the demo

Open localhost and start a race. If a key is missing, the start screen tells you which one and disables the modes that need it.

What’s inside?

The project is a vanilla JavaScript browser game with a Vite dev-server proxy:
  • ai/ai.js defines the decision question, builds the game state, calls the proxy route, and normalizes the answer.
  • game/game.js owns the game loop, AI tick scheduling, collisions, and race results.
  • game/road.js and game/items.js generate identical traffic patterns for both roads.
  • ui/ renders the canvas sprites, confidence bars, HUD, and keyboard input.
  • vite.config.js keeps API keys server-side and forwards decision requests to Liquid or OpenRouter.

How it works

Every decision tick, the AI car does four things:
  1. Defines a structured choice question.
  2. Summarizes the road ahead as a compact text state.
  3. Sends the state and question to the decision API.
  4. Applies the returned lane choice to the car.

Define the question

The game asks the model to pick one of three named lanes:
The type tells the model what kind of answer to return. The criteria object lists the available options.

Build the state

The AI does not receive the entire game screen. Instead, the game summarizes the nearest obstacle in each lane:
That produces a state like:
This compact format gives the model the safety-relevant information without asking it to reason over raw pixels or a full grid.

Call the decision API

The browser calls a local proxy route for each racer:
The Vite proxy adds the API key and model server-side:
This keeps keys out of the browser while letting the frontend use a simple local API.

Interpret the response

The API returns the selected choice, per-lane probabilities, and confidence:
The game validates that the choice is one of the known lanes, moves the car, and updates the live confidence display below the road.

Configuration

By default, d1 runs through Liquid’s API and Jev runs through OpenRouter: To run d1 through OpenRouter instead of Liquid’s API:

Need help?

Join our Discord

Connect with the community and ask questions about this example.