Skip to content

Fix token middle-click clone P2P desync — remote sees floating token instead of stack #406

@arasaka-net

Description

@arasaka-net

When a player middle-clicks a token to duplicate it, the clone is stacked locally but created as a free-floating entity on the remote peer's board. The remote sees the cloned token at coordinates 0px, 15px in #card-layer instead of nested inside the parent token.

Context
Token duplication via middle-click calls createToken(), which appends the new element to #card-layer and fires sendCreateMessage with coordinates 0px, 15px. Control then returns to the auxclick handler, which immediately re-parents the element into the parent token's DOM subtree. The remote peer processes the create-element message and places the clone in #card-layer at the transmitted coordinates — it never receives a stacking instruction. The result is a visual desync: the local player sees a neatly stacked token pile, while the remote player sees a stray token near the top-left corner of the board. This affects every token duplication in a two-player game.

Affected Files

  • src/scripts/token.js:64auxclick handler calls createToken then re-parents the returned element into the parent token, but sendCreateMessage already fired inside createToken with top-level coordinates
  • src/scripts/token.js:76createToken appends to #card-layer and sends P2P create message before the caller can relocate the element
  • src/scripts/p2p.js:159receiveMessage create-element for token places it in #card-layer — no stacking logic exists on the receive path
  • src/scripts/types.ts:31CreateElementMessage content payload has no field to express parent-child stacking relationships

Requirements

  • When a player middle-clicks a token to duplicate it, the remote peer must render the cloned token stacked on the parent token, matching the local DOM structure
  • The P2P message for token duplication must convey the parent token ID so the remote can replicate the stacking
  • Existing free-standing createToken calls (from the token spawner panel) must continue to work without regression
  • A unit test in token.test.js must verify that a middle-click clone sends a message containing the parent token reference

Verification

  • npm test
  • grep -n 'auxclick' src/scripts/token.js
  • npm run typecheck

Not In Scope

Evidence

  • src/scripts/token.js:68-75auxclick handler calls createToken(tokenElement.firstElementChild.id, "0px", "15px"), which fires sendCreateMessage inside, then lastTokenInStack.appendChild(...) moves the element out of #card-layer — the remote never receives the re-parenting
  • src/scripts/token.js:76-83createToken unconditionally appends to #card-layer and calls sendCreateMessage with the raw x, y arguments before returning — no mechanism to defer or customize the P2P message
  • src/scripts/p2p.js:159-182receiveMessage create-element token handler calls createToken(...message.content) and places the result in #card-layer — no code path exists to nest the created token inside another token

Arasaka Queue Planning Division.

Metadata

Metadata

Assignees

No one assigned

    Labels

    P2bugSomething isn't working

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions