Repository navigation
feat(Customizable-Roll-Listener): Rewrite for Beacon sheets - #2363
Open
steverobertsuk wants to merge 35 commits into
Open
steverobertsuk wants to merge 35 commits into
steverobertsuk wants to merge 35 commits into
Conversation
Version 2 is built from ES modules under src/ in the same way as Hexploration and TokenController: Rollup bundles them into CRL.js and the 2.0.0/ snapshot, Prettier formats the output, and the scripts handle version bumps and locale synchronisation. Signed-off-by: Steve Roberts <steve@shadowcomputers.co.uk>
…n chat Version 1.1 only matched some chat output. Its "not parseable" errors were swallowed crashes on rolls with modifiers or text without "##"; its text was used as a raw regular expression; "##" only found the first ten inline rolls; dropped dice counted as crits; and Beacon sheets such as D&D 2024, which post HTML roll cards with their dice in msg.rolls, were never matched at all. The rewrite analyses every message (roll templates, plain chat, /roll results, rollable tables and Beacon advancedroll cards) and matches listeners on templates, message types, plain or regex text, speakers, players, crit/fumble/success/fail, totals and natural dice. Commands support placeholders, can be sent as CRL or the roller, and have cooldowns, ordering, stop-after and loop protection. An inspector explains what a message contains and why each listener did or did not fire. Commands stay as abilities on the existing store character, and rules are mirrored into each ability's description so listeners survive a game copy. Version 1 state, listeners and \create-style commands are upgraded automatically. Chat text encodes Roll20 syntax, because sendChat drops a whole message it cannot resolve. Menus, a Help handout and a Command Deck are translatable; locales other than en-US fall back to English until they are generated. Credits Scott C. as the original author and The Aaron for the 1.1 fixes. Signed-off-by: Steve Roberts <steve@shadowcomputers.co.uk>
…nd-to-end tests The suites cover message analysis and matching (crits, fumbles, dropped dice, targets, text, tables, filters), command and version 1 parsing, placeholders and translation keys, and D&D 2024 checks, attacks, damage and advantage built from cards captured in a live Jumpgate game. The end-to-end suite drives the built bundle in a stubbed Roll20 sandbox, including the version 1 upgrade, game copies and loop protection. Signed-off-by: Steve Roberts <steve@shadowcomputers.co.uk>
Adds a README for GMs, a changelog of what version 2 fixes and adds, a developer guide to the data model and matching, a file map, and a testing guide with the manual checklist and the results from the live D&D 2024 test game. Signed-off-by: Steve Roberts <steve@shadowcomputers.co.uk>
Adds the bundled CRL.js for the One-Click library and its identical 2.0.0/ snapshot. Signed-off-by: Steve Roberts <steve@shadowcomputers.co.uk>
…ames A user reading the README could not find which roll template names to use with --templates. The README and the Help handout now explain what a template name is and how to find one (the inspector, a sheet's macro or the sheet's source), list the templates of the built-in default, D&D 5E by Roll20 (2014) and D&D 2024 sheets, and link to Roll20's roll template articles. The templates prompt and option description point to them. Signed-off-by: Steve Roberts <steve@shadowcomputers.co.uk>
Each version heading now shows its release date, taken from the repository history, in the same style as the other mods' changelogs. Signed-off-by: Steve Roberts <steve@shadowcomputers.co.uk>
…s a table The supported languages were one long comma-separated paragraph, which was hard to scan. They are now a table with the code to use in !crl config language, the language's English name and its native name. Signed-off-by: Steve Roberts <steve@shadowcomputers.co.uk>
…nguages table Each language row now starts with its flag, taken from the locale metadata, so a language is quicker to spot. The flag's name is shown on hover. Signed-off-by: Steve Roberts <steve@shadowcomputers.co.uk>
…images Roll20 does not draw flag emoji in handouts (Windows shows them as letters), so the flags were missing. Each flag is now its Twemoji SVG image, as ConditionTracker does, with the flag's name as alt text and title. Signed-off-by: Steve Roberts <steve@shadowcomputers.co.uk>
Roll20 whispers only the first line of a message and posts every later line publicly. A listener card whose commands span several lines, and the inspector's extra message data (pretty-printed JSON), therefore leaked to the players; found while testing a real version 1 game with MetaScriptToolbox installed. Code blocks now use <br> for line breaks, and every card is kept on one line before it is sent. Signed-off-by: Steve Roberts <steve@shadowcomputers.co.uk>
Tested in a Legacy game holding 47 real version 1 listeners: the upgrade kept every listener's templates, text, roll checks and commands, and the D&D 5E 2014 sheet checks passed. The sheet's NPC attacks use the npcfullatk template, which Roll20's help article does not list, so it is added to the template tables. The README and Help handout now explain that the sheet rolls advantage and disadvantage as two separate d20s, both of which CRL checks. Signed-off-by: Steve Roberts <steve@shadowcomputers.co.uk>
Every locale now holds all 280 strings. Nine files had only their
handout translated, or none of it, and the rest were machine
translations with literal errors ("die" as dying, "roll" as bread
rolls, "speaker" as a loudspeaker) and with commands, options and
typed values translated, so pasted examples would not work. Each file
was translated or reviewed in full, with !crl commands, --options,
placeholders and values such as crit and on kept in English, and the
missing languages-table headings and 2014 sheet advantage note added.
The README, changelog and developer notes describe the translations.
Signed-off-by: Steve Roberts <steve@shadowcomputers.co.uk>
Commands that another Mod sends with sendChat, such as a ScriptCards --@ call, reach the Mod from the player "API". playerIsGM() is false for that player, so every such command was refused with "Only a GM". Messages from the API player are now accepted, and their replies are whispered to the GM. Signed-off-by: Steve Roberts <steve@shadowcomputers.co.uk>
Bumps the version to 2.0.1 for accepting commands sent by other Mods. It goes into the same pull request as 2.0.0, so 2.0.0 joins the previous versions and its snapshot folder is left as it was. The rebuilt script is copied to the new 2.0.1 folder, and the changelog, README, testing checklist, developer notes and the startup test carry the new version. The testing checklist gains a check for a command sent by another Mod. Signed-off-by: Steve Roberts <steve@shadowcomputers.co.uk>
…Mods can send commands The README gained this in the 2.0.1 fix, but the handout still said every command is GM only. The sentence has its own key so the existing translations of the intro stay as they are. Signed-off-by: Steve Roberts <steve@shadowcomputers.co.uk>
… sentence into 23 languages Only the new commands.mods sentence is added. sync-locales also re-sent strings that are meant to stay as they are, such as CRL, the example commands and the seconds unit, so those changes were dropped. The machine translations were checked: Spanish, Ukrainian and Chinese made the GM a director or general manager, Hebrew used the word for bicycles, and Japanese, Korean and Turkish dropped the s from ScriptCards; these were corrected by hand. Note the handout change in the changelog. Signed-off-by: Steve Roberts <steve@shadowcomputers.co.uk>
…t's other-Mods sentence Signed-off-by: Steve Roberts <steve@shadowcomputers.co.uk>
… locales to sync-locales sync-locales used to re-send every string still identical to English on each run. Many are meant to stay English, so Hex (V) and Hex (H) turned into hexadecimal and CRL into a certificate revocation list. It also needed hand-editing all 23 locale files before a reworded English string would be translated again, and sent one request every 2 seconds. - Only strings missing from a locale are translated by default. --untranslated brings back the old behaviour. - --keys a.b,c.d translates the named keys again; unknown keys are an error. - --dry-run lists what would be translated, per locale and key. - --concurrency=N translates N locales at once (default 4); 429s and server errors are retried with back-off. - Placeholder-only strings are not sent, a translation whose placeholders did not survive keeps the English, mask tokens are matched in any case, and files are formatted with the Mod's Prettier settings so unchanged lines stay unchanged. - The estimate before confirming counts the strings to send. The script is now the same file in every Mod. DEVELOPERS.md lists the options. Signed-off-by: Steve Roberts <steve@shadowcomputers.co.uk>
…ields Pak asked on Discord for listeners that trigger only on, for example, D&D 2024 attack cards for swords. --text cannot do this reliably: it also searches the raw content, which for a Beacon card is its HTML, and a weapon name can appear anywhere in the card. - Add --fields (alias --field): conditions separated by &&, each a field name, an operator and a value. = and != compare the whole value, ~ and !~ look for text in it (a regular expression with --regex on), and case is ignored. A missing field counts as empty. - Read fields with their inline rolls replaced by the results. - Check fields after players and before text; the inspector reports "template field does not match". - Show the conditions on the listener card with a Change button, and list --fields in the help, hints and Help handout. - Whisper an error for a condition without an operator or with a bad regular expression, changing nothing. - Test Beacon and roll template fields, and editing, triggering and clearing them by command. The startup test expects version 2.1.0. Signed-off-by: Steve Roberts <steve@shadowcomputers.co.uk>
…23 languages Adds the prompt, card label, inspector reason, errors, hint, Help handout option and matching note for --fields to every locale, and lists --fields in each locale's options. Field names, operators and examples stay literal. Signed-off-by: Steve Roberts <steve@shadowcomputers.co.uk>
- README: a Template Fields section and a row in the filter table, explaining that --text also searches a Beacon card's HTML. - CHANGELOG: a 2.1.0 entry. - DEVELOPERS: the fields rule and where it sits in the matching order. - TESTING: a live check for a 2024 sword attack. - Version 2.1.0 in the README, developer notes and testing checklist. Signed-off-by: Steve Roberts <steve@shadowcomputers.co.uk>
Bumps the version to 2.1.0 for the template field filter. It goes into the same pull request as 2.0.0, so 2.0.1 joins the previous versions and its snapshot folder is left as it was. The rebuilt script is copied to the new 2.1.0 folder, and the One-Click description lists template fields among the filters. Signed-off-by: Steve Roberts <steve@shadowcomputers.co.uk>
…ntent Pak asked on Discord what Success and Failure look for, and how data-rollSubcategory="Attack" could match when the inspector's text does not show it. - README: a Success and Failure section saying that they need a target written into the roll (1d20>15, dice pools, roll-under), so D&D sheet attacks, saves and checks never trigger them; use --total for an AC or DC. An Inspector section saying that --text also searches the raw content, which for a Beacon card is its HTML. - Help handout (English): the same points in Roll Checks, the --results option, the Text filter and The Inspector. - CHANGELOG: a Changed entry under 2.1.0. Signed-off-by: Steve Roberts <steve@shadowcomputers.co.uk>
… raw content texts Brings the Help handout's Roll Checks, --results option, Text filter and Inspector texts in the 23 other languages into line with English, including the new point about D&D rolls. Roll expressions, AC and DC and the typed values stay literal. Signed-off-by: Steve Roberts <steve@shadowcomputers.co.uk>
…p handout Rebuilds CRL.js and the 2.1.0 snapshot, which stay identical. Signed-off-by: Steve Roberts <steve@shadowcomputers.co.uk>
The --fields parser split on "s*&&s*" instead of "\s*&&\s*", so it dropped the letters s next to &&: "title~Attacks&&mode=Normal" became "title~Attack" and "mode=Normal". Signed-off-by: Steve Roberts <steve@shadowcomputers.co.uk>
… the inspector --exclude (or --not) lists text that stops a listener triggering, such as --text sword --exclude dagger. It is searched like --text, in the raw content and the readable text, and the inspector reports "excluded text found". The listener card shows it as Excluded text. The inspector now shows embedded data: images in Raw content as just their type, so Beacon cards' weapon icons no longer fill the 3,000 characters it shows. Listeners still search the full message. Signed-off-by: Steve Roberts <steve@shadowcomputers.co.uk>
…tor texts Signed-off-by: Steve Roberts <steve@shadowcomputers.co.uk>
…ages Signed-off-by: Steve Roberts <steve@shadowcomputers.co.uk>
Signed-off-by: Steve Roberts <steve@shadowcomputers.co.uk>
… icon on its handouts in the Journal The Help and Command Deck handouts now use the plain Customizable Roll Listener icon from Roll20's file store as their journal icon (the handout avatar). The icon is set when a handout is created and added to handouts from earlier versions, so existing games get it too. Roll20 stores the avatar as max.webp with a number, so a handout counts as having the icon when its avatar contains the image's path. Only the webp files exist (thumb.png is a 404), so the URL uses thumb.webp. A test covers new handouts and handouts made before. Signed-off-by: Steve Roberts <steve@shadowcomputers.co.uk>
…rnal icon The root script and the 2.1.0 snapshot are rebuilt without a version bump and remain identical. Signed-off-by: Steve Roberts <steve@shadowcomputers.co.uk>
…nger fills the handout Roll20 always stores a handout's journal icon as the full-size file, whatever size the Mod asks for, and shows that file at its natural size at the top of an open handout. The Customizable-Roll-Listener icon was a 1024 pixel upload, so it filled the handout above the text. The icon now points at a 100 pixel copy of the same artwork. Handouts from earlier builds are matched on the image path, so they change to the small icon the next time the Mod starts. Signed-off-by: Steve Roberts <steve@shadowcomputers.co.uk>
…ll journal icon The built script and its 2.1.0 copy carry the new icon path. The version number is unchanged. Signed-off-by: Steve Roberts <steve@shadowcomputers.co.uk>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
[2.1.0] – 2026-11-01
Added
--fieldsfilters on roll template fields, such as--fields subcategory=Attack && title~swordto trigger only on D&D 2024 attack cards for swords.=and!=compare the whole value,~and!~look for text in it (a regular expression with--regex on), and case is ignored. The inspector lists each message's fields and says when a field does not match. Asked for by Pak on Discord.--excludestops a listener when any of its pieces of text appears, such as--text sword --exclude dagger. It is searched like--text, and the inspector says when excluded text was found. Suggested by Pak on Discord.Changed
successandfailneed a target written into the roll, such as1d20>15, so they never trigger on D&D sheet attacks, saves and checks (use--totalfor an AC or DC), and that--textalso searches the raw content the inspector shows, which for a Beacon card is its HTML.data-rollSubcategory.[2.0.1] – 2026-11-01
Fixed
--@crl|call, are no longer refused with "Only a GM can use Customizable Roll Listener". Roll20 sends them from the player "API", which is not a GM. Their replies are whispered to the GM.Changed
[2.0.0] – 2026-10-29
A full rewrite by MidNiteShadow7 of Scott C.'s Customizable Roll Listener, which was reported as working on some chat output but not all, especially since Beacon sheets arrived, and is no longer supported.
Fixed
roll=criticaland so on) no longer fail with "CRL ERROR ||| Ability: … was not parseable". Version 1 crashed on any roll containing a modifier, a group or a comment, and on text without##, then skipped the listener and logged the error on every chat message.##finds inline rolls at any position. Version 1 only found the first ten ($[[0]]to$[[9]]), so long roll templates were missed, and only converted the first##in each piece of text.(,+,?,.and similar characters silently matched something else.kh/kl) and rerolled dice no longer count as crits or fumbles./rollresults (rollresultandgmrollresultmessages) are read.advancedrollroll cards with no inline rolls or template name, so CRL reads the template, character, title and each roll from the card.!crlcommand are kept in the listener's commands instead of being rolled once and lost.@{…},%{…},[[…]]and?{…}encoded, because Roll20 drops a mod's whole message when it cannot resolve them.\\configdeletes a listener.Added
!crl <command> --option valuesyntax. Listeners can be named by name or ID.>=15,<=2,19-20), and a choice of which dice to check.${who},${character},${player},${template},${total},${natural},${result},${expression},${table},${listener}and${field:name}.!crl inspect: explains the next chat message (type, template and fields, every roll with its dice, the text listeners search) and why each listener did or did not trigger. Useful for Beacon sheets such as D&D 2024.!crl test: runs a listener's commands with sample values.CRL.analyse,CRL.matches,CRL.onMatch.Changed
failmeans a target roll with no successes.\\create,\\edit,\\delete,\\configand\\setcommands still work.src/, bundled with Rollup and tested with the Node test runner.Signed-off-by: Steve Roberts steve@shadowcomputers.co.uk