← All Workshops

MudEngine Part 6: Multiplayer

From Single-Player to Multiplayer

In Part 4 and Part 5 we built a single-player Dioxus GUI. The game state lived entirely in a Signal<World> on each page — no two players could share the same world.

In this part we turn that local app into a multiplayer server. Every player connects via WebSocket to a shared game state running on the server:

  • First visit asks for a name before entering the world
  • A 3×3 grid shows all rooms with player markers for who is inside each room
  • A player list sidebar shows every connected adventurer and their location
  • Movement controls (D-pad buttons) send direction commands through the WebSocket
  • Broadcasting — when one player moves, every other connected player sees the update in real time

Architecture

The game engine is now split into two halves:

  • Server — holds the authoritative player positions, validates movement against the same 9-room grid, and broadcasts state changes to every connected client via WebSocket
  • Client — renders the grid, sends movement commands, and receives broadcasts from the server

We use Dioxus Fullstack with its built-in use_websocket hook. The WebSocket connection carries typed JSON messages: ClientMessage from the player to the server, and ServerMessage from the server to all players.

"🖥️ Server (Axum)" "🌐 Browser A — Alice" "🌐 Browser B — Bob" "WebSocket" "WebSocket" use_websocket send / recv Game UI use_websocket send / recv Game UI #[get] WebSocket endpoint PlayerManager HashMap{id → PlayerInfo} broadcast::Sender fan-out to all clients Room Exits movement validation