Replace clear-then-write pattern with overwrite-in-place: move cursor up to start of rendered area and write new content directly over old lines. Only clear trailing lines if the new render is shorter. This removes the visible blank frame between clear and re-render. |
||
|---|---|---|
| .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.