Multiplayer
WEFA supports three gameplay modes that scale from solo to global play.
Modes
| Mode | Transport | How It Works |
|---|---|---|
| Device | None | Pass-and-play on one device. No network sync. |
| Local | Yjs + WebRTC | Two devices on the same network. Peer-to-peer discovery. |
| World | Yjs + WebSocket relay (hybrid) | Two devices anywhere. Uses relay server for signaling. |
Session Flow
Join Codes
Session codes are 4-6 uppercase alphanumeric characters, excluding ambiguous characters (0, O, 1, I, L). Room naming follows wefa-game-{code}.
Seat Ownership
In network modes (Local/World), each player claims a seat (p0 or p1) via Yjs setup-state sync. Creature selection is seat-owned: each player can only select their own creature, not their opponent's.
Transport Resolution
The Yjs transport is configured based on mode:
Device -> no Yjs session
Local -> webrtc transport
World -> hybrid transport (WebRTC + WebSocket relay fallback)
If no relay URL is configured for World mode, it falls back to wss://demos.yjs.dev as a testing default.
Reward Attribution
Rewards are computed per-seat. The local player's reward is based on their actual seat outcome (win/draw/loss), not a fixed assumption of being player 0.
Key Files
src/modules/yjs.ts- Session creation, join, sync, transport selectionsrc/hooks/yjs/useYjsSession.ts- React hook for session managementsrc/hooks/games/useGameSession.ts- Game session with mode/seat awarenesssrc/machines/gameSessionMachine.ts- Full game session state machine