- Fix compact tmux-like layout (120×30 ref) with side-by-side panels - Fix cosmetic portrait: PlayerAppearance now mutable with ApplyCosmetic() - Add per-style intrinsic colors for all cosmetic types on portrait - Add compact inventory mode (6 rows) for layout views - Add Terminal.Gui renderer (--tui flag) - Add save snapshot generation and --snapshot N CLI loading - Add PlaythroughCapture test for automated output analysis - Add destiny adventure French translation (intro.fr.lor) - Remove FontStyle enum (fonts are collectibles only) - Add proposals.md with 11 rendering improvement suggestions - Update bugs.md (3 FIXMEs resolved)
90 lines
4.3 KiB
Markdown
90 lines
4.3 KiB
Markdown
# Open The Box
|
|
|
|
## Project Overview
|
|
A console-based incremental/idle game built in C# (.NET 9) where players open boxes to discover items, unlock features, and progress through themed adventures. Uses Spectre.Console for rich terminal rendering and Loreline for interactive narrative scripting.
|
|
|
|
## Architecture
|
|
See [specifications.md](specifications.md) for detailed content organization.
|
|
|
|
## Key Directories
|
|
- `src/OpenTheBox/` — Main game source code
|
|
- `content/data/` — JSON data files (items, boxes, crafting recipes)
|
|
- `content/adventures/` — Loreline `.lor` adventure scripts (one folder per theme)
|
|
- `content/localization/` — Translation files
|
|
|
|
## Source Code Structure
|
|
- `Core/` — Game state, enums, item/character models
|
|
- `Core/Enums/` — All enum types (StatType, ResourceType, AdventureTheme, CosmeticSlot, etc.)
|
|
- `Adventures/` — AdventureEngine (Loreline bridge + custom functions)
|
|
- `Simulation/` — Game engines (BoxEngine, MetaEngine, ResourceEngine, CraftingEngine, GameSimulation)
|
|
- `Rendering/` — IRenderer interface, SpectreRenderer, RenderContext, panel components
|
|
- `Rendering/Panels/` — Individual UI panels (PortraitPanel, ResourcePanel, StatsPanel, etc.)
|
|
- `Data/` — ContentRegistry, ItemDefinition, BoxDefinition data loading
|
|
- `Persistence/` — SaveManager, SaveData (JSON serialization)
|
|
- `Localization/` — LocalizationManager, Locale enum
|
|
|
|
## Build & Run
|
|
```
|
|
dotnet build
|
|
dotnet run --project src/OpenTheBox # Classic Spectre.Console mode
|
|
dotnet run --project src/OpenTheBox -- --tui # Terminal.Gui panel layout
|
|
dotnet run --project src/OpenTheBox -- --snapshot 5 # Load snapshot save #5
|
|
```
|
|
|
|
## Test
|
|
```
|
|
dotnet test
|
|
```
|
|
|
|
## Adventure System
|
|
Adventures use Loreline `.lor` script format. Custom functions available in scripts:
|
|
- Inventory: `grantItem(id, qty)`, `hasItem(id)`, `removeItem(id)`
|
|
- Resources: `hasResource(name, min)`, `getResourceValue(name)`, `addResource(name, amount)`
|
|
- Stats: `hasStat(name, min)`, `getStatValue(name)`
|
|
- Cosmetics: `hasCosmetic(id)`, `hasEquipped(slot, style)`
|
|
- Progression: `hasCompletedAdventure(theme)`, `markSecretBranch(id)`, `hasSecretBranch(id)`, `countSecretBranches()`, `allSecretBranches()`
|
|
|
|
Hints for disabled choices use `|||` separator: `Option text|||Hint text #label if condition`
|
|
|
|
full documentation: https://loreline.app/fr/docs/
|
|
|
|
## Pacing Test
|
|
To check game progression balance after modifying loot tables (`content/data/boxes.json`):
|
|
```
|
|
dotnet test --filter "FullRun_PacingReport" --logger "console;verbosity=detailed"
|
|
```
|
|
This runs a full simulation (3 seeds: 42, 123, 777) and prints a report showing when each milestone is first reached (UI features, adventures, cosmetics, resources, crafting, lore). Use this to verify that rebalancing changes produce the desired early-game pacing.
|
|
|
|
Key things to look for:
|
|
- **1st Meta UI unlock** should happen before box ~50 for a good early experience
|
|
- **1st Adventure** should appear before box ~120
|
|
- **All content reachable** within ~1000 boxes (game completion)
|
|
- No long gaps between milestones (>100 boxes without progress feels stale)
|
|
|
|
Weights are in `content/data/boxes.json`. The main generator is `box_of_boxes` (auto-opens, produces the next box). Adjust weights there and in tier boxes (`box_not_great`, `box_ok_tier`, etc.) to tune pacing.
|
|
|
|
## Save Snapshots (Visual Testing)
|
|
Generate save files at 9 progression stages for quick visual testing:
|
|
```
|
|
dotnet test --filter "GenerateSaveSnapshots" --logger "console;verbosity=detailed"
|
|
```
|
|
This creates `saves/snapshot_1.otb` through `saves/snapshot_9.otb` (from 10 boxes to 2000 boxes opened).
|
|
|
|
Load a snapshot directly:
|
|
```
|
|
dotnet run --project src/OpenTheBox -- --snapshot 3
|
|
```
|
|
Where 1-9 corresponds to: (1) very early, (2) first unlocks, (3) several panels, (4) adventures, (5) crafting, (6) most features, (7) near completion, (8) endgame, (9) post-endgame.
|
|
|
|
## Terminal.Gui Mode
|
|
Run with `--tui` for a tmux-like panel layout using Terminal.Gui:
|
|
```
|
|
dotnet run --project src/OpenTheBox -- --tui
|
|
```
|
|
|
|
## Conventions
|
|
- C# 12 with file-scoped namespaces, primary constructors where appropriate
|
|
- Immutable records for value types, sealed classes for services
|
|
- GameState is mutable, passed by reference to engines
|
|
- All user-facing strings go through LocalizationManager
|
|
- Enum names match JSON string values (PascalCase)
|