Jump to content
  • Advertisement
Sign in to follow this  
RandyJohn

Playing alone's no fun! A design issue...

This topic is 4238 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

If you intended to correct an error in the post then please contact us.

Recommended Posts

If I am to develop a simple bird's eye tile based shooter for single play and multi play, how do I go about designing client/servers etc. Within my game, I have a GameEngine class, a GameMaster class (static stuff like Graphics Adapters and Particle lists etc.) and player, particle bullet classes etc. How should I design it such that I can retain most of my current code and be able to multiplay, so's that a person can host a game and play at the same time. Where does 'stuff' go? Does the GameEngine's update function send & receive data to & from other GameEngine classes on other PC's? What's the general setup for this sort of thing?

Share this post


Link to post
Share on other sites
Advertisement
If you are looking at writing your own server/protocol rather than using DirectPlay or something similar, I have some simple ideas to start the discussion...
Quote:

How should I design it such that I can retain most of my current code and be able to multiplay

If the client is more or less finished, I would consider writing a dedicated server, so that a minimum of changes to the client is necessary.
(It doesnt mean that a single PC cant run both a server and a client application simultanously)

The server programs main (if not only) task is to receive requests from all the connected clients, and send replies back (not considering the login process for now) Stuff like bounce checking would be done by the server, before the reply is returned to the respective client/s.

The first serious problem I see is that the render engine can not be bothered with waiting on replies from the server.
Obviously we want the render to update the screen at least at a minimum rate. Say every 36 ms (or faster).
Since the time window that appeares between sending a request to the server and receiving the reply for that request can vary a lot, and will sometimes be more than 36 ms, I would consider making a separate thread in the client to receive these server replies.
If a client has sent a movement request, but still not received the reply, it would have to render the same screen as last frame rather than waiting.

The same thread could also have access to the game objects and be responsable for updating things like object positions and state.
Quote:

Where does 'stuff' go? Does the GameEngine's update function send & receive data to & from other GameEngine classes on other PC's?

I would let the client send the requests immediately (meaning anywhere in the code) without any kind of blocking or waiting.

Quote:
What's the general setup for this sort of thing?

All I know is that there is many ways to do these things. My suggestions are just some ideas for a simple solution

Share this post


Link to post
Share on other sites
So you're saying as soon as player hits left send the left packet to the server rather than build up a 'list' of such movements and send at once? Also UDP or TCP/IP? What you're saying sounds like UDP (I think I can't really remember), is that harder thatn TCP/IP?

Share this post


Link to post
Share on other sites
Quote:

So you're saying as soon as player hits left send the left packet to the server rather than build up a 'list' of such movements and send at once?

Yes exactly. The way I see it you will have to process every packet individually anyway so collecting them would just give you extra synchronization and timing issues. After all we just want to get the packets on their way as soon as possible. That was my idea anyway.

Quote:

Also UDP or TCP/IP? What you're saying sounds like UDP (I think I can't really remember), is that harder thatn TCP/IP?

TCP would be my choise for most games except for FPS games where high transfer speed becomes important.
As you may already know UDP is faster but is also unreliable. Every now and then a UDP packet will get lost or show up out of order. Most professional games would use UDP, and add some kind of re-transmission for lost packages. This can be quite complex to implement and its just not my cup of tea. I dont think I would be able to do it more efficient than TCP anyway, so I wont recommend it unless you realy know what your doing.
However, there is some premade libraries out there that does this for you.
I have some experience with UDT.
The nice thing with UDT is that it uses the same interface as winsock, so you could replace your winsock code with UDT code with a minimum of changes ^^
(If I remember correct you will have to compile the UDT source yourself in order to generate the library file)
Ofcourse, there is loads of solutions out there and I dont have enough experience to say which is better.

Using TCP is pretty much the same as using UDP when it comes to difficulty.
You wont even have to change your code design in order to switch between them.
That goes for both winsock, UDT and DirectPlay.

Share this post


Link to post
Share on other sites
Some games (I think Unreal amongst them?) use UDP like this:
Every information gets a priority, ie. a player dying would have higher priority than a eyecandy particle spawning somewhere.
Every information gets a sequence number.

Then you maintain a list of these informations, and every so often you
1. Delete any outdated information - this would be any information that has a low priority and already has been transmitted x times (the lower priority, the lower the x value).
2. Transmit all remaining information over UDP.

If the information reaches the reciever, it sends an ACK package back with the highest sequence number of the informations recieved.
When (if) the sender recieves this ACK package, it deletes all information with a sequence number lower or equal to that of the ACK package from the list.

I hope that helps a bit :)

Edit:
The advantage of this method is that low priority packages will not build up if there is package loss, like they would with TCP.
You might also want to build in a filtering that removes "obsolete" packages from the list, for example removing the oldest of two player position synchronization packages.

Share this post


Link to post
Share on other sites
Sign in to follow this  

  • Advertisement
×

Important Information

By using GameDev.net, you agree to our community Guidelines, Terms of Use, and Privacy Policy.

Participate in the game development conversation and more when you create an account on GameDev.net!

Sign me up!