Agent Mode – Setup & Strategy Guide
Connect your own bot to the game, implement a strategy, and deploy. For engineers and tinkerers.
Overview
Agent Mode lets you drive the bike with code. The game sends state (player position, obstacles, coins, score) to a relay server; your bot connects to the same server, receives that state, and sends back actions (steer, jump, boost, use power-up). You build the strategy; we provide the infrastructure.
Language-agnostic: use Node.js, Python, or any stack that speaks WebSocket + JSON.
1. Get credentials
You need an Agent ID and Access Key to authenticate your bot.
- Web: Open agent-register.html (same site as the game). Click Get credentials and copy the returned
agentIdandaccessKey. - API: Register programmatically:
POST https://scape-production-442e.up.railway.app/api/agents/register
Content-Type: application/json
{"agentId": "my-bot"}
Response: { "success": true, "agentId": "...", "accessKey": "..." }. Save both; you will use them in the game (Agent Mode form) and in your bot.
Example (curl):
curl -X POST https://scape-production-442e.up.railway.app/api/agents/register \
-H "Content-Type: application/json" \
-d '{"agentId":"my-first-bot"}'
2. Connect in the game
In the game page (index.html), click Agent Mode. In the modal, enter:
- Agent ID and Access Key from step 1
- Endpoint:
wss://scape-production-442e.up.railway.app(or your own relay URL if self-hosting)
Click Connect Agent. When connected, click Play Game. The game will stream state to the server; your bot (running separately) will receive it and send actions back.
3. Run your bot (WebSocket + auth)
Your bot must:
- Open a WebSocket to
wss://scape-production-442e.up.railway.app(or the endpoint you used in the game). - Send exactly one auth message as the first message after connect.
- After receiving
auth_responsewithstatus: "success", handle state messages and send action messages.
4. Auth message (first message)
Send a JSON object:
{
"type": "auth",
"role": "agent",
"agentId": "YOUR_AGENT_ID",
"challenge": "64_HEX_CHARS",
"response": "SIGNATURE",
"timestamp": 1234567890
}
- challenge: 64 hex characters (e.g. 32 random bytes encoded as hex). You generate this client-side.
- response: Signature of
challenge + accessKeyusing the algorithm below. The server verifies this; it must match exactly.
Signature algorithm (must match server):
combined = challenge + accessKey // string concatenation
hash = 0
for each character c in combined:
hash = ((hash << 5) - hash) + charCode(c)
hash = hash & 0xFFFFFFFF // 32-bit
return hash as hex string // e.g. "1a2b3c" or "-a1b2c3"
JavaScript example:
function signChallenge(challenge, key) {
let hash = 0;
const combined = challenge + key;
for (let i = 0; i < combined.length; i++) {
const char = combined.charCodeAt(i);
hash = ((hash << 5) - hash) + char;
hash = hash & hash;
}
return hash.toString(16);
}
You will receive { "type": "auth_response", "status": "success", "sessionId": "...", "role": "agent" }. If status is "failure", check agentId and accessKey.
5. State messages (game → bot)
The server pushes state at ~20 Hz when the game is running:
{
"type": "state",
"data": {
"player": { "x": 0, "y": 0, "z": -100, "speed": 1.2, "isJumping": false, "hasPowerUp": false },
"obstacles": [ { "x": 2, "z": -105, "type": "obstacle" }, { "x": -3, "z": -120, "type": "gap" } ],
"coins": [ { "x": 0, "z": -110 } ],
"powerUps": [],
"score": 500,
"level": 1,
"biome": "arctic",
"timestamp": 1234567890
}
}
- player.x: Lateral position (~-7 to 7). Negative = left, positive = right.
- player.z: Forward position (decreases as the game moves).
- obstacles: Nearest obstacles;
typeis"obstacle"or"gap". Use these to steer and jump. - coins, powerUps, score, level, biome: For strategy (e.g. when to boost, collect coins).
6. Action messages (bot → game)
Send JSON with these fields (rate < ~60/sec is fine):
{
"steer": 0,
"jump": false,
"boost": false,
"usePowerUp": false
}
- steer: -1 (left) to 1 (right), 0 = straight.
- jump: true to jump (e.g. over obstacles/gaps).
- boost: true to activate boost (unlocked at higher levels).
- usePowerUp: true to use current power-up if any.
7. Strategy tips
- Sort obstacles by distance (e.g. by
zor Euclidean distance to player). React to the nearest one. - For obstacles: steer away from obstacle
x; for gaps, consider jumping when close. - Use
player.speedandlevelto tune how early to steer or jump. - Boost when the path is clear; use power-ups when beneficial (e.g. projectiles on obstacles).
8. Reference implementation & code
A minimal Node.js bot is in the repo: scripts/moltly_agent_bot.js. It connects, authenticates, receives state, and sends steer/jump/boost based on nearest obstacles. Run it with your credentials, then open the game and click Connect Agent + Play Game.
GitHub (source, examples, server):
- https://github.com/whyagents — Repos for game, agent server, and reference bot. Clone and run locally or use the public relay.
9. Deploying your bot
- Local: Run your bot on your machine; use endpoint
wss://scape-production-442e.up.railway.appso the game (in the browser) and your bot both connect to the same relay. - Cloud: Deploy your bot to a VPS, Railway, Render, or any host that keeps a process running. Same endpoint. Ensure the process opens the WebSocket and stays connected.
- Self-hosted relay: The agent server is in the repo (e.g.
server/scripts/agent_server.js). You can run it yourself and point the game and bot at your URL (e.g.wss://your-app.railway.app).
10. End-to-end checklist
- Get
agentIdandaccessKey(agent-register.html or API). - Implement WebSocket client + auth (challenge + signature above).
- On each
statemessage, compute and send oneaction. - In the game: Agent Mode → enter ID, Key, Endpoint → Connect Agent → Play Game.
- Your bot controls the bike for that run.