From e199f88d4affcdfc522278cb4e78e00b7ef93ac6 Mon Sep 17 00:00:00 2001 From: TheRON Date: Tue, 28 Apr 2026 11:56:16 -0400 Subject: [PATCH] Update handover-game-dev.md OTIVM-II complete, OTIVM-III defined, full design corpus documented --- docs/handover-game-dev.md | 365 +++++++++++++++++--------------------- 1 file changed, 166 insertions(+), 199 deletions(-) diff --git a/docs/handover-game-dev.md b/docs/handover-game-dev.md index 1872eca..b0e0560 100644 --- a/docs/handover-game-dev.md +++ b/docs/handover-game-dev.md @@ -1,5 +1,5 @@ # Handover — OTIVM Game Development -### Date: 2026-04-27 +### Date: 2026-04-28 ### For: Incoming assistant (game development track) ### Read this completely before doing anything @@ -26,239 +26,205 @@ to real users within seconds of `pm2 restart otivm`. In order: 1. `CLAUDE.md` — workflow, three-shell model, ground rules, deployment facts -2. `docs/roadmap.md` — **read with the warnings in Section 5 of this - document in mind. The roadmap needs rewriting. Do not treat it as - current.** -3. `docs/RFC-TESSERA-4.0-001.md` — the database schema all future - releases depend on -4. `docs/TESSERA-dataset-registry.md` — what data exists, what is - pending, and critically: the restoration layer concept -5. This file +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/architecture/parameter-registry.md` — all simulation parameters, scope, layer, maturity +6. `docs/actors/CHARACTER-FRAMEWORK.md` — six backgrounds, twelve starting parameters +7. `docs/scenarios/SCENARIO-MERCHANT-0000.md` — the BALNEA prologue, background selection +8. `docs/scenarios/SCENARIO-MERCHANT-0001.md` through `0003.md` — the founding trilogy +9. `docs/cities/CITY-OSTIA-0001.md` — Ostia as pressure field, not backdrop +10. `docs/roadmap.md` — where the game is going (warning: body is stale, vision and principles still valid) +11. 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 (otium-dev, 10.0.0.23) +### OTIVM container (otivm-dev, CT 1105) - App user: `otivm` - Repo at `/home/otivm/OTIVM` -- Claude Code runs here as `otivm` user via `work` alias - (`cd ~/OTIVM && claude`) -- Python venv (game): `/home/otivm/venv` -- Python venv (pipeline — do not use): `/home/otivm/pipeline-venv` +- Claude Code runs here as `otivm` user via `work` alias (`cd ~/OTIVM && claude`) +- 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 -### Three Proxmox boxes -- **proliant-dev (srv-a, 10.0.0.11)** — development work happens here -- **staging box** — validation before production -- **production box** — live game served from here +### Five containers on srv-a (10.0.0.11) +See `docs/architecture/infrastructure.md` for the full topology. +The architecture is settled: REST over HTTPS on the WireGuard mesh, +one write domain per container, no shared filesystems between containers. + +| 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) — not on this container - Proxies `otium.civicus.us` → `10.110.0.18:3000` -- Do not look for a vhost on the container ### Gitea - Repo: `https://gitea.barternetwork.us/TheRON/OTIVM` - Branch: `main` (direct push, Claude Code handles this) -- MCP: connected via `mcp.civicus.us` — Claude chat reads any file - directly +- MCP: connected via `mcp.civicus.us` — Claude chat reads any file directly ### Backups -- `vzdump 1105 --compress zstd --storage local --mode snapshot` - on srv-a (root shell) -- Document every backup in `docs/archives.md` immediately after -- Never take a backup without documenting it. Never document one - not taken. +- Command: `vzdump 1105 --compress zstd --storage local --mode snapshot` on srv-a (root shell) +- Document every backup in `docs/archives.md` immediately after — see existing entries for format +- 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`) — serves `dist/` and save API - on port 3000 -- Player state: JSON flat files in `data/saves/` — no database -- TESSERA data: `data/otivm.sqlite3` — read-only by game server, - owned and populated by dataset assistant +- Fastify backend (`server/index.js`) — serves `dist/`, save API, TESSERA map endpoint +- `data/otivm.sqlite3` — TESSERA physical data, read-only by game server +- `data/saves/` — per-player JSON save files (gitignored) +- `better-sqlite3` installed — used by server for TESSERA queries - PM2 under `otivm` user (never root) -- Ecosystem file: `ecosystem.config.cjs` (must be `.cjs` — Vite sets - `"type": "module"`) +- Ecosystem file: `ecosystem.config.cjs` --- -## 4. Current game state — as of 2026-04-27 +## 4. Current game state — as of 2026-04-28 ### OTIVM-I — complete -- Fastify backend serving `dist/` and save API on port 3000 -- Five trade routes, Ostia → Alexandria, all working -- Journal entries firing on dispatch milestones -- Otium/negotium mechanic working -- Per-player save files in `data/saves/` via 8-char hex token -- Token displayed in UI — player can record it to resume on another - device -- 128 concurrent players supported - -### Navigation scaffold — complete -- `src/screens/` directory established -- Game.jsx renamed to `src/screens/Ledger.jsx` -- `App.jsx` manages screen state — ledger and map -- Both screens stay mounted — no state lost on switch +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 -- `src/screens/Map.jsx` — Mediterranean SVG map -- Two-polygon land outline (Europe + Asia Minor, North Africa) — - placeholder coastline, accurate mainland only -- Bounding box: 5°E–38°E / 28°N–48°N, equirectangular projection, - 800×460 canvas -- Five waypoints plotted at hardcoded H3 res-5 cell centres -- Route lines between waypoints — gold when unlocked, muted dashed - when locked -- Current chapter waypoint highlighted in gold, reached waypoints - in green -- `src/constants.js` — provenance fields added to all routes: - `origin_h3_r5`, `origin_region`, `cultural_note` - These are stub values today — become live TESSERA queries in - OTIVM-III -- `src/gameState.js` — structural additions: - - `active_dispatch: null` — records in-progress dispatch - - `events: []` — append-only event log - Each entry: `{ type, route_id, timestamp_utc }` - Types: `dispatch_start`, `dispatch_complete`, `otium`, - `chapter_advance`, `journal_unlock` - This is the sequencing substrate for OTIVM-IX attestation - - `galleyProgress(active_dispatch, now_ms)` — pure function, - returns 0–1 progress float. Returns null if no dispatch active. - - All apply* functions now append to `events` and set/clear - `active_dispatch` +**The map is live and rendering from real TESSERA data.** -### Architecture decisions locked +- `src/screens/Map.jsx` — fog-of-war SVG map +- H7 land cells rendered at real geographic positions (lat/lon from API) +- Progressive reveal by chapter — only visited waypoints are visible +- Sea = permanent darkness — no data needed, no storage needed +- `/api/map/:h5/:epoch` endpoint — H7 land/sea classification with centroids +- Epoch parameterised — default `roman_14bce` (sl_offset_cm = -10) +- `data/otivm.sqlite3` — 12,005 H9 rows, five H5 waypoints, `paleo_epochs` table live +- Session lifecycle — `session_abandoned` event written on new game, old saves preserved +- `active_dispatch`, `events[]` in save state — sequencing substrate for future releases +- `galleyProgress()` utility in gameState.js +- Provenance fields on all routes (`origin_h3_r5`, `origin_region`, `cultural_note`) + +### Architecture decisions locked in OTIVM-II - H3 IDs on all waypoints — permanent, TESSERA-compatible -- `constants.js` / `gameState.js` / `api.js` separation — permanent -- Virtual screens via `display:none` — state preserved in browser -- Save on meaningful events only — not on every tick -- H3 cell centre coordinates hardcoded in `Map.jsx` — h3-js is - server-side only -- Two-polygon land outline — to be replaced in OTIVM-III -- Two polygons not one — avoids cross-sea rendering lines +- Sea hexes are dark by definition — no data, no storage +- `session_abandoned` event — saves are never deleted, they receive a terminal event +- REST API for all inter-container data flows — no shared filesystems +- Per-player SQLite (128 files) replacing JSON saves — planned for OTIVM-III -### Known issue — recorded -- Claude Code collapsed `INITIAL_STATE` onto one line during a prior - session, causing a Vite build failure. Fixed in commit 34176dc. -- Going forward: Claude Code writes content exactly as received, - regardless of how it arrives. +### Known deferred items +- Journal local state does not reset on new game (React state issue, low priority) +- H7 cells rendered as circles — hex geometry deferred pending client-side h3-js +- Map coastline is five isolated H5 clusters — route corridor coverage deferred to OTIVM-III+ +- Roadmap body is stale — rewrite planned under project owner direction --- -## 5. The roadmap — needs rewriting ⚠ +## 5. OTIVM-III — defined, not yet started -**Read `docs/roadmap.md` but do not treat it as authoritative.** -The roadmap was written before the TESSERA 4.0 architecture was -decided. The following assumptions in the current roadmap are now -wrong: +OTIVM-III is the data plumbing release. Three things: -**1. It assumes a completed global TESSERA database.** -The global database (tessera.db) no longer exists on a reachable -server. `data/otivm.sqlite3` is a purpose-built per-waypoint database -(TESSERA 4.0 model). New hexes are added one H5 at a time by the -dataset assistant as the game expands. The roadmap must reflect this. +**1. Per-player SQLite — 128 pre-provisioned databases** -**2. It does not mention the restoration layer.** -`terrain` in `otivm.sqlite3` is modern WorldCover 2021 data. It is -wrong for any historical period. The Mediterranean was 60–70% forested -in Roman times and Mesolithic times. Today the same cells are -classified as built-up, cropland, or drained wetland. +Replace JSON save files in `data/saves/` with SQLite databases in +`data/players/`. Pre-provision all 128 at container setup — no database +created on demand under player load. The schema is defined by the parameter +registry and the SQLite schema document (pending — this is the next +document to be produced). -The restoration layer (HYDE 3.3 + KK10 datasets, not yet on drives) -will correct `terrain` to historically appropriate values. Until that -layer is active, the game must not present terrain data as -historically accurate. +The atomic unit is **time**. The database is a time-series of events. +Current parameter values are derived from event history. The schema must +treat uncertainty, confidence, and perceived-vs-true values as first-class +records, not comments. -This affects the roadmap significantly — terrain-dependent features -(city physical character, environmental hazard, resource availability) -cannot be implemented correctly until the restoration layer is in -place. +**2. RATIONES tab — the third screen** -**3. Release numbering is out of date.** -OTIVM-III in the current roadmap describes "The Factor" (NPC model). -The actual next release should establish the SQLite server connection -and replace the map coastline — both triggered by the database arriving -on the container. Discuss scope with the project owner before any code. +Add a third tab alongside Ledger and Map. This is the disaggregated +accounts — the line items of every NEGOTIVM. Not a dashboard. A Roman +merchant's RATIONES: what was spent at each ITER, on what, at what rate. -**The roadmap rewrite is the first task for the game development -assistant.** Do not write code until the roadmap is current. The -project owner will direct the rewrite. +The player sees a historically authentic accounting surface. The system +records parameters beneath it. Raw parameter values remain hidden or +available only in advanced view. + +**3. Internal API for aggregation (1103)** + +1105 exposes an internal endpoint that 1103 can call on a schedule to +collect player event snapshots for aggregation. Anonymised behavioral +data only — no save file contents transferred raw. + +**Before any OTIVM-III code is written:** +Read `docs/architecture/parameter-registry.md` in full. The schema +must not flatten AVCTORITAS into an integer. Uncertainty, observability, +and perceived-vs-true are structural requirements, not optional features. --- -## 6. The database — what the game can and cannot do +## 6. Design corpus — what ChatGPT produced this session -`data/otivm.sqlite3` is present on the container. It is read-only -from the game's perspective. The dataset assistant owns it. +The following documents were produced in collaboration with ChatGPT and +represent the design substrate for OTIVM-III and beyond. Read them in order. -### What is in the database -- 12,005 H9 rows across five waypoints, all `status=2` (current) -- `paleo_epochs` table — 9 epochs from Eemian to present with sea - level offsets +**Scenarios** (`docs/scenarios/`): +- `SCENARIO-MERCHANT-0000.md` — The BALNEA Conversation (prologue, background selection) +- `SCENARIO-MERCHANT-0001.md` — The Bronze Forge Fire (second-order market logic) +- `SCENARIO-MERCHANT-0002.md` — The Capuan Timber Yard Fire (upstream choke-point logic) +- `SCENARIO-MERCHANT-0003.md` — The FAENUS Offer (capital without cargo) -### Five waypoints -| City | H5 TEXT | H9 cells | -|---|---|---| -| Ostia | `851e805bfffffff` | 2401 | -| Capua | `851e8333fffffff` | 2401 | -| Brundisium | `851e8ba3fffffff` | 2401 | -| Carthago | `85386e23fffffff` | 2401 | -| Alexandria | `853f5ba7fffffff` | 2401 | +These form a trilogy with a prologue. Each success condition is sharper +than the last. The trilogy teaches: event → dependencies → price → capital. -### The canonical game query -Only use cells from complete, current H5 hexes: -```sql -SELECT tc.* -FROM tessera_cells tc -JOIN h5_coverage h5c ON tc.h5 = h5c.h5 -WHERE h5c.status = 2 - AND tc.status = 2 - AND tc.h5 = ? -``` +**Actors** (`docs/actors/`): +- `CHARACTER-FRAMEWORK.md` — twelve parameters, hidden traits, background rules +- `BACKGROUND-0001` through `BACKGROUND-0006` — six asymmetric starting lives -### Field status — what the game can trust -| Field | Trust level | Reason | -|---|---|---| -| `elev_cm` | ✅ Use — with epoch offset | GEBCO 2025, modern MSL. Apply `sl_offset_cm` from `paleo_epochs` for historical periods. | -| `terrain` | ⚠ Modern only | WorldCover 2021. Wrong for Roman/Mesolithic. Do not present as historical until restoration layer is active. | -| `hydro` | ✅ Use with caution | HydroSHEDS v1.1. Rivers have migrated — major drainage correct, fine detail approximate. | -| `geo_dep` | ✅ Use | USGS MRDS. Sparse in places but correct where present. | -| `geo_flag` | ✅ Use | BGR IGME5000. European coverage only. | -| `occ_flag` | ❌ Do not use | Placeholder 0x00 everywhere. Stage 06 not written. | +These are not classes. They are starting parameter profiles that drift +toward decision history over time (`background_drift` parameter). -### H3 conversion in JavaScript -H3 IDs are stored as INTEGER (64-bit) in the database. -In JavaScript: `h3.indexToCell(BigInt(row.h9))` to convert to string. -Server-side only — h3-js is not available in the browser bundle. +**Cities** (`docs/cities/`): +- `CITY-OSTIA-0001.md` — Ostia substrate: urban zones, population model, + infrastructure parameters, social nodes, daily and seasonal rhythm + +Ostia functions as a pressure field. It is not scenery. Every parameter +in the city document connects to actor parameters and scenario triggers. + +**Architecture** (`docs/architecture/`): +- `infrastructure.md` — settled container topology and API protocol +- `terminology.md` — three-layer vocabulary, rejected terms, naming rules +- `latin-bridge.md` — Latin term admission standard and full semantic entries +- `research-brief-roman-venture.md` — ChatGPT research instructions +- `parameter-registry.md` — all parameters, scope, layer, maturity --- -## 7. Dataset assistant — what they are doing in parallel +## 7. The SVCCINUM thread -The dataset assistant owns the pipeline. Current status: +The amber (`SVCCINUM`) in the grain route cargo is not merely a goods label. +It is the first explicit connection between OTIVM and CIVICVS. The amber +originated in Maglemoisian forests in approximately 8000 BCE — the same +territory and period that CIVICVS models. 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. -- `data/otivm.sqlite3` — production database, 12,005 rows ✅ -- `data/staging_otivm.sqlite3` — their working copy, not in git -- `pipeline/seed_extract.py` — old extractor, do not re-run ✅ -- `pipeline/seed_promote.py` — old promotion script, do not re-run ✅ -- `docs/TESSERA-dataset-registry.md` — full dataset inventory ✅ -- `docs/handover-dataset.md` — their track orientation ✅ +This thread runs through the `origin_h3_r5` provenance stub in `constants.js`, +through the SVCCINUM entry in `latin-bridge.md`, through the `occ_flag` stub +parameter in the registry, through to OTIVM-VIII and OTIVM-IX. -**Next dataset work:** -1. Four datasets to be added to USB Drive 1 (project owner action) -2. Per-H5 pipeline to be designed and built -3. Restoration layer — HYDE 3.3 + KK10 integration - -You will be told when the database is updated. You do not run -pipeline scripts. You do not touch `pipeline/` or `data/create_otivm_db.sql`. +Do not lose this thread. It is the architectural consequence of building +both systems on the same physical reality layer from the start. --- @@ -267,17 +233,10 @@ pipeline scripts. You do not touch `pipeline/` or `data/create_otivm_db.sql`. Every change follows this sequence without exception: 1. Claude chat discusses the change and produces one downloadable file -2. The file header contains the Claude Code instruction (path, commit - message) -3. The file body contains the exact content to write to disk -4. Human downloads from Claude chat and pastes into Claude Code - (Shell 1) -5. Claude Code writes to the specified path, commits, pushes -6. Human runs `npm run build` in Shell 2 (otivm shell) -7. Human runs `pm2 restart otivm` in Shell 2 -8. Human confirms in browser at https://otium.civicus.us -9. Human reports result back to Claude chat -10. Claude chat proceeds to the next step +2. Human uploads to Gitea manually, or pastes into Claude Code +3. If code: `npm run build && pm2 restart otivm` +4. Human confirms result +5. Claude chat proceeds to next step **One file. One step. One confirmation. Never batch.** @@ -286,31 +245,39 @@ Every change follows this sequence without exception: ## 9. Hard rules - Never run PM2 as root — always as otivm user -- Never commit secrets — no tokens, no keys, no passwords in any file +- Never commit secrets — no tokens, no keys, no passwords - Never push to main without building — `npm run build` must pass first -- No database for player state — JSON flat files only -- H3 IDs on every location — never a coordinate pair or string name - alone -- One change confirmed before the next — no batching steps -- Never print file contents or code blocks in chat — always - downloadable attachments -- Never make assumptions about what is on disk — always read from - Gitea MCP first -- Do not query `otivm.sqlite3` with raw coordinates — always H3 IDs -- Do not present `terrain` as historically accurate until the - restoration layer is confirmed active by the dataset assistant +- JSON flat files for player state — until OTIVM-III replaces them with SQLite +- H3 IDs on every location — never a coordinate pair or string name alone +- Never make assumptions about disk state — always read from Gitea MCP first +- Uncertainty is a first-class record, not a comment — applies to all schema work +- The data warehouse is the product — the game is the public interface +- Real weather only in CIVICVS — DWD data always, no simulation --- -## 10. Commit messages +## 10. Commit message convention Imperative mood, present tense, under 72 characters. -Example: `Add Mediterranean SVG map to Map screen` not `Added map`. +`Add Mediterranean SVG map to Map screen` not `Added map`. --- -*Handover 2026-04-27 — game development track* -*Database present, paleo_epochs added, 12,005 current rows.* -*Roadmap needs rewriting — first task before any code.* -*terrain field is modern WorldCover — not historically accurate yet.* +## 11. 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 +- `staging_otivm.sqlite3` in sync +- Pipeline venv provisioned at `/home/otivm/pipeline-venv` +- Four datasets pending download to Drive 1 (BGR IGME5000, HYDE 3.3, KK10, HydroRivers) +- Per-H5 pipeline architecture not yet designed — next dataset session task + +When `otium.sqlite3` is expanded with new H5 hexes (OTIVM-III first new +waypoint), the game development assistant will be told. The `/api/map/:h5/:epoch` +endpoint requires no changes — it is already parameterised by H5 ID. + +--- + +*Handover 2026-04-28 — game development track* *Claude chat designs. Claude Code implements. The human decides.*