feat: add OTIVM-III per-player SQLite schema
This commit is contained in:
381
data/create_player_db.sql
Normal file
381
data/create_player_db.sql
Normal file
@@ -0,0 +1,381 @@
|
|||||||
|
-- OTIVM Per-Player Database Schema
|
||||||
|
-- File: data/create_player_db.sql
|
||||||
|
-- Version: OTIVM-III
|
||||||
|
-- Status: Game schema — transitional, designed to be throw-away
|
||||||
|
-- Replaces: data/saves/{session_id}.json (OTIVM-I/II)
|
||||||
|
-- Parallel to: data/create_otivm_db.sql (TESSERA world substrate)
|
||||||
|
--
|
||||||
|
-- Naming conventions: terminology.md Layer 3 (snake_case, period-neutral)
|
||||||
|
-- Timestamp column: recorded_at (never created_at, never timestamp)
|
||||||
|
-- Rows are never deleted — only archived or superseded
|
||||||
|
-- value_true and value_perceived are always separate columns
|
||||||
|
-- confidence_tag is always a first-class column, never a comment
|
||||||
|
--
|
||||||
|
-- When this schema is retired, it becomes a read-only layer
|
||||||
|
-- readable by the Simulator via the existing API translation layer.
|
||||||
|
-- The API is the universal wiring — this schema does not need to
|
||||||
|
-- anticipate the Simulator schema.
|
||||||
|
--
|
||||||
|
-- TheRON — single contributor. AI assistants implement, document,
|
||||||
|
-- flag — do not direct.
|
||||||
|
|
||||||
|
PRAGMA journal_mode = WAL;
|
||||||
|
PRAGMA foreign_keys = ON;
|
||||||
|
PRAGMA user_version = 3; -- OTIVM-III schema version
|
||||||
|
|
||||||
|
-- ============================================================
|
||||||
|
-- TABLE: actor_profile
|
||||||
|
-- One row per actor. The static anchor.
|
||||||
|
-- Created at session initialisation. Never updated — superseded
|
||||||
|
-- by a new row if background is changed (not currently possible
|
||||||
|
-- in OTIVM-III but the structure supports it).
|
||||||
|
-- ============================================================
|
||||||
|
|
||||||
|
CREATE TABLE IF NOT EXISTS actor_profile (
|
||||||
|
actor_id TEXT NOT NULL, -- uuid, matches save file naming
|
||||||
|
session_id TEXT NOT NULL, -- uuid, links to session chain
|
||||||
|
background_id TEXT NOT NULL, -- former_legionary | freedman_trader |
|
||||||
|
-- noble_younger_son | failed_magistrate |
|
||||||
|
-- camp_logistician | guild_scribe
|
||||||
|
actor_name TEXT NOT NULL, -- display name chosen by participant
|
||||||
|
epoch TEXT NOT NULL -- roman_14bce (Layer 3 code token)
|
||||||
|
DEFAULT 'roman_14bce',
|
||||||
|
schema_version INTEGER NOT NULL DEFAULT 3,
|
||||||
|
recorded_at TEXT NOT NULL, -- ISO 8601 UTC
|
||||||
|
PRIMARY KEY (actor_id, recorded_at)
|
||||||
|
);
|
||||||
|
|
||||||
|
-- ============================================================
|
||||||
|
-- TABLE: actor_parameters
|
||||||
|
-- The core parameter table.
|
||||||
|
-- One row per parameter per actor per recorded moment.
|
||||||
|
-- Append-only — new row on every change, old row retained.
|
||||||
|
--
|
||||||
|
-- Parameters with observable: partial or observable: hidden
|
||||||
|
-- carry both value_true (server-side ground truth) and
|
||||||
|
-- value_perceived (what the actor believes or can infer).
|
||||||
|
-- These are never merged into one column.
|
||||||
|
--
|
||||||
|
-- For parameters where perceived == true (observable: full),
|
||||||
|
-- value_perceived is set equal to value_true at write time.
|
||||||
|
--
|
||||||
|
-- confidence_tag vocabulary (from parameter-registry.md):
|
||||||
|
-- measured | indicated | inferred | estimated | unknown
|
||||||
|
--
|
||||||
|
-- observable_level vocabulary:
|
||||||
|
-- full | partial | hidden
|
||||||
|
--
|
||||||
|
-- value columns are TEXT to support ordinal bands (low/medium/high),
|
||||||
|
-- enums, floats, integers, and JSON structures without schema changes.
|
||||||
|
-- The parameter_token identifies what type to expect.
|
||||||
|
-- ============================================================
|
||||||
|
|
||||||
|
CREATE TABLE IF NOT EXISTS actor_parameters (
|
||||||
|
id INTEGER PRIMARY KEY AUTOINCREMENT,
|
||||||
|
actor_id TEXT NOT NULL,
|
||||||
|
parameter_token TEXT NOT NULL, -- from parameter-registry.md token field
|
||||||
|
scope TEXT NOT NULL, -- actor | scenario | relation
|
||||||
|
layer TEXT NOT NULL, -- roman | mesolithic | universal
|
||||||
|
value_true TEXT NOT NULL, -- server-side ground truth
|
||||||
|
value_perceived TEXT NOT NULL, -- actor-side belief (= value_true when full)
|
||||||
|
value_social TEXT, -- market consensus (auctoritas only)
|
||||||
|
confidence_tag TEXT NOT NULL -- measured | indicated | inferred |
|
||||||
|
DEFAULT 'estimated', -- estimated | unknown
|
||||||
|
observable_level TEXT NOT NULL, -- full | partial | hidden
|
||||||
|
drift_source TEXT, -- what caused this value (event_id, or NULL if initial)
|
||||||
|
recorded_at TEXT NOT NULL, -- ISO 8601 UTC
|
||||||
|
superseded_at TEXT, -- NULL if current; set when a newer row replaces this one
|
||||||
|
FOREIGN KEY (actor_id) REFERENCES actor_profile(actor_id)
|
||||||
|
);
|
||||||
|
|
||||||
|
-- Index for fast current-value lookup
|
||||||
|
CREATE INDEX IF NOT EXISTS idx_actor_parameters_current
|
||||||
|
ON actor_parameters (actor_id, parameter_token, superseded_at);
|
||||||
|
|
||||||
|
-- ============================================================
|
||||||
|
-- TABLE: parameter_drift_log
|
||||||
|
-- Append-only event log of every parameter change.
|
||||||
|
-- What changed, why, what triggered it, old and new values.
|
||||||
|
-- The behavioral record. Rows are never deleted.
|
||||||
|
-- This is the source of truth for the Simulator when it
|
||||||
|
-- reads this database as a read-only layer.
|
||||||
|
-- ============================================================
|
||||||
|
|
||||||
|
CREATE TABLE IF NOT EXISTS parameter_drift_log (
|
||||||
|
id INTEGER PRIMARY KEY AUTOINCREMENT,
|
||||||
|
actor_id TEXT NOT NULL,
|
||||||
|
parameter_token TEXT NOT NULL,
|
||||||
|
trigger_type TEXT NOT NULL, -- venture_complete | leg_complete |
|
||||||
|
-- interval_complete | exchange_complete |
|
||||||
|
-- scenario_event | session_start |
|
||||||
|
-- background_drift | manual
|
||||||
|
trigger_ref TEXT, -- venture_id, leg_id, scenario_id, or NULL
|
||||||
|
value_before TEXT NOT NULL,
|
||||||
|
value_after TEXT NOT NULL,
|
||||||
|
delta_note TEXT, -- human-readable reason for drift
|
||||||
|
recorded_at TEXT NOT NULL, -- ISO 8601 UTC
|
||||||
|
FOREIGN KEY (actor_id) REFERENCES actor_profile(actor_id)
|
||||||
|
);
|
||||||
|
|
||||||
|
CREATE INDEX IF NOT EXISTS idx_drift_log_actor
|
||||||
|
ON parameter_drift_log (actor_id, recorded_at);
|
||||||
|
|
||||||
|
-- ============================================================
|
||||||
|
-- TABLE: ventures
|
||||||
|
-- One row per venture (NEGOTIVM in Roman layer).
|
||||||
|
-- Status tracks the lifecycle. Outcome recorded on completion.
|
||||||
|
-- ============================================================
|
||||||
|
|
||||||
|
CREATE TABLE IF NOT EXISTS ventures (
|
||||||
|
venture_id TEXT PRIMARY KEY, -- uuid
|
||||||
|
actor_id TEXT NOT NULL,
|
||||||
|
venture_label TEXT NOT NULL, -- human-readable, e.g. "Ostia to Capua"
|
||||||
|
status TEXT NOT NULL -- planned | active | complete | abandoned
|
||||||
|
DEFAULT 'planned',
|
||||||
|
cargo_type TEXT, -- amphora type, modius goods, etc.
|
||||||
|
cargo_quantity REAL,
|
||||||
|
cargo_unit TEXT, -- amphora | modius | talent | unit
|
||||||
|
cost_total REAL, -- denarii-equivalent, sum of all legs
|
||||||
|
revenue_total REAL, -- denarii-equivalent, at settlement
|
||||||
|
outcome_net REAL, -- revenue_total - cost_total (NULL until complete)
|
||||||
|
outcome_note TEXT, -- narrative summary of outcome
|
||||||
|
recorded_at TEXT NOT NULL, -- ISO 8601 UTC — venture created
|
||||||
|
started_at TEXT, -- ISO 8601 UTC — first leg begun
|
||||||
|
completed_at TEXT, -- ISO 8601 UTC — final settlement
|
||||||
|
FOREIGN KEY (actor_id) REFERENCES actor_profile(actor_id)
|
||||||
|
);
|
||||||
|
|
||||||
|
CREATE INDEX IF NOT EXISTS idx_ventures_actor
|
||||||
|
ON ventures (actor_id, status);
|
||||||
|
|
||||||
|
-- ============================================================
|
||||||
|
-- TABLE: venture_legs
|
||||||
|
-- One row per leg (ITER in Roman layer).
|
||||||
|
-- Indivisible unit of movement within a venture.
|
||||||
|
-- Cost components recorded separately for Simulator readability.
|
||||||
|
-- ============================================================
|
||||||
|
|
||||||
|
CREATE TABLE IF NOT EXISTS venture_legs (
|
||||||
|
leg_id TEXT PRIMARY KEY, -- uuid
|
||||||
|
venture_id TEXT NOT NULL,
|
||||||
|
leg_sequence INTEGER NOT NULL, -- 1, 2, 3... within the venture
|
||||||
|
origin_h3 TEXT NOT NULL, -- H3 cell ID (TESSERA-compatible)
|
||||||
|
destination_h3 TEXT NOT NULL, -- H3 cell ID (TESSERA-compatible)
|
||||||
|
mode TEXT NOT NULL, -- road | sea | river | overland
|
||||||
|
vessel_type TEXT, -- navis_oneraria | actuaria | NULL if land
|
||||||
|
duration_days REAL, -- actual duration (NULL until complete)
|
||||||
|
cost_vectura REAL, -- freight charge (VECTVRA)
|
||||||
|
cost_portoria REAL, -- customs duty (PORTORIVM)
|
||||||
|
cost_other REAL, -- horreum, incidentals
|
||||||
|
cost_total REAL, -- sum of above
|
||||||
|
status TEXT NOT NULL -- planned | active | complete | failed
|
||||||
|
DEFAULT 'planned',
|
||||||
|
delay_days REAL, -- deviation from expected duration
|
||||||
|
delay_cause TEXT, -- weather | congestion | dispute | NULL
|
||||||
|
recorded_at TEXT NOT NULL, -- ISO 8601 UTC — leg created
|
||||||
|
started_at TEXT,
|
||||||
|
completed_at TEXT,
|
||||||
|
FOREIGN KEY (venture_id) REFERENCES ventures(venture_id)
|
||||||
|
);
|
||||||
|
|
||||||
|
CREATE INDEX IF NOT EXISTS idx_legs_venture
|
||||||
|
ON venture_legs (venture_id, leg_sequence);
|
||||||
|
|
||||||
|
-- ============================================================
|
||||||
|
-- TABLE: scenario_state
|
||||||
|
-- Active and archived scenario parameters.
|
||||||
|
-- Transient during active window, archived on close.
|
||||||
|
-- Must not persist into actor_parameters as permanent values —
|
||||||
|
-- scenario parameters are pressures, not conditions.
|
||||||
|
-- ============================================================
|
||||||
|
|
||||||
|
CREATE TABLE IF NOT EXISTS scenario_state (
|
||||||
|
id INTEGER PRIMARY KEY AUTOINCREMENT,
|
||||||
|
scenario_id TEXT NOT NULL, -- e.g. SCENARIO-MERCHANT-0001
|
||||||
|
actor_id TEXT NOT NULL,
|
||||||
|
parameter_token TEXT NOT NULL, -- from parameter-registry.md
|
||||||
|
value_true TEXT NOT NULL,
|
||||||
|
value_perceived TEXT NOT NULL,
|
||||||
|
confidence_tag TEXT NOT NULL DEFAULT 'estimated',
|
||||||
|
observable_level TEXT NOT NULL,
|
||||||
|
recorded_at TEXT NOT NULL, -- ISO 8601 UTC — parameter set
|
||||||
|
archived_at TEXT, -- NULL if active; set on scenario close
|
||||||
|
FOREIGN KEY (actor_id) REFERENCES actor_profile(actor_id)
|
||||||
|
);
|
||||||
|
|
||||||
|
CREATE INDEX IF NOT EXISTS idx_scenario_active
|
||||||
|
ON scenario_state (actor_id, scenario_id, archived_at);
|
||||||
|
|
||||||
|
-- ============================================================
|
||||||
|
-- TABLE: events
|
||||||
|
-- Append-only chronological record of all simulation state
|
||||||
|
-- changes. The atomic unit of history.
|
||||||
|
-- Every event has a recorded_at. No event is undated.
|
||||||
|
-- This table is the substrate for the behavioral model —
|
||||||
|
-- when this database becomes a read-only Simulator layer,
|
||||||
|
-- this table is the primary read target.
|
||||||
|
-- ============================================================
|
||||||
|
|
||||||
|
CREATE TABLE IF NOT EXISTS events (
|
||||||
|
id INTEGER PRIMARY KEY AUTOINCREMENT,
|
||||||
|
actor_id TEXT NOT NULL,
|
||||||
|
event_type TEXT NOT NULL, -- from terminology.md Layer 3 event_type values:
|
||||||
|
-- venture_start | venture_complete |
|
||||||
|
-- leg_start | leg_complete |
|
||||||
|
-- interval_start | interval_complete |
|
||||||
|
-- exchange_complete | session_abandoned |
|
||||||
|
-- chapter_advance | journal_unlock |
|
||||||
|
-- scenario_trigger | scenario_close |
|
||||||
|
-- parameter_drift
|
||||||
|
ref_id TEXT, -- venture_id, leg_id, scenario_id, or NULL
|
||||||
|
ref_type TEXT, -- venture | leg | scenario | actor | NULL
|
||||||
|
payload TEXT, -- JSON — event-specific detail
|
||||||
|
recorded_at TEXT NOT NULL, -- ISO 8601 UTC
|
||||||
|
FOREIGN KEY (actor_id) REFERENCES actor_profile(actor_id)
|
||||||
|
);
|
||||||
|
|
||||||
|
CREATE INDEX IF NOT EXISTS idx_events_actor_time
|
||||||
|
ON events (actor_id, recorded_at);
|
||||||
|
|
||||||
|
CREATE INDEX IF NOT EXISTS idx_events_type
|
||||||
|
ON events (event_type, recorded_at);
|
||||||
|
|
||||||
|
-- ============================================================
|
||||||
|
-- TABLE: background_starting_values
|
||||||
|
-- Seed data — the canonical starting parameter values for
|
||||||
|
-- each of the six backgrounds, per parameter-registry.md.
|
||||||
|
-- Read at actor initialisation to populate actor_parameters.
|
||||||
|
-- Never modified after initial insert.
|
||||||
|
-- ============================================================
|
||||||
|
|
||||||
|
CREATE TABLE IF NOT EXISTS background_starting_values (
|
||||||
|
background_id TEXT NOT NULL,
|
||||||
|
parameter_token TEXT NOT NULL,
|
||||||
|
value_true TEXT NOT NULL,
|
||||||
|
value_perceived TEXT NOT NULL,
|
||||||
|
confidence_tag TEXT NOT NULL DEFAULT 'indicated',
|
||||||
|
observable_level TEXT NOT NULL,
|
||||||
|
notes TEXT,
|
||||||
|
PRIMARY KEY (background_id, parameter_token)
|
||||||
|
);
|
||||||
|
|
||||||
|
-- ============================================================
|
||||||
|
-- SEED DATA: background_starting_values
|
||||||
|
-- Source: parameter-registry.md, section 1 (Actor Parameters)
|
||||||
|
-- Ordinal bands: low | medium | high | distinguished | extensive
|
||||||
|
-- ============================================================
|
||||||
|
|
||||||
|
INSERT OR IGNORE INTO background_starting_values VALUES
|
||||||
|
-- FORMER LEGIONARY
|
||||||
|
('former_legionary', 'auctoritas', 'medium', 'medium', 'indicated', 'partial', 'Reliable but not distinguished'),
|
||||||
|
('former_legionary', 'clientela', 'low', 'low', 'indicated', 'partial', 'Military network, limited commercial reach'),
|
||||||
|
('former_legionary', 'liquiditas', '200', '200', 'measured', 'full', 'Denarii — modest savings'),
|
||||||
|
('former_legionary', 'fama', 'neutral','neutral','indicated', 'partial', NULL),
|
||||||
|
('former_legionary', 'disciplina', 'high', 'high', 'indicated', 'full', NULL),
|
||||||
|
('former_legionary', 'mercatus_scientia', 'low', 'low', 'indicated', 'full', 'Military logistics, not commercial markets'),
|
||||||
|
('former_legionary', 'itineris_scientia', 'high', 'high', 'indicated', 'full', 'Extensive road and route knowledge'),
|
||||||
|
('former_legionary', 'ius_accessus', 'medium', 'medium', 'indicated', 'partial', 'Citizen standing'),
|
||||||
|
('former_legionary', 'periculum_tolerantia', 'high', 'high', 'indicated', 'full', NULL),
|
||||||
|
('former_legionary', 'negotiatio', 'low', 'low', 'indicated', 'full', NULL),
|
||||||
|
('former_legionary', 'litterae', 'medium', 'medium', 'indicated', 'full', NULL),
|
||||||
|
('former_legionary', 'officia_burden', 'low', 'low', 'indicated', 'partial', NULL),
|
||||||
|
|
||||||
|
-- FREEDMAN TRADER
|
||||||
|
('freedman_trader', 'auctoritas', 'low', 'low', 'indicated', 'partial', 'Practical reputation growing faster than social recognition'),
|
||||||
|
('freedman_trader', 'clientela', 'medium', 'medium', 'indicated', 'partial', 'Commercial network, active'),
|
||||||
|
('freedman_trader', 'liquiditas', '350', '350', 'measured', 'full', 'Denarii — working capital'),
|
||||||
|
('freedman_trader', 'fama', 'neutral','neutral','indicated', 'partial', NULL),
|
||||||
|
('freedman_trader', 'disciplina', 'medium', 'medium', 'indicated', 'full', NULL),
|
||||||
|
('freedman_trader', 'mercatus_scientia', 'high', 'high', 'indicated', 'full', NULL),
|
||||||
|
('freedman_trader', 'itineris_scientia', 'medium', 'medium', 'indicated', 'full', NULL),
|
||||||
|
('freedman_trader', 'ius_accessus', 'low', 'low', 'indicated', 'partial', 'Freedman limits on contract enforceability'),
|
||||||
|
('freedman_trader', 'periculum_tolerantia', 'medium', 'medium', 'indicated', 'full', NULL),
|
||||||
|
('freedman_trader', 'negotiatio', 'high', 'high', 'indicated', 'full', NULL),
|
||||||
|
('freedman_trader', 'litterae', 'high', 'high', 'indicated', 'full', NULL),
|
||||||
|
('freedman_trader', 'officia_burden', 'low', 'low', 'indicated', 'partial', NULL),
|
||||||
|
|
||||||
|
-- NOBLE YOUNGER SON
|
||||||
|
('noble_younger_son','auctoritas', 'high', 'high', 'indicated', 'partial', NULL),
|
||||||
|
('noble_younger_son','clientela', 'high', 'high', 'indicated', 'partial', 'Inherited network, not personally built'),
|
||||||
|
('noble_younger_son','liquiditas', '150', '150', 'measured', 'full', 'Denarii — constrained by elder sibling priority'),
|
||||||
|
('noble_younger_son','fama', 'good', 'good', 'indicated', 'partial', NULL),
|
||||||
|
('noble_younger_son','disciplina', 'low', 'low', 'indicated', 'full', NULL),
|
||||||
|
('noble_younger_son','mercatus_scientia', 'low', 'low', 'indicated', 'full', NULL),
|
||||||
|
('noble_younger_son','itineris_scientia', 'low', 'low', 'indicated', 'full', NULL),
|
||||||
|
('noble_younger_son','ius_accessus', 'high', 'high', 'indicated', 'partial', NULL),
|
||||||
|
('noble_younger_son','periculum_tolerantia', 'low', 'low', 'indicated', 'full', NULL),
|
||||||
|
('noble_younger_son','negotiatio', 'medium', 'medium', 'indicated', 'full', NULL),
|
||||||
|
('noble_younger_son','litterae', 'high', 'high', 'indicated', 'full', NULL),
|
||||||
|
('noble_younger_son','officia_burden', 'high', 'medium', 'indicated', 'partial', 'Underestimates informal obligations'),
|
||||||
|
|
||||||
|
-- FAILED MAGISTRATE
|
||||||
|
('failed_magistrate','auctoritas', 'low', 'medium', 'indicated', 'partial', 'True value lower than perceived — falling'),
|
||||||
|
('failed_magistrate','clientela', 'medium', 'medium', 'indicated', 'partial', 'Legal contacts, politically exposed'),
|
||||||
|
('failed_magistrate','liquiditas', '100', '100', 'measured', 'full', 'Denarii — depleted by failed campaign'),
|
||||||
|
('failed_magistrate','fama', 'mixed', 'mixed', 'indicated', 'partial', NULL),
|
||||||
|
('failed_magistrate','disciplina', 'medium', 'medium', 'indicated', 'full', NULL),
|
||||||
|
('failed_magistrate','mercatus_scientia', 'low', 'low', 'indicated', 'full', NULL),
|
||||||
|
('failed_magistrate','itineris_scientia', 'low', 'low', 'indicated', 'full', NULL),
|
||||||
|
('failed_magistrate','ius_accessus', 'high', 'high', 'indicated', 'partial', 'Formal standing intact, practical access eroding'),
|
||||||
|
('failed_magistrate','periculum_tolerantia', 'low', 'low', 'indicated', 'full', NULL),
|
||||||
|
('failed_magistrate','negotiatio', 'medium', 'medium', 'indicated', 'full', NULL),
|
||||||
|
('failed_magistrate','litterae', 'high', 'high', 'indicated', 'full', NULL),
|
||||||
|
('failed_magistrate','officia_burden', 'high', 'high', 'indicated', 'partial', NULL),
|
||||||
|
|
||||||
|
-- CAMP LOGISTICIAN
|
||||||
|
('camp_logistician', 'auctoritas', 'low', 'low', 'indicated', 'partial', NULL),
|
||||||
|
('camp_logistician', 'clientela', 'low', 'low', 'indicated', 'partial', 'Supply chain contacts, narrow'),
|
||||||
|
('camp_logistician', 'liquiditas', '180', '180', 'measured', 'full', 'Denarii — steady savings'),
|
||||||
|
('camp_logistician', 'fama', 'neutral','neutral','indicated', 'partial', NULL),
|
||||||
|
('camp_logistician', 'disciplina', 'high', 'high', 'indicated', 'full', NULL),
|
||||||
|
('camp_logistician', 'mercatus_scientia', 'high', 'high', 'indicated', 'full', 'Bulk goods, logistics pricing'),
|
||||||
|
('camp_logistician', 'itineris_scientia', 'high', 'high', 'indicated', 'full', NULL),
|
||||||
|
('camp_logistician', 'ius_accessus', 'medium', 'medium', 'indicated', 'partial', NULL),
|
||||||
|
('camp_logistician', 'periculum_tolerantia', 'medium', 'medium', 'indicated', 'full', NULL),
|
||||||
|
('camp_logistician', 'negotiatio', 'medium', 'medium', 'indicated', 'full', NULL),
|
||||||
|
('camp_logistician', 'litterae', 'medium', 'medium', 'indicated', 'full', NULL),
|
||||||
|
('camp_logistician', 'officia_burden', 'low', 'low', 'indicated', 'partial', NULL),
|
||||||
|
|
||||||
|
-- GUILD SCRIBE
|
||||||
|
('guild_scribe', 'auctoritas', 'low', 'low', 'indicated', 'partial', NULL),
|
||||||
|
('guild_scribe', 'clientela', 'low', 'low', 'indicated', 'partial', 'Document and account network'),
|
||||||
|
('guild_scribe', 'liquiditas', '120', '120', 'measured', 'full', 'Denarii — modest, careful'),
|
||||||
|
('guild_scribe', 'fama', 'neutral','neutral','indicated', 'partial', NULL),
|
||||||
|
('guild_scribe', 'disciplina', 'medium', 'medium', 'indicated', 'full', NULL),
|
||||||
|
('guild_scribe', 'mercatus_scientia', 'medium', 'medium', 'indicated', 'full', 'Account knowledge, not market instinct'),
|
||||||
|
('guild_scribe', 'itineris_scientia', 'low', 'low', 'indicated', 'full', NULL),
|
||||||
|
('guild_scribe', 'ius_accessus', 'medium', 'medium', 'indicated', 'partial', 'Document access, limited enforcement'),
|
||||||
|
('guild_scribe', 'periculum_tolerantia', 'low', 'low', 'indicated', 'full', NULL),
|
||||||
|
('guild_scribe', 'negotiatio', 'low', 'low', 'indicated', 'full', NULL),
|
||||||
|
('guild_scribe', 'litterae', 'high', 'high', 'indicated', 'full', NULL),
|
||||||
|
('guild_scribe', 'officia_burden', 'low', 'low', 'indicated', 'partial', NULL);
|
||||||
|
|
||||||
|
-- ============================================================
|
||||||
|
-- TABLE: schema_changelog
|
||||||
|
-- Documents schema version history.
|
||||||
|
-- Required: if this database becomes a read-only Simulator
|
||||||
|
-- layer, the Simulator must be able to identify schema version
|
||||||
|
-- and adapt its reader accordingly.
|
||||||
|
-- ============================================================
|
||||||
|
|
||||||
|
CREATE TABLE IF NOT EXISTS schema_changelog (
|
||||||
|
version INTEGER PRIMARY KEY,
|
||||||
|
description TEXT NOT NULL,
|
||||||
|
applied_at TEXT NOT NULL -- ISO 8601 UTC
|
||||||
|
);
|
||||||
|
|
||||||
|
INSERT OR IGNORE INTO schema_changelog VALUES
|
||||||
|
(1, 'OTIVM-I: JSON save files (not SQLite — recorded here for continuity)', '2026-04-25T00:00:00Z'),
|
||||||
|
(2, 'OTIVM-II: JSON save files with TESSERA map integration', '2026-04-28T00:00:00Z'),
|
||||||
|
(3, 'OTIVM-III: Per-player SQLite schema, parameter registry v1', '2026-05-02T00:00:00Z');
|
||||||
|
|
||||||
|
-- ============================================================
|
||||||
|
-- END OF SCHEMA
|
||||||
|
-- To initialise a player database:
|
||||||
|
-- sqlite3 data/saves/{actor_id}.sqlite3 < data/create_player_db.sql
|
||||||
|
--
|
||||||
|
-- To verify integrity after creation:
|
||||||
|
-- sqlite3 data/saves/{actor_id}.sqlite3 "PRAGMA integrity_check;"
|
||||||
|
-- sqlite3 data/saves/{actor_id}.sqlite3 "SELECT COUNT(*) FROM background_starting_values;"
|
||||||
|
-- Expected: 72 rows (12 parameters × 6 backgrounds)
|
||||||
|
-- ============================================================
|
||||||
Reference in New Issue
Block a user