🎉 Celebrating 25 Years of GameDev.net! 🎉

Not many can claim 25 years on the Internet! Join us in celebrating this milestone. Learn more about our history, and thank you for being a part of our community!

More MMORPG Questions

Started by
8 comments, last by B4 22 years, 10 months ago
Currently, the server for RPG game my friend and I are making keeps a list of players, their ID''s, and their locations, etc. in memory. So that if one player moves, it has to check every player in that list to see if they are around the player that is moving. If there is players surrounding the moving player, the server sends information about these players. This method gets very very slow as the number of clients increase, and a lot of CPU time is used. Before this method, we attempted a different approach. We had an integer array, one integer per tile. Each tile would hold the ID of the player if a player was located on that tile. This method requires much less CPU time, however it uses huge amounts of data (a 5000X5000 tile map requires 100MB of RAM). I have been unable to think of any good solutions to this problem, and I was wondering if anyone had advice on this. My other question is about updating information about surrounding players. If I am walking through a map, and I see a person for the first time the server should send me all of the information about that player (this structure is currently around 2000 bytes). However, if I see that player again, or if that player changes weapons, or something similar, the server should not resend the whole 2000 byte structure, since that would be a waste of bandwidth. How is it possible for the server to know when a client needs to send just an update, or the whole structure? I would like to thank all of the people that responded to me in my previous post, I greatly appreciate your advice. It helped me very much, and I thank anyone who contributes in advance.
Advertisement
maybe if you check only one player at a time? Or set like x categories, where x1 hold 100 people, x2 100 people, and then check x1, and shortly after check x2.

"I''''ve sparred with creatures from the nine hells themselves... I barely plan on breaking a sweat here, today."~Drizzt Do''''Urden
------------------------------Put THAT in your smoke and pipe it
I''m not exactly sure what you mean by checking one person at a time, I would eventually have to check each person anyways to see if they are around me.
Split your world into smaller zones, and have the client send the zone it is in when moving. Only check players in that zone. Or just have the client send its X and Y (and possibly Z) position and let the server compute which zone these coordinates are in. Then, once again, only check players in that zone.
What is the best way to group people into different zones?
Also, how would I handle people who are near the edge of a zone?
Hiya..

ok think of it in the same way as your 100MB map file but instead of like 1 block = 1 zone do (say there are 100x100 map blocks is a full screen) 1 zone = 50x50 so a players zone(zx, zy) : zx = x Div 50; zy = y Div 50; and check all players in the zone you are in + the 8 surrounding zones...

each zone should have a linked list of players (or pointing to the player records) and when a player changes zone, remove him from the old zone and place him on the new one ;-)

this way your 5000X5000 array of pointers becomes 100x100 pointers which is much more aceptable ;-) (40000 bytes / 40kb) or you can do the zones larger (but then the cpu time goes up because u have more players in each zone)

Hope that helps

Tim
~ Tim
quote: Original post by B4
Currently, the server for RPG game my friend and I are making keeps a list of players, their ID''s, and their locations, etc. in memory. So that if one player moves, it has to check every player in that list to see if they are around the player that is moving.

First suggestion: keep this list sorted by X or Y coordinate. This allows you to trivially reject a large part of the list instantly. Example: if we have a list sorted on the X coordinate, and we''re dealing with the 34th player on the list, then if player 31 is too far to the left, we know that players 0 to 30 are also too far to the left, so we can ignore them all. Same for players on the other side.

There are many ways of doing such optimisations, such as not using a single list (dividing the game up into regions and having 1 list per region is another way) but sorting on one of the coordinates is very quick to do, easy to maintain, and has good results.

quote: My other question is about updating information about surrounding players. If I am walking through a map, and I see a person for the first time the server should send me all of the information about that player (this structure is currently around 2000 bytes). However, if I see that player again, or if that player changes weapons, or something similar, the server should not resend the whole 2000 byte structure, since that would be a waste of bandwidth. How is it possible for the server to know when a client needs to send just an update, or the whole structure?

Surely you mean ''when a server needs to send just an update''?

I''d use timestamping. Example: Each player object has a timestamp for the last time their appearance changed. You can then compare the timestamp on a player, with the time recorded on the client when it last got an update about that player. This allows you to see whether the appearance has changed since the client last got the information, and therefore more info can be sent to the client. The client then updates its time accordingly. And if the player hasn''t changed since then, you don''t need to send the data.

Also consider breaking up that 2000 byte structure into several sub-units: not necessarily in terms of the C code that represents it, but in terms of how you send it to the client. You might find you only need to send certain parts of it. This is something only you can tell, given your particular code.
Use a quadtree and a map - store pointers to player information.

The map is used for quick access to update status information.

Store a backpointer in the player information to the quadtree node they're in. Jump over to the quad tree, and the players in the surround squares are the only ones that could possibly be visible. Determin the 'radius' in squares given the size of the sqaure and the maximum sight distance. Rip through those squares and do do sphere or circle based collision detection. Voila, butt-quick visiblity detection - at least until everyone is in the same area of the world. In which case you should reduce the maximum sight distance.

You could first do a pass within the player's square, and find everyone that's within a certain threshold of eachother, and use the same results for all of them (just increase the maximum sight distance by the threshold.) You could even do a whole square at a time, and you only need to do the CD on the edge squares.

The only trick left is updating their quad-square when they move. With a heirarchy of squares, the parent square could determine which square they belong in, or pass it on to thier parent if the player left that 'super' sqaure.

Magmai Kai Holmlor
- Not For Rent

2000 bytes!? what's in your player structure?

Edited by - Magmai Kai Holmlor on August 25, 2001 11:13:00 PM
- The trade-off between price and quality does not exist in Japan. Rather, the idea that high quality brings on cost reduction is widely accepted.-- Tajima & Matsubara
Thank you very much for the help, I have a much clearer understanding of how to do these things now.

This topic is closed to new replies.

Advertisement