Tracking clients on a multiplayer game
I'm working on a text based multiplayer rpg but I'm wondering the best way to track clients and determine which clients to send information to. My current idea is to store the socket information in the mysql database I'm using for the game within the character objects. If I do this, would I create a database object the size of a socket and then store the socket as a character string or is there a better way to do this? Also my plan on figuring out who to transmit to is determine if it is a character event, a room event or a world event. With that I could get a list of sockets for the clients meeting the proper criteria. My only concern is if I do this I would have to loop though each client and transmit the information one at a time. Is there a more effecient way of doing this? Just looking for ideas.
- My $0.02
you probably shouldnt store this kind of stuff in a MySQL database. you should keep things like this in memory. databases are more for static, longer term storage.
anyway, the simple solution to this problem is to use a lookup table. what language are you using? if its C++, you can use the std::map. If you have a decent compiler it will have a std:: / stdext::hash_map which is faster (hash map is not standard, but some compilers implement it like VS.net 2k3).
when a player connects (or possibly when he joins the game instead, since people can be connected without being in game, e.g. logging in or creating an account..), you add him to the table. when he disconnects, you remove him. when you want to do something to him, you just look him up based on his key. it would look something like this:
first declare your lookup table
when they connect..
when they send us data..
when they leave..
doing it this way is robust and as fast as it gets.
anyway, the simple solution to this problem is to use a lookup table. what language are you using? if its C++, you can use the std::map. If you have a decent compiler it will have a std:: / stdext::hash_map which is faster (hash map is not standard, but some compilers implement it like VS.net 2k3).
when a player connects (or possibly when he joins the game instead, since people can be connected without being in game, e.g. logging in or creating an account..), you add him to the table. when he disconnects, you remove him. when you want to do something to him, you just look him up based on his key. it would look something like this:
first declare your lookup table
std::map<Socket,Player> players_in_game;
when they connect..
void OnConnect(Socket sock){ //add this player to the game / lookup table players_in_game.insert(std::make_pair(sock,Player()));}
when they send us data..
void OnPacketReceive(Socket sock){ std::map<Socket,Player>::iterator it = players_in_game.find(sock); //if this connection was found in the table if(it != players_in_game.end()) { //do stuff with the player here! } }
when they leave..
void OnDiscoonnect(Socket sock){ //remove him from the lookup table players_in_game.erase(sock);}
doing it this way is robust and as fast as it gets.
FTA, my 2D futuristic action MMORPG
You could use sql for storing connection info but you don't want to have to round trip to a database everytime you need to talk to a client. The database would be used when different machines in your server farm need to find if somebody is logged in or communicate with a non-local user for some other reason (a /tell maybe). You definitely want some sort of cache for local connections though.
My game didn't use sql but it could just as easily done so. Instead I had a special entity server to keep track of these cross-machines things. You would ask it for (say) "user/Drethon" and it would return you info about which server process owned that entity (if any) and could optionally create the entity for you if it didn't already exist. The local server would keep a cache of entities it knew about to save the round trip. Beware that distributed cache coherency is a non-trivial problem.
My game didn't use sql but it could just as easily done so. Instead I had a special entity server to keep track of these cross-machines things. You would ask it for (say) "user/Drethon" and it would return you info about which server process owned that entity (if any) and could optionally create the entity for you if it didn't already exist. The local server would keep a cache of entities it knew about to save the round trip. Beware that distributed cache coherency is a non-trivial problem.
-Mike
That approach does sound better since the data for the clients would not be too large.
The only thing I'm still wondering is for sending the data for say a room event, do you have to loop though all characters in the room and send the data to each one or is there a better way of doing this?
The only thing I'm still wondering is for sending the data for say a room event, do you have to loop though all characters in the room and send the data to each one or is there a better way of doing this?
- My $0.02
Quote:
Original post by Drethon
The only thing I'm still wondering is for sending the data for say a room event, do you have to loop though all characters in the room and send the data to each one or is there a better way of doing this?
thats how i do it.. but why the concern about it? seems pretty fast and simple to me. your only looping through each character in the room, right? or are you looping through a large list of characters and seeing if they are in the same room, and then sending?
FTA, my 2D futuristic action MMORPG
I suppose it depends on how you do it. If you leave the characters in the MySQL, then you would have to generate a list of who is in the room then loop though that list to transmit the data out.
On the other hand going with the idea of keeping the socket data in memory, you could keep a map of the world in memory with where the characters are at and then you would just pull a room from memory and loop though all the characters. I'll have to run the numbers on how much memory that would take but I don't think that would be significant until the world became very large.
I guess I was kind of hoping there was a method to transmit a packet of data to a number of clients at once but I suppose that isn't really possible with the standard socket interface.
On the other hand going with the idea of keeping the socket data in memory, you could keep a map of the world in memory with where the characters are at and then you would just pull a room from memory and loop though all the characters. I'll have to run the numbers on how much memory that would take but I don't think that would be significant until the world became very large.
I guess I was kind of hoping there was a method to transmit a packet of data to a number of clients at once but I suppose that isn't really possible with the standard socket interface.
- My $0.02
Quote:
Original post by Drethon
I suppose it depends on how you do it. If you leave the characters in the MySQL, then you would have to generate a list of who is in the room then loop though that list to transmit the data out.
On the other hand going with the idea of keeping the socket data in memory, you could keep a map of the world in memory with where the characters are at and then you would just pull a room from memory and loop though all the characters. I'll have to run the numbers on how much memory that would take but I don't think that would be significant until the world became very large.
I guess I was kind of hoping there was a method to transmit a packet of data to a number of clients at once but I suppose that isn't really possible with the standard socket interface.
i think you are strongly under estimating how much memory the average PC has. even if you run this on a POS computer i doubt you would have any concerns about memory. you should put things in memory which "feel right" in memory, and players is by far one of them.
just think about this more - lets say your Player class was 100 bytes. even with 10,000 players, this is till under a meg of ram. with 100,000 players, this is under 10 megs of ram. with 128 megs of ram, you could handle one million players and still have over 30 megs left of memory.
FTA, my 2D futuristic action MMORPG
This topic is closed to new replies.
Advertisement
Popular Topics
Advertisement
Recommended Tutorials
Advertisement