# Handover — OTIVM Game Development ### Date: 2026-05-03 ### For: Incoming assistant (game development track) ### Read this completely before doing anything --- ## 0. Your role You are the game development assistant. You design and build the OTIVM browser game at `otium.civicus.us`. You work in Claude chat (claude.ai), produce one file at a time as a downloadable attachment, and the human commits and pushes from the otivm shell. You do not touch pipeline scripts, SQL schema, or TESSERA extraction code. That work belongs to the dataset assistant (see `docs/handover-dataset.md`). You share the OTIVM Gitea repo but work on different files. The game is live. The server is running. Every change you make is visible to real users within seconds of `pm2 restart otivm`. **Workflow — files you produce go to the human, not Claude Code.** Claude Code is expensive. The human writes files to disk directly from the otivm shell and runs git commands copy-pasted from chat. Always provide the exact git commands in chat, ready to copy-paste. Never require manual editing or renaming. --- ## 1. Read these files before writing any code In order: 1. `CLAUDE.md` — workflow, ground rules, deployment facts 2. `docs/architecture/infrastructure.md` — container topology, API protocol 3. `docs/architecture/terminology.md` — three-layer vocabulary, naming convention 4. `docs/architecture/latin-bridge.md` — Latin terms, admission standard, semantic entries 5. `docs/parameter-registry.md` — canonical parameters, scope, layer, maturity 6. `docs/parameter-registry-additions.md` — 44 additional tokens from corpus review 7. `docs/actors/CHARACTER-FRAMEWORK.md` — six backgrounds, twelve starting parameters 8. `docs/scenarios/SCENARIO-MERCHANT-0000.md` — the BALNEA prologue, background selection 9. `docs/scenarios/SCENARIO-MERCHANT-0001.md` through `0003.md` — the founding trilogy 10. `docs/cities/CITY-OSTIA-0001.md` — Ostia as pressure field, not backdrop 11. `docs/Roadmap-OTIVM-IV.md` — OTIVM-IV scope and file inventory (approved) 12. `docs/roadmap.md` — where the game is going 13. This file The parameter registry is the bridge between the design documents and the schema. Read it before touching any database code. --- ## 2. Infrastructure ### OTIVM container (otivm-dev, CT 1105) - App user: `otivm` - Repo at `/home/otivm/OTIVM` - Python venv: `/home/otivm/venv` - Pipeline venv: `/home/otivm/pipeline-venv` - PM2 home: `/home/otivm/.pm2` - Node: `/usr/bin/node` (v22) - App port: 3000 - WireGuard: 10.110.0.18 ### Five containers on srv-a (10.0.0.11) | CT | Role | |---|---| | 1101 | tessera-pipeline | | 1102 | tessera-store (master database) | | 1103 | tessera-dev (aggregation) | | 1104 | apt-cache | | 1105 | otivm-dev (this container) | ### Nginx proxy - Lives on wg-pk (198.58.111.109) - Proxies `otium.civicus.us` → `10.110.0.18:3000` ### Gitea - Repo: `https://gitea.barternetwork.us/TheRON/OTIVM` - Branch: `main` (direct push) - MCP: connected via `mcp.civicus.us` ### Git protocol — mandatory, non-negotiable Before touching any file: ``` git fetch origin main git merge origin/main ``` After making changes: ``` git add [specific named files only — never git add .] git commit -m "scope: description" git push origin main ``` NEVER: `--rebase`, `--force`, `git stash`, `git reset --hard`, `git add .` ### Backups - Command: `vzdump 1105 --compress zstd --storage local --mode snapshot` on srv-a (root shell) - Document every backup in `docs/archives.md` immediately after - Download each dump to workstation cold storage - Never take a backup without documenting it. Never document one not taken. --- ## 3. Stack - React 19 + Vite 8 frontend (`src/`) - Fastify backend (`server/index.js`) - Bootstrap 5.3.3 (vendored, MIT, pinned) — layout and components - Bootstrap Icons 1.11.3 (vendored, MIT, pinned) - `data/otivm.sqlite3` — TESSERA physical data, read-only (`better-sqlite3`) - `data/saves/` — per-player save files (gitignored) - OTIVM-I/II: `{token}.json` - OTIVM-III+: `{token}.sqlite3` (created from `data/create_player_db.sql`) - Both formats coexist. JSON files are never deleted. - `data/create_player_db.sql` — per-player schema (schema version 5) - `data/repair_player_db_fk.sql` — repair script for pre-v5 databases - PM2 under `otivm` user (never root) ### Frontend file structure (OTIVM-IV) ``` src/ config/ contexts.json ← dropdown definition context-actor.json ← ACTOR layout and section config context-forum.json ← FORUM layout and section config context-map.json ← MAP layout and section config components/ Shell.jsx ← sidebar + dropdown + layout grid (built once) Section.jsx ← generic panel renderer (built once) ParameterRow.jsx ← one parameter row CostRow.jsx ← one cost line DriftEntry.jsx ← one drift log entry screens/ Actor.jsx ← ACTOR context screen Forum.jsx ← FORUM context screen Map.jsx ← MAP context (unchanged from OTIVM-II) App.jsx ← Shell wired, three contexts App.css ← project overrides only (Bootstrap handles layout) constants.js ← routes, waypoints, BACKGROUNDS, MS_PER_SIM_DAY gameState.js ← frontend game state logic api.js ← save API calls ``` --- ## 4. Current game state — as of 2026-05-03 ### OTIVM-I — complete Five trade routes Ostia → Alexandria, journal, otium/negotium mechanic, per-player saves via 8-char hex token, 128 concurrent players supported. ### OTIVM-II — complete and live Map live and rendering from real TESSERA data. Fog-of-war SVG, H7 land cells at real geographic positions, progressive reveal by chapter. ### OTIVM-III — complete and live Per-player SQLite live. Schema version 5. Background selection, parameter seeding, ventures, venture_legs, parameter_drift_log all recording correctly. ### OTIVM-IV — complete and live at `3700f5a` **The situation instrument is live.** Server startup message: `OTIVM server running on port 3000 — OTIVM-IV` **What was built:** 1. **Bootstrap 5.3.3 + Bootstrap Icons 1.11.3** — vendored, pinned. 2. **`App.css`** — reduced to project overrides. Roman palette as CSS custom properties. All classes prefixed `otivm-`. 3. **Shell architecture** — `Shell.jsx` and `Section.jsx` built once. Sidebar with context dropdown replaces tab navigation. Four layout types: `single`, `two-col`, `three-col`, `map`. Nine panel types in Section.jsx. 4. **Context JSON files** — four files in `src/config/`. Adding a new context requires one JSON file + one thin screen file. No shell changes. 5. **Sub-components** — `ParameterRow.jsx`, `CostRow.jsx`, `DriftEntry.jsx`. 6. **`Actor.jsx`** — background selection (when `background_id = null`) or full parameter instrument view (three-col: identity/liquiditas, auctoritas three faces/parameters, obligations/drift log). 7. **`Forum.jsx`** — dispatch and otium decisions. Full cost breakdown (vectura/portoria/other) visible on route cards. Periodic expenditures panel. Journal collapsible. 8. **`App.jsx`** — Shell wired. Three contexts: ACTOR, FORUM, MAP. 9. **`server/index.js`** — three named otium expenditure trigger types: `otium_access_fee` (2 dn), `personal_maintenance` (4 dn), `officia_obligation` (2 dn). Each writes a separate drift log entry. 10. **Retired** — `Prologue.jsx` and `Ledger.jsx` deleted. **Otium expenditure constants — source: `docs/economy/cost-calibration-model.md`:** ```javascript const OTIUM_ACCESS_FEE_DN = 2.00 // LOW confidence const PERSONAL_MAINTENANCE_DN = 4.00 // MEDIUM confidence const OFFICIA_OBLIGATION_DN = 2.00 // LOW confidence const OTIUM_CYCLE_TOTAL_DN = 8.00 ``` Change only in `server/index.js` constants block and `Forum.jsx`. **Economic calibration documents in `docs/economy/`:** - `cost-calibration-model.md` — ceramic cup baseline, reference wages - `cost-calibration-additional-goods.md` — garum, grain, amber, marble capital **Five good patterns:** `batch_craft` · `perishable_batch` · `bulk_staple` · `import_luxury` · `commission_heavy` **Market architectural constraints (deferred — must not be violated):** - `observable_level` on every `actor_parameters` row is the Market visibility gate - `value_true` = server ground truth. `value_perceived` = ledger truth. Never conflate. - Every drift log entry must be meaningful to an external reader. **Known deferred items:** - Real cost model — 60/25/15 split is a placeholder - Transformation routes (grain→bread) and barter — architecture defined, not built - Market reader — deferred, constraints documented - H7 cells as circles — hex geometry deferred pending h3-js - Map coastline — five isolated H5 clusters - Terrain — modern WorldCover, restoration layer not yet built ### What OTIVM-V is Not yet defined. Project owner decides scope before development begins. Take a backup and document it before OTIVM-V begins. --- ## 5. Design corpus **Scenarios** (`docs/scenarios/`): - `SCENARIO-MERCHANT-0000.md` — The BALNEA Conversation - `SCENARIO-MERCHANT-0001.md` — The Bronze Forge Fire - `SCENARIO-MERCHANT-0002.md` — The Capuan Timber Yard Fire - `SCENARIO-MERCHANT-0003.md` — The FAENUS Offer **Actors** (`docs/actors/`): - `CHARACTER-FRAMEWORK.md` — twelve parameters, hidden traits, background rules - `BACKGROUND-0001` through `BACKGROUND-0006` — six asymmetric starting lives **Cities** (`docs/cities/`): - `CITY-OSTIA-0001.md` — Ostia substrate **Architecture** (`docs/architecture/`): - `infrastructure.md`, `terminology.md`, `latin-bridge.md` - `parameter-registry.md`, `parameter-registry-additions.md` - `simulation-clock.md` — `MS_PER_SIM_DAY = 3_000` **Economic calibration** (`docs/economy/`): - `cost-calibration-model.md` - `cost-calibration-additional-goods.md` --- ## 6. The SVCCINUM thread The amber (`SVCCINUM`) in the grain route cargo is the first explicit connection between OTIVM and CIVICVS. It originated in Maglemoisian forests in approximately 8000 BCE. When both simulations share a TESSERA substrate, the amber in the MERCATOR's hold will be traceable to a specific H3 cell where a CIVICVS Constructor gathered or traded it. This thread runs through `origin_h3_r5` in `constants.js`, through the SVCCINUM entry in `latin-bridge.md`, through `occ_flag` in the registry, through to OTIVM-VIII and OTIVM-IX. Do not lose it. --- ## 7. Workflow — one file, one step, one confirmation 1. Claude chat produces one downloadable file 2. Human writes to disk: `cp filename src/path/filename` 3. If code: `npm run build` (then `pm2 restart otivm` if server or frontend) 4. Human runs the exact git commands provided in chat — copy-paste, no editing 5. Human confirms 6. Claude chat proceeds **One file. One step. One confirmation. Never batch.** **Git add rule:** Always name the exact file. Never `git add .` **File naming rule:** Downloaded filename = destination filename. No renaming. --- ## 8. Hard rules - Never run PM2 as root — always as otivm user - Never commit secrets - Never push without building - Per-player SQLite for player state - JSON saves coexist — never deleted, never overwritten - H3 IDs on every location — never a coordinate pair alone - Never assume disk state — always read from Gitea MCP first - Uncertainty is a first-class record, not a comment - The data warehouse is the product — the game is the public interface - Real weather only in CIVICVS — DWD data always - Design one step ahead - Bootstrap is vendored and pinned — never use a CDN reference --- ## 9. Commit message convention Imperative mood, present tense, under 72 characters. --- ## 10. What the dataset assistant is doing in parallel See `docs/handover-dataset.md` for full detail. Current state: - `data/otivm.sqlite3` live — 12,005 rows, `paleo_epochs` populated, FK clean - Four datasets pending download (BGR IGME5000, HYDE 3.3, KK10, HydroRivers) - Per-H5 pipeline designed (RFC-TESSERA-4.0-001), not yet coded When `otivm.sqlite3` is expanded with new H5 hexes, the game development assistant will be told. The `/api/map/:h5/:epoch` endpoint needs no changes. --- *Handover 2026-05-03 — game development track* *Claude chat designs. Claude Code implements. The human decides.*