Skip to content

feat(Hexploration): Rewrite for Jumpgate and Legacy games - #2362

Open
steverobertsuk wants to merge 18 commits into
Roll20:masterfrom
steverobertsuk:sr/hexploration-v2-0-0
Open

steverobertsuk wants to merge 18 commits into
Roll20:masterfrom
steverobertsuk:sr/hexploration-v2-0-0

Conversation

@steverobertsuk

@steverobertsuk steverobertsuk commented Oct 30, 2026 •

Copy link
Copy Markdown
Contributor

2.0.0 - 2026-10-29

A full rewrite by MidNiteShadow7 of Ada Lindberg's Hexploration, which no longer worked in Jumpgate games.

Fixed

  • Works in Jumpgate: shapes drawn in Jumpgate (pathv2) can be filled, hexes are drawn as pathv2, and deleted Jumpgate hexes are forgotten.
  • Hexes line up with Jumpgate's regular hex grid. Legacy pages keep the exact version 1 spacing so existing maps stay aligned.
  • Hexes on the far right and bottom of the page are now covered by Inverse Fill.
  • A token near the edge of a hex is now placed in the correct hex.
  • Moving a token on the GM layer, or a monster controlled only by the GM, no longer reveals the map.
  • Tokens dragged quickly across the map no longer skip the hexes in between.
  • Bar, marker and other non-movement changes no longer trigger reveals.
  • No more crashes when a hex, its label or its icon was deleted by hand, when Name Hex is used on something that is not a hex, or when Fill is used with a token selected.
  • Location names are HTML-escaped in chat.
  • Players can no longer run the commands; they are GM only.
  • Large fills are drawn in batches so they do not trip the API's long-running script watchdog.

Added

  • Legacy support continues alongside Jumpgate; the engine is detected automatically.
  • Hex Layer setting: draw on the foreground layer (above tokens) or the token layer. Auto tries the foreground layer first and falls back to the token layer.
  • Reveal Along Path: the whole route a token is dragged along is revealed, including waypoints.
  • Large tokens reveal every hex they cover.
  • Tokens That Reveal setting: player tokens (default), character tokens (the version 1 behaviour) or all tokens.
  • Glimpse reveal mode: hexes within sight turn see-through and clear when entered.
  • Line of Sight can be switched off.
  • Mark Location and Unmark commands for hidden location tokens. The version 1 white-tower marker still works.
  • Announce Discoveries (everyone, GM only, off) and Ping Discoveries settings.
  • Hide Covered Tokens: player-visible names, bars and auras of tokens under covered hexes are switched off until they are uncovered, because Roll20 draws them above the hexes.
  • Reveal and Conceal for selected hexes, shapes and tokens; Reveal Page; Reset Page; Explore.
  • Undo for the last fill, inverse fill or conceal, including the shapes it used.
  • Per-page overrides for the reveal settings.
  • Rescan: rebuilds a page's hex list after a page or game is copied, re-linking name labels and location tokens.
  • Calibrate: lines the hex grid up with tokens snapped to hex centres.
  • Status card for the current page.
  • Help and Command Deck handouts in the Journal.
  • 24 languages.
  • Hexploration.revealAround(token) API for other Mods, and automatic support for tokens moved by TokenMod.
  • Hex Layer, Tokens That Reveal and Language on the One-Click settings page.

Changed

  • Primary command is now !hexploration with subcommands. The version 1 !hexploration_* commands still work.
  • No longer depends on PathMath, MatrixMath, Vector Math or HTML Builder.
  • New installs default to dark hexes with a sight distance of 1. Upgraded games keep their settings.
  • Version 1 state is migrated automatically; hexes whose paths no longer exist are forgotten on startup.
  • Rebuilt with Rollup and Prettier; source split into ES modules with unit and end-to-end tests.

2.0.1 - 2026-10-30

Fixed

  • Glimpse works in Jumpgate. Jumpgate ignores rgb() and rgba() colours on drawn shapes, so glimpsed hexes kept their solid fill. Fill, border and glimpse colours are now converted to #rrggbb or #rrggbbaa for Jumpgate hexes, so rgba() fill colours make see-through hexes too. Hexes left solid by 2.0.0 are repainted the next time a token sees them.
  • The colour swatches on the settings card show colours with transparency. Roll20 chat dropped #rrggbbaa colours and rgb() colours with a fourth value, leaving the swatch empty.

Changed

  • The README lists the colour formats the settings accept and explains how they are used in Jumpgate.
  • The help handout, settings descriptions and README explain how Hex Reveal Distance and Line of Sight work together, with a mountain range example. Neither makes a difference with the default Sight Distance of 1, and Hex Reveal Distance only applies to hexes filled after it is set.

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

Version 1 was concatenated by Grunt and linted by JSHint with globals copied
from ItsATrap. Version 2 uses the same pipeline as ConditionTracker and
CombatEncounterDirector: Rollup bundles ES modules from src/ into
Hexploration.js and a version snapshot folder, Prettier formats the output,
and scripts handle version bumps and locale syncing. Node's built-in test
runner replaces the lint step.

Signed-off-by: Steve Roberts <steve@shadowcomputers.co.uk>
Version 1 stopped working in Jumpgate: shapes drawn there are pathv2
objects, which it looked up as Legacy paths, and its hex sizes were measured
from the Legacy grid. It also relied on four unsupported helper mods.

The rewrite is self-contained and split into ES modules:
- Reads and draws both path and pathv2, choosing by the game engine.
- Uses exact hex geometry: Legacy keeps v1's spacing so old maps stay
  aligned; Jumpgate uses the client's regular 70 px hexes and the page grid
  offset set by the map alignment tool.
- Draws hexes on the foreground layer when available, in batches so large
  fills do not trip the API watchdog.
- Reveals along a token's whole route and under large tokens, with line of
  sight, a glimpse mode and per-hex reveal limits. Only player tokens reveal
  by default, so GM-moved monsters no longer uncover the map.
- Hides player-visible names, bars and auras of tokens under covered hexes,
  because Roll20 draws them above the foreground layer.
- Adds hidden locations, named hexes, reveal and conceal, undo, reset,
  rescan for copied pages, grid calibration, page overrides and a status card.
- Restricts every command to GMs, escapes chat output, and keeps the v1
  commands and migrates v1 state.
- Adds Help and Command Deck handouts and 24 languages. Locales not yet
  translated fall back to English.

Signed-off-by: Steve Roberts <steve@shadowcomputers.co.uk>
The hex grid and path maths are pure modules, so they are tested directly,
including round trips, page coverage, token footprints, calibration and both
path formats. A small stand-in for the Roll20 sandbox loads the built
Hexploration.js and drives real commands and token moves for Jumpgate,
Legacy and v1 upgrade scenarios, failing if the mod logs an error.

Signed-off-by: Steve Roberts <steve@shadowcomputers.co.uk>
The README covers installation, commands, settings, how revealing works,
Jumpgate and Legacy behaviour and the API for other mods, and credits Ada
Lindberg as the original author alongside the new maintainer. CHANGELOG,
DEVELOPERS, MOD_FILE_MAP and TESTING follow the same layout as the other
rebuilt mods; TESTING includes the in-game checklist and test game setup.

Signed-off-by: Steve Roberts <steve@shadowcomputers.co.uk>
Updates script.json for the One-Click library (version 2.0.0, no
dependencies, new description, authors and useroptions for hex layer,
revealing tokens and language) and adds the built Hexploration.js with its
identical 2.0.0 snapshot.

Signed-off-by: Steve Roberts <steve@shadowcomputers.co.uk>
The locale files committed with the rewrite were mostly English stubs, so
every language other than English fell back to the en-US strings.

Machine-translate the full en-US set into the other 23 locales, re-translating
the count messages that were reworded to the "Label: n" style and the new
covered-token strings. Strings the translator returned in English or
half-translated were retranslated; those left matching English are shared
words or Roll20's own names, such as "Status" and "Hex (V)".

Format the locale files with the project's Prettier settings, and rebuild the
script and the 2.0.0 snapshot so they carry the translations.

Signed-off-by: Steve Roberts <steve@shadowcomputers.co.uk>
The changelog listed versions without saying when they were released, which
made it hard to tell how old the version 1 releases are.

Add a date to each version heading, matching ConditionTracker's style. The
version 1 dates are the last change to each version folder on master;
2.0.0 carries the build date and should be updated on submission.

Signed-off-by: Steve Roberts <steve@shadowcomputers.co.uk>
The Help handout listed all 24 languages as one comma-separated line, which
was hard to scan and did not make clear which code to type.

Show them as a table with the English name and flag, the native name, and
the code to use with !hexploration set language. Add the three column
headings to every locale, and rebuild the script and the 2.0.0 snapshot.

Signed-off-by: Steve Roberts <steve@shadowcomputers.co.uk>
Version 1 had src/Chat.js. The rewrite replaced it on a case-insensitive
file system, so git kept the capital C while every import names
./chat.js, which would break the build on a case-sensitive checkout.

Rename the tracked file to chat.js to match the imports and the other mods.

Signed-off-by: Steve Roberts <steve@shadowcomputers.co.uk>
Google Translate read "hex" as hexadecimal in 15 languages, as "witches"
in Afrikaans, and turned "Command Deck" into a ship's deck. Many button
and setting labels were also unnatural, and some help text quoted labels
that did not match the buttons.

Hand-translate the affected strings, review the labels in every locale,
and keep the help text in step with the labels it quotes. Keep "Command
Deck" in English everywhere: it is the name of a handout, so the deck
subtitle now comes from a DECK_TITLE constant rather than a translation.

Signed-off-by: Steve Roberts <steve@shadowcomputers.co.uk>
Roll20 on Windows shows emoji flags as letter pairs, so flags drawn from
an emoji font are unreliable.

Draw each locale's flag as a Twemoji SVG image, as ConditionTracker does:
before each code in the Help handout's language table, on the language
picker buttons, and beside the current language on the settings card.
Rebuild the script and the 2.0.0 snapshot.

Signed-off-by: Steve Roberts <steve@shadowcomputers.co.uk>
Google Translate turned "!hexploration set language" in the Help
handout's language section into Italian words, so Italian users were
told to type a command that does not exist.

Put the command back, and rebuild the script and the 2.0.0 snapshot.

Signed-off-by: Steve Roberts <steve@shadowcomputers.co.uk>
Jumpgate's pathv2 objects silently ignore rgb() and rgba() fill and
stroke colours and keep the colour they already had. The default glimpse
colour is rgba(34,34,34,0.5), so glimpsed hexes in Jumpgate stayed solid
and glimpse appeared not to work, as a user reported. The same applied
to rgba() fill colours meant to make see-through hexes.

Colours written to pathv2 hexes are now converted to #rrggbb, or to
#rrggbbaa when they have transparency; both are accepted and drawn
see-through. Legacy paths accept rgba(), so they keep the colour as set.
The conversion covers new hexes, restyled hexes, undo and glimpse.

Hexes that 2.0.0 marked as glimpsed without changing their colour are
repainted the next time a token sees them.

The test stub now drops pathv2 colours Jumpgate would reject, so the
tests catch this kind of regression.

Signed-off-by: Steve Roberts <steve@shadowcomputers.co.uk>
Roll20 chat strips inline background colours written as #rrggbbaa or as
rgb() with a fourth value, so the swatch next to such a colour on the
settings card was empty. A user found the swatch did not match the
colour they had set.

Swatches now draw colours with transparency as rgba(), which chat keeps,
and opaque colours as #rrggbb. The text beside the swatch still shows the
colour exactly as it was typed.

Signed-off-by: Steve Roberts <steve@shadowcomputers.co.uk>
The colour fixes left it unclear which colour formats the settings
accept and why the colour on a Jumpgate hex can differ in form from the
one typed. A user had used rgb() with a fourth value and could not tell
whether it was supported.

The README gains a Colours section listing the hex, rgb() and rgba()
forms, how transparency is written in each, how Jumpgate hexes are
converted to #rrggbb or #rrggbbaa, and why colour names should be
avoided in Jumpgate. The Fill and Glimpse Colour rows now speak of a
colour with transparency rather than only rgba().

The testing checklist gains glimpse, fill and swatch checks with the
colour forms the user reported.

Signed-off-by: Steve Roberts <steve@shadowcomputers.co.uk>
A user changed Hex Reveal Distance and Line of Sight, saw no difference,
and could not work out what either did from the help. Both behave as
designed, but the help did not say when they matter:

- Hex Reveal Distance is stored on each hex when it is filled, so
  changing it does nothing to hexes already on the map.
- Hexes are revealed nearest first, so Line of Sight only blocks behind
  hexes that stay covered, and needs a Sight Distance of 2 or more.

The help handout, the settings descriptions and the README now say so,
with a mountain range example: fill the mountains with Hex Reveal
Distance 0, then the land beyond with no limit. The README gives the
example as commands in a new Terrain That Blocks Sight section, and
notes that glimpsed hexes do not block Line of Sight.

The five changed strings are translated into all 23 other languages,
using each language's existing setting names so the help matches the
buttons.

Signed-off-by: Steve Roberts <steve@shadowcomputers.co.uk>
Bumps the version to 2.0.1 for the Jumpgate glimpse and colour fixes,
the swatch fix and the clearer sight help. It is released alongside
2.0.0 in the same pull request, so 2.0.0 is added to 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, testing checklist, developer notes and README API example
carry the new version. The README introduction now says "Version 2"
so it does not need changing for each release.

Signed-off-by: Steve Roberts <steve@shadowcomputers.co.uk>
Version 1 had src/Locations.js and src/State.js. The rewrite replaced
them on a case-insensitive file system, so git kept the capitals while
every import names ./locations.js and ./state.js. A clone on a
case-sensitive file system could not build the script.

Rename the tracked files to match the imports, as was done for chat.js.

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