I've wondered about this for a while as I worked on my project, but couldn't quite come up with the best way to expose my problem. I'll start with some context.

Context

I have a game that is divided into rooms. So from an asset point of view, it makes sense to load and unload them on a room by room basis. In my case this boils down to all the textures and audio files required by that room.

However, player triggered events can change the state of any dynamic object in the world, even those that are not on the current room. Furthermore, since the game is multiplayer, even if I'm not seeing the changes immediatly, other players might. So, even if the assets aren't loaded, I still need some way to register that change in state.

The way I'm currently handling this is to keep the entire game world state in memory since the start of the game, and only bother about dynamically loading and unloading its assets.

Which leads to the following questions related to resource management.

Questions

1. Loading and storing the entire game state at once seems reasonable for the scope of my games, but I get the feeling it wouldn't scale very well to larger projects. So how is this usually implemented in massive games such as MMOs that need to update a large amount of entities that are far away from the player?

2. Assets that are guaranteed to be needed for a particular room (such as the room's scenario and static objects) can be loaded when the player enters the room - possibly with a transition or a loading screen in between. But what about assets for unpredictable game entities that might suddenly come into your current room at any time, such as other players?

Would it be reasonable to treat those separately, load them all at once when the game starts, and keep them in memory the entire time, or would it be better to load them and unloaded dynamically in a separate thread? And in that case, does XNA handle loading assets from another thread well?

• Not a direct answer to your question, but XNA's ContentManager class is not itself thread-safe. But you can have multiple content managers on multiple threads. And you can load on a background thread while your game is running. You can inherit from ContentManager and override its methods to implement your own lifetime policies for things that it loads. – Andrew Russell Mar 1 '12 at 12:05
• @AndrewRussell The idea was just to use the same ContentManager but load a few assets from a background thread while the game is running, just to avoid stalling the game. In that scenario, can I "just do it" or would I run into problems? I really need to brush up on concurrency. – David Gouveia Mar 1 '12 at 12:12
• The only issue is that you can'd unload from the default ContentManager without unloading everything it has loaded. You need multiple managers, or to customise it. – Andrew Russell Mar 1 '12 at 12:51

My understanding of most multiplayer games do in fact cull data that is sent to clients. Either by distance, or visibility - if your player is not visible to me in Q3A then I don't need to know what frame of animation is playing, or even which direction you're facing, but the sounds you make could be useful.

I suspect MMOs do much the same - any time where your travel isn't completely visible (when you take a ship on WoW) you can assume you're moving to a different bit of hardware. The state of such a game is actually very simple, which is why we don't have MMOs with Quake like fighting, rather the turn-based affair that you can see happening in the background. The server only needs to send a small amount of the total game-state to the player.

However yes, some assets can be spooled (like the game-world) and others should be held in memory. Particularly player / mob related ones.

Something like Doom the game-state was linked to the gameworld, all the clients pushed up their changes and pulled down the entire world-state from one player's machine (the Green marine always had a slight edge and was always the server in Genuine Doom) - the game was hard-wired to the slowest machine's frame-rate - turn off one machine's turbo, and everyone would slow down.

More advanced games and I believe the general way things are done is with a client-server, even in single-player, one machine runs the server and connects to itself, the other machines connect to it. There is still a slight advantage to the host due to network latency, but you can now pull the server code into a separate executable and run it anywhere. Because the client and server are abstracted, players jump around when there are delays - however, one slow player will not grind down all players.

My understanding of Diablo was that the server maintained the overall game-state, but the clients offloaded much of the work. Where individual Mobs were was unimportant, just recording their state when killed, and drops when they happened. This way the 4 players could be anywhere in the huge game-world and there wouldn't be huge amounts of traffic required.

• What about a game whose server is also one of the clients, such as when you're playing Diablo II over LAN and you're the one hosting the session (at least I believe it is server-client). Would it be any different in that case, since it's not a dedicated server machine? – David Gouveia Mar 1 '12 at 20:06