Advertisement

Strategy game's users actions synchronization

Started by January 08, 2017 05:33 PM
6 comments, last by alexoy 7 years, 10 months ago

Hello,

I'm creating a strategy game (something like turn based) where the world potentially can be very big. I'm interested in how player's actions typically are being synchronized?

Users have limited screens, bigger or smaller. Ofcourse you can move the area, but it is too big in total.

  • If I'll send any player's actions to all players every time - I expect problems with time delays/lagging and network communication. Moreover I don't need that - I still can see a limited area only, so I'm no interested in something that happens 100km far away.

  • If I'll broadcast to the nearest 10m only (for example) - still can be problems for different users - somebody on mobile has too small screen, he can see only nearest 1-2m, for example; For other users with very big screens 10m is absolutely not enough and they want more.

  • If I want a visible distance be dynamic - I have to store all users screen sizes on the server side somehow. Then to send the actions to the users who are able to see that. But this sounds difficult.

What are the optimal solutions for this task? I'm interested in high performance from users point of view, and I want to minimize time delays and network communications.

Thanks!

Question is what actions to what users need to be sent?! Single user doesn't need to get data about all existing users.

For example I make a move - my game-neighbor must see it, so he gets this info from network. But somebody very far away is not interested in this info, so server probably shouldn't send this info to him. But then again problems with different screen sizes (what exactly is "too far away"?!), as I described in the main question

Advertisement

Synchronicity is an illusion. Usually network delays and server processing time isn't noticeable except maybe in high stress situations. Assuming your code is written properly.

First thing, queues. To ensure data on the server is synchronized across all clients, you should use queues to process certain requests to ensure players get a first come, first serve response. It only matters how the server sees the data. The client just receives updates about what's going on server-side. Of course this means the client who sends their request first gets updated on the server first and this will definitely depend on network speeds.Sadly, there is nothing much you can do about that. Someone might be able to expand on this point but I'm sure there are methods to average out response times to clients. If your server is updating at a fixed rate then there is nothing much you can do except hope the client is using a decent network and minimize the length of data you send to them. Better to send byte-sized (hehe pun) pieces than massive chunks.

Second, you should use a region system that is independent of the client's device. The server will send updates based on where the player is viewing and only within a certain radius (or number of surrounding squares/cubes). Photon gives a nice explanation of this. Also, generally, manufacturers use specific display ratios. So you shouldn't be storing screen sizes but screen ratios that are common. If a device doesn't support your list of ratios then the user shouldn't be able to play OR, you should force a specific ratio to be used client side (one that fits within the entire display so elements don't go off screen). Sometimes its better to compromise than to satisfy every user especially in mobile development. Ensure your client works on common devices and worry less about devices that are rarely used.

Scaling should definitely be used. So what is 10m on a laptop might be different on an Iphone (unit to pixel ratio?). That way you know that the client will never zoom out beyond say, 100 square meters and never zoom in to less than 10 square meters. If they do manage to exceed those limits, then you simply don't send updates beyond those limits (server validation) and so if the client is modified it really won't help the player in any way.

Hope this makes sense :)

First: If your game has the ability to load the entire map into memory, and if your game is fun enough that people want to cheat, then some people will write a program that "reads" the map of your world from out of your game's memory space.
Thus, you should build the game so that players CAN zoom out and see everything the game client knows, just to even the playing field. This means that if a player shouldn't be able to see something, then the server shouldn't send it in the first place.

Second: Specifically which communication method you use, depends on your demands. RTS games typically have players send commands to the server for some tick a little bit into the future; the server then forwards all those commands to all players in time to execute that tick.
Other games use other methods, but the idea that the player sends commands for some future "tick" while there are already other commands/ticks outstanding and waiting on resolution is pretty common. This "pipelining" of commands allows you to write a game that progresses faster than the turn-around-time from the slowest player to the server.

And, finally, it's important that all events happen in the same order on all the machines, but it is NOT important that they happen at "exactly the same time" (whatever that may mean, given that the Earth is big enough that Einstein relativity actually affects you!)
enum Bool { True, False, FileNotFound };

First: If your game has the ability to load the entire map into memory, and if your game is fun enough that people want to cheat, then some people will write a program that "reads" the map of your world from out of your game's memory space. Thus, you should build the game so that players CAN zoom out and see everything the game client knows, just to even the playing field. This means that if a player shouldn't be able to see something, then the server shouldn't send it in the first place.

Not being able to zoom out to view the entire game ruined Starcraft 2 for me entirely.

This is probably the best technical dive I've seen into how a large scale RTS works behind the scenes

https://blog.forrestthewoods.com/the-tech-of-planetary-annihilation-chronocam-292e3d6b169a#.vr0wt8oyq

Synchronicity is an illusion. Usually network delays and server processing time isn't noticeable except maybe in high stress situations. Assuming your code is written properly.

First thing, queues. To ensure data on the server is synchronized across all clients, you should use queues to process certain requests to ensure players get a first come, first serve response. It only matters how the server sees the data. The client just receives updates about what's going on server-side. Of course this means the client who sends their request first gets updated on the server first and this will definitely depend on network speeds.Sadly, there is nothing much you can do about that. Someone might be able to expand on this point but I'm sure there are methods to average out response times to clients. If your server is updating at a fixed rate then there is nothing much you can do except hope the client is using a decent network and minimize the length of data you send to them. Better to send byte-sized (hehe pun) pieces than massive chunks.

Second, you should use a region system that is independent of the client's device. The server will send updates based on where the player is viewing and only within a certain radius (or number of surrounding squares/cubes). Photon gives a nice explanation of this. Also, generally, manufacturers use specific display ratios. So you shouldn't be storing screen sizes but screen ratios that are common. If a device doesn't support your list of ratios then the user shouldn't be able to play OR, you should force a specific ratio to be used client side (one that fits within the entire display so elements don't go off screen). Sometimes its better to compromise than to satisfy every user especially in mobile development. Ensure your client works on common devices and worry less about devices that are rarely used.

Scaling should definitely be used. So what is 10m on a laptop might be different on an Iphone (unit to pixel ratio?). That way you know that the client will never zoom out beyond say, 100 square meters and never zoom in to less than 10 square meters. If they do manage to exceed those limits, then you simply don't send updates beyond those limits (server validation) and so if the client is modified it really won't help the player in any way.

Hope this makes sense :)

Thank You! Info about regions from you and Photon eng. is the exact answer to my question. So I need to implement these logical regions and (un-)subscription to them by players. Any recommendations about the size of a single region? If we take a modern typical screen 1920x1200 px - how many regions it should contain? Or it is only a part of one much bigger region?!

Events queues probably are not for me. Game is something like turn based, I don't need to receive 10 events per second for beautiful graphics and movements. As it is a multiplayers game, with shared world, but still turn based - I don't want to make big problems for players who has gone offline or away, but don't want to be killed so easy during that time by other players (there won't be an option to disappear, world is same for all players). In my current plan users will be able to make 1 action during 1 minute by 1 unit. One minute for all players, then reset, and then new minute for new move. May be I'll change the numbers/limits later. So when a new event has appeared - it will be forwarded by server to the related regions, no need to wait or fill queues, because you are allowed to make 1 move per minute only.

What do you think about that?

Advertisement

First: If your game has the ability to load the entire map into memory, and if your game is fun enough that people want to cheat, then some people will write a program that "reads" the map of your world from out of your game's memory space.
Thus, you should build the game so that players CAN zoom out and see everything the game client knows, just to even the playing field. This means that if a player shouldn't be able to see something, then the server shouldn't send it in the first place.

Second: Specifically which communication method you use, depends on your demands. RTS games typically have players send commands to the server for some tick a little bit into the future; the server then forwards all those commands to all players in time to execute that tick.
Other games use other methods, but the idea that the player sends commands for some future "tick" while there are already other commands/ticks outstanding and waiting on resolution is pretty common. This "pipelining" of commands allows you to write a game that progresses faster than the turn-around-time from the slowest player to the server.

And, finally, it's important that all events happen in the same order on all the machines, but it is NOT important that they happen at "exactly the same time" (whatever that may mean, given that the Earth is big enough that Einstein relativity actually affects you!)

Thank you for a reply.

"If your game has the ability to load the entire map into memory" - on server side may be, on client side no. World is shared and it's size potentially can be very big and extendable - don't want somewhen in the future to require 16GB RAM from every user :) But zooming yes, useful option, not implemented yet.

"players send commands to the server for some tick a little bit into the future" - could you describe what means "into the future" technically?

""pipelining" of commands" - my game is something like turn based, I don't need to receive 10 events per second for beautiful graphics and movements. As it is a multiplayers game, with shared world, but still turn based - I don't want to make big problems for players who has gone offline or away, but don't want to be killed so easy during that time by other players (there won't be an option to disappear, world is same for all players). In my current plan users will be able to make 1 action during 1 minute by 1 unit. One minute for all players, then reset, and then new minute for new move. May be I'll change the numbers/limits later. So when a new event has appeared - it will be forwarded by server to the related regions, no need to wait or fill queues, because you are allowed to make 1 move per minute only. What do you think about that?

First: If your game has the ability to load the entire map into memory, and if your game is fun enough that people want to cheat, then some people will write a program that "reads" the map of your world from out of your game's memory space. Thus, you should build the game so that players CAN zoom out and see everything the game client knows, just to even the playing field. This means that if a player shouldn't be able to see something, then the server shouldn't send it in the first place.

Not being able to zoom out to view the entire game ruined Starcraft 2 for me entirely.

This is probably the best technical dive I've seen into how a large scale RTS works behind the scenes

https://blog.forrestthewoods.com/the-tech-of-planetary-annihilation-chronocam-292e3d6b169a#.vr0wt8oyq

A little different thing than I was asking. If I understood right - the main point is about curves - thing where/how you store what happens with one single object. But haven't seen recommendations about which curves must be shared with which users. Have I missed?

Good point about zooming, if you are a "boss" of your army, you would like to know what happens in general with your units. In real world you could do this with you own units only and you almost have no info about enemies.

This topic is closed to new replies.

Advertisement