Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
14 changes: 14 additions & 0 deletions Directory.Build.props
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
<Project>
<!-- Shared build settings for every project in the solution. -->
<PropertyGroup>
<LangVersion>latest</LangVersion>
<Nullable>enable</Nullable>
<ImplicitUsings>enable</ImplicitUsings>
<!-- Deterministic compilation; the SIMULATION determinism is enforced separately
by the Determinism.Tests project per docs/architecture/DETERMINISM-CONTRACT.md. -->
<Deterministic>true</Deterministic>
<InvariantGlobalization>true</InvariantGlobalization>
<GenerateDocumentationFile>false</GenerateDocumentationFile>
<ManagePackageVersionsCentrally>false</ManagePackageVersionsCentrally>
</PropertyGroup>
</Project>
73 changes: 65 additions & 8 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,11 +1,68 @@
# Restaurant (working codename: "Mise")
# Restaurant (working codename: **"Mise"**)

Pre-production. A single-player restaurant-management simulation; spiritual successor to
a 2003-era restaurant tycoon design, rebuilt on a deterministic, engine-agnostic core.
A single-player, desktop-first **restaurant-management simulation** — a spiritual successor to a 2003-era
restaurant tycoon, rebuilt on a deterministic, engine-agnostic core. **Pre-production; currently at
milestone M0.** This is not a finished game, and it will not ship under the "Restaurant Empire" name.

Active development happens on the branch **`foundation/m0-headless-service-lab`** and is
delivered to owners via pull request for review. That branch contains the full project
structure, the planning and architecture documents, and the **M0 Headless Service Lab**.
> **Core fantasy:** *I build one distinctive restaurant whose menu, people, layout, and service work as a
> coherent machine, and then turn that hard-won operating model into a culinary empire.*
>
> **Design spine:** **the menu is the strategy.** A menu determines demand, expectations, ingredient cost,
> kitchen-station load, prep complexity, chef needs, service speed, waste, pricing power, identity, and
> profitability.

See the open pull request (or that branch) for everything. This `main` branch holds only
the license and this pointer until the M0 gate is reviewed and merged by the owners.
## Status: M0 — Headless Service Lab
M0 answers one question, headless, before any graphics:

> *Can menu, pricing, staffing, and capacity decisions create multiple understandable and viable restaurant
> strategies, with visible consequences that make players want to revise their plan and run another service?*

Built: a deterministic simulation core, a playable CLI loop, an automated strategy/distribution/determinism
harness, 74 passing tests, and committed evidence. See [`docs/CURRENT-STATE.md`](docs/CURRENT-STATE.md).

## Repository structure
```
docs/ plans, design & architecture contracts, risks, commercial & playtest docs, archive
src/ RestaurantSim.Core (pure sim) · .Cli (player loop) · .Harness (evidence)
tests/ Core / Determinism / Scenario test projects (74 tests)
fixtures/ (reserved for external fixture data; M0 fixtures are code in Core/M0Content.cs)
reports/ generated evidence: balance/ determinism/ m0/
tools/ (reserved)
```

## Build and run
Requires the **.NET 8 SDK** (pinned in `global.json`).

```bash
dotnet build Restaurant.sln # build everything
dotnet test Restaurant.sln # run all 74 tests

# play the M0 loop (interactive): inspect -> plan -> forecast -> commit -> autopsy -> revise -> run again
dotnet run --project src/RestaurantSim.Cli
# e.g. inside: preset "Balanced Competent" -> forecast -> log on -> run
# or run one strategy non-interactively:
dotnet run --project src/RestaurantSim.Cli -- strategy "Focused Value" lunch-rush 700042

# regenerate the evidence reports (distribution, determinism, example autopsy):
dotnet run -c Release --project src/RestaurantSim.Harness -- --seeds 200 --out reports
```

Generated reports appear under [`reports/`](reports/): `balance/distribution.md`,
`determinism/checksums.md`, `m0/example-forecast-vs-actual.txt`.

## What is explicitly NOT being built yet
No graphics, engine, pathfinding, inventory/suppliers, recipe editor, competitors, campaign, managers,
multiple restaurants, save system, audio, or asset integration. These are on the M0 non-goals list and the
deferred backlog by decision, not oversight. See
[`docs/design/DEFERRED-FEATURES.md`](docs/design/DEFERRED-FEATURES.md). Only M0 is authorized.

## Read next
- [`docs/MASTER-PLAN.md`](docs/MASTER-PLAN.md) — the active plan (and the change record over the archived v1).
- [`docs/CURRENT-STATE.md`](docs/CURRENT-STATE.md) — what's true right now.
- [`docs/NEXT-ACTION.md`](docs/NEXT-ACTION.md) — the single next authorized action (re-verify reality first).
- [`docs/design/M0-PROTOTYPE-CONTRACT.md`](docs/design/M0-PROTOTYPE-CONTRACT.md) — the M0 scope and gate.
- [`docs/architecture/DETERMINISM-CONTRACT.md`](docs/architecture/DETERMINISM-CONTRACT.md) — the numeric/RNG rules.

## License
Proprietary; all rights reserved. Commercial game in pre-production. See [`LICENSE`](LICENSE). Third-party
asset packages are recorded in [`docs/assets/`](docs/assets/) and deliberately not committed here.
64 changes: 64 additions & 0 deletions Restaurant.sln
Original file line number Diff line number Diff line change
@@ -0,0 +1,64 @@

Microsoft Visual Studio Solution File, Format Version 12.00
# Visual Studio Version 17
VisualStudioVersion = 17.0.31903.59
MinimumVisualStudioVersion = 10.0.40219.1
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "src", "src", "{7A4E9898-B55F-4C7F-A8B5-E3F3AAF7D1FB}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "RestaurantSim.Core", "src\RestaurantSim.Core\RestaurantSim.Core.csproj", "{76FDF7CF-8D13-4276-BD40-F7C40FBEA33B}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "RestaurantSim.Cli", "src\RestaurantSim.Cli\RestaurantSim.Cli.csproj", "{16E8E8DE-EB36-4C07-AF78-4A981E83D700}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "RestaurantSim.Harness", "src\RestaurantSim.Harness\RestaurantSim.Harness.csproj", "{C3EC1423-7B14-4105-9F57-FAFD6DC29724}"
EndProject
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "tests", "tests", "{F5189331-BA8E-459C-AFE2-96DFBEF12582}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "RestaurantSim.Core.Tests", "tests\RestaurantSim.Core.Tests\RestaurantSim.Core.Tests.csproj", "{85D535DB-22A5-4739-9CFD-F39EA4449ED7}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "RestaurantSim.Determinism.Tests", "tests\RestaurantSim.Determinism.Tests\RestaurantSim.Determinism.Tests.csproj", "{286BD256-4FE4-4E75-B075-A9E5916827BF}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "RestaurantSim.Scenario.Tests", "tests\RestaurantSim.Scenario.Tests\RestaurantSim.Scenario.Tests.csproj", "{DD4ECF63-0452-420F-A364-B8355014B761}"
EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
Debug|Any CPU = Debug|Any CPU
Release|Any CPU = Release|Any CPU
EndGlobalSection
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE
EndGlobalSection
GlobalSection(ProjectConfigurationPlatforms) = postSolution
{76FDF7CF-8D13-4276-BD40-F7C40FBEA33B}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{76FDF7CF-8D13-4276-BD40-F7C40FBEA33B}.Debug|Any CPU.Build.0 = Debug|Any CPU
{76FDF7CF-8D13-4276-BD40-F7C40FBEA33B}.Release|Any CPU.ActiveCfg = Release|Any CPU
{76FDF7CF-8D13-4276-BD40-F7C40FBEA33B}.Release|Any CPU.Build.0 = Release|Any CPU
{16E8E8DE-EB36-4C07-AF78-4A981E83D700}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{16E8E8DE-EB36-4C07-AF78-4A981E83D700}.Debug|Any CPU.Build.0 = Debug|Any CPU
{16E8E8DE-EB36-4C07-AF78-4A981E83D700}.Release|Any CPU.ActiveCfg = Release|Any CPU
{16E8E8DE-EB36-4C07-AF78-4A981E83D700}.Release|Any CPU.Build.0 = Release|Any CPU
{C3EC1423-7B14-4105-9F57-FAFD6DC29724}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{C3EC1423-7B14-4105-9F57-FAFD6DC29724}.Debug|Any CPU.Build.0 = Debug|Any CPU
{C3EC1423-7B14-4105-9F57-FAFD6DC29724}.Release|Any CPU.ActiveCfg = Release|Any CPU
{C3EC1423-7B14-4105-9F57-FAFD6DC29724}.Release|Any CPU.Build.0 = Release|Any CPU
{85D535DB-22A5-4739-9CFD-F39EA4449ED7}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{85D535DB-22A5-4739-9CFD-F39EA4449ED7}.Debug|Any CPU.Build.0 = Debug|Any CPU
{85D535DB-22A5-4739-9CFD-F39EA4449ED7}.Release|Any CPU.ActiveCfg = Release|Any CPU
{85D535DB-22A5-4739-9CFD-F39EA4449ED7}.Release|Any CPU.Build.0 = Release|Any CPU
{286BD256-4FE4-4E75-B075-A9E5916827BF}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{286BD256-4FE4-4E75-B075-A9E5916827BF}.Debug|Any CPU.Build.0 = Debug|Any CPU
{286BD256-4FE4-4E75-B075-A9E5916827BF}.Release|Any CPU.ActiveCfg = Release|Any CPU
{286BD256-4FE4-4E75-B075-A9E5916827BF}.Release|Any CPU.Build.0 = Release|Any CPU
{DD4ECF63-0452-420F-A364-B8355014B761}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{DD4ECF63-0452-420F-A364-B8355014B761}.Debug|Any CPU.Build.0 = Debug|Any CPU
{DD4ECF63-0452-420F-A364-B8355014B761}.Release|Any CPU.ActiveCfg = Release|Any CPU
{DD4ECF63-0452-420F-A364-B8355014B761}.Release|Any CPU.Build.0 = Release|Any CPU
EndGlobalSection
GlobalSection(NestedProjects) = preSolution
{76FDF7CF-8D13-4276-BD40-F7C40FBEA33B} = {7A4E9898-B55F-4C7F-A8B5-E3F3AAF7D1FB}
{16E8E8DE-EB36-4C07-AF78-4A981E83D700} = {7A4E9898-B55F-4C7F-A8B5-E3F3AAF7D1FB}
{C3EC1423-7B14-4105-9F57-FAFD6DC29724} = {7A4E9898-B55F-4C7F-A8B5-E3F3AAF7D1FB}
{85D535DB-22A5-4739-9CFD-F39EA4449ED7} = {F5189331-BA8E-459C-AFE2-96DFBEF12582}
{286BD256-4FE4-4E75-B075-A9E5916827BF} = {F5189331-BA8E-459C-AFE2-96DFBEF12582}
{DD4ECF63-0452-420F-A364-B8355014B761} = {F5189331-BA8E-459C-AFE2-96DFBEF12582}
EndGlobalSection
EndGlobal
48 changes: 48 additions & 0 deletions docs/CURRENT-STATE.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,48 @@
# Current State

**As of:** 2026-07-28 · **Branch:** `foundation/m0-headless-service-lab` (delivered as a PR into `main`)
**Milestone:** M0 — Headless Service Lab. **Most recent gate decision:** none yet (awaiting owner review).

## What is complete
- Repository initialized; full structure; license; determinism/architecture/design/product/risk/commercial/
playtest/asset docs; the original v1 charter preserved immutably in `docs/archive/2026-07-28/`.
- **M0 simulation core** (`src/RestaurantSim.Core`): deterministic, integer-only, seeded streams, no wall
clock — service simulator, demand/choice model, quality/satisfaction, economy, causal autopsy, forecast,
FNV-1a state checksum. Fixtures: 3 segments, 12 recipes, 8 employees, 3 market scenarios, 9 named strategies.
- **CLI** (`src/RestaurantSim.Cli`): inspect → plan → forecast → commit → autopsy → revise → run again.
- **Harness** (`src/RestaurantSim.Harness`): distribution/dominance/determinism analysis → `reports/`.
- **Tests:** 74 passing across 3 projects (invariants, determinism, golden scenarios, balance properties).
- **Evidence** (200 seeds/cell) committed under `reports/`.

## Latest test status
`dotnet test` → **74 passed, 0 failed** (Core 36, Determinism 30, Scenario 8). Re-run to confirm.

## Latest determinism status
Harness determinism check: **PASS** for the sampled matrix (same seed ⇒ identical checksum). Golden
checksums locked in `tests/RestaurantSim.Scenario.Tests`. Cross-OS CI comparison is an OPEN item.

## Balance status
Distinct winning strategies across 3 markets: **2 of 3** → no single dominant strategy. Poor strategies all
post negative medians and are legibly diagnosed. See `reports/balance/distribution.md` and
`docs/design/M0-BALANCE-HYPOTHESES.md`.

## What is partially complete / not started
- **Human playtests:** NOT gathered. The Builder cannot fabricate them. Plan/script/consent are ready in
`docs/playtests/`. This is the owners' step; the fun/comprehension/replay half of the M0 gate is pending.
- **Cross-OS determinism CI:** not wired (local double-run + golden checksums are active).
- Everything M1+ (spatial, persistence, identity, delegation, city, campaign, content, presentation): **not
started, not authorized.**

## Known defects / caveats
- None blocking. Known limitation (by design, not a defect): in a single service with no repeat visits,
throughput dominates profit and quality has limited economic teeth — see DECISION-LOG D-012. This is a
finding for M1, not a bug.

## Scope audit
Clean. No item from the M0 hard non-goals list was built (no graphics/engine/pathfinding/inventory/
suppliers/recipe-editor/competitors/campaign/managers/save-system/assets). Asset packages remain quarantined
and uncommitted.

## How to run
See `README.md`. `dotnet test` for tests; `dotnet run --project src/RestaurantSim.Harness` for evidence;
`dotnet run --project src/RestaurantSim.Cli` for the playable loop.
62 changes: 62 additions & 0 deletions docs/DECISION-LOG.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,62 @@
# Decision Log

Every important decision: date, decision, status (provisional | locked), rationale, alternatives,
consequences, owner, and conditions to revisit. Newest first.

---

### 2026-07-28 · D-012 · Balance signal: throughput dominates a single service (honest M0 finding)
- **Status:** locked (as a finding, not a change)
- **Decision:** Record that, in M0's single-service scope, covers-served is the dominant profit lever and
quality/satisfaction have limited economic teeth (only via comped failures). Do NOT fix this by building
repeat-visit/reputation systems (M1/M2 scope).
- **Rationale:** Faithful to M0 non-goals; the gap is itself a useful design signal for M1.
- **Owner:** Builder → owners. **Revisit:** at M1 design (repeat visits/reviews give quality teeth).

### 2026-07-28 · D-011 · Failed dishes are comped (no revenue, ingredient still paid)
- **Status:** locked · **Owner:** Builder
- **Decision:** A botched dish earns no revenue but consumes ingredients, giving execution economic weight
in a single service. **Alternatives:** remake loops (unbounded), pay-in-full (no teeth). **Revisit:** if
M1 repeat-visit feedback makes this redundant.

### 2026-07-28 · D-010 · Kitchen concurrency = 4 dishes per cook (`Tuning.SlotsPerCook`)
- **Status:** provisional · **Decision:** one cook oversees several covers at once (active-vs-passive cook
time abstraction) so throughput matches demand. **Revisit:** replace with an explicit active/passive
time model at M1 if needed.

### 2026-07-28 · D-009 · M0 fixtures: 3 segments, 12 recipes, 8 employees, 3 market scenarios
- **Status:** locked for M0 · **Rationale:** smallest set that produces context-dependent, non-dominant
strategies (proven in `reports/balance/distribution.md`). **Revisit:** M0.5 calibration.

### 2026-07-28 · D-008 · Numeric determinism: integer cents, basis points, milli, fixed-point; no float
- **Status:** locked · **Owner:** Builder · **Rationale:** floating point is the top threat to
cross-machine reproducibility (accepted review finding). Enforced by a reflection test. See ADR-002.

### 2026-07-28 · D-007 · Seeded, named, per-entity RNG streams (SplitMix64); never System.Random
- **Status:** locked · See ADR-003. **Consequence:** adding a roll to one entity cannot perturb another.

### 2026-07-28 · D-006 · Authoritative engine-agnostic C# core; presentation is a read model
- **Status:** locked · See ADR-001/ADR-004. **Consequence:** the renderer owns no truth; the sim runs
headless. **Revisit:** never for M0; the boundary is the whole point.

### 2026-07-28 · D-005 · First-commercial cut = through M3
- **Status:** provisional (planning boundary) · **Owner:** owners · See FIRST-COMMERCIAL-CUT. **Revisit:**
if M0–M3 evidence changes the viable scope.

### 2026-07-28 · D-004 · Fantasy continuity: flagship stays hand-authored; chains are delegated
- **Status:** provisional (assumption with a deferred proof gate) · See FANTASY-CONTINUITY.

### 2026-07-28 · D-003 · Launch model (premium vs Early Access) left OPEN pending platform answers
- **Status:** open · **Owner:** owners · **Rationale:** premium was locked before the platform question in
v1; de-locked here. See EARLY-ACCESS-DECISION. **Revisit:** before the store page goes up.

### 2026-07-28 · D-002 · Owner-supplied asset packages quarantined; none in M0; none committed
- **Status:** locked · See ASSET-QUARANTINE / ASSET-PROVENANCE. Downtown MegaKit is CC0 (cleared for later);
the rest are unclear/legacy → do not use.

### 2026-07-28 · D-001 · Ship on a branch as a PR the owners review/merge; never direct to main
- **Status:** locked · **Owner:** owners · **Rationale:** independent review before M1; the PR is the review
surface. The Builder does not declare M1 ready.

### 2026-07-28 · D-000 · Design spine preserved: "the menu is the strategy"; core fantasy unchanged
- **Status:** locked · The v1 charter is archived immutably; the active plan is a change record over it.
Loading