-- ── The schema fragment ───────────────────────────────────────────────────
--
-- Core replays this file on EVERY boot, statement by statement, immediately
-- after its own schema.sql and before it seeds defaults (MODULE_API.md §2.6).
--
-- **There is no migration runner anywhere in this project, and that is a
-- decision rather than an omission.** Core's own schema is one idempotent file
-- replayed the same way. So a module's schema is not a sequence of changes to
-- apply once — it is a statement of what the tables should look like, written so
-- that running it against a database that already matches does nothing.
--
-- Which means: every CREATE TABLE carries IF NOT EXISTS and every ALTER carries
-- IF NOT EXISTS. A statement that succeeds once and fails afterwards presents as
-- a module that worked until the first restart.
--
-- **And it means CHANGING a table is an ALTER, never an edit to its CREATE.**
-- `CREATE TABLE IF NOT EXISTS` does nothing at all when the table is already
-- there, so an edited column definition takes effect on a fresh install and on no
-- existing one — the worst possible split, because your development database is
-- usually the fresh one. Add the column with
-- `ALTER TABLE … ADD COLUMN IF NOT EXISTS`, below the CREATE, and leave the
-- CREATE describing what a new install gets.
--
-- ── What core checks, and when ────────────────────────────────────────────
--
-- Core validates this file at LOAD time, before your module mounts anything —
-- so a rule broken here costs you the mount entirely rather than leaving you
-- with half-created tables and routes that 503. What is left for replay time is
-- the class only the database can answer: an unknown column type, a bad foreign
-- key. Those are post-mount and do answer 503.
--
--   • **Leading verbs are an allowlist: CREATE, ALTER, INSERT, UPDATE.** Not a
--     DROP denylist. This file replays every boot, so a TRUNCATE or a DELETE
--     would empty a table on every restart.
--   • **Every table you create must be prefixed with your module id** —
--     `examplegame_` here. Nothing else in the database is yours to create.
--   • **No table core declares, and none another module has claimed.**
--
-- A foreign key INTO a core table is allowed, and works because core's schema is
-- already in place when this runs. The reverse is not, and could not be: it
-- would make core's schema depend on your module being installed.
--
-- Teardown is `purge.sql`, which no boot ever runs. See it.


-- ── World status ──────────────────────────────────────────────────────────
-- One row, id 1, holding the last thing the game server said about itself.
--
-- A singleton row rather than a settings key because it is *observed state* and
-- not configuration: it is written by whatever ingests from your sidecar, and an
-- operator never edits it. In a real module the writer is the sidecar ingest;
-- here `boot.js` writes it once so the page has something to render.
-- `updated_at` carries no `ON UPDATE CURRENT_TIMESTAMP`, deliberately. That
-- clause fires only when an UPDATE actually CHANGES a value, so a writer sending
-- the same numbers back — which is what a quiet game looks like — leaves the
-- timestamp frozen at the first write, and the row then goes stale while nothing
-- is wrong. The writer sets the column explicitly instead; see
-- `model/worldStatus/worldStatus.db.js`.
CREATE TABLE IF NOT EXISTS examplegame_world_status (
  id           TINYINT UNSIGNED NOT NULL PRIMARY KEY,
  online       TINYINT(1)       NOT NULL DEFAULT 0,
  players      INT UNSIGNED     NOT NULL DEFAULT 0,
  world_name   VARCHAR(120)     NULL,
  updated_at   DATETIME         NOT NULL DEFAULT CURRENT_TIMESTAMP
);

-- Seed the singleton. `INSERT IGNORE` rather than a plain INSERT: this runs
-- again on every boot, and the second run must be a no-op rather than a
-- duplicate-key error that fails the whole replay.
INSERT IGNORE INTO examplegame_world_status (id, online, players) VALUES (1, 0, 0);
