Files
otivm/docs/handover-game-dev.md
2026-05-03 15:23:25 -04:00

12 KiB

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.us10.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 architectureShell.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-componentsParameterRow.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. RetiredPrologue.jsx and Ledger.jsx deleted.

Otium expenditure constants — source: docs/economy/cost-calibration-model.md:

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.mdMS_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.