Thoughts on Multiplayer Game Co-operation and Distributed Computing
Since being on holiday I've been making some progress on my game prototype. I've implemented the foundations for a multi-player experience. This has been quite interesting. Firstly, I tried to implement a simple client-server architecture using TCP sockets by implementing a GameServer (if you want to be the game server) or GameClients (for each player that doesn't).
The first implementation was slow due to the constant verification that TCP has to do to ensure that traffic arrives, in order and without packet loss. I tried to implement it instead without such guarantees using UDP and indeed this improved the performance drastically.
The basic design is a system where each client registers with the game server, akin to joining a lobby in a multi-player game and as each new player arrives in the lobby details about the player is captured, such as asking the client to tell the GameServer who he is (NickName). The game server stores reference to where the client is - if we're using TCP then this will be the socket that the client used to communicate with the server, if using UDP (which is faster, so preferred) then we store the client's source port on the game server (I use connected UDP). This way the game server can talk back to the client, something like this.
How it all works, is that if a client raises an event such as moving the player, this event is serialized and forwarded to the game server, who then in return distributes that same message to all the other game clients (with the exception of the original sender). In doing so the original sender's nickname is labelled as the target of the event so that when the message reaches the clients, they know who in the system that event is for, i.e it's for the player that moved, so each client can move that particular player in that particular way so that all players see the same player move on their screens. Equally, if the game server (who is also a player) moves, this event is serialized and sent to all players, again labelling the event as being from the game server player's nickname. Each system has an event queue that is added to by reading these events off the network when they are sent by the Game server - here is a simple design.
In general, the mechanism works well in terms of the coordination of notifying other players what one specific player did. I've yet to integrate it fully to actually see the player that moved, move the same way on all the other player's screens - but the messaging and the networking is all there - backed by UDP or TCP. Getting the architecture setup in this way is a milestone. Like most things that are well implemented, it takes time to move from each stage of the design because one needs to fully evaluate what the next stage needs/should be and, more importantly, that it will be useful and not a wasted effort of coding. In this way, designing and thinking is an important next step and when I reach a milestone like this, I like to take a break and think about how to move from this milestone to the next one. So that's where I am right now.
One thing that has become clear is that in order to fully create a multi-player game, where all participants move and respond on each players screen, requires level initialization so that we can dynamically initialize a level with as many players as having joined, and then tell all of them to use the same level initialization and level creation parameters when starting the level on their screens in the same way, i.e complete with all the positions of all the other players. So there needs to be some dynamic collaboration to say, 'hey, these are all the players and they are here and here in the level, go and create the level that way when the game starts'. This needs to be done on all clients so all clients look the same way so that messages targeted for players actually reach players because they have been added/created to the same level that all other players are playing. This is the next milestone.
But while I know what needs to be done, I've been travelling and working and well it's a great time to do other things while you're at a milestone and you don't need to finish anything yet as you've not started the next thing. So, I've been thinking about the general idea behind distributed networking and participant collaboration (because that is what a multiplayer system is really), and how it is generally an information collaboration system used for many types of problems. You could use it for collaborating on individual results that a client has come up with, in like a distributed computing scenario. I think this is where computer games technology is so interesting and useful for so many other things, particularly via network programming - as it allows you to design systems that can be used in other distributed scenarios like to create say a map-reduce environment or some other clustering environment where resources, results and information are shared across multiple participants just like in a multi-player game. The interesting thing is that it's not just about communicating across the network, its about communicating across the network to inform other people what you've done or what someone else has done, and in so many applications knowing what exactly someone has done in your network is useful because its the basis for collaboration or at least, of information sharing.
In many ways, I already knew this from my work creating the distributed broker but it never actually told everyone else what one person is doing, it never radiated the effects of one person to all others concerned, and it also never used UDP, so that is cool.
What are the applications or concerns for such a system?
- Too much information perhaps, not everyone wants to know about all other's information, but in games we definitely do, we want to know exactly what the other players are doing so that we can emulate that behaviour on all our screens. In fact, this would be useful in distributing real-time messages to multiply display boards, say at an airport or train terminal.
- With so much data flying around, security and integrity of that data are important, particularly if you need to be 100% sure that the information you've received is exactly as it was intended (it hasn't changed, ie its integrity is in check) and that it's absolutely from the person who sent it. So perhaps ensuring that the data transmitted is secure is important, generally. For a coordinated and distributed algorithm implemented a distributed game agents absolutely. For a network game, maybe a lack of security could compromise the integrity of the game (someone is changing the network data and messing things up)
- Latency would be an issue for games, if it takes ages to act on a piece of information, then the real-time nature of a game is compromised. If the system is not real-time, then this wouldn't matter - it gets it when it gets it. Could implement the TCP mechanism to improve the reliability in these types of systems. Possibly compression, encryption and hashing be used to improve both the security and latency by reducing the size of transmitted data, but how would it affect the performance?
- A system that reports all the activity of others could be useful for auditing purposes - ie replicating what has happened to multiple places that it guaranteed that what has happened can be verified.
- It could also be a useful way to distribute the same information to agents that use it differently like each one applies or uses the data differently, say uses a distinct algorithm and this way multiple 'tests' could be run in parallel, i.e each receiving agent can run use the received data at the same time and report back its results.
I can't think of any more uses but distributed computing is basically what we're talking about and that is a huge field. I'd like to probably think a little more about the security of distributed computing, particularly in networked games or how implementing it could affect the gaming experience. That's perhaps for another day.