From ab619f4b73fd64a0f1ce211dc4a46c26b8f34fc6 Mon Sep 17 00:00:00 2001 From: slaguru666 <111923774+slaguru666@users.noreply.github.com> Date: Wed, 12 Aug 2026 22:45:52 +0100 Subject: [PATCH] Remove the dice textures and the whole Dice So Nice path MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 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 --- README.md | 14 +-- dice/custodians-agency.png | Bin 44215 -> 0 bytes dice/custodians-displaced.png | Bin 15068 -> 0 bytes dice/custodians-drift.png | Bin 4040 -> 0 bytes dice/custodians-registry.png | Bin 1535 -> 0 bytes dice/texture-shadowsquares.png | Bin 785 -> 0 bytes dice/texture-starfield.png | Bin 970 -> 0 bytes dice/texture-threshold.png | Bin 826 -> 0 bytes docs/DEPLOY.md | 3 +- package.json | 1 - packs/armour/LOG | 10 +- packs/armour/LOG.old | 2 +- packs/expedition/LOG | 10 +- packs/expedition/LOG.old | 2 +- packs/gear/LOG | 10 +- packs/gear/LOG.old | 2 +- packs/lastadmission/LOG | 10 +- packs/lastadmission/LOG.old | 2 +- packs/npcs/LOG | 10 +- packs/npcs/LOG.old | 2 +- packs/powers/LOG | 10 +- packs/powers/LOG.old | 2 +- packs/pregens/LOG | 10 +- packs/pregens/LOG.old | 2 +- packs/primer/LOG | 10 +- packs/primer/LOG.old | 2 +- packs/prologue/LOG | 10 +- packs/prologue/LOG.old | 2 +- packs/rules/LOG | 10 +- packs/rules/LOG.old | 2 +- packs/skills/LOG | 10 +- packs/skills/LOG.old | 2 +- packs/slice/LOG | 10 +- packs/slice/LOG.old | 2 +- packs/starter/LOG | 10 +- packs/starter/LOG.old | 2 +- packs/tables/LOG | 10 +- packs/tables/LOG.old | 2 +- packs/talents/LOG | 10 +- packs/talents/LOG.old | 2 +- packs/vehicles/LOG | 10 +- packs/vehicles/LOG.old | 2 +- packs/weapons/LOG | 10 +- packs/weapons/LOG.old | 2 +- ringbrp.mjs | 117 ++-------------------- system.json | 2 +- tools/make-dice-textures.mjs | 176 --------------------------------- 47 files changed, 119 insertions(+), 398 deletions(-) delete mode 100644 dice/custodians-agency.png delete mode 100644 dice/custodians-displaced.png delete mode 100644 dice/custodians-drift.png delete mode 100644 dice/custodians-registry.png delete mode 100644 dice/texture-shadowsquares.png delete mode 100644 dice/texture-starfield.png delete mode 100644 dice/texture-threshold.png delete mode 100644 tools/make-dice-textures.mjs diff --git a/README.md b/README.md index a410f7c..b09ae2c 100644 --- a/README.md +++ b/README.md @@ -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 @@ -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,11 +176,11 @@ 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: ``` -check-rules: OK — 87 rules, 21 files scanned, 3 aliases + 41 constant sets checked, 275 formulas verified +check-rules: OK — 87 rules, 20 files scanned, 3 aliases + 41 constant sets checked, 275 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 diff --git a/dice/custodians-agency.png b/dice/custodians-agency.png deleted file mode 100644 index ede5423250a7c9fb71f6e91842b26f363047c499..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 44215 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 diff --git a/dice/texture-shadowsquares.png b/dice/texture-shadowsquares.png deleted file mode 100644 index ce0baf492185c40c15bb2db4d484f274aa2e5cbe..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 785 zcmeAS@N?(olHy`uVBq!ia0y~yU<5K58911L)MWvCLk0$>8=fwXAr*7pURLC53E*)! z$nU5SP+;>;|6_+}cDZWble0V2M13cl=l-^w7jZ3l&&lWer^1{1~! zY7CcH9A+_i2s30dDfluh;T#nl4UmCO42$1zpZdu?!^L~*0bo*R@O1TaS?83{1OWYy B$bA3+ diff --git a/dice/texture-starfield.png b/dice/texture-starfield.png deleted file mode 100644 index 01bff07df291523d2fecbc89c50bcaf0368c6c1d..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 970 zcmeAS@N?(olHy`uVBq!ia0y~yU<5K58911L)MWvCLk0%siJmTwAr*7p-rbvfC_us? z&||Kau);>smzRv4mL=G!xOob4Y3VfbZhLRZEWowS?*E?eoBsa!bV*)!=a=*9=e&6=+0Nim%n#CpY?4j`Yslq~at$WJ$i^b8fZGKV{4T`#;O`uD z%ee;+|9r!te3k{nRWOwxr^Z+|?eSy?|F=B9ICJgQ1xseae9*Av^o40RuNDjY%;H3M z6|$W>8Dx%~*X@4jaoU$*hbq+H$TlD=KFx7JaGKANqKr$^3>g!YpaHfeoISzcYV#va zflR$dp!Z*1pAMvr8Bsz4Y|IA^?O9=myA3Y+5U_|TVuR}(Yop?@=1FNx$S%N)BXqaQ z@gHal3H$K4(x&0=KZ|SAKghRdl|BAjF)t<9Ci5M{Q5Bly*2RypMN5R%dJ(sWwhWnS z*wO>CT`v7BPv*ly{7anDbO%J>WBBgNr6_MjaF86Z?Nf-iMOXam=Je%Q^=I=PNc_X| zNvUUxsXv2+3WmW*i51y#6Sh5I2y%}w5{y>zoL#_lWAeE_z?7l;LylpdIL3}Ia5kT7S?4)frHYW=OPchCJ!b+~%`4P$~D;{-K^ zODqnv7(9d-GMN;78J2K1m<$3zzGTbouWP??Xy4v%f7~gDXg6+q;C#kj=i8Hy<=g*! zp1_OdvGfbm<@VbrD;~dm{f*$giRjXUz~6%~DsVgLHZUE1<1y$R&~S9SDV$KqGyBSn SlRtrZg2B_(&t;ucLK6W00pTD3 diff --git a/docs/DEPLOY.md b/docs/DEPLOY.md index ca19129..f6baee7 100644 --- a/docs/DEPLOY.md +++ b/docs/DEPLOY.md @@ -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 diff --git a/package.json b/package.json index ff40461..6f7f6b9 100644 --- a/package.json +++ b/package.json @@ -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" diff --git a/packs/armour/LOG b/packs/armour/LOG index 9af6dcb..c7e3f23 100644 --- a/packs/armour/LOG +++ b/packs/armour/LOG @@ -1,5 +1,5 @@ -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:44:48.920895 172817000 Recovering log #3 +2026/08/12-22:44:48.921047 172817000 Level-0 table #5: started +2026/08/12-22:44:48.921223 172817000 Level-0 table #5: 4591 bytes OK +2026/08/12-22:44:48.921517 172817000 Delete type=0 #3 +2026/08/12-22:44:48.921554 172817000 Delete type=3 #2 diff --git a/packs/armour/LOG.old b/packs/armour/LOG.old index 33dcd7c..7792940 100644 --- a/packs/armour/LOG.old +++ b/packs/armour/LOG.old @@ -1 +1 @@ -2026/08/12-20:33:03.500947 17385b000 Delete type=3 #1 +2026/08/12-22:44:33.287733 16f5db000 Delete type=3 #1 diff --git a/packs/expedition/LOG b/packs/expedition/LOG index 3b80967..96ac7df 100644 --- a/packs/expedition/LOG +++ b/packs/expedition/LOG @@ -1,5 +1,5 @@ -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:44:48.946376 17382f000 Recovering log #3 +2026/08/12-22:44:48.946637 17382f000 Level-0 table #5: started +2026/08/12-22:44:48.946788 17382f000 Level-0 table #5: 4129 bytes OK +2026/08/12-22:44:48.947029 17382f000 Delete type=0 #3 +2026/08/12-22:44:48.947065 17382f000 Delete type=3 #2 diff --git a/packs/expedition/LOG.old b/packs/expedition/LOG.old index e88cdbf..7110bdd 100644 --- a/packs/expedition/LOG.old +++ b/packs/expedition/LOG.old @@ -1 +1 @@ -2026/08/12-20:33:03.577064 17385b000 Delete type=3 #1 +2026/08/12-22:44:33.362147 16edcf000 Delete type=3 #1 diff --git a/packs/gear/LOG b/packs/gear/LOG index 1557d48..7aade72 100644 --- a/packs/gear/LOG +++ b/packs/gear/LOG @@ -1,5 +1,5 @@ -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:44:48.922471 173023000 Recovering log #3 +2026/08/12-22:44:48.923346 173023000 Level-0 table #5: started +2026/08/12-22:44:48.923621 173023000 Level-0 table #5: 31614 bytes OK +2026/08/12-22:44:48.923809 173023000 Delete type=0 #3 +2026/08/12-22:44:48.923836 173023000 Delete type=3 #2 diff --git a/packs/gear/LOG.old b/packs/gear/LOG.old index af538de..44758ca 100644 --- a/packs/gear/LOG.old +++ b/packs/gear/LOG.old @@ -1 +1 @@ -2026/08/12-20:33:03.503203 174067000 Delete type=3 #1 +2026/08/12-22:44:33.290003 16f5db000 Delete type=3 #1 diff --git a/packs/lastadmission/LOG b/packs/lastadmission/LOG index 9f7f1cd..bc3d885 100644 --- a/packs/lastadmission/LOG +++ b/packs/lastadmission/LOG @@ -1,5 +1,5 @@ -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:44:48.936635 17200b000 Recovering log #3 +2026/08/12-22:44:48.937301 17200b000 Level-0 table #5: started +2026/08/12-22:44:48.937794 17200b000 Level-0 table #5: 45532 bytes OK +2026/08/12-22:44:48.938219 17200b000 Delete type=0 #3 +2026/08/12-22:44:48.938275 17200b000 Delete type=3 #2 diff --git a/packs/lastadmission/LOG.old b/packs/lastadmission/LOG.old index 18ce244..4a3b718 100644 --- a/packs/lastadmission/LOG.old +++ b/packs/lastadmission/LOG.old @@ -1 +1 @@ -2026/08/12-20:33:03.557918 172843000 Delete type=3 #1 +2026/08/12-22:44:33.345401 16e5c3000 Delete type=3 #1 diff --git a/packs/npcs/LOG b/packs/npcs/LOG index b765c35..b5e9426 100644 --- a/packs/npcs/LOG +++ b/packs/npcs/LOG @@ -1,5 +1,5 @@ -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:44:48.907196 173023000 Recovering log #3 +2026/08/12-22:44:48.908927 173023000 Level-0 table #5: started +2026/08/12-22:44:48.910392 173023000 Level-0 table #5: 225945 bytes OK +2026/08/12-22:44:48.910874 173023000 Delete type=0 #3 +2026/08/12-22:44:48.910934 173023000 Delete type=3 #2 diff --git a/packs/npcs/LOG.old b/packs/npcs/LOG.old index b1a810e..4af5cd8 100644 --- a/packs/npcs/LOG.old +++ b/packs/npcs/LOG.old @@ -1 +1 @@ -2026/08/12-20:33:03.540045 172843000 Delete type=3 #1 +2026/08/12-22:44:33.327015 16f5db000 Delete type=3 #1 diff --git a/packs/powers/LOG b/packs/powers/LOG index 4834b19..c9b9114 100644 --- a/packs/powers/LOG +++ b/packs/powers/LOG @@ -1,5 +1,5 @@ -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:44:48.917345 172817000 Recovering log #3 +2026/08/12-22:44:48.917660 172817000 Level-0 table #5: started +2026/08/12-22:44:48.917794 172817000 Level-0 table #5: 3295 bytes OK +2026/08/12-22:44:48.918046 172817000 Delete type=0 #3 +2026/08/12-22:44:48.918081 172817000 Delete type=3 #2 diff --git a/packs/powers/LOG.old b/packs/powers/LOG.old index 3d4a447..e06ec38 100644 --- a/packs/powers/LOG.old +++ b/packs/powers/LOG.old @@ -1 +1 @@ -2026/08/12-20:33:03.569801 17304f000 Delete type=3 #1 +2026/08/12-22:44:33.356982 16edcf000 Delete type=3 #1 diff --git a/packs/pregens/LOG b/packs/pregens/LOG index 9acd8c4..f879377 100644 --- a/packs/pregens/LOG +++ b/packs/pregens/LOG @@ -1,5 +1,5 @@ -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:44:48.896053 17200b000 Recovering log #3 +2026/08/12-22:44:48.898901 17200b000 Level-0 table #5: started +2026/08/12-22:44:48.902279 17200b000 Level-0 table #5: 545293 bytes OK +2026/08/12-22:44:48.902701 17200b000 Delete type=0 #3 +2026/08/12-22:44:48.902787 17200b000 Delete type=3 #2 diff --git a/packs/pregens/LOG.old b/packs/pregens/LOG.old index c3bcbd1..a390901 100644 --- a/packs/pregens/LOG.old +++ b/packs/pregens/LOG.old @@ -1 +1 @@ -2026/08/12-20:33:03.524869 17385b000 Delete type=3 #1 +2026/08/12-22:44:33.311753 16e5c3000 Delete type=3 #1 diff --git a/packs/primer/LOG b/packs/primer/LOG index eca5296..186daa8 100644 --- a/packs/primer/LOG +++ b/packs/primer/LOG @@ -1,5 +1,5 @@ -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:44:48.925841 17382f000 Recovering log #3 +2026/08/12-22:44:48.926073 17382f000 Level-0 table #5: started +2026/08/12-22:44:48.926304 17382f000 Level-0 table #5: 21613 bytes OK +2026/08/12-22:44:48.926557 17382f000 Delete type=0 #3 +2026/08/12-22:44:48.926598 17382f000 Delete type=3 #2 diff --git a/packs/primer/LOG.old b/packs/primer/LOG.old index c5553e8..72124e1 100644 --- a/packs/primer/LOG.old +++ b/packs/primer/LOG.old @@ -1 +1 @@ -2026/08/12-20:33:03.565946 17304f000 Delete type=3 #1 +2026/08/12-22:44:33.353318 16edcf000 Delete type=3 #1 diff --git a/packs/prologue/LOG b/packs/prologue/LOG index 60f77cb..44b46d1 100644 --- a/packs/prologue/LOG +++ b/packs/prologue/LOG @@ -1,5 +1,5 @@ -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:44:48.939398 17200b000 Recovering log #3 +2026/08/12-22:44:48.940505 17200b000 Level-0 table #5: started +2026/08/12-22:44:48.941454 17200b000 Level-0 table #5: 43953 bytes OK +2026/08/12-22:44:48.942198 17200b000 Delete type=0 #3 +2026/08/12-22:44:48.942249 17200b000 Delete type=3 #2 diff --git a/packs/prologue/LOG.old b/packs/prologue/LOG.old index c4507dc..200e76c 100644 --- a/packs/prologue/LOG.old +++ b/packs/prologue/LOG.old @@ -1 +1 @@ -2026/08/12-20:33:03.562330 17385b000 Delete type=3 #1 +2026/08/12-22:44:33.349699 16f5db000 Delete type=3 #1 diff --git a/packs/rules/LOG b/packs/rules/LOG index 61c65b9..9f296bb 100644 --- a/packs/rules/LOG +++ b/packs/rules/LOG @@ -1,5 +1,5 @@ -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:44:48.927292 172817000 Recovering log #3 +2026/08/12-22:44:48.927647 172817000 Level-0 table #5: started +2026/08/12-22:44:48.928175 172817000 Level-0 table #5: 33484 bytes OK +2026/08/12-22:44:48.928522 172817000 Delete type=0 #3 +2026/08/12-22:44:48.928579 172817000 Delete type=3 #2 diff --git a/packs/rules/LOG.old b/packs/rules/LOG.old index 08142f9..c8e350f 100644 --- a/packs/rules/LOG.old +++ b/packs/rules/LOG.old @@ -1 +1 @@ -2026/08/12-20:33:03.575038 17304f000 Delete type=3 #1 +2026/08/12-22:44:33.360431 16e5c3000 Delete type=3 #1 diff --git a/packs/skills/LOG b/packs/skills/LOG index f7a5c0b..c52d119 100644 --- a/packs/skills/LOG +++ b/packs/skills/LOG @@ -1,5 +1,5 @@ -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:44:48.913614 172817000 Recovering log #3 +2026/08/12-22:44:48.914288 172817000 Level-0 table #5: started +2026/08/12-22:44:48.914458 172817000 Level-0 table #5: 7590 bytes OK +2026/08/12-22:44:48.914739 172817000 Delete type=0 #3 +2026/08/12-22:44:48.914773 172817000 Delete type=3 #2 diff --git a/packs/skills/LOG.old b/packs/skills/LOG.old index 48e55bb..6d0b24f 100644 --- a/packs/skills/LOG.old +++ b/packs/skills/LOG.old @@ -1 +1 @@ -2026/08/12-20:33:03.494044 17304f000 Delete type=3 #1 +2026/08/12-22:44:33.281949 16edcf000 Delete type=3 #1 diff --git a/packs/slice/LOG b/packs/slice/LOG index 7d6c2dc..7fbc5a6 100644 --- a/packs/slice/LOG +++ b/packs/slice/LOG @@ -1,5 +1,5 @@ -2026/08/12-20:33:19.277727 175abb000 Recovering log #3 -2026/08/12-20:33:19.278352 175abb000 Level-0 table #5: started -2026/08/12-20:33:19.278612 175abb000 Level-0 table #5: 16902 bytes OK -2026/08/12-20:33:19.278891 175abb000 Delete type=0 #3 -2026/08/12-20:33:19.278925 175abb000 Delete type=3 #2 +2026/08/12-22:44:48.943128 17200b000 Recovering log #3 +2026/08/12-22:44:48.943292 17200b000 Level-0 table #5: started +2026/08/12-22:44:48.943546 17200b000 Level-0 table #5: 16902 bytes OK +2026/08/12-22:44:48.943901 17200b000 Delete type=0 #3 +2026/08/12-22:44:48.943932 17200b000 Delete type=3 #2 diff --git a/packs/slice/LOG.old b/packs/slice/LOG.old index 323f0de..67e4d93 100644 --- a/packs/slice/LOG.old +++ b/packs/slice/LOG.old @@ -1 +1 @@ -2026/08/12-20:33:03.567928 17385b000 Delete type=3 #1 +2026/08/12-22:44:33.355279 16e5c3000 Delete type=3 #1 diff --git a/packs/starter/LOG b/packs/starter/LOG index 2e5eaaa..fd4c1cc 100644 --- a/packs/starter/LOG +++ b/packs/starter/LOG @@ -1,5 +1,5 @@ -2026/08/12-20:33:19.268400 175abb000 Recovering log #3 -2026/08/12-20:33:19.269480 175abb000 Level-0 table #5: started -2026/08/12-20:33:19.270081 175abb000 Level-0 table #5: 82299 bytes OK -2026/08/12-20:33:19.270432 175abb000 Delete type=0 #3 -2026/08/12-20:33:19.270471 175abb000 Delete type=3 #2 +2026/08/12-22:44:48.931234 17200b000 Recovering log #3 +2026/08/12-22:44:48.932452 17200b000 Level-0 table #5: started +2026/08/12-22:44:48.933139 17200b000 Level-0 table #5: 82299 bytes OK +2026/08/12-22:44:48.933493 17200b000 Delete type=0 #3 +2026/08/12-22:44:48.933538 17200b000 Delete type=3 #2 diff --git a/packs/starter/LOG.old b/packs/starter/LOG.old index c268fb3..c79d586 100644 --- a/packs/starter/LOG.old +++ b/packs/starter/LOG.old @@ -1 +1 @@ -2026/08/12-20:33:03.550640 174067000 Delete type=3 #1 +2026/08/12-22:44:33.337758 16f5db000 Delete type=3 #1 diff --git a/packs/tables/LOG b/packs/tables/LOG index 4f10513..937a7a9 100644 --- a/packs/tables/LOG +++ b/packs/tables/LOG @@ -1,5 +1,5 @@ -2026/08/12-20:33:19.280144 176ad3000 Recovering log #3 -2026/08/12-20:33:19.280500 176ad3000 Level-0 table #5: started -2026/08/12-20:33:19.280605 176ad3000 Level-0 table #5: 3739 bytes OK -2026/08/12-20:33:19.280818 176ad3000 Delete type=0 #3 -2026/08/12-20:33:19.280857 176ad3000 Delete type=3 #2 +2026/08/12-22:44:48.944808 172817000 Recovering log #3 +2026/08/12-22:44:48.944973 172817000 Level-0 table #5: started +2026/08/12-22:44:48.945086 172817000 Level-0 table #5: 3739 bytes OK +2026/08/12-22:44:48.945317 172817000 Delete type=0 #3 +2026/08/12-22:44:48.945349 172817000 Delete type=3 #2 diff --git a/packs/tables/LOG.old b/packs/tables/LOG.old index b4dc008..d0fb875 100644 --- a/packs/tables/LOG.old +++ b/packs/tables/LOG.old @@ -1 +1 @@ -2026/08/12-20:33:03.544720 17385b000 Delete type=3 #1 +2026/08/12-22:44:33.331276 16e5c3000 Delete type=3 #1 diff --git a/packs/talents/LOG b/packs/talents/LOG index 2302910..6204424 100644 --- a/packs/talents/LOG +++ b/packs/talents/LOG @@ -1,5 +1,5 @@ -2026/08/12-20:33:19.253872 1762c7000 Recovering log #3 -2026/08/12-20:33:19.254006 1762c7000 Level-0 table #5: started -2026/08/12-20:33:19.254155 1762c7000 Level-0 table #5: 5770 bytes OK -2026/08/12-20:33:19.254377 1762c7000 Delete type=0 #3 -2026/08/12-20:33:19.254415 1762c7000 Delete type=3 #2 +2026/08/12-22:44:48.915783 173023000 Recovering log #3 +2026/08/12-22:44:48.915922 173023000 Level-0 table #5: started +2026/08/12-22:44:48.916069 173023000 Level-0 table #5: 5770 bytes OK +2026/08/12-22:44:48.916313 173023000 Delete type=0 #3 +2026/08/12-22:44:48.916348 173023000 Delete type=3 #2 diff --git a/packs/talents/LOG.old b/packs/talents/LOG.old index 703cc08..f7759d7 100644 --- a/packs/talents/LOG.old +++ b/packs/talents/LOG.old @@ -1 +1 @@ -2026/08/12-20:33:03.496700 174067000 Delete type=3 #1 +2026/08/12-22:44:33.284515 16e5c3000 Delete type=3 #1 diff --git a/packs/vehicles/LOG b/packs/vehicles/LOG index 85fd291..8450cde 100644 --- a/packs/vehicles/LOG +++ b/packs/vehicles/LOG @@ -1,5 +1,5 @@ -2026/08/12-20:33:19.262214 175abb000 Recovering log #3 -2026/08/12-20:33:19.262355 175abb000 Level-0 table #5: started -2026/08/12-20:33:19.262536 175abb000 Level-0 table #5: 6939 bytes OK -2026/08/12-20:33:19.262774 175abb000 Delete type=0 #3 -2026/08/12-20:33:19.262806 175abb000 Delete type=3 #2 +2026/08/12-22:44:48.924550 17200b000 Recovering log #3 +2026/08/12-22:44:48.924684 17200b000 Level-0 table #5: started +2026/08/12-22:44:48.924837 17200b000 Level-0 table #5: 6939 bytes OK +2026/08/12-22:44:48.925120 17200b000 Delete type=0 #3 +2026/08/12-22:44:48.925163 17200b000 Delete type=3 #2 diff --git a/packs/vehicles/LOG.old b/packs/vehicles/LOG.old index 09ad129..0e04bb5 100644 --- a/packs/vehicles/LOG.old +++ b/packs/vehicles/LOG.old @@ -1 +1 @@ -2026/08/12-20:33:03.505366 174067000 Delete type=3 #1 +2026/08/12-22:44:33.292038 16fde7000 Delete type=3 #1 diff --git a/packs/weapons/LOG b/packs/weapons/LOG index 9c3364a..95ecea5 100644 --- a/packs/weapons/LOG +++ b/packs/weapons/LOG @@ -1,5 +1,5 @@ -2026/08/12-20:33:19.257047 1772df000 Recovering log #3 -2026/08/12-20:33:19.257521 1772df000 Level-0 table #5: started -2026/08/12-20:33:19.257788 1772df000 Level-0 table #5: 14767 bytes OK -2026/08/12-20:33:19.258070 1772df000 Delete type=0 #3 -2026/08/12-20:33:19.258099 1772df000 Delete type=3 #2 +2026/08/12-22:44:48.918709 173023000 Recovering log #3 +2026/08/12-22:44:48.919008 173023000 Level-0 table #5: started +2026/08/12-22:44:48.919255 173023000 Level-0 table #5: 14767 bytes OK +2026/08/12-22:44:48.919627 173023000 Delete type=0 #3 +2026/08/12-22:44:48.919674 173023000 Delete type=3 #2 diff --git a/packs/weapons/LOG.old b/packs/weapons/LOG.old index 3e894da..8cdd7d9 100644 --- a/packs/weapons/LOG.old +++ b/packs/weapons/LOG.old @@ -1 +1 @@ -2026/08/12-20:33:03.498976 172843000 Delete type=3 #1 +2026/08/12-22:44:33.286188 16e5c3000 Delete type=3 #1 diff --git a/ringbrp.mjs b/ringbrp.mjs index aae9c32..50655aa 100644 --- a/ringbrp.mjs +++ b/ringbrp.mjs @@ -1075,7 +1075,6 @@ export async function skillRoll({ } ); - rbDressDice(roll, actor); await roll.toMessage({ speaker: speaker ?? ChatMessage.getSpeaker({ actor }), content, @@ -1108,7 +1107,7 @@ export async function majorWoundRoll({ actor, woundType = "blunt", monofilament console.error("Custodians | majorWoundRoll called without an actor"); return null; } - const r = rbDressDice(await new Roll("1d10").evaluate(), actor); + const r = await new Roll("1d10").evaluate(); let result = r.total; if (monofilament && result >= 4) result = 10; // spec §3.3 shift else if (blunt && result === 10) result = 9; @@ -1171,7 +1170,7 @@ export async function hitLocationRoll({ target, damage, mode = "ranged", } const sys = target.system; const speciesId = sys.speciesProfile || "baseline"; - const r = rbDressDice(await new Roll("1d20").evaluate(), target); + const r = await new Roll("1d20").evaluate(); const loc = locationFor(r.total, speciesId, mode); const live = (sys.locations ?? []).find(l => l.id === loc.id); const max = live?.max ?? locationMaxHp(sys.hp?.max ?? 1, loc.frac); @@ -1280,7 +1279,7 @@ export async function rollReaction(combatant) { : reactionPrintedFrom(rb.base, f.loadOverride); const mod = reactionModifier({ aim: f.aim ?? 0, edge: !!f.edge, drag: !!f.drag }); - const roll = rbDressDice(await new Roll(`1d${RINGBRP.reaction.die}`).evaluate(), actor); + const roll = await new Roll(`1d${RINGBRP.reaction.die}`).evaluate(); const raw = roll.total; const coherence = actor.system?.coherence?.value ?? 10; const shown = fluxDie(raw, coherence); @@ -2384,7 +2383,7 @@ export async function fall(actor, metres, { soft = false, controlled = false } = content: `

${game.i18n.format("RINGBRP.Fall.Short", { m: metres })}
` }); return { damage: 0 }; } - const roll = rbDressDice(await new Roll(plan.formula).evaluate(), actor); + const roll = await new Roll(plan.formula).evaluate(); await roll.toMessage({ speaker: ChatMessage.getSpeaker({ actor }), flavor: game.i18n.format("RINGBRP.Fall.Flavor", { m: metres, dice: plan.formula }) }); // armourApplied true: the fall ignores armour, and this is how we say so. @@ -2417,7 +2416,7 @@ export async function asphyxiate(actor, { held = 0, prepared = true } = {}) { export async function burn(actor, bandId = "clothes", { round = 1 } = {}) { if (!actor) return null; const band = fireBandFor(bandId); - const roll = rbDressDice(await new Roll(band.damage).evaluate(), actor); + const roll = await new Roll(band.damage).evaluate(); // Armour on the round you catch, and never after. A sealed suit is the exception // and the GM should say so by running it as a `spark` that never spreads. const armour = (band.armour && round === 1) ? (Number(actor.system.armourPoints) || 0) : 0; @@ -2436,7 +2435,7 @@ export async function burn(actor, bandId = "clothes", { round = 1 } = {}) { * armour is only ever half of one, at contact. */ export async function detonate({ formula = "4d6", radius = 6, targets = [] } = {}) { - const roll = rbDressDice(await new Roll(formula).evaluate(), null); + const roll = await new Roll(formula).evaluate(); await roll.toMessage({ flavor: game.i18n.format("RINGBRP.Blast.Flavor", { formula, r: radius }) }); const out = []; @@ -4292,7 +4291,7 @@ export async function rollCharacteristicsDialog({ actorName = "" } = {}) { const rollOne = async k => { const cell = el.querySelector(`tr[data-ch="${k}"] .rb-roll-value`); if (!cell || cell.dataset.value) return; // rolled is rolled - const roll = rbDressDice(await new Roll(CHARACTERISTIC_DICE[k]).evaluate()); + const roll = await new Roll(CHARACTERISTIC_DICE[k]).evaluate(); await roll.toMessage({ flavor: game.i18n.format("RINGBRP.Gen.RolledChar", { ch: game.i18n.localize(`RINGBRP.Char.${k}`) }) @@ -4538,105 +4537,6 @@ Hooks.on("preCreateItem", (item, data) => { * The colourset is chosen per roll from the roller's Coherence, so the dice * themselves report the one number the players are trying not to look at. * ============================================================ */ -const RB_DICE = { - textures: { - "custodians-registry": { name: "Registry", file: "custodians-registry.png" }, - "custodians-drift": { name: "Drift", file: "custodians-drift.png" }, - "custodians-displaced": { name: "Displaced", file: "custodians-displaced.png" }, - "custodians-agency": { name: "Agency", file: "custodians-agency.png" } - }, - // one colourset per Coherence band, plus the plain agency set - sets: [ - { name: "custodians-anchored", description: "Custodians — Anchored", - foreground: "#f2ea72", background: "#18268d", outline: "#0c125b", - edge: "#6674d8", texture: "custodians-registry", material: "metal" }, - { name: "custodians-loose", description: "Custodians — Loose", - foreground: "#f2ea72", background: "#16215f", outline: "#0c125b", - edge: "#6674d8", texture: "custodians-registry", material: "plastic" }, - { name: "custodians-adrift", description: "Custodians — Adrift", - foreground: "#ecefee", background: "#141e78", outline: "#0c125b", - edge: "#7a6cc8", texture: "custodians-drift", material: "plastic" }, - { name: "custodians-unmoored", description: "Custodians — Unmoored", - foreground: "#ff7a5c", background: "#101a6e", outline: "#08103f", - edge: "#ff7a5c", texture: "custodians-drift", material: "glass" }, - { name: "custodians-displaced", description: "Custodians — Displaced", - foreground: "#c9b6ff", background: "#0c0e3c", outline: "#000000", - edge: "#8a6cc0", texture: "custodians-displaced", material: "glass" }, - { name: "custodians-agency", description: "Custodians — Agency issue", - foreground: "#f2ea72", background: "#16215f", outline: "#0c125b", - edge: "#a8b2e3", texture: "custodians-agency", material: "metal" } - ] -}; - -/** Which set an agent rolls, from the band they are in. */ -export function diceSetFor(actor) { - const band = coherenceBand(actor?.system?.coherence?.value ?? 10); - return `custodians-${band?.id ?? "anchored"}`; -} - -/** Tag a Roll so Dice So Nice draws it in the roller's colours. */ -function rbDressDice(roll, actor) { - if (!roll?.dice?.length) return roll; - const colorset = diceSetFor(actor); - for (const d of roll.dice) { - d.options.colorset = colorset; - d.options.appearance = { ...(d.options.appearance ?? {}), colorset }; - } - return roll; -} - -/** - * The custom Dice So Nice skins are OFF. - * - * Registering them with "preferred" makes them the default for everybody in the world, - * which overrides whatever dice a player had already chosen for themselves — the system - * helping itself to a setting that belongs to the user. Turned off at the author's - * request; flip this to true to put them back, and everything below still works. - * - * The textures in dice/ and the generator behind `npm run dice` are left alone. Nothing - * reads them while this is false, and deleting work to turn a feature off is a poor - * trade. - */ -const RB_DICE_ENABLED = false; - -Hooks.once("diceSoNiceReady", async (dice3d) => { - if (!RB_DICE_ENABLED) return; - try { - dice3d.addSystem({ id: "custodians", name: "The Custodians" }, "preferred"); - - // addTexture returns a Promise and the colourset that references a texture must - // not be registered before it resolves, or the die renders untextured. - await Promise.all(Object.entries(RB_DICE.textures).map(([id, t]) => - dice3d.addTexture(id, { - name: t.name, composite: "source-over", - source: `systems/ringbrp/dice/${t.file}` - }))); - - for (const set of RB_DICE.sets) { - dice3d.addColorset({ - ...set, category: "The Custodians", - font: "Michroma", visibility: "visible" - }, set.name === "custodians-anchored" ? "default" : "showcase"); - } - - // The percentile pair is the game's core roll, so it is the one worth dressing. - dice3d.addDicePreset({ - type: "d100", system: "custodians", - labels: ["00", "10", "20", "30", "40", "50", "60", "70", "80", "90"] - }); - dice3d.addDicePreset({ type: "d10", system: "custodians", - labels: ["0", "1", "2", "3", "4", "5", "6", "7", "8", "9"] }); - for (const t of ["d4", "d6", "d8", "d12", "d20"]) { - const n = Number(t.slice(1)); - dice3d.addDicePreset({ type: t, system: "custodians", - labels: Array.from({ length: n }, (_, i) => String(i + 1)) }); - } - console.log("Custodians | dice registered with Dice So Nice"); - } catch (err) { - console.warn("Custodians | could not register dice", err); - } -}); - Hooks.on("renderItemDirectory", (app, html) => { const root = html instanceof HTMLElement ? html : html?.[0]; if (!root || !game.user.isGM || root.querySelector(".rb-genbar")) return; @@ -5890,7 +5790,6 @@ export async function rollWeaponDamage({ actor = null, weapon, level = "success" roll = await new Roll(usesDm ? formula + dm : formula).evaluate(); } - rbDressDice(roll, actor); const note = level === "critical" ? game.i18n.localize("RINGBRP.Chat.DamageCritical") : level === "special" ? game.i18n.localize("RINGBRP.Chat.DamageSpecial") : ""; @@ -6204,7 +6103,7 @@ Hooks.once("init", () => { usePower, grantPower, ARTS, powerCostFor, crossBack, generateMissionCase, missionDialog, salvageFrom, crossingArtPoolFor, crossingGrantsArt, crossingCostFor, returnCrossing, - rollWeaponDamage, diceSetFor, + rollWeaponDamage, restFor, endOfCase, gearBonusFor, hasTalent, talentAvailable, useTalent, requisition, armCleanScene, resetTalents, generateCharacter, generateNPC, generateDialog, installContent, grantFullSkillList, diff --git a/system.json b/system.json index 6dde8fd..eefd591 100644 --- a/system.json +++ b/system.json @@ -2,7 +2,7 @@ "id": "ringbrp", "title": "The Custodians", "description": "A Basic Roleplaying game of agents who cross the crossing to contain what should not be there — and who come back a little less from here each time.", - "version": "1.0.6", + "version": "1.0.7", "compatibility": { "minimum": 13, "verified": "14.364" diff --git a/tools/make-dice-textures.mjs b/tools/make-dice-textures.mjs deleted file mode 100644 index f01b368..0000000 --- a/tools/make-dice-textures.mjs +++ /dev/null @@ -1,176 +0,0 @@ -/** - * Dice textures for The Custodians, generated rather than drawn. - * - * Written as raw RGBA and encoded to PNG with node:zlib, so the repo gains no - * image dependency and the textures can be regenerated deterministically. Every - * pattern is tileable — Dice So Nice wraps these across a die face, and a seam - * shows up immediately on a d20. - * - * The set is the setting: the Custodians keep a filing system, and the game is - * about that filing system being wrong. So the dice carry a ruled grid, and the - * further an agent drifts from their own reality the more the grid stops agreeing - * with itself. - * - * node tools/make-dice-textures.mjs - */ -import { deflateSync } from "node:zlib"; -import { writeFile, mkdir } from "node:fs/promises"; - -const SIZE = 256; - -/* ---------- a minimal PNG encoder: RGBA, no interlace ---------- */ -function crc32(buf) { - let c, table = crc32.table; - if (!table) { - table = crc32.table = new Int32Array(256); - for (let n = 0; n < 256; n++) { - c = n; - for (let k = 0; k < 8; k++) c = c & 1 ? 0xedb88320 ^ (c >>> 1) : c >>> 1; - table[n] = c; - } - } - c = -1; - for (let i = 0; i < buf.length; i++) c = table[(c ^ buf[i]) & 0xff] ^ (c >>> 8); - return (c ^ -1) >>> 0; -} - -function chunk(type, data) { - const len = Buffer.alloc(4); len.writeUInt32BE(data.length); - const td = Buffer.concat([Buffer.from(type, "ascii"), data]); - const crc = Buffer.alloc(4); crc.writeUInt32BE(crc32(td)); - return Buffer.concat([len, td, crc]); -} - -function png(width, height, rgba) { - const ihdr = Buffer.alloc(13); - ihdr.writeUInt32BE(width, 0); ihdr.writeUInt32BE(height, 4); - ihdr[8] = 8; ihdr[9] = 6; ihdr[10] = 0; ihdr[11] = 0; ihdr[12] = 0; - // each scanline is prefixed with filter byte 0 - const raw = Buffer.alloc(height * (width * 4 + 1)); - for (let y = 0; y < height; y++) { - raw[y * (width * 4 + 1)] = 0; - rgba.copy(raw, y * (width * 4 + 1) + 1, y * width * 4, (y + 1) * width * 4); - } - return Buffer.concat([ - Buffer.from([0x89, 0x50, 0x4e, 0x47, 0x0d, 0x0a, 0x1a, 0x0a]), - chunk("IHDR", ihdr), - chunk("IDAT", deflateSync(raw, { level: 9 })), - chunk("IEND", Buffer.alloc(0)) - ]); -} - -/* ---------- deterministic noise, so a rebuild is byte-identical ---------- */ -let seed = 20260810; -const rnd = () => (seed = (seed * 1664525 + 1013904223) >>> 0) / 4294967296; - -const canvas = () => Buffer.alloc(SIZE * SIZE * 4); -const put = (buf, x, y, r, g, b, a = 255) => { - const i = ((y & (SIZE - 1)) * SIZE + (x & (SIZE - 1))) * 4; - buf[i] = r; buf[i + 1] = g; buf[i + 2] = b; buf[i + 3] = a; -}; -const fill = (buf, r, g, b, a = 255) => { - for (let i = 0; i < buf.length; i += 4) { buf[i] = r; buf[i + 1] = g; buf[i + 2] = b; buf[i + 3] = a; } -}; - -/* ============================================================ - 1. REGISTRY — the ruled grid of a filing system, kept true. - ============================================================ */ -function registry() { - const b = canvas(); - fill(b, 24, 38, 141); // ultramarine ground - for (let i = 0; i < SIZE; i++) { - for (const step of [32]) { - for (let k = 0; k < SIZE; k += step) { - put(b, i, k, 102, 116, 216); // --rb-line - put(b, k, i, 102, 116, 216); - } - } - for (let k = 16; k < SIZE; k += 32) { // fainter half-lines - put(b, i, k, 60, 78, 175); - put(b, k, i, 60, 78, 175); - } - } - // registry ticks at the intersections - for (let x = 0; x < SIZE; x += 64) for (let y = 0; y < SIZE; y += 64) { - for (let d = -3; d <= 3; d++) { put(b, x + d, y, 242, 234, 114); put(b, x, y + d, 242, 234, 114); } - } - return b; -} - -/* ============================================================ - 2. DRIFT — the same grid, no longer agreeing with itself. - Used for agents who have come loose from their own reality. - ============================================================ */ -function drift() { - const b = canvas(); - fill(b, 20, 30, 120); - const wobble = y => Math.round(6 * Math.sin(y / 14) + 3 * Math.sin(y / 5.5)); - for (let i = 0; i < SIZE; i++) { - for (let k = 0; k < SIZE; k += 32) { - put(b, i + wobble(i), k, 122, 108, 200); - put(b, k, i + wobble(i), 122, 108, 200); - } - } - for (let n = 0; n < 900; n++) { // grain where it has torn - const x = (rnd() * SIZE) | 0, y = (rnd() * SIZE) | 0; - put(b, x, y, 200, 120, 150, 255); - } - for (let x = 0; x < SIZE; x += 64) for (let y = 0; y < SIZE; y += 64) { - const ox = ((rnd() * 7) | 0) - 3, oy = ((rnd() * 7) | 0) - 3; - for (let d = -3; d <= 3; d++) { put(b, x + d + ox, y + oy, 255, 122, 92); put(b, x + ox, y + d + oy, 255, 122, 92); } - } - return b; -} - -/* ============================================================ - 3. DISPLACED — the grid is gone. What is left is not filed. - ============================================================ */ -function displaced() { - const b = canvas(); - fill(b, 12, 14, 60); - for (let n = 0; n < 5200; n++) { - const x = (rnd() * SIZE) | 0, y = (rnd() * SIZE) | 0; - const v = 40 + ((rnd() * 90) | 0); - put(b, x, y, v, v * 0.5, v * 0.7); - } - // a few surviving fragments of rule, going nowhere - for (let n = 0; n < 26; n++) { - const x = (rnd() * SIZE) | 0, y = (rnd() * SIZE) | 0, len = 6 + ((rnd() * 22) | 0); - const horiz = rnd() > 0.5; - for (let d = 0; d < len; d++) { - if (horiz) put(b, x + d, y, 150, 120, 190); else put(b, x, y + d, 150, 120, 190); - } - } - return b; -} - -/* ============================================================ - 4. AGENCY — brushed plate, for the agency-issue set. - ============================================================ */ -function agency() { - const b = canvas(); - for (let y = 0; y < SIZE; y++) { - for (let x = 0; x < SIZE; x++) { - const grain = 6 * Math.sin(x / 1.7 + y / 90) + (rnd() * 7 - 3.5); - const v = 30 + grain; - put(b, x, y, 22 + v, 33 + v, 95 + v); - } - } - for (let k = 0; k < SIZE; k += 48) for (let i = 0; i < SIZE; i++) put(b, i, k, 90, 104, 190); - return b; -} - -const TEXTURES = { - "custodians-registry": registry, - "custodians-drift": drift, - "custodians-displaced": displaced, - "custodians-agency": agency -}; - -await mkdir(new URL("../dice/", import.meta.url), { recursive: true }); -for (const [name, make] of Object.entries(TEXTURES)) { - const buf = png(SIZE, SIZE, make()); - await writeFile(new URL(`../dice/${name}.png`, import.meta.url), buf); - console.log(` ${name}.png ${SIZE}x${SIZE} ${(buf.length / 1024).toFixed(1)} kB`); -} -console.log("Custodians | dice textures written");