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
9 changes: 9 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,15 @@ Icon?
/assets-quarantine/
/vendor-assets/

# --- V0 visual correction: our ORIGINAL Blender-generated kit IS committed ---
# The scene references these GLBs, so a reviewer needs them in the repo. They are our
# own procedurally-generated (CC0-equivalent) assets, not restricted third-party binaries.
# The blanket *.glb ignore above still quarantines everything else.
!visual/RestaurantVisualSandbox/assets/generated/
!visual/RestaurantVisualSandbox/assets/generated/*.glb
# Source .blend files are NOT committed: the tools/blender/*.py scripts are the source of
# truth and regenerate them deterministically (keeps the public repo free of binary bloat).

# --- Local scratch ---
/scratch/
/tmp/
Expand Down
28 changes: 28 additions & 0 deletions docs/art/ANIMATION-STANDARD.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
# Animation Standard — current status & the gap

## What exists in this correction
**Static posed variants, swapped per scenario beat.** `build_characters.py` bakes a fixed
pose per role/action (cook lean, server carry, customer sit/wait/stand); `CorrectedView`
spawns the right variant at the right place. There is **no skeletal rig, no animation clips,
and no in-engine motion** of characters. The only motion evidence is a **camera-orbit**
recording, not an animated service.

## Why (honest)
- Session scope: a robust rig + skinning + retargeting pipeline is the highest-effort,
highest-risk item (the contract's Loop-D stop-risk). It was deliberately deferred so the
rest of the coherent scene could be delivered.
- Static poses already beat sliding capsules for reading role and telling the bottleneck
story in stills and at a paused management view.

## What a real animation baseline needs (next art task, NOT done here)
1. One shared humanoid **skeleton** on the `CHAR_` base (export rigged GLB with an `AnimationPlayer`).
2. Retarget the **CC0 Universal Animation Library** (already verified CC0, ~1:1 scale in the
V0 asset test) or hand-key rough clips: idle, walk, carry-tray, cook-at-station, wipe-table,
sit, wait-impatient, place/pick-up.
3. Godot `AnimationTree`/playback driven by the same Mock snapshot, plus simple path lerps so
characters move between waypoints instead of teleporting per beat.

## Acceptance (deferred)
Motion should communicate the service story (servers hustling, cooks working, guests waiting)
rather than merely translating placeholders. Until then, this remains the **#1 known gap**
and the strongest reason the gate is *Pass-with-notes*, not *Pass*.
41 changes: 41 additions & 0 deletions docs/art/BLENDER-PIPELINE.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
# Blender → GLB → Godot Pipeline

Reproducible, procedural, headless. Source of truth = the Python scripts, not `.blend`.

## Tools
- Blender **5.2.0 LTS** — `/Applications/Blender.app/Contents/MacOS/Blender`
- Godot **4.7.1-stable** — `~/.local/opt/godot/Godot.app/Contents/MacOS/Godot`
- macOS / Apple M3 Max. `1 Blender metre = 1 Godot unit = 1 real metre`.

## Layout
```
tools/blender/
_bkit.py shared helpers + warm PALETTE; per-piece GLB export (origin at floor)
build_furniture.py FURN_ (8) build_kitchen.py KIT_ (12)
build_characters.py CHAR_ (9) build_environment.py ENV_ (8)
build_props.py PROP_ (8) export_all.py regenerate all 45
validate_exports.py import each GLB, report tris + floor origin
visual/RestaurantVisualSandbox/assets/generated/*.glb (committed — the scene needs them)
visual/RestaurantVisualSandbox/art-source/blender/ (.blend NOT committed — regenerable)
```

## Regenerate
```bash
BL=/Applications/Blender.app/Contents/MacOS/Blender
OUT=visual/RestaurantVisualSandbox/assets/generated
"$BL" --background --python tools/blender/export_all.py -- --out "$OUT" # all 45
"$BL" --background --python tools/blender/build_kitchen.py -- --out "$OUT" # one kit
"$BL" --background --python tools/blender/validate_exports.py -- --out "$OUT" # QA
```
Godot imports GLBs on the next editor scan (`godot --path <proj> --editor --quit --headless`).

## Export rules (enforced by `_bkit.export_piece`)
Transforms applied · Y-up · one joined mesh per piece · origin at floor contact (wall-mounted
decor origins at their mount point by design) · uniform scale · low-tri (12–72 tris/piece).
Naming prefixes: `ENV_ FURN_ KIT_ PROP_ CHAR_ MAT_`.

## Why `.blend` is not committed
The generators are deterministic, so the `.blend` files are disposable build artifacts. Keeping
only the `.py` source + the committed GLB outputs keeps the public repo free of binary bloat
while remaining fully reproducible. The `*.glb` quarantine in `.gitignore` is overridden only
for `assets/generated/` (our original, CC0-equivalent output).
35 changes: 35 additions & 0 deletions docs/art/CHARACTER-STYLE-GUIDE.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
# Character Style Guide

Stylized low-poly people (`tools/blender/build_characters.py`) replacing the V0 capsules.
Parametric `person(clothing, skin, hair, pose, prop, hat, apron)` builds head + hair + torso +
arms + legs + shoes and bakes a pose.

## Proportions
~1.8 m tall, slightly enlarged head for character appeal, chunky beveled limbs. Origin
between the feet at the floor. Low-tri.

## Role = colour + a second, non-colour signal
| Role | Colour | Second signal |
|---|---|---|
| Cook | white (`chef_white`) | **toque** + apron, cooking lean |
| Server | blue (`server_blue`) | **apron** + **tray** (plate + glass), carry pose |
| Host | teal (`host_teal`) | **clipboard**, at the podium |
| Busser | green (`busser_green`) | **bus bin**, carry pose |
| Customer | warm/varied | no staff prop; sit / wait / stand poses |

Identity never relies on colour alone — cook toque, server tray, host clipboard, busser bin,
and posture all read at management distance and survive desaturation better than shirt colour.

## Variants / poses (9 GLB)
Customers: `Sit_A`, `Sit_B`, `Wait_A`, `Stand_A` (skin/hair/clothing variety). Staff:
`Host_Stand`, `Server_Carry`, `Server_Idle`, `Cook_Cook`, `Busser_Carry`.
`CorrectedView` swaps the right pose variant per scenario beat.

## Status — the top remaining gap
These are **static posed meshes, NOT skeletally rigged/animated** (see `ANIMATION-STANDARD.md`).
Good enough to read role + action in stills and to tell the bottleneck story by placement;
not yet "acting" in motion. A skeletal rig + retargeted clips is the #1 next art task.

## Evidence
`reports/visual/v0-correction/screenshots/42-character-lineup.png`, plus the close-ups
`20-kitchen-closeup.png` / `21-foh-closeup.png`.
28 changes: 28 additions & 0 deletions docs/art/ENVIRONMENT-KIT-STANDARD.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
# Environment & Kitchen Kit Standard

One coherent kit, not a pile of models. All pieces procedural (`tools/blender/`), low-tri,
joined to one mesh per piece, origin at floor contact (wall-mounted decor at its mount point).

## Inventory (45 GLB, `assets/generated/`)
- **FURN_ (8):** Table_4Top, Table_2Top, Chair, Booth, HostStand, WaitBench, ServiceStation, BusTub.
- **KIT_ (12):** Grill, Range, Fryer, PrepStation, ColdStation, Sink, Dishwasher, Fridge,
Shelves, Pass (with heat-lamp bar), TicketRail, HeatLamp.
- **ENV_ (8):** Window, DoorFront, Sign, Plant, WallArt, PendantLight, MenuBoard, Awning.
- **PROP_ (8):** PlateClean, PlateFood, PlateDirty, Glass, BillFolder, PlaceSetting,
Centerpiece, TicketStrip.

## Scale & modularity
Metric (`v0_config` / real dims): counter/service height 0.90 m, table 0.75 m, chair seat
0.45 m, door 2.05 m. Pieces are instanced and placed by `corrected_restaurant.gd`; the same
GLB is reused everywhere (shared kit → low draw calls, ~600 for the whole scene).

## Materials
Shared warm palette from `_bkit.PALETTE`; each piece embeds only the materials it uses.
Steel for the kitchen line; warm woods for dining; terracotta/plaster for the shell.

## Budget
12–72 tris/piece; whole scene ~130–158 visible mesh instances, ~318k–479k primitives,
~305 MB VRAM (see `PERFORMANCE`). Add pieces by writing a builder fn + adding to `PIECES`.

## Evidence
`reports/visual/v0-correction/screenshots/40-furniture-kit.png`, `41-kitchen-kit.png`.
31 changes: 31 additions & 0 deletions docs/art/HUD-READABILITY-STANDARD.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
# HUD & Readability Standard

The core correction to PR #4: the HUD must **stop explaining the scenario by default**, and
the physical scene must carry the story. Implemented in `corrected_view.gd`.

## Three modes (decoupled)
- **Presentation (default):** clock + an **aggregate 5-dot pressure meter** derived from the
snapshot. **No scenario name, no debug labels, no giant gauges.** The player reads the
problem from the world (props, actors, tickets, piled plates, queues).
- **Readability overlay:** adds **subtle** floating state pips over problem tables and busy
stations (small emissive spheres) + small queue counts. A backup for the physical read, not
a replacement.
- **Debug:** adds world-space labels — scenario title, per-station queue numbers, mode name.
Developer-only.

## Decoupling the MOCK tag from the headline
The `MOCK / SCRIPTED` disclosure lives in a **corner**, always available, and is **independent**
of the scenario headline (the PR #4 review flagged that hiding the headline also hid the tag —
fixed by making them separate HUD elements).

## Physical-first storytelling (the point)
State is shown by **objects and behaviour** first: place settings vs plated food vs dirty
plates + bill folders on tables; cooks massed at the congested grill; servers empty-handed at
the pass (kitchen tell) vs plates piling under the heat lamp (FOH tell); a guest queue at the
host stand (host tell). Colour/pips are secondary.

## Known limit
At full overview the fine per-table state still benefits from the readability pips; the
physical tells read most clearly in the close-up / paused view. Evidence:
`reports/visual/v0-correction/screenshots/30-hud-presentation.png`, `31-hud-readability.png`,
`32-hud-debug.png`.
35 changes: 35 additions & 0 deletions docs/art/V0-CORRECTION-CURRENT-STATE.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
# V0 Visual Correction — Current State (living handoff)

Re-confirm the repository's actual state (`git log`, on-disk assets) before trusting this.

| Field | Value |
|---|---|
| Branch | `fix/v0-visual-baseline-correction` (from frozen V0 `a9a4230`) |
| Tip | advances per commit — run `git log --oneline a9a4230..HEAD` for the live tip |
| Engine / tools | Godot 4.7.1-stable · Blender 5.2.0 LTS (both outside the repo, not committed) |
| PR | target **#6 → `prototype/v0-3d-restaurant-sandbox`**, unmerged, review-only |
| Merged? | No. PR #4 and the M0 backend branches are untouched. |
| Latest Art PM decision | **None yet — awaiting independent visual review.** |

## Complete
Reproducible Blender→GLB→Godot pipeline; **45-piece kit** (FURN/KIT/CHAR/ENV/PROP);
integrated warm, frame-filling restaurant (`Corrected.tscn`); 4 scenarios via the frozen
MockService; **3 decoupled HUD modes**; physical bottleneck choreography; 14 screenshots +
3 before/after montages + a camera-orbit recording + `performance.csv`; the correction doc set.

## Partial / limited
- **Iteration depth = 2–3 real render-review cycles per component, not the mandated 5** (§16) —
compressed to a single session; reported honestly.
- Steel/material shading reads a bit flat; some role/state nuance leans on the readability pips
at full overview.

## Unstarted / deferred
- **Skeletal character animation** (Loop D) — characters are static posed variants; #1 gap.
- Full 5×-per-loop iteration; a true exterior/storefront camera; the 8 animated recordings.
- The independent 3-reviewer sub-agent critique (attempted; failed on an API outage) — folded
into a lead self-assessment in the report; **true independent review is the recommended next gate.**

## Status flags
Performance: **above target** (worst ~8.5 ms / ~120 FPS on M3 Max). Asset licensing: all
original Blender-generated (CC0-equivalent); no restricted binaries; `.blend` not committed.
Scope: all §26 non-goals absent; no backend/M1.
17 changes: 17 additions & 0 deletions docs/art/V0-CORRECTION-DECISION-LOG.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
# V0 Visual Correction — Decision Log

Date 2026-07-29/30 · Owner: Lead Visual Builder · all **provisional** pending independent
review unless noted.

| # | Decision | State | Rationale / alternatives / revisit |
|---|---|---|---|
| D1 | **Procedural Blender-Python pipeline** (scripts as source) over manual `.blend` sculpting | Locked (V0-c) | Deterministic, reviewable, diff-able, headless. Alt: hand-modelled `.blend` (not reproducible, binary bloat). Revisit if hand-art is needed for hero assets. |
| D2 | **Commit generated GLBs; do NOT commit `.blend`** | Locked (V0-c) | Scene needs the GLBs; `.blend` regenerable from scripts. Revisit if `.blend` become the source. |
| D3 | **Rear open-kitchen layout**, ~13×10 m, frame-filling | Provisional | Kills PR #4 dead floor; shows front + back of house together. Alts: side kitchen / L-shape (not built — a full 3-candidate Loop-A comparison is deferred). Revisit in review. |
| D4 | **Warm dining + cooler kitchen** lighting, ACES+SSAO | Provisional | Front/back separation + warmth + management clarity. Revisit materials/lighting depth. |
| D5 | **Hybrid-C retained + tuned closer** (dist 12.8, pitch 33) | Provisional | Preserves the PR #4-reviewed camera; closer to read characters/props. Revisit default zoom in the human test. |
| D6 | **Static posed characters; skeletal animation deferred** | Provisional (gap) | Session scope + Loop-D risk. Beats capsules for stills; NOT motion. #1 next task. See `ANIMATION-STANDARD.md`. |
| D7 | **Physical-first storytelling + decoupled 3-mode HUD** (headline ≠ MOCK tag) | Locked (principle) | Directly answers the PR #4 ruling ("HUD explains, world doesn't"). Revisit pip subtlety. |
| D8 | **Iteration depth compressed to 2–3 cycles** (not the mandated 5) | Provisional (honest caveat) | Single-session scope; prioritised a coherent whole scene over 5× on one component. Reported truthfully, not faked. Revisit by deepening per-loop iteration. |
| D9 | **All assets original Blender-generated (CC0-equivalent)**; Quaternius CC0 available but unused in core | Locked (V0-c) | Original identity; no restricted binaries. |
| D10 | **Independent sub-agent critique replaced by lead self-assessment** (API outage) | Forced | The scores in the report are the builder's own; TRUE independent review is the recommended next gate (Action: Continue). |
34 changes: 34 additions & 0 deletions docs/art/V0-CORRECTION-NEXT-ACTION.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
# V0 Visual Correction — Next Authorized Action (living handoff)

Re-confirm the repository's actual state before trusting this document. It records intent as
of 2026-07-29/30 and should be re-verified against `git status`, `git log`, and the on-disk
assets and renders before it is acted on.

## The ONE next authorized action

**Open PR #6 (`fix/v0-visual-baseline-correction` → `prototype/v0-3d-restaurant-sandbox`) for
independent visual review, and have that review provide the true independent art /
readability / technical-art critique** (the sub-agent critique attempted here failed on an
API outage; the report carries a lead self-assessment in its place).

That is the entire authorized scope of the next step.

## Explicitly NOT authorized
Merging PR #6 (or PR #4), running the five-person human test, backend / `RestaurantSim.Core`
integration, M1, final art production, production animation/navigation, or a restaurant
construction system.

## Reproduce before reviewing
```bash
BL=/Applications/Blender.app/Contents/MacOS/Blender
GODOT=~/.local/opt/godot/Godot.app/Contents/MacOS/Godot
PROJ=visual/RestaurantVisualSandbox
"$BL" --background --python tools/blender/export_all.py -- --out "$PROJ/assets/generated"
"$GODOT" --path "$PROJ" --editor --quit --headless # import GLBs
"$GODOT" --path "$PROJ" # open res://scenes/sandbox/Corrected.tscn
```

## Most valuable follow-up work (for the Art PM to weigh, not yet authorized)
1. **Skeletal character animation** (the #1 gap — see `ANIMATION-STANDARD.md`).
2. Deepen iteration to the full 5× per loop on layout, characters, and lighting.
3. Richer materials (steel, wood grain) and a proper exterior/storefront shot.
77 changes: 77 additions & 0 deletions docs/art/V0-VISUAL-CORRECTION-CONTRACT.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,77 @@
# V0 Visual Baseline Correction — Contract

**Track:** V0 Visual Baseline Correction (Blender + Godot art pass)
**Branch:** `fix/v0-visual-baseline-correction` (from frozen V0 `a9a4230`)
**Target PR:** #6 → `prototype/v0-3d-restaurant-sandbox` (not `main`) · **unmerged, review-only**
(the assignment predicted #5; that number was taken by an M0 backend PR)

## The ruling this answers

The V0 technical scaffold passed (isolation, project structure, cameras, scale, scenario
scripting, mock/sim separation, evidence capture, readability instrumentation). The
**player-facing visual baseline failed**: it read as a debug diagram — primitive furniture,
capsule people, floating labels, oversized gauges, dead floor, HUD explaining the answer.

**This correction replaces the presentation while preserving the scaffold.** It does **not**
start M1, integrate `RestaurantSim.Core`, or make final production art.

## The question (§1)

> Can an early but coherent 3D restaurant scene look and move enough like a real game that a
> viewer becomes interested, understands operational problems primarily through **physical
> behavior**, and can imagine the finished product without excusing it as a debug prototype?

## Visual direction (§2)

A **stylized, warm, handcrafted restaurant diorama**: softened chunky silhouettes, restrained
detail, warm dining / cooler kitchen light, expressive activity, strong management-distance
clarity. Not hyperrealism, not a generic asset-pack look, not a copy of any commercial game.

## Pipeline (§5–§7)

```
tools/blender/*.py (procedural source of truth)
→ Blender 5.2 headless → deterministic GLB (visual/…/assets/generated/)
→ Godot 4.7.1 scene assembly + warm lighting + visual-only scripted snapshot
```
1 Blender metre = 1 Godot unit = 1 real metre. Transforms applied; intentional origins
(furniture at floor, doors at hinge, characters between feet); GLB interchange; naming
prefixes `ENV_ FURN_ KIT_ PROP_ CHAR_ MAT_ COL_ SOCKET_`. **`.blend` files are not
committed** (regenerable from the scripts); the **generated GLBs are committed** (the scene
needs them; they are our original assets).

## HUD policy (§13) — the core correction

Decouple the scenario **headline** from the **MOCK tag**. Three modes:
- **Presentation** (default): minimal HUD, time/pause, small pressure summary, selection info.
**No scenario answer, no debug labels, no giant gauges.**
- **Readability overlay:** subtle table-state / station-pressure / workload / queue cues.
- **Debug:** full labels, scenario title, mock timeline, queue numbers.
The `MOCK / SCRIPTED` disclosure may sit in a corner during testing, independent of the headline.

## Bottlenecks must read physically (§14)

Kitchen vs FOH vs host must differ through **behavior and accumulation** (tickets piling,
plates under heat lamps, servers empty-handed at the pass, dirty tables stacking, entrance
queue) — **before** any overlay, not via a tall red bar or a headline.

## Non-goals (§26) — deliberately absent

No backend integration / authoritative sim / production AI / navigation / construction /
inventory / suppliers / menu / pricing / hiring / progression / save / multi-restaurant /
campaign / reviews / marketing / final sound / music / VFX / shaders / customization /
accessibility impl / Steam / final optimization / complete production asset library.

## Iteration & gate

Every major visual component runs **≥5 genuine iterations** (render → score → revise →
re-render) against the §18 rubric; independent adversarial reviewers (art / readability /
tech-art) critique each batch. Gate verdict lives in
`reports/visual/v0-correction/V0-VISUAL-CORRECTION-REPORT.md` using the exact
`Verdict / Action` block. **Continue** = recommend independent visual review; it does NOT
authorize human testing, merging, backend integration, M1, or final art.

## Stop rule (§31)

Stop after the correction, iteration loops, evidence, the focused PR, and the report. Do not
merge, run the 5-person human test, integrate the backend, begin M1, or begin final art.
Loading