3
\$\begingroup\$

I'm making a 2D, top down MMO game. ATM I can connect a player to a server and they get the map data from a DB. They can move around and hit some stuff and if they move near a viewport edge, the server sends new data etc.

Even a few players can do this, but since I don't have an, lets call it, "update manager" which tells the players where they are and the DB that the map has been altered. It's just a read only game at the moment.

My idea is, to tell the server where a player is and how big his viewport is. Then if any other player is in this viewport, the server will distribute the updates to each other player.

So I wouldn't have to tell the whole world what's going on.

The problem, however, is the ping.

If I have a ping of ~300ms, every other player would probably "jump" over the map, and not move smoothly. I could keep this synchronized with vector clocks, but it would still lag.

Also, how to keep the players from cheating? All ideas I got, don't really work. The only "safe" thing seems to be to calculate the game on the server and client, then throw away all data when the calculations are wrong. But this seems rather excessive to me.

--- Edit ---

Ok, I had some ideas after I read the comments.

  1. I will send an absolute state to the server for ever game entity I have. This state object will consist of the position, orientation, speed and an "action", which can be anything someone can do.

  2. I'm gonna keep the clients seperated in "small" arrays, each representing a area of the map. So I can calculate which client is near or in my viewport and needs to get my information.

  3. I have to find out if it's possible to get a timestamp of the request, to use it for sanity checking, so no player can send me actions from an invalid time-range to get his actions evaluated before the other players.

  4. Only only updates from other clients and errors from the server get sent to the client, if everything is ok the server just takes the informations.

\$\endgroup\$

2 Answers 2

6
\$\begingroup\$

You have identified the key problems. Your "bounding box" solution to what-to-update seems fine. You may want to make the update box a little wider than the view box, so that actors outside the view are already available if your player starts walking.

The usual solutions to jumping are:

  1. Some assumptions, e.g. other players keep moving in the same direction until the client knows otherwise. This allows the client to project what will happen, providing smooth movement of the other players.

  2. Interpolation / gentle catch up: when the client is told that a player should be 5 squares away from what the client currently sees, instead of jumping him to that position, he is slowly animated to his new projected position over time. So clients will see false information, but activity will appear smooth to them, which is the important thing! If the player is very far away from his correct position (e.g. >15 squares), then jumping him to the new position may be preferable.

You got the right idea about cheating. Only the server should decide what really happened, with the information he has. The clients must defer to whatever the server says, and throw away any wrong information they have.

For this reason, sometimes crucial feedback such as death-animations, frag count, player health, are not automatically updated/projected on the client; instead the client must wait for updates/triggers from the server, before such things are shown. The delay this necessarily causes is seen as a better payoff than showing the client false information.

So animations such as small explosions of a projectile can be shown, if they are identical whether or not they hit a player. But animations describing a hit on a player might be better off delayed, if it is important to players that these are always correct.

\$\endgroup\$
3
  • \$\begingroup\$ Thank you! :) The interpolation idea seems rather easy to implement. But the cheating thing seems kinda complex. I have a "virtual viewport" in mind, which will be generated for each player on the server and kept up to date.I will have to send every click and key-stroke to the server, but only the corrections from server to the clients, I guess... \$\endgroup\$
    – K..
    Commented May 16, 2012 at 13:23
  • 1
    \$\begingroup\$ @da_b0uncer you probably don't need to send every keystroke and click, but every action. The server need not handle button clicks, with their up and down animation, it only needs to handle the decision of weather or not clicking the button is a legal action at that time. If the user has a hacked client that lets them keep clicking 'super attack with 60 second cooldown' over and over, the server need only be capable of rejecting them. \$\endgroup\$
    – DampeS8N
    Commented May 16, 2012 at 14:07
  • \$\begingroup\$ I see... hum... are there any well known methods of sanity checking? \$\endgroup\$
    – K..
    Commented May 16, 2012 at 14:29
2
\$\begingroup\$

The viewport technique is a primitive form of what's called "area of interest filtering". You can Google that for a variety of more advanced variations that may work better for you.

For the second problem, there are a number of tricks you can use to alleviate it. The first is what JoeyTwiddle mentioned: interpolating positions.

However, doing only that will not be enough. You'll end up with constant lag in position.

The next thing you can do is predictive updates. If the server has measures a lag of 50ms, then the serve would send a position for 50ms in the future rather than the current position. Combine with interpolating.

The server can also send both a velocity and a position to the client, and the client can perform its own movement updates, periodically being corrected by the server. Again, combine with interpolation. You also need a bit of work to make sure that you dont send a velocity right before the character stops moving, causing the client to overshoot position; accounting for lag helps here too.

\$\endgroup\$
4
  • \$\begingroup\$ I read some stuff about "area of interest" but I guess my idea with the predefined square-tiles is the best, it just sucks if I want more than 9 squares. Probably there are some events which concern more than 9 squares, but I will handle them seperatly. like "if this boss dies, every monster gets a little bit stronger" where all monsters simply listen to this special event. \$\endgroup\$
    – K..
    Commented May 17, 2012 at 13:38
  • \$\begingroup\$ The monsters aren't being run on the client, so that's a slightly different case. The tricky bits are things like sound, or fast movin objects that may be far offscreen now but will be onscreen next frame. \$\endgroup\$ Commented May 17, 2012 at 16:55
  • 1
    \$\begingroup\$ There's also more advanced ways of doing things when you have richer terrain layouts. E.g., in a dungeon game where players can't see through/over walls, or when using fog of war, and so on. Especially in games where you don't want the players to be able to mod the client or use a special proxy to see entities that they shouldn't normally be able to see. \$\endgroup\$ Commented May 17, 2012 at 16:57
  • \$\begingroup\$ ah yes, you're right. but atm I plan to let the players see everything on the screen. :) \$\endgroup\$
    – K..
    Commented May 17, 2012 at 19:53

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .