diff --git a/AGENTS.md b/AGENTS.md index 0809419..a8e072c 100644 --- a/AGENTS.md +++ b/AGENTS.md @@ -36,6 +36,8 @@ When you run into a repeatable problem during testing (e.g. port assignment coll - Multi-socket TestClient tests must use `with TestClient(app) as client` so sockets share one event loop; separate portals can hang on cross-socket broadcasts. Close sockets explicitly before asserting disconnect messages. Override lifespan when using an isolated test database. +- For browser QA, use a temporary database (for example, `DATABASE_URL=sqlite:////tmp/pirats-qa.db`) and `PIRATS_PURGE_ENABLED=false`. Normal app startup migrates the selected database and automatically purges stale games. + ## Versioning & changelog The app shows its version number and a player-facing changelog in the ☰ menu → About. Both come from `frontend/src/lib/changelog.js` (rendered by `frontend/src/components/AboutModal.svelte`). diff --git a/TODO.md b/TODO.md index 07d9c15..40ec1fd 100644 --- a/TODO.md +++ b/TODO.md @@ -37,5 +37,5 @@ ## Words Words Words -- [ ] **TLDR rules**. A one page summary sheet of the rulebook, for the impatient +- [x] **TLDR rules**. A one page summary sheet of the rulebook, for the impatient - [ ] **Suggestions.** Take a pass through all of the suggestions in suggestions.js, rewrite ones that are stiff, awkward, or don't fit the theme/setting as described in the rulebook. Move the suggestion pool from suggestions.js into a backend API endpoint. diff --git a/frontend/src/lib/changelog.js b/frontend/src/lib/changelog.js index 8c2afb0..839576b 100644 --- a/frontend/src/lib/changelog.js +++ b/frontend/src/lib/changelog.js @@ -6,10 +6,11 @@ // - Add a CHANGELOG entry only when a commit changes something players can // see. Skip refactors, tests, and tooling. Keep wording player-facing. -export const VERSION = 45; +export const VERSION = 46; // Newest first. Each entry: { version, date: 'YYYY-MM-DD', changes: [string, ...] }. export const CHANGELOG = [ + { version: 46, date: '2026-09-04', changes: ['Added a printable TL;DR rules page, linked at the top of the full rulebook.'] }, { version: 44, date: '2026-09-04', changes: ['Crew Objectives opens as one connected panel, with the toggle and checklist sharing a border and background.'] }, { version: 43, date: '2026-09-04', changes: ['The crew roster keeps players in the same order when roles or ranks change, including when someone becomes the Deep.'] }, { version: 42, date: '2026-09-04', changes: ['Gats require a description, including older Gats that were left blank. Read descriptions on character sheets or hover over Gat icons in the crew roster.', 'Gat descriptions and prompts follow Gat Taxes correctly and clear when you create a new recruit.'] }, diff --git a/pyproject.toml b/pyproject.toml index 893a0b9..ed0762f 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -29,7 +29,7 @@ pirats = "pirats.main:main" where = ["src"] [tool.setuptools.package-data] -pirats = ["static/**/*", "rules.html", "migrations/**/*"] +pirats = ["static/**/*", "rules.html", "rules-tldr.html", "migrations/**/*"] [tool.pytest.ini_options] pythonpath = ["src"] diff --git a/src/pirats/main.py b/src/pirats/main.py index cfb443b..fac3436 100644 --- a/src/pirats/main.py +++ b/src/pirats/main.py @@ -358,6 +358,10 @@ app.include_router(api, prefix="/api") def rules_page(): return FileResponse(BASE_DIR / "rules.html", media_type="text/html") +@app.get("/rules/tldr", include_in_schema=False) +def rules_tldr_page(): + return FileResponse(BASE_DIR / "rules-tldr.html", media_type="text/html") + # Mount SPA static_dir = BASE_DIR / "static" if os.path.exists(static_dir): diff --git a/src/pirats/rules-tldr.html b/src/pirats/rules-tldr.html new file mode 100644 index 0000000..851ed4b --- /dev/null +++ b/src/pirats/rules-tldr.html @@ -0,0 +1,194 @@ + + + + + +Rats with Gats — TL;DR Rules + + + + + + + + +
+
+

Rats with Gats — TL;DR

+

Ordinary rats. Math Magic. Extremely questionable piracy. A one-page rules reference.

+ +
+
+
+

1. Muster the crew

+

3–6 players; one deck with both Jokers. Everyone makes a Pi-Rat: looks, smell, first words, math ability, and what others like/hate about them. Names come later.

+

Write 3 Secret Pirate Techniques, swap them with other players, then assign your new techniques to J, Q and K.

+

Random starting ranks: one Rank 3 (first Deep), one Rank 1 (first Pi-Rat), everyone else Rank 2 (choose either role).

+

Hand limits: highest rank 4, middle 3, lowest 2; compare the whole crew. Captain gets +1. Draw your starting hand to its limit. Draw immediately when your hand limit increases.

+
+
+

2. Set a scene

+

At least one player is a Pi-Rat (take action); at least one is the Deep (world, NPCs and trouble). Last scene’s Deep must play Pi-Rats next.

+

Shuffle discards into the deck. Keep unfinished Obstacles and draw until the list has at least Deep players + 1 cards, plus any accumulated Joker increases.

+

The Deep frames an urgent problem using the Obstacle tables. First scene: steal the ship you’re on!

+

Suit themes: ♣ shootin’ & stabbin’; ♠ sneakin’ & schemin’; ♦ swimmin’ & sailin’; ♥ shoutin’ & singin’.

+
+
+

3. Face a Challenge

+
    +
  1. The Deep states success/failure stakes and applies one or more Obstacles.
  2. +
  3. Play up to one card per Obstacle. Beat its current value to succeed. Equal, lower or no card = failure.
  4. +
  5. One success passes the Challenge; every failed Obstacle adds a complication. Narrate success using your card’s suit (or Technique).
  6. +
  7. Stack played cards beneath each Obstacle. The last card sets its next value; the original card keeps its suit/color.
  8. +
  9. After resolution, draw a replacement for each of your cards matching the original Obstacle’s color, even on failure.
  10. +
+

Discard an Obstacle and its column after one success per player in the whole group.

+
+
+

4. Know your cards

+

A = 1; 2–10 = printed value. A Gat adds +1 to black cards; a Name adds +1 to red cards.

+

J / Q / K: your assigned Secret Pirate Technique automatically succeeds. As an Obstacle or the last card beneath one, its value is the challenged Pi-Rat’s rank.

+

Joker in hand: before or after a Challenge, discard and replace one Obstacle (and its column); discard the Joker. Drawn as an Obstacle: discard it; permanently increase the list requirement by 1 starting next scene.

+

Helping: only with multiple applied Obstacles. Each helper plays one card and shares the outcome; helpers don’t draw replacements.

+

Duels: attacker plays a temporary Obstacle; defender responds normally. Discard the duel cards afterward. Only the defender gets color-match replacements.

+
+
+

5. Chase glory

+

Personal, in order: get a Gat → earn a Name → die like a pirate (or retire). The group decides when you’ve earned each. First two: +1 rank each; third: give another Pi-Rat +1 rank.

+

Crew, in order: steal a ship → choose a Captain → commit piracy.

+

Captain: highest rank after taking a ship; can be challenged for command. +1 hand limit, final say in crew disputes and vote ties; −1 rank whenever they personally fail a Challenge.

+

Gat / Name Taxes: ask an eligible crewmate to take your Challenge for a random card. Refusal puts their Gat or Name at stake. Read the full tax rules before using them.

+
+
+

6. Wrap up & go again

+

The Deep may end the scene once every participating Pi-Rat has faced a Challenge and had an Objective opportunity, or no Obstacles remain, or all Pi-Rats have fled/been incapacitated.

+

Flee before or after a Challenge; you’re out of the scene and don’t count as progressing or completing Objectives that scene.

+

Between scenes: everyone votes for another Pi-Rat who wasn’t Deep; most votes earns +1 rank. Resolve ties together (Captain breaks ties). Apply Objective rank rewards.

+

Only the previous Deep may discard any cards and refill to their hand limit. Rotate roles and set the next scene.

+

End the story when the group is ready—ideally after everyone tries the Deep, each rat earns an Objective, and the crew completes all three. Celebrate!

+
+
+ +
+ + + diff --git a/src/pirats/rules.html b/src/pirats/rules.html index 7018f48..4bda43b 100644 --- a/src/pirats/rules.html +++ b/src/pirats/rules.html @@ -336,6 +336,7 @@ a { color: var(--neon-cyan); }

Rats with Gats

A Story Game about the Pi-Rats of Yeld!

+

Short on time? Read the TL;DR rules →

Written & Designed by Nick Smith · Art by J. Richmond · Produced by Sally Hsu · Support: Maia and EmmaVoid