I have recently released a realtime simulation game, and I am wondering if it would be possible to extend it with multiplayer without too many changes.
The game is a Sim game with a detailed AI and nature simulation and it is based on the XNA framework.
I have carefully separated the game code in a Simulation and a Client part, where the Simulation can run without a Client. The Client takes care of graphis and input. It takes player input and sends commands to the Sim using the Command design pattern.
How many changes would a limited multiplayer feature require? I am thinking of having no more than 3-4 players in a single game.
Would the Simulation need to run on a server, on one of the player machines, or would it need to be split up?
Is my game project multiplayer ready?
Would the Simulation need to run on a server, on one of the player machines, or would it need to be split up?
Running it on a server is easier.
You have to understand that 99.999% of the time players will not be able to connect to each other directly over the internet.
Games that are played over the internet but run the simulation on a player's computer have to have a matchmaker server hosted by a third party to bypass firewalls.
One common way for realtime simulations to be made multi-player is explained in detail in the excellent article 1500 Archers on a 28.8. Essentially, you write a fully deterministic simulation, and then only the inputs need to be sent over the network. Unfortunately, writing a full deterministic simulation isn't easy at the best of times, but it will be especially difficult to convert a large existing simulation to be that way. Note that this model does impact on the game design, you might notice that multi-player RTS games typically respond with a "yes, commander" before applying orders, this is to hide the latency of the input being fed into the network.
If your simulation doesn't feature too much data, you might get away with alternatives, such as selectively synchronising parts of the game state using area of interest management to prioritise the changes.
It really depends on the game though. What can you tell us about it?
I believe my simulation is (almost) deterministic. I have a gameplay recording feature which saves the Commands sent from the player to the Sim. I also store the seed for the random number generator. After I have done a little more work on it, I hope I will be able to replay a game perfectly by simply loading the Commands and executing them at the appropriate time.
Otherwise, my idea was to update the rendering part of the Client by polling the Simulation (server) a few times every second, instead of every frame as it does now. I am already doing interpolation of moving renderables each frame on the Client.
The game uses indirect control, so players are conditioned to expect delays from the time they issue a command until the agents respond to it.
You should be able to make that work for multiplayer, although there's probably still work ahead.
For example -- does your simulation think that there is "a player," or does it actually explicitly reference "the specific player in question" everywhere it needs to?
I did a rather big refactoring of the game to achieve the architecture we have now. Before that the the game was a monolith. The architecture has served us well when we implemented save/load as well as recorded games for debugging. I hope we can continue to reap the rewards from this investment.
If I can perfect the recorded game feature, the road to getting simulations on each player computer to run in sync should not be that long. Then I can probably keep most of the code we have already. I will still need a system to send out commands and manage the time steps as described in the article. I also need to figure out how to set up a server that will handle this task.
The Simulation should already be indifferent to who the player is. I am using the concept of allegiances which receive Commands. The allegiances can be either player- or AI-controlled.
Are there any network frameworks/libraries that are recommended for XNA games on Steam..?
Or you can invoke the Steam SDK using P/Invoke. Creating P/Invoke wrappers for APIs is often pretty easy.
So, there is good and bad news about going to a fully deterministic synchronized random number seed system.
The good news is that it solves a *lot* of issues in networking.
The bad news is that it is a fail hard solution. If you get out of sync at all, it fails catastrophically.