A neon, after-hours arcade that lives entirely in your terminal.
Six hand-crafted games, one cabinet menu, zero coins required — rendered with crisp Unicode art, a cohesive color palette, and a responsive layout that adapts to any terminal size.
╔═╗ ╦═╗ ╔═╗ ╔═╗ ╔╦╗ ╔═╗ NEON DISTRICT / AFTER HOURS
╠═╣ ╠╦╝ ║ ╠═╣ ║║ ║╣ ● 6 CABINETS ONLINE
╩ ╩ ╩╚═ ╚═╝ ╩ ╩ ═╩╝ ╚═╝ BUILD 1.2 · INPUT READY
- Six complete games — reflex, logic, risk, and a custom math puzzle.
- Arcade cabinet menu — browse machines, preview the mission, and quick-launch with number keys.
- Pure terminal UI — built on
@opentui/react, so the whole experience is React components rendering to the terminal. - Responsive layout — side panels, previews, and stat strips appear or collapse based on your terminal dimensions.
- Self-contained logic — every game's rules live in plain, testable TypeScript classes with no UI dependencies.
- Instant feedback — live stat readouts, status indicators, legends, and operator notes for each cabinet.
| # | Game | Tag | Objective |
|---|---|---|---|
| 01 | Snake | REFLEX |
Thread the grid, collect signal fruit, and protect your tail. |
| 02 | Sudoku | LOGIC |
Fill every row, column, and 3×3 sector without repeats. |
| 03 | Minesweeper | RISK |
Reveal every safe cell and flag the buried charges. |
| 04 | 2048 | MERGE |
Slide equal tiles together and build toward the 2048 tile. |
| 05 | Tic-Tac-Toe | DUEL |
Local two-player — claim a line of three before the board fills. |
| 06 | Cross Multiply | PRODUCT |
Mark factors so every row and column reaches its target product. |
Cross Multiply is the headliner: a procedurally generated logic puzzle with five difficulties (
easy→mythic), guaranteed-unique solutions, a hearts system, hints, and endless level progression.
This project runs on Bun — no separate compiler or bundler needed.
# 1. Install dependencies
bun install
# 2. Start the arcade
bun startThat's it. The arcade boots straight into the cabinet menu.
Tip: For the full experience (side panels and previews), give your terminal some room — roughly 104+ columns and 27+ rows. Smaller terminals are fully supported; the layout simply compacts to fit.
bun dev # run with hot reload (--watch)
bun test # run the game-logic + UI test suites
bun run typecheck # strict TypeScript checking (tsc --noEmit)| Key | Action |
|---|---|
↑ ↓ / J K |
Choose a cabinet |
Enter / Space |
Power up the selected game |
1–6 |
Quick-launch by number |
Q |
Power off |
| Key | Action |
|---|---|
Arrows / WASD |
Move / steer |
R |
Restart the current board |
Esc / Q |
Return to the cabinet |
Each game also has its own keys — Space to pause Snake, 1–9 to fill
Sudoku, F to flag mines, Tab/V/E to switch Cross Multiply modes,
I for a hint, and more. The on-screen key hints bar always shows the
controls relevant to where you are.
The architecture cleanly separates game logic from presentation:
src/
├── games.ts # Pure TypeScript game engines — no UI, fully testable
│ # SnakeGame · SudokuGame · MinesweeperGame
│ # Game2048 · TicTacToeGame · CrossMultiplyGame
└── index.tsx # The OpenTUI/React app: cabinet menu, game views,
# layout, keyboard routing, and the neon theme
tests/
├── games.test.ts # Unit tests for the game engines
└── ui.test.tsx # Tests for the rendered interface
games.tsholds each game as a self-contained class with deterministic, injectable randomness (new SnakeGame(myRandom)) — which is exactly what makes the logic straightforward to unit-test.index.tsxwires those engines into React components that render to the terminal via OpenTUI, handles a single global keyboard listener, and drives Snake's real-time loop with a render-tick interval.
| Layer | Choice |
|---|---|
| Runtime | Bun |
| UI framework | @opentui/react + @opentui/core |
| Library | React 19 |
| Language | TypeScript (strict mode) |
| Script | Command | Description |
|---|---|---|
start |
bun run src/index.tsx |
Launch the arcade |
dev |
bun --watch src/index.tsx |
Launch with hot reload |
test |
bun test |
Run all tests |
typecheck |
bunx tsc --noEmit |
Type-check without emitting |
LOCAL PLAY · NO COINS
Made for the terminal. Press Enter to power up. →