- Fix arrow selection line count calculation (overcounted by 1 due to trailing newline, causing progressive line truncation on each redraw) - Replace sync Loreline bridge with queue-based async pattern to avoid "Cannot wait on monitors" WASM deadlock - Add bounded input buffer (8 keys, DropOldest) to prevent held-key accumulation - Set Spectre.Console Profile.Height on all AnsiConsole.Create calls to prevent PlatformNotSupportedException on Console.WindowHeight - Add explicit Loreline.dll reference + TrimmerRootAssembly for WASM - Use MSBuild CopyGameContent target instead of Content/Link for static file serving in Blazor WASM - Add WASM guards for file I/O in ContentRegistry, LocalizationManager, AdventureEngine - Enforce min 120x30 terminal dimensions in xterm.js - Add Playwright E2E tests (6 tests: page load, language selection, full flow, multi-box progression, extended play, adventure) |
||
|---|---|---|
| .github/workflows | ||
| content | ||
| src | ||
| tests | ||
| .gitignore | ||
| bugs.md | ||
| CLAUDE.md | ||
| GDD.md | ||
| global.json | ||
| init.ps1 | ||
| OpenTheBox.cmd | ||
| OpenTheBox.slnx | ||
| publish.ps1 | ||
| README.md | ||
| specifications.md | ||
| TODO.md | ||
Open The Box
A CLI box-opening game where curiosity is the engine and every box is a mystery. Built in C# on .NET 10 with a progressive interface that evolves as you play.
Open a box. It contains another box. That one has a key. The key opens a chest. The chest holds a story fragment. The story unlocks a character. The character reveals a place. The place offers an adventure. The adventure rewards... a box.
Features
- Progressive CLI -- Start with bare
Console.ReadLinenumbered menus. Unlock colors, arrow-key navigation, panels, portraits, and full layouts by finding Meta Boxes. - 25+ box types with weighted loot tables, conditional drops, and nested auto-opening boxes.
- 9 interactive adventures powered by Loreline scripting (Space, Medieval, Pirate, Contemporary, Sentimental, Prehistoric, Cosmic, Microscopic, Dark Fantasy).
- 160+ items -- cosmetics, materials, consumables, adventure tokens, lore fragments, fortune cookies.
- 34 crafting recipes across 16 workstation types.
- Auto-activation system -- items interact automatically (key + chest, badge + adventure).
- Character customization -- hair, eyes, body, legs, arms, tints with ASCII portrait.
- Bilingual -- full English and French support (UI + adventures).
- Save/Load -- JSON-based save files.
- Music Box --
Console.Beepmelodies (Windows). - Fortune Cookies -- 20 box-themed wisdom messages.
Architecture
The game follows the Black Box Sim pattern (Brian Cronin): strict separation between simulation and presentation.
Input (keyboard)
|
v
GameAction -- command sent to the simulation
|
v
+----------------+
| GameSimulation | -- BLACK BOX: zero I/O, pure logic
| (GameState) |
+-------+--------+
|
v
GameEvent[] -- events describing what happened
|
v
+----------------+
| IRenderer | -- BasicRenderer (phase 0) or SpectreRenderer (phases 1-8)
+----------------+
The simulation never reads input or writes output. It receives actions and returns events. The game loop in Program.cs bridges input/renderer to simulation.
Prerequisites
- Windows 10/11
- .NET 10 SDK -- install via
winget install Microsoft.DotNet.SDK.10
Setup
git clone <repo-url>
cd openthebox
.\init.ps1
The init script will:
- Check for .NET 10 SDK (offers to install if missing)
- Download Loreline v0.7.1 DLL
- Restore NuGet packages (Spectre.Console)
Build & Run
dotnet build
dotnet run --project src/OpenTheBox
Distribute
Desktop (self-contained)
dotnet publish src/OpenTheBox -c Release -r win-x64 -o "builds/$(Get-Date -Format yyyyMMdd_HHmmss)_win"
dotnet publish src/OpenTheBox -c Release -r linux-x64 -o "builds/$(Get-Date -Format yyyyMMdd_HHmmss)_linux"
This produces a self-contained single-file executable. The target machine does not need .NET installed. Distribute the entire folder (exe + content/).
Web (Blazor WASM → itch.io)
dotnet publish src/OpenTheBox.Web -c Release -o publish
The publish/wwwroot/ folder contains a static site playable in any browser. Upload it to itch.io as an HTML5 project.
CI/CD: The GitHub Actions workflow .github/workflows/deploy-itch.yml automatically publishes to itch.io (user: Lythom, channel: html5) on every push to main. Requires the BUTLER_API_KEY secret configured in the repository.
Tests
dotnet test
43 content validation tests verify all JSON data files deserialize correctly, cross-references are valid, and localization keys exist.
Project Structure
openthebox/
+-- src/OpenTheBox/
| +-- Program.cs # Entry point, game loop
| +-- Core/ # Pure models, enums, no dependencies
| +-- Simulation/ # BLACK BOX: GameSimulation, engines, actions, events
| +-- Rendering/ # IRenderer, BasicRenderer, SpectreRenderer, Panels
| +-- Adventures/ # Loreline integration
| +-- Persistence/ # Save/Load
| +-- Localization/ # JSON string manager
+-- src/OpenTheBox.Web/
| +-- Program.cs # Blazor WASM entry point
| +-- WebGameHost.cs # Async game loop for browser
| +-- WebTerminal.cs # xterm.js ↔ C# bridge
| +-- WebSaveManager.cs # localStorage saves
| +-- wwwroot/ # HTML, JS, CSS served to browser
+-- .github/workflows/
| +-- deploy-itch.yml # CI: build WASM + Butler push to itch.io
+-- content/
| +-- data/ # boxes.json, items.json, interactions.json, recipes.json
| +-- strings/ # en.json, fr.json
| +-- adventures/ # 9 themes, each with .lor + .fr.lor files
+-- GDD.md # Game Design Document (French)
+-- init.ps1 # Setup script
+-- global.json # Pins .NET 10 SDK
Tech Stack
| Component | Technology |
|---|---|
| Runtime | .NET 10, C# 14 |
| CLI rendering | Spectre.Console |
| Interactive fiction | Loreline (.lor scripts) |
| Serialization | System.Text.Json |
| Localization | JSON string tables + Loreline translation files |
Terminal GUI
All content is expected to be renderer in a 120x30 characters frame.
License
All rights reserved.