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
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.
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 tarball
Others install into Pi with:
pi install /path/to/pigame/dist/pi-pigame
pi install /path/to/pigame/dist/pigame-0.1.0.tgz
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 |
|
d 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
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.
Whenscore
increases, 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 |
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.
npm run smoke:eat
npm run smoke:eat:headed
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 (d auto loop + single-step moves).Work in progress (MVP: Pi + LLM drives Snake via observe / move).
Phase notes: docs/implementation.md.