Commit Graph

24 Commits

Author SHA1 Message Date
bfe982251e Add teaching mode: admin can seed themselves as scene-1 Deep
An admin can now opt into "teaching mode" from the lobby, seeding
themselves as the Rank-3 player who must play the Deep in the first
scene (instead of leaving it to the random starting-rank roll), so they
can run the table for new crews.

- Game.teaching_deep_player_id (+ Alembic migration)
- maybe_finish_assign_techniques honors it before rolling ranks, so both
  the normal flow and the dev-mode skip path respect it
- Admin-gated POST .../teaching-mode toggle (pre-rank phases only)
- Lobby checkbox UI, greyed out if another admin already volunteered

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-14 09:14:58 -07:00
5a9d712c95 Add Cancel button to character-creation Revise flows
Clicking Revise on basic records, techniques, or J/Q/K assignment now
offers a Cancel button that throws away any edits made since Revise and
restores the previously-saved values. Basic-records cancel is a pure
client-side toggle; techniques/face cancel re-submit a snapshot taken at
Revise time (since Revise immediately unsubmits/unassigns server-side).
Also added Cancel to the recruit-creation basic-records revise.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-14 09:09:24 -07:00
45fefc0c71 Add modal name popup when a Pi-Rat earns a Name
When a Pi-Rat completes their second objective and ranks up, they now
get a blocking modal popup (NameModal.svelte, rendered by Dashboard
across all phases) to claim their Pirate Name, rather than an optional
box buried in their character sheet. Removed the old inline prompt-box
and its handler from CharacterSheet.svelte.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-14 09:05:02 -07:00
3bb4940df7 Hide deep's hand 2026-06-14 08:57:08 -07:00
55f4085d7a Add likes/hates to character sheet UI 2026-06-13 09:58:16 -07:00
56cdebdeda Fix off-by-one in rollback button placement
A rollback button on event E restores the state just after E. So the
button on the latest event was a no-op (you're already there), while the
scene-start event -- a valid earliest target -- correctly has one. The
visible set was effectively shifted one event late.

Hide the button on whichever event sits at the current position (the
rollback head if set, else the latest checkpoint, now supplied by the
backend as state.latest_checkpoint_id since the frontend's own reduce
over the async-populated accumulator wasn't reliably reactive). In live
play the latest event loses its redundant button; when rolled back, the
"you are here" event has none while earlier events show rollback and
later ones show redo.

Verified in a browser across live, rolled-back, and redo states.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-13 09:03:52 -07:00
6964aeabb6 Add undoable rollback/redo (Phase 2)
Rolling back is now non-destructive: instead of truncating the future,
it restores the target checkpoint's snapshot and points
Game.rollback_head_checkpoint_id at it. Later checkpoints/events are
kept and rendered greyed; rolling forward to one redoes the rollback
(same endpoint). The abandoned future is discarded only when a new
action is taken from a rolled-back state -- maintain_rollback_history
truncates it, clears the head, and bumps rollback_timeline_version,
now the sole trigger for the frontend log reset.

- Game.rollback_head_checkpoint_id (nullable; in SNAPSHOT_EXCLUDE) +
  Alembic migration.
- crud_rollback: rollback_to_checkpoint sets the head (None at latest);
  _discard_future + head-clear + version-bump moved into the next scene
  action's capture.
- EventLog.svelte: greyed future, redo (forward) affordance, a "rolled
  back" banner; dropped the now-misleading destructive confirm.
- Tests rewritten for head-pointer semantics (+ redo, action-after-
  rollback truncation, scene-end head clear); HTTP integration test
  extended to drive the full cycle over the wire.

Verified end-to-end in a browser: rollback greys the future and reverts
live state (captaincy/ranks), redo restores it, no errors.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-13 08:25:06 -07:00
a7f174b214 Add game-state rollback (Phase 1)
Full-state JSON snapshots let a scene be rolled back to an earlier
action. All game state lives in game_id-scoped tables, so a checkpoint
is just a serialized dump of the gameplay rows and rollback restores
it -- sidestepping deterministic replay (the deck shuffle is
materialized into state and captured verbatim).

- Checkpoint table + GameEvent.checkpoint_id (tri-state) +
  Game.rollback_timeline_version (models.py, Alembic migration).
- crud_rollback.py: serialize/apply/capture/seal-purge/rollback.
- Capture is driven by the broadcast middleware: snapshot per action
  while in the `scene` phase, seal+purge otherwise. Confined to the
  current scene; older scenes' checkpoints are purged at scene end.
- POST /game/{gid}/player/{pid}/rollback (routes_rollback.py),
  server-enforced for Admins and Deep players.
- EventLog.svelte: per-event rollback buttons + timeline reconciliation.
- Remove the orphaned /scene/rollback per-card-play undo (dead code
  since d7f8483, never wired up; superseded by full-state rollback).

Phase 1 truncates the future immediately; the greyed/undoable redo is
deferred to Phase 2.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-13 06:02:56 -07:00
d04e5013fa Streamline dead Pi-Rat rank voting
Dead and awaiting-recruit Pi-Rats can no longer be nominated to rank up
(they'd reset to Rank 1 anyway). submit_rank_vote rejects them, and the
upkeep dropdown only lists living, in-play crewmates via the shared
eligible_vote_nominees helper.

When a voter has no eligible nominees (e.g. a lone survivor whose only
crewmates are the previous Deep and a dead rat) they now skip voting
entirely and can ready up directly, instead of deadlocking — which is
why dead players were previously left nominable. The roster shows such
players as "No vote".

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-06-12 21:21:38 -07:00
e502155af7 More detailed card tooltips
Card tooltips now show what a card represents *as* an Obstacle (the
rulebook obstacle table entry) in addition to its suit theme, which is
relevant when challenging another Pi-Rat. The obstacle tables are served
from the backend via GET /api/obstacles (single source of truth in
cards.py) and cached client-side in cards.js, with a retry so a transient
first-load failure doesn't silently disable the tooltips.

Enriched everywhere cards appear in the challenge flow: hand/board cards
(Card.svelte), PvP defend buttons and the temporary-obstacle line
(ChallengePanel), and the duel card selector, which also shows an
inline description of what the chosen card becomes as an Obstacle.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-06-12 21:05:20 -07:00
952b1be872 Uncommit feature in character creation
Players can now unlock and revise any reasonably revisable choice while
character creation is ongoing: basic Rat Records (also in recruit
creation), submitted techniques (until the swap phase begins), J/Q/K
face-card assignments (until everyone is ready), and Like/Hate answers
written for crewmates. New endpoints unsubmit-techniques and
unassign-face-techniques clear the locked-in state server-side so the
phase machine waits for the revision.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-06-12 17:05:52 -07:00
ba32c96b7b Light mode update 2026-06-12 16:57:07 -07:00
fa37cffe47 Technique swapping implementation 2026-06-12 16:46:03 -07:00
121f2f7498 Player minimum of 3 to start a game or scene
Enforced server-side in lobby/start and confirm_scene_setup via
crud_base.has_min_players; Dev Mode bypasses it so local single-player
testing still works. Lobby and scene-setup UIs show a player-count
message instead of the start button when below the minimum.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-06-12 16:16:49 -07:00
5ad9c9db07 Multiple admins
Adds Player.is_admin (creator starts with it; backfilled by migration).
Admin-key-authenticated POST /admin/set-admin grants/revokes it from the
admin panel; the creator's privileges can't be revoked. Admin-gated
backend routes (dev mode, skip character creation) and frontend controls
(corner menu, lobby start, scene start, end story) now check is_admin
instead of is_creator, and admins get the admin_key in their state blob
so granted players can open the admin panel.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-06-12 16:03:14 -07:00
3395b127b4 Dev mode revamp 2026-06-12 11:50:34 -07:00
f61201144f Dead Pi-Rat reroll rework 2026-06-12 11:32:15 -07:00
0744893e7b Re-theme the app: token-based CSS and a full face lift
CSS refactor: every color, font, radius, and shadow is now defined once
in theme.css; all other styles derive translucent variants with
color-mix(), so re-theming means editing one file. Removed the
duplicate core.css/style.css import chains, dead styles, and the
Bootstrap/Tailwind orphan classes that were silently unstyled
(the main reason the splash page looked broken).

New "Lantern & Brine" look: brass and parchment on a lantern-lit
ink-navy night, Pirata One wordmark with Alegreya SC/Sans body fonts
(self-hosted via fontsource — they were previously referenced but
never loaded), parchment-faced playing cards, and a rebuilt splash
page. Inline color styles in components were replaced with semantic
classes (prompt-box, notice-banner, status chips, etc.), the rulebook's
embedded palette was updated to match, and the leftover Vite favicon
and "frontend" page title were replaced.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-06-12 06:50:00 -07:00
b72aea9747 Combine Rules and Admin corner links into one upper-right menu
Replace the fixed Rules link (upper-left) and the creator-only Admin
link (upper-right) with a single collapsible ☰ Menu in the upper right,
leaving the event log alone in its corner. CornerMenu always lists the
Rules link; pages can contribute context-specific entries through the
extraMenuLinks store, which Dashboard uses for the creator-only Admin
link. This gives future misc sub-pages a home without eating more
screen corners.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-06-12 01:47:56 -07:00
ed7900656d Replace copy-link alert() with inline button feedback
The lobby Copy buttons now flip to a transient "✓ Copied" label instead
of popping a modal alert, matching the admin page's copy buttons.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-06-12 01:18:48 -07:00
3a00774b50 Fable will fix it! Pt 3 2026-06-12 01:13:11 -07:00
a074ff77b1 Fable will fix it! Pt 2 2026-06-11 21:32:00 -07:00
443acd8400 Fable will fix it! 2026-06-11 15:57:08 -07:00
58a7e4d4f1 Switch to Svelte 2026-06-11 14:39:41 -07:00