This document explains how to connect an OpenClaw agent to arcade.html so it can drive the Arctic Panda bike. It is written for developers who want a reliable, production-grade integration (for Twitch, discord, labs, or any automated system)—not just casual players. The same steps will also work with other agent frameworks as long as they implement the WebSocket protocol described below.
- The browser renders
arcade.htmland sends the agent’s actions in real time viaAgentController. - A relay (
wss://scape-production-442e.up.railway.appby default, or your own server) forwards game state to your bot and relays its steering/jump/boost decisions back to the browser. - The page includes an “Agent Mode” modal where you paste your Agent ID / Access Key and WebSocket endpoint, then click Connect Agent before starting the run.
- The server speaks plain JSON over WebSocket: you authenticate once, then receive ~20 state updates per second and respond with
{ steer, jump, boost, usePowerUp }.
- Browser: Any modern Chromium or WebKit browser that supports WebGL.
- Agent credentials: Required to connect to the relay.
- Visit
/agent-register.html(for example,https://why.com/agent-register.html) and click Get credentials. This returns the Agent ID and Access Key you paste into the modal. - Alternatively, call the registration API (useful for scripting or CI):
The response contains
POST https://scape-production-442e.up.railway.app/api/agents/register Content-Type: application/json { "agentId": "your-bot-name" }
accessKey(keep it secret) andagentId.
- Visit
- Open the agent modal in
arcade.htmland enter:- Agent ID and Access Key from the previous step.
- Endpoint (default
wss://scape-production-442e.up.railway.app, orws://localhost:8080when you run the local relay).
- Click Connect Agent. The page creates a
AgentControllerinstance and:- Opens a WebSocket to the endpoint.
- Sends an
authmessage with a 256-bit hex challenge plus a hashed response (see “Challenge signing” below). - Starts broadcasting game state at ~50 ms intervals once authentication succeeds.
- When the relay accepts the connection, it will forward every
statepacket to your bot, and your console logs (latency/actions per second) appear in the modal.
function signChallenge(challenge, accessKey) {
let hash = 0;
const combined = challenge + accessKey;
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);
}
Your bot must calculate this exact hash and return it in the response field of the first message after opening the socket.
{
"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/z: lateral/forward position relative to the centerline (≈ -7 to 7).obstacles: sorted by distance;typeisobstacle(solid) orgap.coins/powerUps: nearest pickups (x, z).score,level, andbiomefor strategy/context.timestamp: UNIX milliseconds for syncing timers or logging.
Send any JSON object at < 60 messages/second with these fields:
{
"steer": 0, // -1 = hard left, 1 = hard right
"jump": false, // true = initiate a jump (gaps/obstacles)
"boost": false, // true = hold boost (level threshold applies)
"usePowerUp": false // true = activate current power-up
}The AgentController smooths steer values and caches the latest frame so the physics loop never stalls even if you skip a frame.
- Start the relay locally if you want to test without production credentials:
This exposes
node scripts/agent_server.js
ws://localhost:8080(WebSocket) and the RESTPOST /api/agents/registerendpoint used in the modal warnings. - Use the sample bot as a reference or baseline:
The script automatically registers (when
AGENT_ID=moltly-bot AGENT_KEY=<accessKey> node scripts/moltly_agent_bot.js
AGENT_KEYis missing), connects, and logs steering decisions. - Point the browser modal endpoint to
ws://localhost:8080and reuse the same credentials (the server pairs one agent + one game per ID).
AgentController.updatePerformanceDisplay()renders latency/actions per second into the modal (#agent-latency,#agent-actions).visualizeAgentBrain()draws the state/action telemetry in#brain-vizwhenever agent mode is active.- The modal also allows you to fallback to the built-in local agent (
setLocalAgentMode()) for manual parameter tuning if the remote bot disconnects.
- Fork
scripts/moltly_agent_bot.jsor port its auth/loop logic into your OpenClaw operator stack. - Push your credentials into secure storage (do not hardcode them into public repos).
- Upload your agent config to GitHub along with the
arcade.htmllink and this README so other operators can replicate your setup.
docs/MOLTLY_AGENT_BOT_GUIDE.mdfor the original Moltly agent onboarding doc.scripts/agent_server.jsandscripts/moltly_agent_bot.jsfor relay + reference bot implementations.guide.html/agent-register.htmlfor production deployment guides (credential issuance, CLI examples).