2 Sync and Permissions
Flaig edited this page 2026-10-03 23:13:42 +02:00

Sync, Saving and Permissions

  • The client that calls play() rolls random values, resolves directions, walls and snapping, and sends the resulting keyframes to everyone else. All clients show the same animation.
  • Animations are played through Foundry's own token animation (Token#animate), so vision, lighting and occlusion follow the token while it moves. Nothing is written to the world during the animation.
  • Saved moves are written once, by the client that started the animation, after the token's last step, through Foundry's movement API (TokenDocument#move, so movement history, regions and preMoveToken hooks work). Foundry's own wall and cost constraints are skipped for that save because TokenMove already applied walls; the saved position is exactly the one that was animated.
  • If that user can't update the token, the active GM saves it (see Settings). If the save doesn't happen or ends somewhere else (no permission, no GM, a module blocked or changed the move), the token is reset to its actual saved position on every client, a warning is shown, the reason is logged to the console, and play() resolves with completed: false.
  • If the client that started the animation switches scenes mid-animation, its saved moves are saved right away (the clients still on the scene play the animation to that position).
  • Starting a new TokenMove animation on a token cancels the rest of the older animation for that token only; other tokens of the older animation continue. A cancelled animation's unsaved moveTo/moveBy is dropped.
  • sync: false plays only on your screen (useful for previews). Saved moves are still saved and the token then jumps to its new position for everyone else.

Wall collision

With walls enabled, each straight movement is tested once with Foundry's Token#checkCollision (the same movement-restriction test Foundry uses for dragging tokens) from where the token will be at that point in the animation. A blocked movement stops half a token before the wall. For saved moves the stopping point is snapped to the grid if the snapped position is also reachable. restore() is never blocked, since it returns to a legal position.