โ† All Workshops

MudEngine Part 8: Inventory & Chat

Run it!

Start the fullstack dev server. The server loads game.toml with the new items fields.

Serve the interactive MUD
dx serve --open
๐Ÿงช Testing Inventory & Chat

Open two browser tabs side by side:

Tab 1 โ€” Alice

  1. Enter name: Alice
  2. Click Enter the World โ€” Alice spawns in Town Square
  3. The room items list shows "loaf of bread" under "๐Ÿ“ฆ Items here"
  4. Type take loaf of bread in the command input and press Enter
  5. The item disappears from the room list and appears in Alice's inventory panel
  6. The floating player list shows Alice carrying "loaf of bread"
  7. A system message appears in chat: "โšก Alice picks up loaf of bread."

Tab 2 โ€” Bob

  1. Enter name: Bob
  2. Bob spawns in Town Square and sees "loaf of bread" is gone
  3. Bob's floating player list shows Alice's inventory item
  4. Bob sees the system message about Alice taking the bread

Chat

  1. Alice types say hello Bob! and presses Enter
  2. Bob's chat panel shows: "Alice: hello Bob!"
  3. Alice's chat panel also shows the same message

Chat is room-scoped

  1. Alice walks north to Hilltop
  2. Both tabs show the move. Alice is in Hilltop, Bob is in Town Square
  3. Alice types say Can you hear me?
  4. Alice sees her own message
  5. Bob does not see the message โ€” he's in a different room

Drop items

  1. Bob walks north to Hilltop to meet Alice
  2. Bob types drop bread โ€” but Bob doesn't have the bread, nothing happens
  3. Alice types drop loaf of bread
  4. "loaf of bread" reappears in Hilltop's room items
  5. Alice's inventory is empty
  6. Both see the system message

Inventory edge cases

  1. Alice takes the bread again
  2. Bob tries take loaf of bread โ€” fails (Alice already has it)
  3. Alice walks south to Town Square while carrying the bread
  4. Alice drops the bread โ€” it appears in Town Square, not Hilltop
  5. Bob walks back to Town Square and takes it โ€” succeeds

Persistence โ€” items survive server restarts

  1. Alice picks up the "loaf of bread" from Town Square
  2. Close Alice's tab โ€” a system message shows: "โšก Alice drops loaf of bread." The bread is back in Town Square
  3. Refresh Bob's tab โ€” Bob reconnects and the bread is in Town Square where Alice dropped it
  4. Open game.toml โ€” the file now has an empty [[players]] section (Alice disconnected) and her items were returned to the room they were in

Disconnect drops all items

  1. Alice takes "loaf of bread" and walks to Hilltop
  2. Alice closes her browser tab
  3. Bob sees: "โšก Alice drops loaf of bread." โ€” the bread appears in Hilltop (Alice's last room), not in Town Square
  4. Bob walks to Hilltop and takes the bread โ€” it works

Items are persisted in game.toml

Open game.toml after taking and dropping items. Each room's items list reflects the current state:

  • When you take an item, it's removed from the room's items list and added to the player's items
  • When you drop an item, it's removed from the player and added back to the room
  • When a player disconnects, all their items are dropped into their current room

Stop the server with Ctrl+C and restart it โ€” items are still in their last known locations in game.toml.

The floating player list always shows every connected player, their current room, and the items they carry. It never scrolls away because it's fixed to the viewport.

๐Ÿšฆ Troubleshooting

"field items is missing" compiler error on serde derives โ†’ You added items to TomlRoom and TomlPlayer but not to the runtime types (PlayerInfo, RoomInfo, RoomData). Every struct that mirrors the TOML data needs the field.

"cannot find type ChatMessage" โ†’ Add the helper struct: #[derive(Clone, Debug)] struct ChatMessage { from: String, message: String, room: usize, is_mine: bool }. It goes just before the Game component.

Chat messages appear for everyone regardless of room โ†’ Check the Chat message receive handler. The client should filter using msg.room == my_room. If you're not tracking room in the ChatMessage struct, add the field.

Item doesn't appear in inventory after taking โ†’ The ItemTaken handler on the client pushes the item to the player entry in the players signal. Verify the handler matches the player_id field from the broadcast. Also check that the server's Take handler adds the item to player.items before broadcasting.

"my_info" is moved when used inside the for msg loop โ†’ The my_info value is computed from signals outside the rsx! block. In the chat rendering section, we call my_info.as_ref() inside the for loop body rather than capturing the outer value by reference. The pattern shown in the code (let is_same_room = my_info.as_ref().map_or(...)) avoids ownership issues because it reads from the signal each time.

Floating player list overlaps the grid โ†’ Ensure .game-layout { margin-right: 250px } is in your CSS. Adjust the value if your panel or margin is different.

Command input does nothing on Enter โ†’ Check that onkeydown uses Key::Enter (not "Enter" string). In Dioxus 0.7, key events return the Key enum, not a string.