Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
101 commits
Select commit Hold shift + click to select a range
8257b1f
Gaslight: add SCRIPTING_DESIGN.md for reactive per-player automation …
KenanMillet Jun 19, 2026
fce9023
Gaslight scripting: clarify viewer.* semantics — iterate each, any-pa…
KenanMillet Jun 19, 2026
36fa63f
Gaslight scripting: fix registration timing — on handout create/modif…
KenanMillet Jun 19, 2026
ab3f6f8
Gaslight scripting: trigger rules — auto from conditions only, manual…
KenanMillet Jun 19, 2026
2d69fe6
Gaslight scripting: resolve open questions — trigger map, error handl…
KenanMillet Jun 19, 2026
2b7102a
Gaslight scripting: basic evaluation engine — eval command, pin detec…
KenanMillet Jun 19, 2026
70a65f7
Gaslight: bump version to 2.0.0, add versioned folder
KenanMillet Jun 19, 2026
33ad756
Gaslight scripting: fix eval to resolve target to linked copy on view…
KenanMillet Jun 19, 2026
80e1807
Gaslight scripting: document pin placement semantics (master=all, pla…
KenanMillet Jun 19, 2026
1a48249
Gaslight scripting: add gm.* namespace for master page opt-in evaluation
KenanMillet Jun 19, 2026
9a8f826
Gaslight scripting: dry run shows viewer-page token name+id and playe…
KenanMillet Jun 19, 2026
357c752
Gaslight scripting: improve dry run formatting — line breaks, bold la…
KenanMillet Jun 19, 2026
c4a9391
Gaslight scripting: support self-contained pins, handout gmNotes conf…
KenanMillet Jun 19, 2026
d637557
Gaslight scripting: pin title falls back to linked handout name, then…
KenanMillet Jun 19, 2026
69c8e8c
Gaslight scripting: add [GLS] tag convention, strip from display in chat
KenanMillet Jun 19, 2026
6cdec57
Gaslight scripting: dry run uses --echo through pipeline, clean up co…
KenanMillet Jun 19, 2026
148ab98
Gaslight scripting: use destructuring in --echo handler
KenanMillet Jun 19, 2026
a4bffc0
Gaslight scripting: rename --dry to --dry-run for suite parity
KenanMillet Jun 19, 2026
7c9c54a
Gaslight scripting: remove hr from pin header, fix multi-pin ordering
KenanMillet Jun 19, 2026
f06b1fe
Gaslight scripting: fix nameless token showing ID twice in dry run
KenanMillet Jun 19, 2026
88fe2b1
Gaslight scripting: fix parseConfigText HTML stripping, has filter ch…
KenanMillet Jun 19, 2026
75b19d8
Gaslight scripting: add trigger map, change:attribute + change:graphi…
KenanMillet Jun 19, 2026
c0baaf9
Gaslight scripting: add generic change:graphic handler for token prop…
KenanMillet Jun 19, 2026
434c179
Gaslight scripting: triggers are per-page — player page change evalua…
KenanMillet Jun 19, 2026
c077b71
Gaslight: fix getLinkId regex — stop at whitespace, strip HTML before…
KenanMillet Jun 19, 2026
62a5a64
Gaslight scripting: simplify variable resolution — just substitute to…
KenanMillet Jun 19, 2026
8237409
Gaslight scripting: fix Fetch compProp — inject into PropContainers c…
KenanMillet Jun 20, 2026
953a0ac
Gaslight scripting: add Roll Capture design section — rules, extracti…
KenanMillet Jun 20, 2026
9b4d450
Gaslight scripting: document D&D 5E roll structure and proposed captu…
KenanMillet Jun 20, 2026
6981d4a
RollCapture: initial design document — generic roll capture with D&D …
KenanMillet Jun 20, 2026
2528d55
Gaslight scripting: reference RollCapture as separate script, remove …
KenanMillet Jun 20, 2026
104daf6
RollCapture: add example capture rules for 5 systems to design doc
KenanMillet Jun 20, 2026
39aa983
RollCapture: generic when/default format, no arrows, add choose() for…
KenanMillet Jun 20, 2026
966edf6
RollCapture: finalize format — field-name refs, multi-capture, choose…
KenanMillet Jun 20, 2026
4bbea75
RollCapture: remove storage from capture rules — consumers decide whe…
KenanMillet Jun 20, 2026
40faf71
RollCapture: rewrite examples to multi-capture block format, update e…
KenanMillet Jun 20, 2026
ed4939b
RollCapture v0.1.0: working scaffold — rule parsing, template matchin…
KenanMillet Jun 23, 2026
3b3e4ba
RollCapture: remove diagnostic script
KenanMillet Jun 23, 2026
00c141d
RollCapture: auto-resolve choose() when all values are equal
KenanMillet Jun 23, 2026
74ac625
Gaslight v1.1.0: unified relay — universal auto-relay, ID scanning, r…
KenanMillet Jun 25, 2026
b16fe8d
Gaslight v1.1.0: unified relay with loop prevention, versioned folder
KenanMillet Jun 25, 2026
5a985b3
Gaslight: update file header to v1.1.0 with full command list and dep…
KenanMillet Jun 25, 2026
153660a
Gaslight: help handout always updates on init, fix merge description,…
KenanMillet Jun 25, 2026
714d287
Gaslight: fix selective relay handout wording, add --except to TODO
KenanMillet Jun 25, 2026
0b950a8
Gaslight: remove resolved SelectManager known issue
KenanMillet Jun 25, 2026
9e5fe72
Merge branch 'Roll20:master' into Gaslight
KenanMillet Jun 25, 2026
100df16
RollCapture: fire character abilities (rc_any, rc_name, rc_default) w…
KenanMillet Jun 25, 2026
0b588f4
RollCapture: drop variable — emit bare capture names + full msg, cons…
KenanMillet Jun 25, 2026
1300423
RollCapture: add SCRIPT_NAME, Map-based callbacks with sourceId dedup…
KenanMillet Jun 25, 2026
168ef7d
RollCapture: fix whisper splitting — use br instead of newlines
KenanMillet Jun 25, 2026
7551e1b
RollCapture: use code tags in help whisper
KenanMillet Jun 25, 2026
68314f9
RollCapture: fix rules newlines, prevent !rollcapture-ready from trig…
KenanMillet Jun 25, 2026
faea095
RollCapture: drop ---ROLLCAPTURE--- marker, rules shows handout links…
KenanMillet Jun 25, 2026
f743430
RollCapture: fix handout links — use anchor tags instead of markdown
KenanMillet Jun 25, 2026
4f4c16d
RollCapture: strip [RollCapture]/[RC] tag from display names in chat …
KenanMillet Jun 25, 2026
2285ab6
RollCapture: comment lines (#), rule command shows created/found, new…
KenanMillet Jun 25, 2026
12de244
RollCapture: wrap new rule handout content in pre/code block
KenanMillet Jun 25, 2026
f15b889
RollCapture: use template literal for rule handout content
KenanMillet Jun 25, 2026
975e9ed
RollCapture: add rule command to help message
KenanMillet Jun 25, 2026
a3f9714
RollCapture v0.1.0: PR-ready — script.json, README, versioned folder,…
KenanMillet Jun 25, 2026
98ae3e6
Merge branch 'Roll20:master' into RollCapture
KenanMillet Jun 25, 2026
fd397d9
Merge Gaslight v1.1.0 into Gaslight-scripting
KenanMillet Jun 25, 2026
c799cfe
Gaslight scripting: prevent relaying of scripted commands via --scrip…
KenanMillet Jun 25, 2026
8b1f59f
RollCapture: emit charId, fire for all matching characters, warn on d…
KenanMillet Jun 25, 2026
ee9c647
Gaslight scripting: RollCapture integration — onCapture writes attrib…
KenanMillet Jun 25, 2026
45dafd7
Gaslight scripting: viewer aggregation (any/all/max/min), quote-aware…
KenanMillet Jun 25, 2026
5646ee5
Gaslight scripting: fix HTML entity decoding in handout content, gl_ …
KenanMillet Jun 25, 2026
13cbfe1
Gaslight scripting: fix extractOpLhs || boundary, HTML entity decodin…
KenanMillet Jun 25, 2026
677127a
Gaslight scripting: add gm.* namespace — same aggregation as viewer.*…
KenanMillet Jun 25, 2026
9afef8d
Gaslight scripting: always show assign button when no single token au…
KenanMillet Jun 25, 2026
122f2d0
Gaslight scripting: fallback token resolution from charId on master p…
KenanMillet Jun 25, 2026
0995a3e
Gaslight scripting: fix pin type (revert to 'pin'), fix gmnotes gl_ r…
KenanMillet Jun 25, 2026
37106fe
Gaslight scripting: manually trigger pin evaluation after capture wri…
KenanMillet Jun 25, 2026
cfedbde
Gaslight scripting: support // comments in scripts (full-line and inl…
KenanMillet Jun 25, 2026
201e858
Gaslight scripting: add join() aggregate for viewer/gm token IDs in c…
KenanMillet Jun 25, 2026
2a2dd71
Gaslight scripting: add scripting section to help handout, eval comma…
KenanMillet Jun 25, 2026
3a9c262
Gaslight v2.0.0: scripting engine — reactive per-player automation, R…
KenanMillet Jun 25, 2026
7728fad
Merge branch 'Gaslight' of https://github.com/KenanMillet/roll20-api-…
KenanMillet Jun 25, 2026
0e4cf53
Merge branch 'RollCapture' into dev
KenanMillet Jun 26, 2026
10d2df6
Anchor v2.2.0: selection-based parenting — first selected = parent wh…
KenanMillet Jun 26, 2026
781f8ca
Anchor: fix 'new' flag — include in isNewAnchor check
KenanMillet Jun 26, 2026
43335a6
Anchor: remove from parent unanchors children, up/down flags for disa…
KenanMillet Jun 26, 2026
7d70268
Anchor v2.2.0: -- prefix for modifiers (--new, --up, --down), --persi…
KenanMillet Jun 26, 2026
ab23c46
Anchor v2.2.0: bump header/script.json version, update README and hel…
KenanMillet Jun 26, 2026
ebad719
Anchor: fix anchorChildrenByAnchorId is object not array — use Object…
KenanMillet Jun 26, 2026
a722199
Anchor: force --up/--down disambiguation for all commands when token …
KenanMillet Jun 26, 2026
bcb0c1c
Anchor: add --up/--down disambiguation to center command
KenanMillet Jun 26, 2026
c8942b0
Anchor: flesh out Help handout — quick start, modifiers, disambiguati…
KenanMillet Jun 26, 2026
8657912
Anchor v2.2.1: fix child offset scaling — include parent scale in tra…
KenanMillet Jun 26, 2026
750d48f
Anchor v2.2.1: unify flip into transform matrix — no more manual offs…
KenanMillet Jun 26, 2026
c302563
Anchor v2.2.1: auto-set lockMovement when left+top are locked, track …
KenanMillet Jun 26, 2026
ebd057a
Anchor v2.2.1: lockMovement requires tracked+locked, add --up/--down …
KenanMillet Jun 26, 2026
3d119f6
Anchor v2.2.1: use clearPlacementLockIfNeeded consistently everywhere
KenanMillet Jun 26, 2026
10c84d1
Anchor v2.2.1: add setPlacementLockIfNeeded helper, call from lockCom…
KenanMillet Jun 26, 2026
e4d0e72
Anchor v2.2.1: state migration for scale-normalized offsets, lockMove…
KenanMillet Jun 26, 2026
b4bb512
Anchor: rename versioned folder 2.2.0 → 2.2.1
KenanMillet Jun 26, 2026
71d2c65
Anchor v2.2.1: update README changelog, script.json version
KenanMillet Jun 26, 2026
12ac860
Anchor: add --up/--down to lock/unlock in README, note lockMovement b…
KenanMillet Jun 26, 2026
41c19b6
Mirror v1.1.0: --ignore-selected, auto lockMovement for hard-linked l…
KenanMillet Jun 26, 2026
5475fab
Mirror v1.1.0: fix header version
KenanMillet Jun 26, 2026
1adfbbb
Mirror: fix syntax error — missing function close before generateDevDocs
KenanMillet Jun 26, 2026
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2,705 changes: 2,705 additions & 0 deletions Anchor/2.2.1/anchor.js

Large diffs are not rendered by default.

77 changes: 55 additions & 22 deletions Anchor/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -20,15 +20,21 @@ Attach child tokens to an anchor token so they automatically follow its position

## Quick Start

Select one or more tokens and run:
Select a parent token and one or more child tokens, then run:

```
!anchor
```

An invisible anchor token is auto-created at the first selected token's position on the GM layer. Move the anchor — the children follow.
The first selected token becomes the parent anchor. The rest become children that follow the parent's transforms.

To use an existing token as the anchor instead:
To auto-create an invisible anchor instead (children move together with no visible parent):

```
!anchor --new
```

To use an existing token as the anchor by ID:

```
!anchor <anchor_token_id>
Expand All @@ -38,15 +44,22 @@ To use an existing token as the anchor instead:

## Commands

All commands accept `[ignore-selected]` to skip the current token selection, and `[child_id...]` to specify tokens explicitly by ID.
All commands accept `[--ignore-selected]` to skip the current token selection, and `[child_id...]` to specify tokens explicitly by ID.

### Anchoring

```
!anchor [anchor_id] [component flags] [ignore-selected] [child_id...]
!anchor [anchor_id] [component flags] [--ignore-selected] [--new] [--persist] [child_id...]
```

Anchor selected/listed tokens to `anchor_id`. If `anchor_id` is omitted or not a valid token, an invisible anchor token is auto-created at the first child's position. The auto-created token is destroyed automatically when its last child is removed. Add `persist` to keep it even when childless.
Anchor selected/listed tokens to `anchor_id`.

**Selection-based parenting** (when no `anchor_id` is given):
- **Multiple tokens selected:** first selected = parent, rest = children.
- **One token selected (not already anchored):** auto-creates an invisible anchor.
- **One token selected (already anchored):** reports existing relationship.
- **`--new` flag:** force auto-create an invisible anchor (all selected become children).
- **`--persist`:** keep auto-created anchors even when childless (otherwise auto-destroyed).

**Default components** (when no flags given): position, rotation, scale, width, height, flipv, fliph.

Expand All @@ -71,11 +84,12 @@ Anchor selected/listed tokens to `anchor_id`. If `anchor_id` is omitted or not a

**Examples:**
```
!anchor -- anchor selected token(s), all default components
!anchor -- first selected = parent, rest = children
!anchor --new -- auto-create invisible anchor, all selected = children
!anchor --new --persist -- same, but anchor persists when childless
!anchor -x -rot -layer -- anchor x-position, rotation, and layer only
!anchor anchor-all -- anchor everything including z-order
!anchor -OtyABCDEF123 -- anchor to an existing token
!anchor persist -- auto-create anchor and keep it when childless
!anchor -OtyABCDEF123 -- anchor selected to an existing token by ID
```

When z-order anchoring (`-z` / `anchor-z`) is active, call `Anchor.updateZOrder(anchorObj)` from another script (e.g. EasyReZorder) after moving the anchor in z-order to propagate the new stack to children.
Expand All @@ -85,68 +99,74 @@ When z-order anchoring (`-z` / `anchor-z`) is active, call `Anchor.updateZOrder(
### Removing

```
!anchor remove [ignore-selected] [child_id...]
!anchor remove [--up] [--down] [--ignore-selected] [child_id...]
```

Remove the anchor relationship from tokens. Does not delete the anchor token itself.
Remove anchor relationships from tokens.
- **Child selected:** removes it from its parent.
- **Parent selected:** unanchors all its children.
- **Both parent and child:** removes both directions. Use `--up` (remove parent link only) or `--down` (remove children only) to disambiguate.

---

### Locking and Unlocking

```
!anchor lock [component flags] [ignore-selected] [child_id...]
!anchor unlock [component flags] [ignore-selected] [child_id...]
!anchor lock [component flags] [--up] [--down] [--ignore-selected] [child_id...]
!anchor unlock [component flags] [--up] [--down] [--ignore-selected] [child_id...]
```

**Lock** freezes components — manual moves are undone every poll tick, and anchor changes to those components are ignored. With no component flags, locks all components.
**Lock** freezes components — manual moves are undone every poll tick, and anchor changes to those components are ignored. With no component flags, locks all components. When both left+top are tracked and locked, `lockMovement` is set on the token to prevent dragging entirely.

**Unlock** releases components. With no component flags, unlocks everything.

**`--down`** — when a parent is selected, apply to all children. **`--up`** — apply to own parent link. Required when token is both parent and child.

Components can be locked before they are tracked ("pre-locked") — they will activate automatically when tracking is added via `track`.

---

### Tracking

```
!anchor track [component flags] [ignore-selected] [child_id...]
!anchor untrack [component flags] [ignore-selected] [child_id...]
!anchor retrack [component flags] [ignore-selected] [child_id...]
!anchor track [component flags] [--down] [--ignore-selected] [child_id...]
!anchor untrack [component flags] [--down] [--ignore-selected] [child_id...]
!anchor retrack [component flags] [--ignore-selected] [child_id...]
```

Modify which components are tracked on existing relationships without disturbing other stored offsets.

- **`track`** — add components, recording the current relative state as the offset.
- **`untrack`** — remove components. Does not affect locked state.
- **`retrack`** — replace the tracked set entirely. No flags = default set.
- **`--down`** — when a parent is selected, apply to all children instead of the parent's own relationship.

---

### Other Commands

```
!anchor center [ignore-selected] [child_id...]
!anchor center [--ignore-selected] [child_id...]
```
Snap children to anchor centre (offset 0,0, rotation 0°, scale 1:1).

```
!anchor update [ignore-selected] [child_id...]
!anchor update [--ignore-selected] [child_id...]
```
Force an immediate transform sync for children.

```
!anchor info [ignore-selected] [child_id...]
!anchor info [--ignore-selected] [child_id...]
```
Whisper anchor state to the caller. Shows tracked components with stored values, lock status (🔒), and pre-locked untracked components. With no tokens selected or specified, shows all anchored tokens on the current page.

```
!anchor chain [component flags] [ignore-selected] [child_id...]
!anchor chain [component flags] [--ignore-selected] [child_id...]
```
Mutually anchor tokens in a ring (A→B, B→C, C→A). Move any one and all others follow. Useful for syncing tokens across pages or creating peer-linked groups.

```
!anchor unchain [ignore-selected] [child_id...]
!anchor unchain [--ignore-selected] [child_id...]
```
Dissolve a chain ring. Select any one token in the ring (or even a child of a ring member) — the ring is detected and all relationships in it are removed.

Expand Down Expand Up @@ -289,6 +309,19 @@ The public API changed:

## Changelog

### v2.2.1
- Fix: child position offset now scales with parent size (proper matrix transform with scale)
- Fix: flip mirroring handled via scale matrix instead of manual negation
- Auto `lockMovement` when both left+top are tracked AND locked (clears when conditions change)
- State migration: old pixel offsets auto-normalized to anchor-size-relative on first load

### v2.2.0
- Selection-based parenting: first selected = parent when multiple tokens selected
- `--new` flag: force auto-create invisible anchor (all selected become children)
- `--up` / `--down` modifiers for `remove`, `track`, `untrack` disambiguation
- `--persist` and `--ignore-selected` as preferred syntax (bare words still work)
- `remove` from parent now unanchors all children

### v2.1.0
- Rewrite with full ES6 modernisation (IIFE module pattern, `const`/`let`, arrow functions)
- Added component flags system with short aliases (`-x`, `-rot`, `-z`, etc.)
Expand Down
Loading
Loading