We will extend CodeBuddy to support a fully operational Friend-vs-Friend Match mode. By leveraging high-fidelity browser storage event synchronization, we can achieve real-time multiplayer states across distinct browser tabs/windows without needing a dedicated backend socket server!
sequenceDiagram
participant HostTab as Host Browser Tab
participant LocalStorage as Browser LocalStorage
participant FriendTab as Friend Browser Tab
HostTab->>LocalStorage: Create Room 'CB-1234' (Opponent: Friend)
Note over HostTab: Host enters Lobby<br/>Waiting for Friend...
FriendTab->>LocalStorage: Join Room 'CB-1234'
Note over LocalStorage: Registers Friend Participant
LocalStorage-->>HostTab: 'storage' event triggers<br/>Host sees Friend joined!
HostTab->>LocalStorage: Click "Initialize Battle" (status: active)
LocalStorage-->>FriendTab: 'storage' event triggers<br/>Friend tab auto-launches Arena!
HostTab->>LocalStorage: Submit Solution (Weighted AI Evaluation)
LocalStorage-->>FriendTab: Friend Arena HUD updates: "Host Submitted!"
FriendTab->>LocalStorage: Submit Solution (Weighted AI Evaluation)
LocalStorage-->>HostTab: Both submitted! Render side-by-side results.
- State changes:
opponentType:'bot' | 'friend'myParticipantId:'host-user' | 'friend-user'
- Actions & Operations:
createRoom(settings):- If setting
opponentType === 'friend':- Initialize room with host only.
- Save state to
localStorageunderpatternlab_cb_room_${code}.
- If
opponentType === 'bot': behaves as before (spawns bot jerry/devbot/coder-x).
- If setting
joinRoom(code):- Look up
patternlab_cb_room_${code}inlocalStorage. - If found:
- Register friend participant:
{ id: 'friend-user', name: 'Challenger (Friend)', ... }. - Save updated state to
localStorage. - Set
myParticipantId: 'friend-user'.
- Register friend participant:
- Look up
syncFromStorage(roomState):- Utility to force-feed raw updates received from cross-tab events into the local Zustand store.
updateParticipantState(updates):- Throttled action to update the user's specific participant details (code, status, solve metrics) and sync to
localStoragefor cross-tab transmission.
- Throttled action to update the user's specific participant details (code, status, solve metrics) and sync to
We will introduce a React Hook that manages live cross-tab subscriptions while in the lobby or active match:
- Listens to
'storage'events globally. - When an update matches
patternlab_cb_room_${activeRoomCode}, it parses the updated state and updates the Zustand store. - Listens to window unload events to automatically mark participants as "Disconnected" or "Left Match".
- Create battle controls:
- Toggle between "Challenge Bot Companion" and "Invite a Friend (Multiplayer)".
- If "Invite a Friend" is active:
- Hide bot selectors.
- Show helper overlay: "Invite link code is copyable. Share it with a friend who can open PatternLab in another tab or device to battle!"
- Waiting Lobby wait-state:
- If Host: Shows "Initialize Battle Arena" button. If friend has not joined, the button remains disabled: "Waiting for friend to connect..."
- If Friend: Shows a glowing loading ring: "Connected! Waiting for host to initiate the battle arena..."
- Keep opponent cards updated dynamically:
- If
opponentType === 'friend', render friend participant name/avatar and active submission state in the HUD. - Throttled sync allows both tabs to see if the other is actively typing or submitted, creating a massive gaming battle atmosphere!
- If
- Verify build compiler success using
npm run build.
- Open a browser window to
http://localhost:5173/codebuddyand choose "Invite a Friend" battle setup. - Generate Room Code (e.g.
CB-5832). - Open a second tab / incognito window to
http://localhost:5173/codebuddyand enter room codeCB-5832. - Confirm both tabs sync instantly: Host sees Friend join, Friend wait screen says "Waiting for host to start..."
- Click "Initialize Battle" in Host tab, confirm both tabs auto-route to active coding arenas.
- Type solutions in both editors and verify completions declare the accurate winner side-by-side!