
Dragging a token into the token bin removes it from the local DOM but never sends a sendDeleteMessage, so the opponent still sees the token on their board.
Context
The P2P protocol includes a delete-element message type that is correctly used when a card is deleted via the Delete key (keyboard.js:49). However, the token bin deletion path in the ungrab handler of createToken calls tokenElement.remove() without notifying the peer. In a multiplayer game this means binned tokens persist on the opponent's screen indefinitely, creating a desynchronized board state. The fix is to call sendDeleteMessage(tokenElement.id) before removing the element, matching the pattern already established in keyboard.js.
Affected Files
src/scripts/token.js:36 — Add sendDeleteMessage(tokenElement.id) before tokenElement.remove()
src/scripts/token.js:2 — Import sendDeleteMessage from ./p2p.js
src/scripts/token.test.js — Add test verifying sendDeleteMessage is called when token lands in the bin
Requirements

Verification
- npm test -- --reporter=verbose src/scripts/token.test.js
- npm run lint
- grep -n 'sendDeleteMessage' src/scripts/token.js
Not In Scope
- Do not add P2P sync for token flipping or stacking — those are separate issues
- Do not refactor the ungrab handler beyond adding the send call
- Do not modify
p2p.js receive-side handling
Evidence
src/scripts/token.js:36 — tokenElement.remove() is called when the token overlaps the bin, but no sendDeleteMessage call precedes it
src/scripts/keyboard.js:49-50 — Card deletion correctly calls sendDeleteMessage(selectedCard.id) before selectedCard.remove(), establishing the expected pattern
src/scripts/token.js:1-3 — sendDeleteMessage is not imported — only sendCreateMessage is imported from ./p2p.js
Arasaka Queue Planning Division.

Dragging a token into the token bin removes it from the local DOM but never sends a
sendDeleteMessage, so the opponent still sees the token on their board.Context
The P2P protocol includes a
delete-elementmessage type that is correctly used when a card is deleted via the Delete key (keyboard.js:49). However, the token bin deletion path in theungrabhandler ofcreateTokencallstokenElement.remove()without notifying the peer. In a multiplayer game this means binned tokens persist on the opponent's screen indefinitely, creating a desynchronized board state. The fix is to callsendDeleteMessage(tokenElement.id)before removing the element, matching the pattern already established inkeyboard.js.Affected Files
src/scripts/token.js:36— AddsendDeleteMessage(tokenElement.id)beforetokenElement.remove()src/scripts/token.js:2— ImportsendDeleteMessagefrom./p2p.jssrc/scripts/token.test.js— Add test verifyingsendDeleteMessageis called when token lands in the binRequirements
sendDeleteMessageis called with the token's id before the element is removed from the DOMsendDeleteMessageis imported from./p2p.jsintoken.jstoken.test.jsconfirms thatsendDeleteMessageis invoked whenisPointWithinElementreturnstruefor the token bin duringungrabVerification
Not In Scope
p2p.jsreceive-side handlingEvidence
src/scripts/token.js:36—tokenElement.remove()is called when the token overlaps the bin, but nosendDeleteMessagecall precedes itsrc/scripts/keyboard.js:49-50— Card deletion correctly callssendDeleteMessage(selectedCard.id)beforeselectedCard.remove(), establishing the expected patternsrc/scripts/token.js:1-3—sendDeleteMessageis not imported — onlysendCreateMessageis imported from./p2p.jsArasaka Queue Planning Division.