glytch/fktry/CONTRACTS.md
type-two 1a769e6cbd Baseline: GLYTCH prototype, FKTRY lore codex, scaffold + 5-lane orchestration docs
- index.html: WIMVEE GLYTCH match-the-glitch prototype (playable)
- docs/FKTRY_LORE.md: world bible / MODELBEAST asset codex
- fktry/: vite+three+TS scaffold, contracts, main loop, seed data
- fktry/MASTERPLAN.md + CONTRACTS.md + lanes/LANE-{SIM,RENDER,UI,SCREEN,DATA}.md:
  round protocol and Round 1 orders for parallel Opus 4.8 executors

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-07-17 15:51:12 +10:00

58 lines
2.7 KiB
Markdown

# CONTRACTS — how the lanes fit together (ORCHESTRATOR-OWNED)
The binding type definitions live in [`src/contracts.ts`](src/contracts.ts) — that file
is the law. This doc explains the shape of the machine in prose.
## Data flow
```
data/*.json ──▶ main.ts loads GameData
┌───────────┼─────────────────────────┐
▼ ▼ ▼
sim.init() renderer.init() ui.init() / screen.init()
30 tps fixed timestep: sim.tick()
├─▶ sim.snapshot() ──▶ renderer.render(snap, alpha) (every rAF)
│ ──▶ ui.update(snap, events)
└─▶ sim.drainEvents() ─▶ screen.onEvents(events)
user input: UI builds Commands ─▶ bus.dispatch ─▶ sim.enqueue
renderer supplies pickTile + ghost preview
```
## Ownership map
| Path | Owner | Everyone else |
|---|---|---|
| `src/contracts.ts`, `src/main.ts`, root config, this doc, `MASTERPLAN.md` | orchestrator | read-only |
| `src/sim/**` | LANE-SIM | read-only |
| `src/render/**`, `public/assets/**` (consumption) | LANE-RENDER | read-only |
| `src/ui/**` | LANE-UI | read-only |
| `src/screen/**` | LANE-SCREEN | read-only |
| `data/**` | LANE-DATA | read-only |
| `lanes/LANE-X.md` NOTES section | lane X | orchestrator writes ORDERS section |
| `../docs/FKTRY_LORE.md` | canon | read-only for all lanes |
## Key invariants
- **Snapshot is read-only.** Renderer/UI/Screen never mutate it. Sim may reuse
internal buffers between snapshots; consumers must not hold references across frames.
- **All mutation goes through Commands.** No lane reaches into sim internals.
- **Events are drained once per frame by main.ts** and fanned out; consumers get the
same array — treat it as immutable.
- **IDs are data-driven.** Renderer/UI/Screen never hard-code item/machine ids; they
key off `GameData` and the `asset` field. New content should light up with zero code.
- **`alpha`** in `renderer.render(snap, alpha)` is the 0..1 fraction between the last
sim tick and the next — use it to interpolate belt item positions for smooth motion.
- **Belt visual speed** derives from `MachineDef.beltSpeed` and `BeltItem.t`; sim owns
the truth, renderer owns the smoothness.
- **Coordinates**: tile grid, origin at world center, +x east, +y south. `Dir` 0..3 =
N,E,S,W clockwise. Machine `pos` = origin corner (min x, min y of footprint).
## Contract-change requests
Written in your lane NOTES as `CONTRACT REQUEST: <what> — <why>`. The orchestrator
batches them between rounds. Until granted, work around locally inside your lane.