Skip to content

Commit b49be03

Browse files
ralyodioclaude
andauthored
feat(games): /games — a six-game arcade in the pit (#364)
`/games` lists the cabinet, `/games <game>` plays one. Six games — tetris, snake, pac-man, tic-tac-toe, chess and hangman — sharing one frame, one key decoder and one driver, so the arcade looks like an arcade rather than six weekend projects. No menus and no options screens: `/games tetris` is already playing when the frame lands, and every game reads arrows, quits on q and restarts on r, with its controls written along the bottom of the game itself. The games are pure — create a state, hand it a key, hand it a tick, ask it for rows — and everything touching a terminal lives in runGame(). That is what makes test/games.test.mjs able to finish real games of tetris and pac-man, prove the tic-tac-toe opponent cannot be beaten in 40 games of random play, and check chess's castling, en passant, promotion and mate detection without a TTY anywhere near it. Chess plays by the real rules against an alpha-beta search. Its reply runs on the clock rather than inside the keypress, so your own move is drawn before it starts thinking. Also available as `moshcode games` from a shell; listing works in a pipe, playing needs a real terminal and says so. Co-authored-by: Claude Opus 5 (1M context) <noreply@anthropic.com>
1 parent c8778ed commit b49be03

13 files changed

Lines changed: 2196 additions & 1 deletion

README.md

Lines changed: 42 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -50,6 +50,7 @@ or miss one that does. A test fails the build when it drifts.
5050
| `moshcode doh` | hosting | run the DNS-over-HTTPS resolver |
5151
| `moshcode site` <br>`serve` | hosting | install web-server config for a Moshpit name |
5252
| `moshcode template` <br>`templates` | hosting | scaffold a stack for a Moshpit-hosted service |
53+
| `moshcode games` <br>`game` `arcade` | arcade | the moshcode arcade — six games, no menus |
5354
| `moshcode pwd` <br>`where` | system | show the current directory and git context |
5455
| `moshcode engines` | engines | list engines and installation status |
5556
| `moshcode tools` | tools | list workflow tools and installation status |
@@ -581,6 +582,47 @@ event, and publishes it to the displayed relays. Both flows leave the final
581582
confirmation in the browser. If the pit is remote or headless, `/post` prints
582583
the composer URL instead.
583584

585+
## The arcade (`/games`)
586+
587+
Six games, in the pit or straight from a shell. There are no menus, no options
588+
screens and no difficulty prompts — `/games tetris` is already playing.
589+
590+
```sh
591+
moshcode games # the cabinet (pit: /games)
592+
moshcode games tetris # play one (pit: /games tetris)
593+
moshcode games --json # the roster, for a machine
594+
```
595+
596+
```
597+
TETRIS score 1200 · lines 12
598+
┌────────────────────────────────┐
599+
│ · · · · ████· · · · NEXT │
600+
│ · · · · ████· · · · │
601+
│ · · · · · · · · · · ████████ │
602+
│ · · · · · · · · · · │
603+
│ · · · ████· · · · · LVL 2 │
604+
│ ████████████· ██████ │
605+
└────────────────────────────────┘
606+
← → move · ↑ rotate · ↓ drop one · space slam · q quit
607+
```
608+
609+
| game | |
610+
|---|---|
611+
| `tetris` | stack the bricks, clear the lines, outrun gravity |
612+
| `snake` | eat, grow, and try not to eat yourself |
613+
| `pacman` | eat the dots, dodge the ghosts, `` makes them edible |
614+
| `tictactoe` | three in a row against an opponent that cannot be beaten |
615+
| `chess` | full rules — castling, en passant, promotion — and it plays back |
616+
| `hangman` | six wrong letters and you are done for |
617+
618+
Every one of them works the same way: arrows move, `q` quits, `r` starts
619+
another, and the controls are written along the bottom of the game itself. Each
620+
draws in place rather than on the alternate screen, so the board you finished on
621+
stays in your scrollback.
622+
623+
Playing needs a real terminal, because they read single keypresses — `moshcode
624+
games` on its own lists them anywhere, including a pipe.
625+
584626
## Settings sync (`/save` and `/load`)
585627

586628
Your pit becomes yours by accretion — a dozen aliases, herd rules you tuned until

bin/moshcode.mjs

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,7 @@ import { describeUninstall, uninstallPlan } from "../src/uninstall.mjs";
2222
import { mcpCommand, pluginCommand, skillCommand } from "../src/integrations.mjs";
2323
import { stocksCommand } from "../src/advisor.mjs";
2424
import { cryptoCommand } from "../src/crypto.mjs";
25+
import { gamesCommand } from "../src/games.mjs";
2526
import { canOpenBrowser, openBrowser } from "../src/open-url.mjs";
2627
import { locate, tilde } from "../src/pwd.mjs";
2728
import { createPrd, listPrds, authoringPrompt } from "../src/prd.mjs";
@@ -398,6 +399,11 @@ async function main() {
398399
if (code) process.exitCode = code;
399400
return;
400401
}
402+
if (cmd === "games" || cmd === "game" || cmd === "arcade") {
403+
const code = await gamesCommand(rest);
404+
if (code) process.exitCode = code;
405+
return;
406+
}
401407
if (cmd === "console") {
402408
const code = await consoleCommand(rest);
403409
if (code) process.exitCode = code;

src/cli-schema.mjs

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,7 @@ export const COMMAND_GROUPS = [
2424
{ key: "tools", title: "tools" },
2525
{ key: "extend", title: "extend" },
2626
{ key: "script", title: "script" },
27+
{ key: "arcade", title: "arcade" },
2728
{ key: "account", title: "account" },
2829
{ key: "hosting", title: "hosting" },
2930
{ key: "system", title: "system" },
@@ -392,6 +393,27 @@ export const CORE_CLI_COMMANDS = [
392393
seeAlso: ["site"],
393394
},
394395
{ name: "templates", aliasOf: "template", description: "alias for template" },
396+
{
397+
name: "games",
398+
group: "arcade",
399+
description: "the moshcode arcade — six games, no menus",
400+
synopsis: [
401+
["moshcode games", "the cabinet, and what each one is"],
402+
["moshcode games <game>", "play it, right here in the terminal"],
403+
],
404+
flags: [["--json", "the roster, machine-readable", ""]],
405+
examples: [
406+
["moshcode games", "what is in the arcade"],
407+
["moshcode games tetris", ""],
408+
["moshcode games chess", "real rules, and it plays back"],
409+
["moshcode games pacman", "dots, ghosts, three lives"],
410+
],
411+
seeAlso: ["help"],
412+
note: "every game works the same way: arrows move, q quits, r starts another. "
413+
+ "Playing needs a real terminal because they read single keypresses — `moshcode games` on its own lists them anywhere.",
414+
},
415+
{ name: "game", aliasOf: "games", description: "alias for games" },
416+
{ name: "arcade", aliasOf: "games", description: "alias for games" },
395417
{
396418
name: "pwd",
397419
group: "system",
@@ -907,6 +929,8 @@ export const PIT_COMMANDS = [
907929
description: "crypto market data from advis0r.com" },
908930
{ name: "plugin", aliases: ["plugins"], args: "<verb> [name]", cli: "plugin",
909931
description: "install moshcode's slash commands into Claude Code" },
932+
{ name: "games", aliases: ["game", "arcade", "play"], args: "[game]", cli: "games",
933+
description: "the arcade — tetris, snake, pac-man, tic-tac-toe, chess, hangman" },
910934
{ name: "socials", aliases: ["social"], pitOnly: true,
911935
description: "list social networks available for posting" },
912936
{ name: "post", args: '<social> "message"', pitOnly: true,

0 commit comments

Comments
 (0)