Skip to content

feat(SyncPage): Rewrite for Jumpgate - #2376

Open
steverobertsuk wants to merge 11 commits into
Roll20:masterfrom
steverobertsuk:sr/syncpage-v1
Open

steverobertsuk wants to merge 11 commits into
Roll20:masterfrom
steverobertsuk:sr/syncpage-v1

Conversation

@steverobertsuk

Copy link
Copy Markdown
Contributor

1.0.0 (2026-11-04)

A full rewrite by MidNiteShadow7 of Robin Kuiper's SyncPage 0.1.9, which had not changed since 2018. The 0.1 set-up is carried over and !sync still works.

Fixed

  • Jumpgate drawings and walls (pathv2), doors and windows were never mirrored.
  • An object made on any page was copied to every page whose name contained that page's name ("Town" → "Town Hall", "Old Town"), even with no _synced pages at all.
  • Deleting anything on a page that was not synced threw an error in the API console.
  • Every sandbox start emptied and rebuilt every copy, so object IDs changed (turn order, TokenHome and other Mods lost track), hides on copies were lost and players' tokens were recreated.
  • Links were wiped on every start (setDefaults checked the wrong key), so with Reload Refresh off nothing stayed linked.
  • The original page was found with split('_'), so "Forest_Road_synced" linked to "Forest", and names were matched case-sensitively.
  • When the original page was missing, syncing stopped until the next restart.
  • Show/Hide wrote the text "undefined" into GM Notes, and moved the source token's layer as well as the copies'.
  • A token whose picture could not be copied crashed the copy, or got a placeholder picture.
  • Page settings went only from the original to one _synced page, missed every Jumpgate lighting setting, and archiving the original archived the copy.
  • Read-only properties were passed to createObj, and GM Notes were never copied.
  • Changes made by other Mods were never mirrored and could not be repaired.
  • Renaming a page to end in _synced wiped and rebuilt it without warning.

Added

  • Named sync groups, made from the menu or with group create / group add, stored by page ID so renaming a page is safe. Any number of pages per group, with a source page as the reference.
  • Pairing: a page made with Roll20's Duplicate Page is matched object by object (marketplace art kept), and anything missing is copied. Objects that match nothing are handled by a setting: ask, copy or leave.
  • Per-copy hiding kept in state, in two modes: GM layer, or remove and recreate (nothing left for players to find; turn order kept).
  • Players card: who is on which page, buttons to move each player (split party), gather everyone and restore the layout, and a show/hide grid for selected tokens.
  • Repair with a preview, Pause/Resume, Undo and a Recycle bin per group.
  • Settings, each with every option, globally and per group: delete mode, hide mode, leftovers, new objects, token properties and page settings kept per page, layers not synced, page settings on/off, repair on start, player card, recycle bin size, language.
  • TokenMod changes are mirrored; a public API (getGroup, getLinked, notify, isHidden, onSync, repair) for other Mods.
  • SyncPage - Help and SyncPage - Command Deck handouts, in 24 languages. One-Click options for every setting.

Changed

  • The main command is !syncpage; !sync and 0.1's custom command still work.
  • State lives in state.SyncPage; 0.1's state.SYNCPAGE is read once and left in place.
  • True Copy is gone: Roll20's Duplicate Page does it better.

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

Version 1.0 is built from ES modules under src/ in the same way as
DeathTracker, PageFX and TokenController: Rollup bundles them into
SyncPage.js and the 1.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>
Version 0.1.9 had not changed since 2018. It only knew tokens, text and
Legacy paths, so Jumpgate drawings, walls, doors and windows were never
mirrored. It linked pages by a "_synced" name suffix and copied any new
object to every page whose name merely contained the original's name,
threw on deletes from pages that were not synced, wiped its own links
on every start, then emptied and rebuilt every copy so object IDs
changed, and kept show/hide flags as text in GM Notes (writing
"undefined" there and moving the source token too).

Roll20 still cannot hide an object from only some players on one page,
so mirrored pages are still the way to do it. The rewrite keeps pages
in named sync groups stored by page ID and mirrors every object type
(Jumpgate lights are tokens) and page settings both ways. Pages made
with Roll20's Duplicate Page are paired object by object, which keeps
marketplace art the API cannot copy. Hiding is per copy and kept in
state, on the GM layer or by removing and recreating the copy. A
players card moves players with split party and remembers the layout.
Repair (with a preview), pause and resume, undo and a recycle bin keep
copies in step after changes SyncPage could not see.

Every choice is a setting with all its options, globally or per group,
from one settings table that also drives the settings card, the
One-Click options and the Help handout. An echo guard compares values
SyncPage wrote, because the client saves doors and pages again after an
API change. Button data waits in state behind short single-use IDs.

The 0.1 set-up is carried over: "_synced" pages become groups, old
links are kept, GM Notes flags become hidden copies and a custom
command stays as an alias; True Copy is dropped in favour of Duplicate
Page. Menus, a Help handout and a Command Deck are translatable; locales
other than en-US fall back to English until they are translated.

Credits Robin Kuiper as the original author.

Signed-off-by: Steve Roberts <steve@shadowcomputers.co.uk>
…ests

The stub stands in for the Roll20 sandbox as Jumpgate was seen to
behave in the test game: createObj and set() raise no events, a Legacy
path's shape reads back as _path, and graphics only take library
images. The suites cover every 0.1.9 defect, all six object types,
pairing a Duplicate Page copy, the echo guard, per-page properties and
page settings, excluded layers, each delete mode with undo, both hide
modes, repair, pause and resume, players and layouts, settings and
One-Click options, button expiry, migration from 0.1.9, the public API
and the handouts.

Signed-off-by: Steve Roberts <steve@shadowcomputers.co.uk>
The README explains why mirrored pages are still needed (Roll20 has no
per-player visibility on one page), the Duplicate Page workflow, what
is mirrored, hiding, players, repair and every setting with its
options. The changelog lists the 0.1.9 defects fixed and Robin
Kuiper's earlier releases (0.1.0 and the 0.1.8 beta from his GitHub,
and 0.1.9). DEVELOPERS, MOD_FILE_MAP and TESTING describe the modules,
state, the Jumpgate behaviour the code relies on, and the live test
results from Mod Test Lab - SyncPage.

Signed-off-by: Steve Roberts <steve@shadowcomputers.co.uk>
Google's translate endpoint refused every request (HTTP 429), so the
menus, messages and handouts were translated by Claude instead. Each
file has the same keys, placeholders and command words as en-US, uses
each language's usual term for the game master, and renders with no
missing strings. Roll20's own localised names for Duplicate Page, split
party and the GM layer were not checked against its interface.

Signed-off-by: Steve Roberts <steve@shadowcomputers.co.uk>
Builds SyncPage.js and its 1.0.0/ snapshot from src/, with all 24
languages.

Signed-off-by: Steve Roberts <steve@shadowcomputers.co.uk>
The Help and Command Deck handouts now use the plain SyncPage 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>
The root script and the 1.0.0 snapshot are rebuilt without a version bump and remain identical.

Signed-off-by: Steve Roberts <steve@shadowcomputers.co.uk>
…dout

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 SyncPage 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>
The built script and its 1.0.0 copy carry the new icon path. The version number is unchanged.

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