Skip to content

feat(Customizable-Roll-Listener): Rewrite for Beacon sheets - #2363

Open
steverobertsuk wants to merge 13 commits into
Roll20:masterfrom
steverobertsuk:sr/crl-v2-0-0
Open

steverobertsuk wants to merge 13 commits into
Roll20:masterfrom
steverobertsuk:sr/crl-v2-0-0

Conversation

@steverobertsuk

Copy link
Copy Markdown
Contributor

[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

  • Listeners with a roll result (roll=critical and 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.
  • A roll result without text now checks the rolls. Version 1 skipped the check, so such listeners triggered on every message using the template.
  • ## 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.
  • Text is plain text unless a listener asks for a regular expression. Version 1 used it as a regular expression, so text containing (, +, ?, . and similar characters silently matched something else.
  • Dropped dice (advantage, disadvantage, kh/kl) and rerolled dice no longer count as crits or fumbles.
  • Damage dice rolling their highest face are no longer crits when a d20 was rolled (configurable per listener).
  • A roll exactly on its target is a success and not also a failure.
  • Rollable table results can be matched as text.
  • /roll results (rollresult and gmrollresult messages) are read.
  • Rolls from Beacon sheets such as D&D 2024 are read: they arrive as advancedroll roll cards with no inline rolls or template name, so CRL reads the template, character, title and each roll from the card.
  • Inline rolls and roll templates typed into a !crl command are kept in the listener's commands instead of being rolled once and lost.
  • Multi-line commands are sent one message per line, as a macro would be, instead of as one message.
  • Malformed commands, missing listeners and commands from other mods no longer crash the Mod sandbox; problems are whispered to the GM with a hint.
  • CRL no longer reacts to its own menus, and a listener that keeps triggering itself is switched off instead of looping.
  • Listener names may contain commas, and any field can be cleared.
  • GM cards never spill into public chat. Roll20 whispers only the first line of a message and posts the rest publicly, so listener cards with multi-line commands and the inspector's extra message data used to leak; cards are now kept on one line.
  • Menus no longer go missing: text shown in chat has @{…}, %{…}, [[…]] and ?{…} encoded, because Roll20 drops a mod's whole message when it cannot resolve them.
  • The help no longer says that \\config deletes a listener.
  • Upgrading no longer wipes the mod's state when the schema changes.

Added

  • Chat menus with a card per listener and buttons to change every setting, and a Command Deck handout.
  • Help handout, and documentation (README, TESTING, DEVELOPERS, MOD_FILE_MAP), including how to find a sheet's roll template names, the templates of common sheets and links to Roll20's roll template articles.
  • New !crl <command> --option value syntax. Listeners can be named by name or ID.
  • Filters for message types, speakers / characters (including the character in the roll template) and players.
  • Roll checks for totals and natural die results (>=15, <=2, 19-20), and a choice of which dice to check.
  • Placeholders in commands: ${who}, ${character}, ${player}, ${template}, ${total}, ${natural}, ${result}, ${expression}, ${table}, ${listener} and ${field:name}.
  • Commands can be sent as CRL or as the character who rolled, per listener or as a setting.
  • Per-listener on/off switch, cooldown, ordering and "stop after this one".
  • !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.
  • Option to ignore chat sent by other mods.
  • Listener rules are mirrored into each ability's description, so listeners survive copying the game.
  • Public API for other mods: CRL.analyse, CRL.matches, CRL.onMatch.
  • Translations into 23 languages, chosen with a language setting.

Changed

  • Text matching ignores upper and lower case.
  • fail means a target roll with no successes.
  • Version 1 listeners are converted automatically; the version 1 \\create, \\edit, \\delete, \\config and \\set commands still work.
  • Source split into ES modules under src/, bundled with Rollup and tested with the Node test runner.

Signed-off-by: Steve Roberts steve@shadowcomputers.co.uk

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>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant