A goblin raid on the heroes' guild: sneak in, whack some squires, loot the shinies, and escort the Goblin King home.
β³ Loading network libraryβ¦
You'll be the host: your tab runs the real game and everyone else follows.
Finding each other (signaling). There is no game server. When you create or join a room, the local MQTT client in this file (TinyMqtt β raw MQTT 3.1.1 packets over secure WebSockets) connects to two public MQTT brokers (EMQX and HiveMQ) and publishes "I'm in room XXXX" on a topic derived from the app ID + room code. Peers who spot each other there exchange WebRTC offers, answers, and ICE candidates through the broker β that's all the brokers are for, and the Wire log panel shows it happening. Only ONE broker both players can reach needs to work; the second is redundancy.
Playing (game traffic). After the handshake, peers hold a direct, encrypted
WebRTC DataChannel to each other. Every game message flows peer-to-peer; the brokers
sit idle. Three named channels ride on top: intent (guests β host: "I want to
move/attack/open this door"), state (host β everyone: the entire game state),
and chat (everyone β everyone: goblin squawking).
Host-authoritative. Only the host mutates state. Every action β including the
host's own β funnels through one handleIntent() function that checks "is it
your turn, is that legal right now?" and silently drops anything that isn't. Dice rolls,
dungeon generation, and monster brains run only on the host; guests just render what
they're told. That's also the anti-cheat: a hacked client can ask for anything,
but the host only grants legal moves.
Full-state sync. After every change the host broadcasts the whole state object with a sequence number; receivers discard anything older than what they've already got. Wasteful in theory, delightfully simple in practice β and it makes late joiners free: when a new peer connects, the host just sends them the current state and they're caught up.
Departures. A vanished guest "ghosts out": dropped from the turn order (releasing the Goblin King if they were escorting him), and the game moves on. If the host vanishes, the game survives via host failover β the payoff of full-state sync. Every peer already holds the complete current game, so the survivors each apply the same deterministic rule ("smallest peer id still in the room becomes host") and agree on an heir with zero negotiation. The heir flips its host flag, ghosts the old host's goblin, and broadcasts; everyone else sees the new hostId in that broadcast. If a network hiccup ever makes two peers claim the throne, the same rule settles it: a host that hears from a smaller-id host demotes itself and adopts their state. The "den collapses" overlay only appears if you never received a state snapshot at all β then there's nothing to inherit.
Room Movement + Power = 10, Accuracy + Health = 10.
The den collapses. The remaining goblins scatter into the night.
The raid succeeded. Songs will be screeched about this.