← All Workshops

MudEngine Part 8: Inventory & Chat

Step 5 / 10

Update load_game_state and save_game_state

Now that the data models carry items, the load and save functions need to convert the new field between TOML and runtime types.

Update load_game_state to map TomlRoom.items and TomlPlayer.items into the runtime types. Update save_game_state to serialize them back. Also update the RoomInfo construction in the WebSocket endpoint.

mud-engine/src/main.rs
fn load_game_state(path: &str) -> GameState {
    let content = std::fs::read_to_string(path)
        .unwrap_or_else(|e| panic!("Failed to read {}: {}", path, e));
    let toml_game: TomlGame = toml::from_str(&content)
        .unwrap_or_else(|e| panic!("Failed to parse {}: {}", path, e));

    let rooms: Vec<RoomData> = toml_game
        .rooms
        .iter()
        .map(|r| RoomData {
            id: r.id,
            name: r.name.clone(),
            description: r.description.clone(),
            exits: r
                .exits
                .iter()
                .map(|e| (e.direction.clone(), e.destination))
                .collect(),
            items: r.items.clone(),
        })
        .collect();

    let players: HashMap<String, PlayerInfo> = toml_game
        .players
        .iter()
        .map(|p| {
            let pi = PlayerInfo {
                id: p.id.clone(),
                name: p.name.clone(),
                room: p.room,
                items: p.items.clone(),
            };
            (p.id.clone(), pi)
        })
        .collect();

    GameState { rooms, players }
}
mud-engine/src/main.rs
pub fn save_game_state(state: &GameState) {
    let toml_game = TomlGame {
        rooms: state
            .rooms
            .iter()
            .map(|r| TomlRoom {
                id: r.id,
                name: r.name.clone(),
                description: r.description.clone(),
                exits: r
                    .exits
                    .iter()
                    .map(|(d, dest)| TomlExit {
                        direction: d.clone(),
                        destination: *dest,
                    })
                    .collect(),
                items: r.items.clone(),
            })
            .collect(),
        players: state
            .players
            .values()
            .map(|p| TomlPlayer {
                id: p.id.clone(),
                name: p.name.clone(),
                room: p.room,
                items: p.items.clone(),
            })
            .collect(),
    };
    let toml_str = toml::to_string_pretty(&toml_game).unwrap();
    std::fs::write("game.toml", toml_str).unwrap();
}
💡 Item cloning

You'll notice we use .clone() on item strings in several places. Items are small strings — Vec<String> is cheap to clone. In a production MUD with thousands of items you might use Arc<String> or interned IDs, but for a workshop demo the simplicity of cloning strings is the right trade-off.

Step 5 / 10