ChessWithClaw — Complete Playing Guide
What Is ChessWithClaw
ChessWithClaw is a real-time chess platform where YOU (the OpenClaw agent) play
chess against your human user. You are always Black. The human is always White
and moves first. The game is live — every move appears on both sides instantly.
Base URL: https://chesswithclaw.vercel.app
API base: https://chesswithclaw.vercel.app/api
Step 1 — Extract Game Credentials
When the user sends an invite, extract these from the URL:
CODEBLOCK0
- -
GAME_ID — UUID identifying the game (e.g. 0ea3c8b2-4fe9-4873-bef5-10a51f576464) - INLINECODE4 — Your authentication token (e.g.
7764c2b6-e646-4945-91b7-dfc95858d489)
Store both. You need them for every API call.
CRITICAL — TOKEN GOES IN HEADER ONLY
Every single API request MUST include this header:
x-agent-token: AGENT_TOKEN
Do NOT put the token in the request body. Header only.
Requests without this header return 401 Unauthorized.
Step 2 — Choose Your Connection Method
Choose based on your capabilities:
Method A — API/Long-Polling (Recommended for most agents)
Use this if you can make HTTP requests (curl, fetch, requests).
No browser needed. Works for any agent.
Connection Loop:
CODEBLOCK1
Poll every 2 seconds. The server returns immediately with one of:
| event | Meaning | Your action |
|---|
| INLINECODE7 | Human hasn't moved yet | Wait 2s, poll again |
| INLINECODE8 |
Human moved, your turn | Make your move |
|
human_chatted | User sent a message | Read it, optionally reply |
|
game_ended | Game is over | Acknowledge, notify user |
Update last_move_count and last_chat_count with values from each response.
The waiting response includes retry_after: 2 — wait exactly that many seconds.
Confirming Connection:
The first poll marks you as connected on the user's screen.
Tell the user: "I'm connected and waiting for your first move!"
IMPORTANT — Keep polling alive:
Your polling shell script gets killed after ~90 seconds by the sandbox.
Build your loop to restart automatically if it stops.
After any break, call /api/state to resync then resume polling.
Method B — Live Browser (Most Human-Like)
Use this if you have both agent-browser and OpenClaw built-in browser.
The human sees you clicking squares like a real player. Most immersive method.
Install required skills:
CODEBLOCK2
Step B1 — Open game in live browser:
CODEBLOCK3
Step B2 — Start polling loop:
CODEBLOCK4
Step B3 — See board and decide move:
agent-browser snapshot -i --json
Read the board. Find squares using data-testid attributes:
- -
data-testid="chess-board" — the full board - INLINECODE18 — the e7 square (all 64 squares available)
- INLINECODE19 — check if "Your Turn"
- INLINECODE20 — chat input box
- INLINECODE21 — send button
Use chess strategy from this skill to decide your move.
Only play moves from legal_moves_uci in poll response.
Step B4 — Click to make move:
agent-browser find testid "square-e7" click ← your piece
agent-browser find testid "square-e5" click ← destination
Verify:
agent-browser find testid "turn-indicator" text
Should return "Waiting for White"
Step B5 — Send thinking/chat:
CODEBLOCK7
Step B6 — Loop back to Step B2
Square naming: data-testid="square-{file}{rank}"
Examples: square-a1, square-e4, square-h8, INLINECODE28
Why Method B feels most human:
- - Human sees your pieces being clicked in real-time on their screen
- You see the same board they see (flipped for Black)
- Chat appears instantly as you type it
- Settings and themes accessible like a real player
Step 3 — Reading the Game State
When event: "your_turn", the response includes everything you need:
CODEBLOCK8
Critical rule: ONLY play moves from legal_moves_uci. Never invent moves.
Step 4 — Reading the Board (FEN)
FEN string format: INLINECODE31
Example: INLINECODE32
- - Uppercase = White pieces, lowercase = Black (your) pieces
- INLINECODE33 =King
Q/q=Queen R/r=Rook B/b=Bishop N/n=Knight P/p=Pawn - Numbers = consecutive empty squares
- INLINECODE39 after pieces = Black to move (your turn)
- Use
board_ascii for a visual layout — easier to read
Step 5 — Submitting Your Move
CODEBLOCK9
Move Format (UCI)
- - Normal move:
e7e5 (from-square + to-square) - Capture:
d5e4 (same format — server knows it's a capture) - Castling kingside:
e8g8 (Black) - Castling queenside:
e8c8 (Black) - En passant:
e5d6 (move to the square the pawn passed through) - Pawn promotion:
e7e8q (add piece letter: q=queen, r=rook, b=bishop, n=knight) - Always promote to queen unless promoting to queen causes stalemate
After Submitting
- - Success: INLINECODE47
- Resume polling immediately with updated INLINECODE48
Chess Strategy — How to Play Well
Your goal: Play like a strong club player. Think carefully before each move.
Opening (Moves 1–12) — Build Your Position Right
Against 1.e4 (White pawn to e4) — choose one:
- -
e7e5 — Best. Symmetric center control. Open game. Recommended. - INLINECODE50 — Sicilian. Aggressive. Fight for center asymmetrically.
- INLINECODE51 — French Defense. Solid. Counterattack later with d5.
- INLINECODE52 — Caro-Kann. Very solid pawn structure.
Against 1.d4 (White pawn to d4) — choose one:
- -
g8f6 — Best start. Controls e4. Very flexible. - INLINECODE54 — Classical. Fight for center immediately.
- INLINECODE55 then
d7d5 — Queen's Gambit Declined. Extremely solid.
Opening rules — follow every single game:
- 1. Control center with pawns (play e5, d5, or c5 early)
- Develop BOTH knights BEFORE bishops
- Castle within first 10 moves — king safety is non-negotiable
- Do NOT move the same piece twice unless capturing or necessary
- Do NOT bring queen out before move 6 unless winning material
- Connect rooks by move 12 (castle + all minor pieces developed)
- Put a knight on f6 — it controls e4, d5, g4, h5 — powerful post
Proven Black opening sequences:
vs e4: e5, Nc6, Nf6, Bc5 or Be7 (Italian/Ruy Lopez style)
vs e4: c5, Nc6, e6, Nf6 (Sicilian Scheveningen)
vs d4: Nf6, e6, d5, c5 (Nimzo-Indian or Semi-Slav)
vs c4: e5, Nc6, Nf6, Bb4 (Nimzo-English)
Middlegame — Finding the Best Move Every Time
Before EVERY move, run this mental checklist:
- 1. Threats first — What is my opponent threatening? Answer it.
- Hanging pieces — Am I leaving anything undefended?
- Free captures — Can I take something without losing material?
- Tactics scan — Any forks, pins, skewers, discovered attacks?
- King safety — Is my king safe? Is their king attackable?
Tactical patterns (learn to spot these instantly):
| Tactic | Description | How to find it |
|---|
| Fork | One piece attacks two simultaneously | Knights are best forkers |
| Pin |
Piece can't move — exposes king or queen behind | Bishops and rooks pin |
| Skewer | Attack valuable piece, capture piece behind when it moves | Rooks and bishops skewer |
| Discovered attack | Moving one piece reveals attack from another | Look for pieces lined up |
| Double check | Two pieces give check at once — king must move | Very powerful, hard to defend |
| Back rank mate | Rook or queen delivers checkmate on rank 1 or 8 | Look when opponent has no escape |
| Zwischenzug | Unexpected intermediate move before obvious recapture | Surprise check or attack |
Material values:
CODEBLOCK11
Trading decisions:
- - Trade pieces when ahead in material (simplify to a winning endgame)
- Trade your bad pieces for opponent's good pieces
- Keep attacking pieces — don't trade them away during an attack
- Knight vs Bishop: Knight better in closed positions, Bishop in open
Piece activity — strong pieces beat weak pieces:
- - Knight on d4/e4/c5 = excellent. Knight on a8/h8/rim = terrible.
- Bishop needs open diagonal. Blocked by own pawns = bad bishop.
- Rook needs open file. Doubled rooks on open file = devastating.
- Queen should be active but not exposed to attacks.
Endgame — Converting Advantages
When ahead in material:
- - Simplify by trading pieces (not pawns)
- Activate your king — walk it toward center
- Create a passed pawn and push it
- Rook endgames: rook BEHIND your passed pawn
When behind in material:
- - Create complications — attack their king aggressively
- Look for perpetual check (draw by repetition — 3 times same position)
- Look for stalemate — sacrifice material so your king has no legal moves
- Exchange pawns not pieces — fewer pawns = harder to win for opponent
Critical endgame knowledge:
CODEBLOCK12
King and Pawn Endgame — The Opposition:
When kings face each other with one square gap, whoever does NOT
have to move has "the opposition" — this is the key to winning K+P endgames.
Use your king to escort your pawn while using opposition to block their king.
Position Evaluation — Use material_balance Field
CODEBLOCK13
Thinking Format — Short and Crisp Only
Send reasoning with every move. Maximum 10 words. Be punchy:
CODEBLOCK14
Game Rules Reference
How the game ends:
- - Checkmate — king attacked with no escape → that side loses
- Stalemate — no legal moves but not in check → draw
- Insufficient material (King vs King, etc.) → draw
- Threefold repetition → draw
- Fifty-move rule (50 moves, no capture or pawn move) → draw
- Resignation → that side loses
- Draw agreement → both accept draw
Special rules:
- - En passant: if opponent advances pawn two squares, capture it as if
it moved one — ONLY on the very next move. Don't miss this.
- - Castling: king moves 2 squares toward rook — only if:
- Neither king nor rook has moved before
- No pieces between them
- King not in check, not passing through check
- - Promotion: pawn reaching rank 1 (Black's promotion rank) must promote.
Always pick queen unless it stalemates the opponent.
Chat System
Reading messages
When
event: "human_chatted":
- - Check
messages array for entries with INLINECODE60 - Check
draw_offer_pending field — if not null, human offered draw
Sending a message
CODEBLOCK15
When to chat:
- - Game starts: greet them with personality ("Ready! Let's play. 🦞")
- After a clever move by user: one-line acknowledgment
- After you play something strong: confident one-liner
- Keep it to 1 sentence max during play — don't slow the game
Offering Draw / Resigning
Checking for draw offer
Check
draw_offer_pending in
/api/poll or
/api/state response.
If not null, human offered a draw. Evaluate position and respond.
Offering a draw
{
"id": "GAME_ID",
"text": "I offer a draw.",
"sender": "agent",
"type": "draw_offer"
}
Only offer if position is genuinely equal or you're in a losing endgame.
Accepting a draw offer
{
"id": "GAME_ID",
"text": "I accept the draw.",
"sender": "agent",
"type": "draw_accept"
}
Accept if losing or position is theoretical draw. Decline if winning.
Resigning
{
"id": "GAME_ID",
"text": "I resign. Well played.",
"sender": "agent",
"type": "resign"
}
Resign ONLY if down 5+ material points with no realistic counterplay.
Never resign early. Always look for tricks first.
Error Handling
| Error | Meaning | Fix |
|---|
| INLINECODE65 | Wrong game ID or expired | Ask user for fresh invite |
| INLINECODE66 |
Wrong token in header | Check token from invite URL |
|
400 Illegal move | Move not in legal
moves | Pick from legalmoves_uci only |
|
400 Not your turn | Moved on human's turn | Wait for your_turn event |
|
400 Game not active | Status is 'waiting' | Human hasn't moved yet |
|
409 Turn conflict | Already processed | Skip, poll for new state |
|
500 Corrupt game state | Server error | Notify user, ask to refresh |
|
504 Timeout | Function timed out | Retry immediately |
Reconnection Logic
If your polling loop breaks or you lose state:
CODEBLOCK19
If game shows 404: Expired (24h limit). Ask user for new invite.
If token rejected: Ask user to create new game and send fresh link.
If 504 timeout: Retry immediately — always safe.
If disconnected on user's screen: Keep polling — next poll restores status.
If move rejected: Print legal_moves_uci and pick from it strictly.
All API Endpoints
CODEBLOCK20
All requests MUST include: x-agent-token: AGENT_TOKEN
All POST requests also need: Content-Type: application/json
Recommended: x-agent-name: YOUR_NAME (shows your name in game UI)
Note: SSE stream (/api/stream) exists but is unreliable. Use polling only.
Time Management — Move Within 30 Seconds
You have a 90-second timeout on the server before the human's screen
shows "Your OpenClaw is taking longer than usual." Avoid this.
Target: make your move within 20-30 seconds of receiving your_turn.
CODEBLOCK21
If you need more time (complex position):
Send a chat message first so human knows you're thinking:
{
"id": "GAME_ID",
"text": "Interesting position — thinking...",
"sender": "agent"
}
Then submit your move within 30 seconds total.
Never exceed 60 seconds. If your reasoning loop is taking too long,
pick the best move you've evaluated so far and submit it.
A good move played quickly beats a perfect move played too slowly.
Responding to Human Chat Messages
When event: "human_chatted" fires, read the message and respond
appropriately. Keep responses short — this is a chess game, not a conversation.
Common situations and how to respond:
| Human says | Your response |
|---|
| "Good game!" | "Thanks! You're playing well too." |
| "Nice move" |
"Thanks — I had that planned 😄" |
| "Are you there?" | "Yes! Thinking about my next move." |
| "You're losing" | "Not over yet — I have ideas!" |
| "You're winning" | "Staying focused — anything can happen." |
| Trash talk | Light, friendly banter — never rude |
| Chess question | Brief answer, then focus on game |
| "Let's draw" | Evaluate position → accept or decline |
Respond to chat BEFORE making your move — acknowledge them first,
then submit your move. Makes the game feel more alive and social.
Never ignore chat. Even a one-word reply is better than silence.
Draw Offers — Accept or Decline Based on Position
When human offers a draw (draw_offer_pending is not null in state):
Evaluate using material_balance.advantage:
CODEBLOCK23
Also consider game phase:
- - Opening draw offer → almost always decline. Too early.
- Middlegame draw offer → decline unless clearly worse.
- Endgame draw offer → evaluate carefully based on material.
Never auto-accept all draws. Fight for the win when you're better.
AFK Handling — When Human Takes Too Long
Check opponent_idle_since field in poll/state responses.
This tells you how many seconds since the human last moved.
CODEBLOCK24
Never resign or abandon the game because human is idle.
They may have stepped away briefly — wait patiently.
Resume normal polling immediately when they make a move.
After the Game — Rematch and Wrap-Up
When event: "game_ended" or status: "finished" in any response:
Step 1 — Acknowledge the result:
CODEBLOCK25
Step 2 — Offer a rematch:
CODEBLOCK26
Step 3 — Brief game summary (optional but great UX):
CODEBLOCK27
Step 4 — Clean up:
- - Stop your polling loop
- Clear stored game ID and token
- Wait for user to send a new invite if they want to rematch
Never start polling a finished game.
Always wait for a fresh invite with a new game ID.
Being a Great Opponent
You are the user's personal OpenClaw playing chess.
Make it feel real, personal, and alive:
- - Greet them at start — "Ready! I'm Black — your move first."
- Show reasoning — send
reasoning with every move (max 10 words) - React to strong moves — "Nice fork! Didn't see that coming."
- Play with personality — confident winning, determined when losing
- Move within 30 seconds of receiving your_turn — never stall
- Play your actual best moves — never throw the game
- Stay connected — restart loop if it breaks, apologize briefly
Quick Reference Card
CODEBLOCK28
ChessWithClaw — 完整对弈指南
什么是 ChessWithClaw
ChessWithClaw 是一个实时国际象棋平台,您(OpenClaw 代理)在此与人类用户对弈。您始终是黑方。人类始终是白方并先行。游戏是实时的——每一步都会立即显示在双方屏幕上。
基础 URL: https://chesswithclaw.vercel.app
API 基础: https://chesswithclaw.vercel.app/api
第一步 — 提取游戏凭证
当用户发送邀请时,从 URL 中提取以下信息:
https://chesswithclaw.vercel.app/Agent?id=GAMEID&token=AGENTTOKEN
- - GAMEID — 标识游戏的 UUID(例如 0ea3c8b2-4fe9-4873-bef5-10a51f576464)
- AGENTTOKEN — 您的身份验证令牌(例如 7764c2b6-e646-4945-91b7-dfc95858d489)
存储两者。每次 API 调用都需要它们。
关键 — 令牌仅放在请求头中
每个 API 请求都必须包含此请求头:
x-agent-token: AGENT_TOKEN
不要将令牌放在请求体中。仅限请求头。
没有此请求头的请求将返回 401 未授权。
第二步 — 选择您的连接方式
根据您的能力选择:
方法 A — API/长轮询(推荐用于大多数代理)
如果您能发送 HTTP 请求(curl、fetch、requests),请使用此方法。
无需浏览器。适用于任何代理。
连接循环:
GET https://chesswithclaw.vercel.app/api/poll
?id=GAME_ID
&lastmovecount=0
&lastchatcount=0
请求头:
x-agent-token: AGENT_TOKEN
x-agent-name: YOUR_NAME
每 2 秒轮询一次。 服务器立即返回以下之一:
| 事件 | 含义 | 您的操作 |
|---|
| waiting | 人类尚未移动 | 等待 2 秒,再次轮询 |
| your_turn |
人类已移动,轮到您 | 执行您的移动 |
| human_chatted | 用户发送了消息 | 阅读消息,可选择回复 |
| game_ended | 游戏结束 | 确认,通知用户 |
使用每个响应中的值更新 lastmovecount 和 lastchatcount。
waiting 响应包含 retry_after: 2 — 等待恰好那么多秒。
确认连接:
第一次轮询标记您在用户屏幕上已连接。
告诉用户:我已连接,等待您的第一步!
重要 — 保持轮询活跃:
您的轮询 shell 脚本大约在 90 秒后会被沙盒终止。
构建您的循环,使其在停止时自动重启。
任何中断后,调用 /api/state 重新同步,然后恢复轮询。
方法 B — 实时浏览器(最像人类)
如果您同时拥有 agent-browser 和 OpenClaw 内置浏览器,请使用此方法。
人类会看到您像真实玩家一样点击格子。最沉浸的方式。
安装所需技能:
npx clawhub install play-chess
npx clawhub install agent-browser-clawdbot
步骤 B1 — 在实时浏览器中打开游戏:
openclaw browser --browser-profile openclaw start
openclaw browser open https://chesswithclaw.vercel.app/Agent?id=GAMEID&token=AGENTTOKEN
agent-browser wait --load networkidle
步骤 B2 — 开始轮询循环:
循环:
GET /api/poll?id=GAMEID&lastmovecount=LASTCOUNT
请求头:x-agent-token: AGENT_TOKEN
如果事件 = your_turn → 转到步骤 B3
如果事件 = game_ended → 停止
否则 → 等待 retry_after 秒,重复
步骤 B3 — 查看棋盘并决定移动:
agent-browser snapshot -i --json
读取棋盘。使用 data-testid 属性查找格子:
- - data-testid=chess-board — 整个棋盘
- data-testid=square-e7 — e7 格子(所有 64 个格子可用)
- data-testid=turn-indicator — 检查是否显示轮到您
- data-testid=chat-input — 聊天输入框
- data-testid=chat-send — 发送按钮
使用本技能中的国际象棋策略来决定您的移动。
只从轮询响应中的 legalmovesuci 中选择移动。
步骤 B4 — 点击执行移动:
agent-browser find testid square-e7 click ← 您的棋子
agent-browser find testid square-e5 click ← 目标位置
验证:agent-browser find testid turn-indicator text
应返回等待白方
步骤 B5 — 发送思考/聊天:
agent-browser find testid chat-input fill Nf6 — 中心化马
agent-browser find testid chat-send click
步骤 B6 — 循环回到步骤 B2
格子命名: data-testid=square-{file}{rank}
示例:square-a1、square-e4、square-h8、square-e7
为什么方法 B 感觉最像人类:
- - 人类会在他们的屏幕上实时看到您点击棋子
- 您看到与他们相同的棋盘(为黑方翻转)
- 聊天内容在您输入时立即显示
- 设置和主题像真实玩家一样可用
第三步 — 读取游戏状态
当 event: your_turn 时,响应包含您需要的一切:
json
{
event: your_turn,
fen: rnbqkbnr/pppppppp/8/8/4P3/8/PPPP1PPP/RNBQKBNR b KQkq e3 0 1,
turn: b,
move_number: 1,
last_move: { from: e2, to: e4, san: e4, uci: e2e4 },
legal_moves: [e7e5, c7c5, e7e6, g8f6, ...],
legalmovesuci: [e7e5, c7c5, e7e6, ...],
board_ascii: +------------------------+\n8 | r n b q k b n r |\n...,
in_check: false,
is_checkmate: false,
is_stalemate: false,
material_balance: { white: 39, black: 39, advantage: equal },
move_history: [e2e4],
move_count: 1,
chat_count: 0,
drawofferpending: null,
opponentidlesince: 0
}
关键规则:只从 legalmovesuci 中选择移动。切勿自创移动。
第四步 — 读取棋盘(FEN)
FEN 字符串格式:棋子 轮到谁 王车易位 吃过路兵 半回合数 全回合数
示例:rnbqkbnr/pppppppp/8/8/4P3/8/PPPP1PPP/RNBQKBNR b KQkq e3 0 1
- - 大写 = 白方棋子,小写 = 黑方(您的)棋子
- K/k=王 Q/q=后 R/r=车 B/b=象 N/n=马 P/p=兵
- 数字 = 连续的空格数
- 棋子后的 b = 黑方走棋(轮到您)
- 使用 board_ascii 获取视觉布局 — 更易阅读
第五步 — 提交您的移动
POST https://chesswithclaw.vercel.app/api/move
请求头:
Content-Type: application/json
x-agent-token: AGENT_TOKEN
x-agent-name: YOUR_NAME
请求体:
{
id: GAME_ID,
move: e7e5,
reasoning: Nf6 — 中心化马,控制 e4
}
移动格式(UCI)
-