← All Workshops
MudEngine Part 9: The Twin Guardians
Step 11 / 11
Congratulations!
You just added a two-player cooperative quest to the MUD engine!
What we achieved:
- Quest data in game.toml — a
[quest]section defines the guardian pedestals and reward passage alongside rooms and items - Dynamic room exits — exits that appear and disappear based on game state, managed at runtime by the server
- Real-time quest broadcasting —
QuestEventmessages announce quest activation and deactivation to all players - Atomic quest logic —
update_quest()runs inside theGAME_STATElock, evaluating conditions and mutating state atomically on every player move and disconnect - Safe deactivation — when the quest deactivates, players inside the vault are teleported back to Town Square
- Quest UI — a quest panel shows guardian status (✅ active / ⏳ waiting) and action buttons for descending/ascending
- Return path — the vault gets a return exit ("up" back to Town Square) when the portal opens
Architecture recap
┌─────────────────────────────┐
│ game.toml [quest] │
│ guardians: sun, moon │
│ reward: room 4 → room 9 │
└─────────────┬───────────────┘
│ load at startup
▼
┌─────────────────────────────┐
│ GameState.quest │
│ config + previously_active │
└─────────────┬───────────────┘
│
┌───────────────────┼───────────────────┐
▼ ▼ ▼
Player moves Player leaves Player disconnects
│ │ │
└───────────────────┼───────────────────┘
▼
update_quest() runs
inside the Mutex lock
│
┌─────────────┴─────────────┐
▼ ▼
Add/remove exit Broadcast QuestEvent
to/from room 4 & 9 to all connected clients
What's next?
- Quest persistence — save
completedflag togame.tomlso quest progress survives restarts - Multiple quests — a quest registry supporting many independent quests with different phases
- Full NPC dialog trees — NPCs with multiple dialog lines, branching conversations, and quest giver logic
- Timed quests — quests that must be completed within a time limit, with countdown UI
- Quest items — items that only appear while a quest is active (spawned by quest events)
- Boss encounters — a room with a monster that spawns when the quest activates
📚 What we learned
| Concept | How we used it |
|---|---|
| Quest config in TOML | [quest] section with guardian rooms and reward definition, parsed into TomlQuest |
| Dynamic exits | Room exits added/removed at runtime based on quest state; existing can_move picks them up automatically |
| Server-side quest evaluation | update_quest() checks if all guardian rooms are occupied, transitions state atomically |
| Quest event broadcasting | ServerMessage::QuestEvent { active, message } announced to all clients on state change |
| Quest completion detection | check_quest_completion() fires when retrieval_item enters completion_room — checks both floor and inventory |
| Three-phase quest flow | Phase 1: guardians open gate → Phase 2: hero retrieves item → Phase 3: item reaches King, quest won |
| NPC dialog | King Aldric's speech changes based on quest state — portal active, fragment in hand, or quest complete |
| Safe deactivation | Players in the vault are teleported back to source room when guardians part |
| Client quest UI | QuestDisplay signal driven by server state; shows guardian status, phase hints, and completion banner |
| Return path | Vault gets a return exit ("up") when the portal opens, ensuring players can always leave |
| Two-player minimum for gate | state.players.len() >= 2 prevents a single player from activating both pedestals |
| Completed quest lock | Once completed = true, update_quest short-circuits — guardians can leave without penalty |
Step 11 / 11