11/04/2008

Implementing Multiplayer

At the moment I am plugging SDL_Net into Ocean Horizons, the newly added basic AI and movement states need to send/receive requests to/from server game in multiplayer game, there are also tons of things needed to be addressed in network/SDL_Net/server game in general:


Message Struct:
Ocean Horizons needs an universal serialized header format to identify a message's type, length and possibly a timestamp indicating the birth of such message in game time.


Serializing Game Objects over Network:
Generally sending a whole object over network is a big nono in most applications. However, in a game like Ocean Horizons, such thing is unavoidable. Probably I will just copy-paste the save to file serialization functions and replace FILE/OFSTREAM buffer with a char* buffer =D Reusable codes *cough*


Sending AI order/action changes events over Network:
AI Order/Action are the fundamentals of a simple "state-machine" AI used in pretty much every game genre, sometimes they are also referred as "Goals" in games have relatively higher level intelligence, e.g:FPS bots.
An Order/Action should be as simple and as small in size as possible, since they change alot in a game, and every object that has AI has at least 1 instance of both.
For example, when sending an attack-some-target order, you will need:
1.The attacker
2.The target
3.IF in range THEN attack ELSE move-to-attack
4.IF move-to-attack THEN get-target-position

The order 'ATTACK' is just an enum or constant that is probably only 1 byte if you have less than 255 order types(well if you have more than 255 order types, you fail at making a game =o), while the attacker and the target are probably multiple bytes objects, to minimize the network overhead you will need an unique id for every object in game, sending Unique Id(usually 4-8 bytes, depends on how you handle Unique Id and how many objects your game has) is much more efficient than serializing the 2 objects, both in time and in space.

In Server Client model Ocean Horizons will be using the overhead of Sending AI order/action will be significant on server, basically one AI order/action message will need to be send [number of players] times by the server, so having slim AI order/action messages will be critical.


Synchronization over Network:
Synchronization is a bit tricky in a game with tons of objects, if you synchronize all objects every few second, you will probably run out of bandwidth. Though if you don't synchronize them frequently enough, desynchronization will happen, which is bad because one or more players might be playing an entirely different game from others..
Server Client model should minimize desynchronization, but it does come at a price:the reduced responsiveness when you are issuing orders, executing commands as non-server player. Basically you have to do:

1.Someone needs to issue order 'move to X' for my ship with id 123
2.Send Request TYPE:SHIP_ORDER_MOVE SOURCE:123 TARGETX:0 TARGETY:0 to server
3.Server receives Request and Process, if it's a valid order then send granted Request to all connected players
4.The original Request Sender being one of the connected players, so he receives granted Request and his ship begins to move to X eventually..


In-game join:
To join in game you probably need to download the last server game save and synchronize with all server's game states. I think there is no other simple and efficient way to do this..


Handling Dropped Player/Player X has left:
The best way of doing this I have seen is openttd's: when one player drops/leaves his units/buildings remain intact but got taken over by AI, other player or the dropped/left player may join to regain control over his old assets later.

I typed too much again =/

No comments: