compw00tergame designer
2026-07-04 2026-07-04-compw00ter-build-plan-tracker-design.md

compw00ter — Build-Plan Tracker & Phased Roadmap

Date: 2026-07-04 Status: Design — approved, ready for implementation plan.

A host-facing project board built into the Hero Builder site: an interactive, DB-backed tracker of the phased build plan that takes compw00ter from "Hero Builder done" to "playable at the LAN party." Two deliverables in one: the tracker page (plan.php) and the seeded phase content (the roadmap).

Why

The game is a large, multi-subsystem build (Node engine, w00t economy, incidents, player client, admin panel, bosses). We need a single place to see what's done, what's in flight, and what's next — and to manage it live as work moves. It lives on the site itself, alongside the other host tools (Heroes / Vocab / Workbench).

Decisions locked in brainstorming

  • Page type: interactive DB-backed tracker (not static markdown, not kanban).
  • Deadline: none fixed — phases are dependency-ordered, no countdown.
  • Granularity: phases plus checkable tasks; phase progress = % tasks done.
  • Database: the same data/compw00ter.db, new tables (not a separate file).
  • Reordering: up/down buttons, not drag (matches progressive-enhancement style).
  • Access: unauthenticated internal tool, same as the rest of the app.

Part A — The tracker

Data model

Two new tables in data/compw00ter.db, added idempotently to sql/schema.sql:

CREATE TABLE IF NOT EXISTS plan_phases (
    id         INTEGER PRIMARY KEY AUTOINCREMENT,
    name       TEXT    NOT NULL,
    blurb      TEXT    NOT NULL DEFAULT '',
    sort_order INTEGER NOT NULL DEFAULT 0,
    created_at TEXT    NOT NULL,
    updated_at TEXT    NOT NULL
);

CREATE TABLE IF NOT EXISTS plan_tasks (
    id         INTEGER PRIMARY KEY AUTOINCREMENT,
    phase_id   INTEGER NOT NULL REFERENCES plan_phases(id) ON DELETE CASCADE,
    title      TEXT    NOT NULL,
    note       TEXT    NOT NULL DEFAULT '',
    status     TEXT    NOT NULL DEFAULT 'todo',   -- todo | doing | done | blocked
    sort_order INTEGER NOT NULL DEFAULT 0,
    created_at TEXT    NOT NULL,
    updated_at TEXT    NOT NULL
);
  • The four statuses are a fixed enum defined in includes/config.php (e.g. W00T_PLAN_STATUSES = ['todo', 'doing', 'done', 'blocked']), consistent with how the other enums live there.
  • Phase progress is computed, never storeddone / total tasks — so it can never drift from the underlying tasks.
  • ON DELETE CASCADE cleans up tasks when a phase is deleted. (Requires PRAGMA foreign_keys = ON per connection; set in Database.)

Files

Follows the existing Hero Builder shape exactly:

plan.php                 -- the board page (read + render)
plan_save.php            -- POST action handler (CSRF-checked) for all writes
classes/PlanRepository.php  -- all plan SQL, mirroring HeroRepository
includes/header.php      -- add "Plan" to the nav
sql/schema.sql           -- + plan_phases, plan_tasks (idempotent)
sql/seed.sql / seeder    -- seed the initial phases + tasks on a fresh DB

PlanRepository exposes: allPhasesWithTasks(), addPhase(), addTask(), updateTask(), setTaskStatus(), deleteTask(), deletePhase(), movePhase(dir), moveTask(dir), and a phaseProgress() helper (or progress computed inline from the loaded task list).

Page behaviour (plan.php)

  • Renders each phase as a card: name, blurb, a progress bar (computed %), and its tasks listed beneath, ordered by sort_order.
  • Each task shows a status chip (todo / doing / done / blocked), its title, and an optional note.
  • Uses the project palette from assets/style.css; done tasks visually muted, blocked tasks flagged, doing tasks highlighted.

Interactions (all POST → plan_save.php, CSRF-checked)

Every write is POST with a CSRF token (csrf_field() / csrf_check() from bootstrap.php), then redirects back to plan.php (PRG pattern), matching hero_save.php.

Action action= Effect
Cycle task status cycle_status todo → doing → done → blocked → todo
Add task add_task new task in a phase
Edit task edit_task change title / note
Delete task delete_task remove one task
Add phase add_phase new phase at end
Edit phase edit_phase change name / blurb
Delete phase delete_phase remove phase + its tasks (cascade)
Move phase move_phase up / down (swap sort_order)
Move task move_task up / down within its phase

Progressive enhancement

Everything works JS-off as plain form submits with full-page round-trips (status cycling is a one-button form per task; add-task is an inline form). A later JS layer (in the spirit of assets/builder.js) may intercept these for no-reload updates, but is not required for the page to be fully usable.

Access & security

  • Same posture as the rest of the app: no auth (internal LAN-party host tool).
  • SQL via prepared statements only; output escaped with e().
  • All state changes are POST + CSRF; GET plan.php is read-only.

Part B — The seeded roadmap

Dependency-ordered, no calendar. Seeded on a fresh DB. Phase 1 is seeded as done to reflect current reality. Fully editable afterwards — this is a starting skeleton, not a contract.

Phase 1 — Hero Builder & tooling (done)

  • Hero/ability/trait CRUD — done
  • Editable vocabularies (incident types, vice states, vices, meters) — done
  • Design Workbench (spec/) — done
  • Map grid editor (map/) — done

Phase 2 — Content lock

Fill the data the engine will need before writing engine code.

  • Complete the 10-hero roster, each with abilities + traits
  • Seed the incident catalogue into the DB (from the incident-catalogue spec)
  • Finalise meters and vices → vice-states

Phase 3 — Engine core (Node + WebSocket, port 6767)

  • Boot the WS server on 6767
  • Load the roster/content from compw00ter.db via better-sqlite3
  • Client connect / identify / room model
  • The round/tick loop — in-game hours as ~30s real rounds (game window + interlude)

Phase 4 — The w00t engine (attendance economy)

  • The schedule/timetable (hourly activities, per-room requirements)
  • Per-room quorum check during the game window
  • w00t fills on attendance, drains on empty chairs
  • Lose condition (w00t → 0 = collapse); score = party uptime

Phase 5 — Meters, traits & incidents

  • Meter drain over time; refill at a source (move there)
  • Traits fire at a meter extreme → reset meter, pull player off rig, spawn incident
  • Incident HP model (clear by ability damage); tiers (blocker / puller / standard / supply)
  • Abilities: fight / cleanse / provide; soft-counter, type-match ≈ 3×; escalation

Phase 6 — Player client

  • The player's game screen: their meters, abilities, position, nearby incidents
  • Movement between rooms / to sources
  • Using abilities on incidents; targeting

Phase 7 — Live admin panel

  • Privileged admin WS client showing live match state
  • Timeline lane of director-scheduled incidents & bosses
  • Trigger-now; inject an incident (type / location / severity)
  • Drop a boss; fire a chosen player's trait manually

Phase 8 — Bosses & richer layers

  • Named bosses: The Wife, The Martin
  • The hero counter-web
  • Team mini-games

Phase 9 — Playtest & tune

  • Number tuning (meter/incident/w00t rates)
  • Balance passes
  • LAN dry-run

Testing

  • Data layer: extend tests/smoke.php (or a sibling) to exercise PlanRepository — create phase, add tasks, cycle status, compute progress, delete-cascades.
  • UI: php -S 127.0.0.1:<port>, drive plan.php / plan_save.php with curl or Playwright (add task, cycle status, verify progress bar).
  • Always check the error log after PHP changes (grep w00t the shared log).

Out of scope (YAGNI)

  • Auth / per-user boards — single shared board.
  • Drag-and-drop reordering — up/down buttons only.
  • Due dates, assignees, comments/history — status + note is enough.
  • Any game-engine code — this is the tracker for it, not the engine.