2 Commits
Author SHA1 Message Date
slaguru666andClaude Opus 5 cbad87ba98 Add Occult, Religion and Psychology, and the Panic track
From the first game's list. The three skills are not decoration — they are the
levers on the new track, which is why they arrived together.

PANIC, 0 to 5, up. It is the other half of Coherence and the rules page says so
in the first line, because a table that confuses them will make the wrong call
at the worst moment:

    Coherence   what knowing has cost you       weeks     10-0, down
    Panic       what is happening to you NOW    minutes    0-5, up

A trigger gives a point with NO ROLL. Asking for a die to find out whether you
are frightened slows the scene and tells the player how to feel; the die is for
getting rid of it, which is the interesting direction.

    0 steady · 1 rattled · 2 shaken -5% · 3 losing it -10%
    4 overwhelmed -20% · 5 broken

The first point is free on purpose, so the opening shock of a scene costs the
table nothing. At 5 you break — freeze, flee or fixate, choose fast — and come
back at 3, not at 0, because breaking is not a rest.

Relief is where the skills come in. A success takes one point, a special takes
two. Psychology is the only thing that steadies somebody who is NOT you.
Religion steadies you alone and does not care whether you are right. Occult is
the odd one: naming a thing correctly, out loud, helps everybody who can hear —
the department's actual work, and the only relief that reaches a room. Plus
POW×5 to steady yourself, and your anchor object once per case, which is what
that briefing scene was for.

The three skills are placed in six registers rather than left floating: Occult
to the professor and to Registry, Psychology to the doctor and to Interview,
Religion to Antiquities and Pathology.

Guards, because a track nothing reads is this project's oldest failure: the five
new rules carry spot-checks in check-rules, and check-behaviour gains nine tests
— the free first point, monotonic penalties, only 5 breaking, clamping at both
ends, breaking not clearing the track, special taking two, every band/trigger/
relief having a label, and every relief naming a skill the catalogue actually
has.

Verified in a live game: penalty reaches the roll (58 → 58 → 53 → 48 → 38 for
panic 0-4, criticals and specials recomputed with it), the full arc runs 0 → 2 →
4 → eased to 2 → pushed to 5 → breaks → 3 with no errors, the sheet shows the
band, and the rules journal has a Panic page generated from the same tables.

Version 1.1.0.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-08-12 22:55:11 +01:00
slaguru666andClaude Opus 5 ab619f4b73 Remove the dice textures and the whole Dice So Nice path
Deleted: the seven PNGs in dice/, tools/make-dice-textures.mjs, the `npm run
dice` script, the RB_DICE colourset and texture tables, diceSetFor, the
diceSoNiceReady hook, and rbDressDice — which was tagging ten roll sites with
coloursets that no longer existed. 99 lines of module, plus the assets.
README and DEPLOY updated; they still advertised all of it.

Recoverable with `git revert` if it is ever wanted back.

This also explains the 01-that-was-12. The RESULT was never wrong: skillRoll
rolls one 1d100 and grades on roll.total, and the chat card derives the tens and
units it prints from that same total. Checked all 100 values of percentileFaces
and 60 live rolls — the printed faces reconstruct the graded number every time,
with no mismatches.

What disagreed was the ANIMATION. The custom addDicePreset labels registered for
d100 and d10 remapped which physical face means what, so Dice So Nice could land
showing 01 while the roll behind it was 12. Nothing downstream ever read the
animated faces, so no roll was ever adjudicated on the wrong number — but a
table watching the dice had every reason to believe otherwise, which is its own
kind of wrong. Disabling the skins in 1.0.6 already removed it; deleting them
makes it permanent.

Verified in a running Foundry after removal: skill roll, weapon damage, hit
location, major wound and Coherence all resolve and post their cards, no errors,
and game.ringbrp.diceSetFor is gone from the API.

Version 1.0.7.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-08-12 22:45:52 +01:00
160 changed files with 511 additions and 428 deletions
+11 -11
View File
@@ -28,7 +28,8 @@ git clone https://gitea.timevans.uk/slaguru666/RingBRP.git ringbrp
```
Requires **Foundry v13+** (verified against v14.364). No modules are required. Dice So
Nice is supported but optional — the system registers four of its own dice textures.
Nice works if you have it, using your own dice — the system ships no dice skins and does
not touch anybody's dice settings.
### Deploying to a remote Foundry server
@@ -47,7 +48,7 @@ packs or regenerate art on that machine:
```bash
npm install # pulls classic-level, used to write the LevelDB packs
npm run build # rebuilds packs/ from tools/content.mjs
npm run check # the three guards; the build refuses to run if they fail
npm run check # the five guards; the build refuses to run if they fail
```
To update a deployed server: `git pull` and restart Foundry. If the pull touches
@@ -64,13 +65,13 @@ changing underneath a running server.
| **Postings** | 25, each with a key characteristic, trained skills, talents and its own kit |
| **Trades** | 10 ordinary jobs the department recruits from, plus induction |
| **Catalogue** | 236 items — 123 gear, 62 weapons, 32 armour, 19 vehicles |
| **Skills / talents** | 59 skills, 19 talents |
| **Skills / talents** | 62 skills, 19 talents |
| **Bestiary** | 21 statblocks across folklore, horror and the far side |
| **Eras** | modern, antique, future, anomalous — the agency is old and never abolishes anything |
| **Icons** | 292, all generated from `tools/icons.mjs`; no external art |
| **Starter scenario** | **BLACK PLATFORM**, a six-player action starter, importable as a single Adventure |
| **Compendia** | pregens, NPCs, skills, weapons, armour, gear, vehicles, powers, tables, rules, the starter |
| **Rules journal** | 12 pages, generated from `rules.mjs` so the book cannot drift from the code |
| **Rules journal** | 13 pages, generated from `rules.mjs` so the book cannot drift from the code |
<!-- box:end -->
---
@@ -152,13 +153,12 @@ template.json data model for every Actor and Item type
templates/ Handlebars sheets
styles/ one stylesheet
lang/en.json all user-facing text
icons/ dice/ fonts/ generated art
icons/ fonts/ art/ generated art
packs/ built LevelDB compendia (committed — see Deploying)
tools/
content.mjs the catalogue: skills, weapons, armour, gear, vehicles, NPCs
build-packs.mjs builds packs/ — runs the three guards first and refuses on failure
build-packs.mjs builds packs/ — runs the five guards first and refuses on failure
make-icons.mjs draws all 231 icons
make-dice-textures.mjs
rules-text.mjs generates the rules journal FROM rules.mjs
mission.mjs the case generator
mission-tables.mjs its content tables
@@ -176,13 +176,13 @@ stops being identity-equal to what it aliases, if a constant is re-declared as a
literal, or if an exported rule has no spot-check. The packs used to be built under
one set of numbers and played under another; this makes that impossible to ship.
The build runs all three guards before it writes anything:
The build runs all five guards before it writes anything:
<!-- guards:start -->
```
check-rules: OK — 87 rules, 21 files scanned, 3 aliases + 41 constant sets checked, 275 formulas verified
check-rules: OK — 92 rules, 20 files scanned, 3 aliases + 45 constant sets checked, 290 formulas verified
check-kits: OK — 25 roles, 10 trades, 218 catalogue items, every kit key resolves, every posting can use what it carries, every loadout distinct
check-lang: OK — en.json, 945 keys, no leaf/branch collisions
check-behaviour: OK — 46 behavioural tests
check-lang: OK — en.json, 976 keys, no leaf/branch collisions
check-behaviour: OK — 55 behavioural tests
```
<!-- guards:end -->
Binary file not shown.

Before

Width:  |  Height:  |  Size: 43 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 15 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 3.9 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.5 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 785 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 970 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 826 B

+1 -2
View File
@@ -33,10 +33,9 @@ Only if you intend to edit the catalogue there:
```bash
npm install # classic-level, for writing LevelDB
npm run check # the three guards
npm run check # the five guards
npm run build # rebuilds packs/
node tools/make-icons.mjs # redraws all icons
node tools/make-dice-textures.mjs # regenerates the Dice So Nice textures
```
`npm run build` runs the guards first and aborts if any fails, so a broken catalogue
+32 -1
View File
@@ -943,5 +943,36 @@
"RINGBRP.Item.ArtRating": "Rating",
"RINGBRP.Item.PushCost": "Push cost",
"RINGBRP.Item.PushRule": "What pushing does",
"RINGBRP.Item.Origin": "Where it came from"
"RINGBRP.Item.Origin": "Where it came from",
"RINGBRP.Panic.Label": "Panic",
"RINGBRP.Panic.Steady": "Steady",
"RINGBRP.Panic.SteadyNote": "You are all right. You are doing the job.",
"RINGBRP.Panic.Rattled": "Rattled",
"RINGBRP.Panic.RattledNote": "Your hands are not quite steady. No penalty — the first one is free.",
"RINGBRP.Panic.Shaken": "Shaken",
"RINGBRP.Panic.ShakenNote": "−5% to everything. You keep checking the way you came in.",
"RINGBRP.Panic.Losing": "Losing it",
"RINGBRP.Panic.LosingNote": "−10% to everything. You are talking too fast and not hearing answers.",
"RINGBRP.Panic.Overwhelmed": "Overwhelmed",
"RINGBRP.Panic.OverwhelmedNote": "−20% to everything. One more and you go.",
"RINGBRP.Panic.Broken": "Broken",
"RINGBRP.Panic.BrokenNote": "You freeze, run, or go at it. Choose one, take it, and come back at 3.",
"RINGBRP.Panic.Trig.WrongThing": "Something that should not be there",
"RINGBRP.Panic.Trig.Touched": "It touched you",
"RINGBRP.Panic.Trig.Body": "A body",
"RINGBRP.Panic.Trig.Known": "Somebody you knew",
"RINGBRP.Panic.Trig.Dark": "The lights went",
"RINGBRP.Panic.Trig.Wounded": "A major wound",
"RINGBRP.Panic.Trig.Named": "It said your name",
"RINGBRP.Panic.Relief.Steady": "Steady yourself (POW×5)",
"RINGBRP.Panic.Relief.Religion": "Religion — something older than the department",
"RINGBRP.Panic.Relief.Psychology": "Psychology — talk somebody else down",
"RINGBRP.Panic.Relief.Occult": "Occult — name it, out loud, for everyone who can hear",
"RINGBRP.Panic.Relief.Anchor": "Your anchor, once per case",
"RINGBRP.Panic.Gained": "{name} — panic {from} → {to}",
"RINGBRP.Panic.Eased": "{name} — panic {from} → {to}",
"RINGBRP.Panic.Breaks": "BREAKS — freeze, flee, or fixate. Choose, take it, come back at 3.",
"RINGBRP.Panic.NoChange": "No change.",
"RINGBRP.Flavour.Panicking": "panicking ({mod}%)",
"RINGBRP.Chat.ToEverything": "to everything"
}
-1
View File
@@ -6,7 +6,6 @@
"scripts": {
"build": "node tools/build-packs.mjs && node tools/update-readme.mjs",
"icons": "node tools/make-icons.mjs",
"dice": "node tools/make-dice-textures.mjs",
"check": "node tools/check-rules.mjs && node tools/check-kits.mjs && node tools/check-lang.mjs && node tools/check-templates.mjs && node tools/check-behaviour.mjs",
"test": "npm run check",
"readme": "node tools/update-readme.mjs"
Binary file not shown.
Binary file not shown.
Binary file not shown.
+1 -1
View File
@@ -1 +1 @@
MANIFEST-000004
MANIFEST-000002
+1 -5
View File
@@ -1,5 +1 @@
2026/08/12-20:33:19.258824 175abb000 Recovering log #3
2026/08/12-20:33:19.258964 175abb000 Level-0 table #5: started
2026/08/12-20:33:19.259113 175abb000 Level-0 table #5: 4591 bytes OK
2026/08/12-20:33:19.259390 175abb000 Delete type=0 #3
2026/08/12-20:33:19.259432 175abb000 Delete type=3 #2
2026/08/12-22:54:48.028748 16ea07000 Delete type=3 #1
-1
View File
@@ -1 +0,0 @@
2026/08/12-20:33:03.500947 17385b000 Delete type=3 #1
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
+1 -1
View File
@@ -1 +1 @@
MANIFEST-000004
MANIFEST-000002
+1 -5
View File
@@ -1,5 +1 @@
2026/08/12-20:33:19.281748 1772df000 Recovering log #3
2026/08/12-20:33:19.282130 1772df000 Level-0 table #5: started
2026/08/12-20:33:19.282266 1772df000 Level-0 table #5: 4129 bytes OK
2026/08/12-20:33:19.282510 1772df000 Delete type=0 #3
2026/08/12-20:33:19.282542 1772df000 Delete type=3 #2
2026/08/12-22:54:48.107122 16f213000 Delete type=3 #1
-1
View File
@@ -1 +0,0 @@
2026/08/12-20:33:03.577064 17385b000 Delete type=3 #1
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
+1 -1
View File
@@ -1 +1 @@
MANIFEST-000004
MANIFEST-000002
+1 -5
View File
@@ -1,5 +1 @@
2026/08/12-20:33:19.260549 1772df000 Recovering log #3
2026/08/12-20:33:19.260715 1772df000 Level-0 table #5: started
2026/08/12-20:33:19.261020 1772df000 Level-0 table #5: 31614 bytes OK
2026/08/12-20:33:19.261257 1772df000 Delete type=0 #3
2026/08/12-20:33:19.261283 1772df000 Delete type=3 #2
2026/08/12-22:54:48.030538 16e1fb000 Delete type=3 #1
-1
View File
@@ -1 +0,0 @@
2026/08/12-20:33:03.503203 174067000 Delete type=3 #1
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
+1 -1
View File
@@ -1 +1 @@
MANIFEST-000004
MANIFEST-000002
+1 -5
View File
@@ -1,5 +1 @@
2026/08/12-20:33:19.273026 175abb000 Recovering log #3
2026/08/12-20:33:19.273575 175abb000 Level-0 table #5: started
2026/08/12-20:33:19.273963 175abb000 Level-0 table #5: 45532 bytes OK
2026/08/12-20:33:19.274265 175abb000 Delete type=0 #3
2026/08/12-20:33:19.274316 175abb000 Delete type=3 #2
2026/08/12-22:54:48.091041 16ea07000 Delete type=3 #1
-1
View File
@@ -1 +0,0 @@
2026/08/12-20:33:03.557918 172843000 Delete type=3 #1
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
+1 -1
View File
@@ -1 +1 @@
MANIFEST-000004
MANIFEST-000002
+1 -5
View File
@@ -1,5 +1 @@
2026/08/12-20:33:19.245248 1762c7000 Recovering log #3
2026/08/12-20:33:19.246727 1762c7000 Level-0 table #5: started
2026/08/12-20:33:19.248205 1762c7000 Level-0 table #5: 225945 bytes OK
2026/08/12-20:33:19.248498 1762c7000 Delete type=0 #3
2026/08/12-20:33:19.248546 1762c7000 Delete type=3 #2
2026/08/12-22:54:48.072716 16f213000 Delete type=3 #1
-1
View File
@@ -1 +0,0 @@
2026/08/12-20:33:03.540045 172843000 Delete type=3 #1
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
+1 -1
View File
@@ -1 +1 @@
MANIFEST-000004
MANIFEST-000002
+1 -5
View File
@@ -1,5 +1 @@
2026/08/12-20:33:19.255310 175abb000 Recovering log #3
2026/08/12-20:33:19.255554 175abb000 Level-0 table #5: started
2026/08/12-20:33:19.255695 175abb000 Level-0 table #5: 3295 bytes OK
2026/08/12-20:33:19.255978 175abb000 Delete type=0 #3
2026/08/12-20:33:19.256022 175abb000 Delete type=3 #2
2026/08/12-22:54:48.101253 16ea07000 Delete type=3 #1
-1
View File
@@ -1 +0,0 @@
2026/08/12-20:33:03.569801 17304f000 Delete type=3 #1
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
+1 -1
View File
@@ -1 +1 @@
MANIFEST-000004
MANIFEST-000002
+1 -5
View File
@@ -1,5 +1 @@
2026/08/12-20:33:19.232393 175abb000 Recovering log #3
2026/08/12-20:33:19.235807 175abb000 Level-0 table #5: started
2026/08/12-20:33:19.239193 175abb000 Level-0 table #5: 545293 bytes OK
2026/08/12-20:33:19.239934 175abb000 Delete type=0 #3
2026/08/12-20:33:19.240034 175abb000 Delete type=3 #2
2026/08/12-22:54:48.053348 16f213000 Delete type=3 #1
-1
View File
@@ -1 +0,0 @@
2026/08/12-20:33:03.524869 17385b000 Delete type=3 #1
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
+1 -1
View File
@@ -1 +1 @@
MANIFEST-000004
MANIFEST-000002
+1 -5
View File
@@ -1,5 +1 @@
2026/08/12-20:33:19.263420 1762c7000 Recovering log #3
2026/08/12-20:33:19.263582 1762c7000 Level-0 table #5: started
2026/08/12-20:33:19.263817 1762c7000 Level-0 table #5: 21613 bytes OK
2026/08/12-20:33:19.264044 1762c7000 Delete type=0 #3
2026/08/12-20:33:19.264079 1762c7000 Delete type=3 #2
2026/08/12-22:54:48.098549 16ea07000 Delete type=3 #1
-1
View File
@@ -1 +0,0 @@
2026/08/12-20:33:03.565946 17304f000 Delete type=3 #1
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
+1 -1
View File
@@ -1 +1 @@
MANIFEST-000004
MANIFEST-000002
+1 -5
View File
@@ -1,5 +1 @@
2026/08/12-20:33:19.275275 175abb000 Recovering log #3
2026/08/12-20:33:19.275814 175abb000 Level-0 table #5: started
2026/08/12-20:33:19.276182 175abb000 Level-0 table #5: 43953 bytes OK
2026/08/12-20:33:19.276489 175abb000 Delete type=0 #3
2026/08/12-20:33:19.276529 175abb000 Delete type=3 #2
2026/08/12-22:54:48.095111 16f213000 Delete type=3 #1
-1
View File
@@ -1 +0,0 @@
2026/08/12-20:33:03.562330 17385b000 Delete type=3 #1
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
+1 -1
View File
@@ -1 +1 @@
MANIFEST-000004
MANIFEST-000002
+1 -5
View File
@@ -1,5 +1 @@
2026/08/12-20:33:19.264705 176ad3000 Recovering log #3
2026/08/12-20:33:19.265215 176ad3000 Level-0 table #5: started
2026/08/12-20:33:19.265531 176ad3000 Level-0 table #5: 33484 bytes OK
2026/08/12-20:33:19.265770 176ad3000 Delete type=0 #3
2026/08/12-20:33:19.265802 176ad3000 Delete type=3 #2
2026/08/12-22:54:48.104875 16fa1f000 Delete type=3 #1
-1
View File
@@ -1 +0,0 @@
2026/08/12-20:33:03.575038 17304f000 Delete type=3 #1
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
+1 -1
View File
@@ -1 +1 @@
MANIFEST-000004
MANIFEST-000002
+1 -5
View File
@@ -1,5 +1 @@
2026/08/12-20:33:19.251838 175abb000 Recovering log #3
2026/08/12-20:33:19.252367 175abb000 Level-0 table #5: started
2026/08/12-20:33:19.252611 175abb000 Level-0 table #5: 7590 bytes OK
2026/08/12-20:33:19.252941 175abb000 Delete type=0 #3
2026/08/12-20:33:19.252982 175abb000 Delete type=3 #2
2026/08/12-22:54:48.022621 16ea07000 Delete type=3 #1
-1
View File
@@ -1 +0,0 @@
2026/08/12-20:33:03.494044 17304f000 Delete type=3 #1
Binary file not shown.
Binary file not shown.
Binary file not shown.

Some files were not shown because too many files have changed in this diff Show More