English | 中文
General game agent on Pi + LLM (e.g. DeepSeek).
Design codename: GameMind. First demo game: Neon Snake.
Remote: git@github.com:ifoxhz/pigame.git
Welcome. Contributions of any kind and any ideas are welcome — let’s make the Pi agent more fun.
Pi + LLM = brain (strategy / when to stop)
pigame = scaffolding only
tools = eyes / hands / feet
| Layer | Role |
|---|---|
| Pi + LLM | Decide what to do; judge when the goal is done |
game_observe | Eyes — see the screen → AgentState |
game_move / game_wait | Hands & feet — act / wait |
npm run smoke:* / /game eat | Test scaffolding only — hardcoded loops for CI; not the agent path |
There is no game_eat_food / game_survive tool. The model loops observe → move itself.
| Tool | Notes |
|---|---|
| Node.js | ≥ 20 recommended (--experimental-strip-types) |
| npm | Comes with Node |
| Pi CLI | Required for the agent path (pi on PATH) |
| LLM in Pi | e.g. DeepSeek configured in your Pi settings |
| WSLg / display | Only for visible Chromium (HEADED=1) |
git clone git@github.com:ifoxhz/pigame.git
cd pigame # or your local folder name
npm install --prefix pigame
npx --prefix pigame playwright install chromium
Default game (no extra clone): pigame/games/snake.html — a vendored Neon Snake with agent mode (see below).
Anyone who clones this repo gets the patched game automatically; Adapter loads it on /game connect.
Only if you want the original continuous-loop game for comparison:
git clone git@github.com:Digiman/mini-game-studio-ai-gen.git
# HTTPS: https://github.com/Digiman/mini-game-studio-ai-gen.git
SNAKE_HTML=./mini-game-studio-ai-gen/games/snake.html HEADED=1 pi -e ./.pi/extensions/pigame.ts
Live site (reference): https://digiman.github.io/mini-game-studio-ai-gen/
No separate compile step for smokes: Node strip-types runs TypeScript directly.
Root package.json only proxies scripts into pigame/.
git clone git@github.com:ifoxhz/pigame.git
cd pigame # or your local folder name
npm install --prefix pigame
npx --prefix pigame playwright install chromium
cd /path/to/pigame
HEADED=1 pi -e ./.pi/extensions/pigame.ts
In the Pi TUI (in order):
/game connect
/skill:eat-food
Or paste this prompt instead of the skill:
Use only game_observe, game_move, and optionally game_wait.
Prefer groundTruth grid coords. Eat one food: observe → move → repeat.
When score increases, stop and report before/after score.
Do not reverse 180°.
Watch the Playwright Chromium window (snake freezes between moves).
When done:
/game disconnect
After code changes in a live session: /reload, then /game disconnect → /game connect again.
# Adapter + perception + I/O only (no Pi / no LLM)
npm run smoke:eat
npm run smoke:eat:headed
npm run pack:pi
Produces:
dist/pi-pigame/ — installable directorydist/pigame-0.1.0.tgz — npm tarballOthers install into Pi with:
pi install /path/to/pigame/dist/pi-pigame
# or
pi install /path/to/pigame/dist/pigame-0.1.0.tgz
# after you publish to npm:
# npm publish ./dist/pigame-0.1.0.tgz
# pi install npm:pigame
From a git clone (without packing), they can also:
pi install ./pigame
Then restart Pi or /reload. First time: npx playwright install chromium (from the installed package dir if needed).
Problem: Upstream Snake ticks on its own. While the LLM is in a long observe → think → move chain, the snake has already moved, so decisions are stale and play feels clumsy.
What we ship: pigame/games/snake.html (see pigame/games/README.md)
| Behavior | Meaning |
|---|---|
Auto gameLoop | Paused after connect (setAgentMode(true)) |
game_observe | World stays frozen (no time pass) |
game_move | setDir + exactly 1 grid step (MOVE_STEPS to change) |
No special startup flag is required for agent mode — connect uses the vendored file by default.
| Variable | Default | Meaning |
|---|---|---|
SNAKE_HTML | pigame/games/snake.html | Override HTML path |
MOVE_STEPS | 1 | Grid steps per game_move |
HEADED | unset | 1 → show Chromium |
This is the intended product flow: you open Pi; the LLM uses tools.
cd /path/to/pigame
HEADED=1 pi -e ./.pi/extensions/pigame.ts
# or: pi (auto-loads .pi/extensions/pigame.ts if the project is trusted)
After code changes: /reload.
You should see something like: GameMind ready — LLM tools: game_observe, game_move, game_wait.
In Pi:
/game connect
Playwright opens Chromium and loads pigame/games/snake.html (agent-mode), then Start.
World is frozen until each game_move.
Do not open snake.html in your own browser — only the Playwright window is controlled.
Optional: /game observe to sanity-check AgentState.
Example (DeepSeek / any model in Pi):
Use only
game_observe,game_move, and optionallygame_wait.
Eat one food: observe → choose a direction → move → repeat.
Whenscoreincreases, stop and report before/after score.
Do not reverse 180° from the previous move.
Or load the skill: /skill:eat-food.
game_observe → read player / food / score
game_move → one step toward food
game_observe → …
… until the model decides the goal is done …
| Command | Action |
|---|---|
/game | Status + help |
/game connect | Start Playwright Neon Snake |
/game observe | Compact AgentState (manual check) |
/game state | Full AgentState JSON |
/game reset | Restart round |
/game disconnect | Close browser |
/game mock | Switch to mock adapter |
/game eat | Test scaffolding — scripted auto-eat |
/game survive | Test scaffolding — scripted play until death |
| Tool | Role |
|---|---|
game_observe | Eyes |
game_move | Hands / feet (up / down / left / right) |
game_wait | Wait |
npm run smoke:*)These commands do not use Pi or an LLM. They run fixed policies (eatFoodLoop / surviveUntilEnd) to verify Adapter + Perception + I/O. Use them for CI and debugging — not as the agent design.
# Eat one food (score 0 → 10), headless
npm run smoke:eat
# Same with visible Chromium (WSLg)
npm run smoke:eat:headed
# Long run until death (or stop at a score)
npm run smoke:survive:headed
MAX_SCORE=50 npm run smoke:survive:headed
| Command | What it checks (scaffolding) |
|---|---|
npm run smoke | Mock adapter / AgentState pipeline |
npm run smoke:snake | Playwright open + Start + key + screenshot |
npm run smoke:perception | CV fixture + live perception |
npm run smoke:eat | Scripted steer until score↑ |
npm run smoke:survive | Scripted loop until game over (or MAX_SCORE) |
npm run smoke:*:headed | Same with HEADED=1 |
| Variable | Default | Meaning |
|---|---|---|
HEADED | unset | 1 / true → show Chromium |
SNAKE_HTML | vendored agent snake | Path override |
MOVE_STEPS | 1 | Steps per move (agent mode) |
MAX_SCORE | none | Survive stops when score ≥ value |
MAX_STEPS | 50000 | Survive step cap |
STEP_MS | 200 | Visual delay between smoke moves |
HOLD_MS | 5000–8000 | Keep window open after headed runs |
Neon Snake has no clear — only death; MAX_SCORE is an artificial stop for tests.
.
├── README.md / README.zh-CN.md
├── package.json # script proxies
├── docs/ # design & schema
├── pigame/ # main package
│ ├── games/snake.html # DEFAULT agent-mode Neon Snake (vendored)
│ ├── games/README.md
│ ├── extensions/pigame.ts
│ ├── skills/
│ ├── scripts/ # smoke:* (test scaffolding)
│ └── src/
├── .pi/extensions/pigame.ts # Pi entry
└── mini-game-studio-ai-gen/ # optional upstream clone (SNAKE_HTML=…)
Design docs: docs/README.md.
| Issue | Fix |
|---|---|
Missing pigame/games/snake.html | Pull latest pigame — file is in-repo |
| Want upstream continuous loop | SNAKE_HTML=./mini-game-studio-ai-gen/games/snake.html (clone Digiman first) |
| Snake runs by itself while LLM thinks | You are not on agent-mode HTML; check default path / SNAKE_HTML |
ENOENT package.json at root | Use root scripts or cd pigame |
| No Chromium window | HEADED=1 or *:headed; check WSLg / echo $DISPLAY |
| Opened Snake yourself, nothing happens | Only Playwright’s window is controlled |
| Pi extension not loaded | pi -e ./.pi/extensions/pigame.ts then /reload |
Thanks to Mini Game Studio (Digiman/mini-game-studio-ai-gen) for the original Neon Snake and HTML game collection.
We vendor a patched copy under pigame/games/ for Pi + LLM agent-mode testing (paused auto loop + single-step moves).
Work in progress (MVP: Pi + LLM drives Snake via observe / move).
Phase notes: docs/implementation.md.
3 commits
TypeScript
78.4%
HTML
19.6%
JavaScript
2.0%
English | 中文
General game agent on Pi + LLM (e.g. DeepSeek).
Design codename: GameMind. First demo game: Neon Snake.
Remote: git@github.com:ifoxhz/pigame.git
Welcome. Contributions of any kind and any ideas are welcome — let’s make the Pi agent more fun.
Pi + LLM = brain (strategy / when to stop)
pigame = scaffolding only
tools = eyes / hands / feet
| Layer | Role |
|---|---|
| Pi + LLM | Decide what to do; judge when the goal is done |
game_observe | Eyes — see the screen → AgentState |
game_move / game_wait | Hands & feet — act / wait |
npm run smoke:* / /game eat | Test scaffolding only — hardcoded loops for CI; not the agent path |
There is no game_eat_food / game_survive tool. The model loops observe → move itself.
| Tool | Notes |
|---|---|
| Node.js | ≥ 20 recommended (--experimental-strip-types) |
| npm | Comes with Node |
| Pi CLI | Required for the agent path (pi on PATH) |
| LLM in Pi | e.g. DeepSeek configured in your Pi settings |
| WSLg / display | Only for visible Chromium (HEADED=1) |
git clone git@github.com:ifoxhz/pigame.git
cd pigame # or your local folder name
npm install --prefix pigame
npx --prefix pigame playwright install chromium
Default game (no extra clone): pigame/games/snake.html — a vendored Neon Snake with agent mode (see below).
Anyone who clones this repo gets the patched game automatically; Adapter loads it on /game connect.
Only if you want the original continuous-loop game for comparison:
git clone git@github.com:Digiman/mini-game-studio-ai-gen.git
# HTTPS: https://github.com/Digiman/mini-game-studio-ai-gen.git
SNAKE_HTML=./mini-game-studio-ai-gen/games/snake.html HEADED=1 pi -e ./.pi/extensions/pigame.ts
Live site (reference): https://digiman.github.io/mini-game-studio-ai-gen/
No separate compile step for smokes: Node strip-types runs TypeScript directly.
Root package.json only proxies scripts into pigame/.
git clone git@github.com:ifoxhz/pigame.git
cd pigame # or your local folder name
npm install --prefix pigame
npx --prefix pigame playwright install chromium
cd /path/to/pigame
HEADED=1 pi -e ./.pi/extensions/pigame.ts
In the Pi TUI (in order):
/game connect
/skill:eat-food
Or paste this prompt instead of the skill:
Use only game_observe, game_move, and optionally game_wait.
Prefer groundTruth grid coords. Eat one food: observe → move → repeat.
When score increases, stop and report before/after score.
Do not reverse 180°.
Watch the Playwright Chromium window (snake freezes between moves).
When done:
/game disconnect
After code changes in a live session: /reload, then /game disconnect → /game connect again.
# Adapter + perception + I/O only (no Pi / no LLM)
npm run smoke:eat
npm run smoke:eat:headed
npm run pack:pi
Produces:
dist/pi-pigame/ — installable directorydist/pigame-0.1.0.tgz — npm tarballOthers install into Pi with:
pi install /path/to/pigame/dist/pi-pigame
# or
pi install /path/to/pigame/dist/pigame-0.1.0.tgz
# after you publish to npm:
# npm publish ./dist/pigame-0.1.0.tgz
# pi install npm:pigame
From a git clone (without packing), they can also:
pi install ./pigame
Then restart Pi or /reload. First time: npx playwright install chromium (from the installed package dir if needed).
Problem: Upstream Snake ticks on its own. While the LLM is in a long observe → think → move chain, the snake has already moved, so decisions are stale and play feels clumsy.
What we ship: pigame/games/snake.html (see pigame/games/README.md)
| Behavior | Meaning |
|---|---|
Auto gameLoop | Paused after connect (setAgentMode(true)) |
game_observe | World stays frozen (no time pass) |
game_move | setDir + exactly 1 grid step (MOVE_STEPS to change) |
No special startup flag is required for agent mode — connect uses the vendored file by default.
| Variable | Default | Meaning |
|---|---|---|
SNAKE_HTML | pigame/games/snake.html | Override HTML path |
MOVE_STEPS | 1 | Grid steps per game_move |
HEADED | unset | 1 → show Chromium |
This is the intended product flow: you open Pi; the LLM uses tools.
cd /path/to/pigame
HEADED=1 pi -e ./.pi/extensions/pigame.ts
# or: pi (auto-loads .pi/extensions/pigame.ts if the project is trusted)
After code changes: /reload.
You should see something like: GameMind ready — LLM tools: game_observe, game_move, game_wait.
In Pi:
/game connect
Playwright opens Chromium and loads pigame/games/snake.html (agent-mode), then Start.
World is frozen until each game_move.
Do not open snake.html in your own browser — only the Playwright window is controlled.
Optional: /game observe to sanity-check AgentState.
Example (DeepSeek / any model in Pi):
Use only
game_observe,game_move, and optionallygame_wait.
Eat one food: observe → choose a direction → move → repeat.
Whenscoreincreases, stop and report before/after score.
Do not reverse 180° from the previous move.
Or load the skill: /skill:eat-food.
game_observe → read player / food / score
game_move → one step toward food
game_observe → …
… until the model decides the goal is done …
| Command | Action |
|---|---|
/game | Status + help |
/game connect | Start Playwright Neon Snake |
/game observe | Compact AgentState (manual check) |
/game state | Full AgentState JSON |
/game reset | Restart round |
/game disconnect | Close browser |
/game mock | Switch to mock adapter |
/game eat | Test scaffolding — scripted auto-eat |
/game survive | Test scaffolding — scripted play until death |
| Tool | Role |
|---|---|
game_observe | Eyes |
game_move | Hands / feet (up / down / left / right) |
game_wait | Wait |
npm run smoke:*)These commands do not use Pi or an LLM. They run fixed policies (eatFoodLoop / surviveUntilEnd) to verify Adapter + Perception + I/O. Use them for CI and debugging — not as the agent design.
# Eat one food (score 0 → 10), headless
npm run smoke:eat
# Same with visible Chromium (WSLg)
npm run smoke:eat:headed
# Long run until death (or stop at a score)
npm run smoke:survive:headed
MAX_SCORE=50 npm run smoke:survive:headed
| Command | What it checks (scaffolding) |
|---|---|
npm run smoke | Mock adapter / AgentState pipeline |
npm run smoke:snake | Playwright open + Start + key + screenshot |
npm run smoke:perception | CV fixture + live perception |
npm run smoke:eat | Scripted steer until score↑ |
npm run smoke:survive | Scripted loop until game over (or MAX_SCORE) |
npm run smoke:*:headed | Same with HEADED=1 |
| Variable | Default | Meaning |
|---|---|---|
HEADED | unset | 1 / true → show Chromium |
SNAKE_HTML | vendored agent snake | Path override |
MOVE_STEPS | 1 | Steps per move (agent mode) |
MAX_SCORE | none | Survive stops when score ≥ value |
MAX_STEPS | 50000 | Survive step cap |
STEP_MS | 200 | Visual delay between smoke moves |
HOLD_MS | 5000–8000 | Keep window open after headed runs |
Neon Snake has no clear — only death; MAX_SCORE is an artificial stop for tests.
.
├── README.md / README.zh-CN.md
├── package.json # script proxies
├── docs/ # design & schema
├── pigame/ # main package
│ ├── games/snake.html # DEFAULT agent-mode Neon Snake (vendored)
│ ├── games/README.md
│ ├── extensions/pigame.ts
│ ├── skills/
│ ├── scripts/ # smoke:* (test scaffolding)
│ └── src/
├── .pi/extensions/pigame.ts # Pi entry
└── mini-game-studio-ai-gen/ # optional upstream clone (SNAKE_HTML=…)
Design docs: docs/README.md.
| Issue | Fix |
|---|---|
Missing pigame/games/snake.html | Pull latest pigame — file is in-repo |
| Want upstream continuous loop | SNAKE_HTML=./mini-game-studio-ai-gen/games/snake.html (clone Digiman first) |
| Snake runs by itself while LLM thinks | You are not on agent-mode HTML; check default path / SNAKE_HTML |
ENOENT package.json at root | Use root scripts or cd pigame |
| No Chromium window | HEADED=1 or *:headed; check WSLg / echo $DISPLAY |
| Opened Snake yourself, nothing happens | Only Playwright’s window is controlled |
| Pi extension not loaded | pi -e ./.pi/extensions/pigame.ts then /reload |
Thanks to Mini Game Studio (Digiman/mini-game-studio-ai-gen) for the original Neon Snake and HTML game collection.
We vendor a patched copy under pigame/games/ for Pi + LLM agent-mode testing (paused auto loop + single-step moves).
Work in progress (MVP: Pi + LLM drives Snake via observe / move).
Phase notes: docs/implementation.md.
3 commits
TypeScript
78.4%
HTML
19.6%
JavaScript
2.0%