client /server
In my current game design i want to have multi-player support, I would like to write my engine in a client/server model way. First off where do I start, How do I create messages etc, what if my game isnt connected to the internet, what do i do, I have a simple plan on paper but would like a simple tutorial or something, also I plan on allowing players to play with users on phones/pda so are there any tutorials on this sort of thing.
Quote:
First off where do I start, How do I create messages etc
I would say, start by learning how to use a networking API, like winsock, and try making little test applications with it to see what you can do and how you can do it.
Quote:
what if my game isnt connected to the internet, what do i do
You can run both a server and a client on the same machine, like the Quake derived games do, or you can simply implement a server and a client in the same build... Your client might already run a local version of the game when it connects to a server in order to predict what the actual game server will do.
Quote:
I have a simple plan on paper but would like a simple tutorial or something
There are winsock tutorials, a few tutorials explaining some basic network models... There is also a document around somewhere talking about the implementation of the networking in Quake and QuakeWorld I believe. Just remember that in the end, you will need to create something of your own, their solutions won't directly apply to what you want to do.
Quote:
also I plan on allowing players to play with users on phones/pda so are there any tutorials on this sort of thing.
You would have to check which networking APIs those use. However, as long as they can transmit data over TCP/IP, there should be no problem in using similar network programming techniques on these devices.
For winsock, check out these links.
http://msdn.microsoft.com/library/default.asp?url=/library/en-us/dnanchor/html/ntwrkprot.asp
http://www.tangentsoft.net/wskfaq/
Check out my website for more software development links.
http://www.dslextreme.com/users/kuphryn/links.html
Kuphryn
http://msdn.microsoft.com/library/default.asp?url=/library/en-us/dnanchor/html/ntwrkprot.asp
http://www.tangentsoft.net/wskfaq/
Check out my website for more software development links.
http://www.dslextreme.com/users/kuphryn/links.html
Kuphryn
Hello JinJo,
In your messages that you will create to send your data,
always at lest include a version number, type of msg, packet size.
I would have something like.
struct msghdr
{
Byte version; // start out at 1
Byte endian; // if you need to go cross platform with different endian
short msghdr_size; // size of your message hdr so header can grow with version number. Doesn’t need to be very big maybe even a byte since msghdr should very change a lot.
int msg_tpe; // type of message
int size_msg; // size of message following.
}
then by send this 12 byte message as the first 12 bytes of your actual msg you can always know every message version, endian, size of data used in newer version of message header, and type of message, then the size of message following the msghdr.
ex.
version 1 msghdr
has version=1, endain=0 for little, msghdr_size=0 no new data memebrs type=2 and size=200
version 2 msghdr had added to it a time field.
struct msghdr
{
Byte version; // start out at 2
Byte endian; // if you need to go cross platform with different endian
short msghdr_size; // size of your message hdr so header can grow with version number. for version 1 = 0 version 2 = 8
int type; // tye of message
int size_msg; // size of message following.
double time; // time of message maybe
}
now you still read 12 bytes but now you also read in another 8 bytes before you can get to the message your sending. ie 200 bytes.
If you are a version 1 client your read and throw away the 8 bytes of time. If you are a version 2 client you can use the 8 bytes of time.
This method allows for older clients to still be able to send/recv data form newer clients/servers.
Just some ideas for you.
Lord Bart :)
In your messages that you will create to send your data,
always at lest include a version number, type of msg, packet size.
I would have something like.
struct msghdr
{
Byte version; // start out at 1
Byte endian; // if you need to go cross platform with different endian
short msghdr_size; // size of your message hdr so header can grow with version number. Doesn’t need to be very big maybe even a byte since msghdr should very change a lot.
int msg_tpe; // type of message
int size_msg; // size of message following.
}
then by send this 12 byte message as the first 12 bytes of your actual msg you can always know every message version, endian, size of data used in newer version of message header, and type of message, then the size of message following the msghdr.
ex.
version 1 msghdr
has version=1, endain=0 for little, msghdr_size=0 no new data memebrs type=2 and size=200
version 2 msghdr had added to it a time field.
struct msghdr
{
Byte version; // start out at 2
Byte endian; // if you need to go cross platform with different endian
short msghdr_size; // size of your message hdr so header can grow with version number. for version 1 = 0 version 2 = 8
int type; // tye of message
int size_msg; // size of message following.
double time; // time of message maybe
}
now you still read 12 bytes but now you also read in another 8 bytes before you can get to the message your sending. ie 200 bytes.
If you are a version 1 client your read and throw away the 8 bytes of time. If you are a version 2 client you can use the 8 bytes of time.
This method allows for older clients to still be able to send/recv data form newer clients/servers.
Just some ideas for you.
Lord Bart :)
It's a noble goal to support various versions of the system talking to each other, although the testing turns into a nightmare after a while. You might want to support only version N and N-1 at the same time, so that people who "stay current" can update while online, or something.
You could negotiate endian-ness when the connection is established, and just store the endian-ness of the client in your structure about the client, so you don't have to send that data everytime.
Or you could set the high bit of the version when the client is some specific endian-ness, assuming you don't need more than 128 versions of the message.
Or you could make sure that you always put data in in network order (or at least a well-defined network order), and pull it out using the same byte order, and that way you don't need to worry about the endian-ness of the data at all, which is what most cross-platform games actually do.
Also, sending a 32 kB packet on a modem will take about 6 seconds, assuming you have a perfect connection -- usually, it'll take more like 12 seconds. To get latency down, you really want your packets to be < 256 bytes, and thus, you can use a single byte for the length, and save a little more space in that header.
You could negotiate endian-ness when the connection is established, and just store the endian-ness of the client in your structure about the client, so you don't have to send that data everytime.
Or you could set the high bit of the version when the client is some specific endian-ness, assuming you don't need more than 128 versions of the message.
Or you could make sure that you always put data in in network order (or at least a well-defined network order), and pull it out using the same byte order, and that way you don't need to worry about the endian-ness of the data at all, which is what most cross-platform games actually do.
Also, sending a 32 kB packet on a modem will take about 6 seconds, assuming you have a perfect connection -- usually, it'll take more like 12 seconds. To get latency down, you really want your packets to be < 256 bytes, and thus, you can use a single byte for the length, and save a little more space in that header.
enum Bool { True, False, FileNotFound };
This topic is closed to new replies.
Advertisement
Popular Topics
Advertisement
Recommended Tutorials
Advertisement