The Bloom filter idea sounds great, but I'm unsure of how you'd implement it in practice. If you're treating it as a bunch of false positive collisions, what's the client supposed to do in the time while it waits for the server to report that it's not a real collision?
Trusting The Client
Does it need to do something? It's perfectly acceptable if it shows "kaboom" when the next tick's server reply comes in (OP says 20 updates per second, so that's not long), is it not? Player will still be standing on the trap then.The Bloom filter idea sounds great, but I'm unsure of how you'd implement it in practice. If you're treating it as a bunch of false positive collisions, what's the client supposed to do in the time while it waits for the server to report that it's not a real collision?
Normally, a game has a pattern more or less like this: Client says "I'm moving to XYZ", and starts simulating locally to cover the network latency, and shows the move to the user, assuming the move will be OK. Eventually, the server confirms the move (or well, does not).
In this case, the server's reply might very well be: "Move confirmed. Oh by the way, you stepped on a trap".
In real life, when you step on a land mine, there is a fraction of a second while you're already lifting your foot again before you realize the "click", and then the mine only goes off half a second or so later. That seems to be a "works perfectly OK" method of building land mines. They wouldn't do that if it didn't work. I'd assume nobody will find a similar (indeed much shorter) delay disturbing or even immersion-breaking in a game.
It's certainly possible to get a send-commands-only game working, because in theory it should be no different and any updates in between are redundant. In practice, having regular updates in between slices up your potential timing errors into smaller chunks so that there are fewer surprises, which in turn let you make stronger assumptions about position (and thereby your ability to verify it). The MMOs I've worked on, and some (most?) FPS games, worked this way.
Some game types, eg. many RTSes, require that all clients are synchronized, and this usually requires waiting for a positive response before moving. I think that is what HPlus was referring to (in another thread?) But it's not a universal solution to all games. Most action games allow the client to start moving locally, and send corrections later if necessary.
You say that the game gets unsynced by following this approach, but actually, all games are always unsynced. All you can do is attempt to minimize the amount, and the effect, of the desynchronisation. You can never get around the fact that some packet might take longer to reach one player than it did to reach another, and that's nothing to do with waiting for confirmations or not. In fact, the wait-for-confirmation method usually is the least likely to get out of sync because the server tries to notify everybody of a change at the same time. The approach where you start moving locally is more prone to problems because if the server has a 50ms hiccup then the other players get a 50ms extra delay between that player moving locally on their own machine and that player being seen to move on the other player machines. This is the tradeoff you make for responsiveness.
Whether you need 20 messages per second (don't call them packets, especially if you're using TCP, because the protocol decides what goes in a packet, not you) is down to your game type, bandwidth, etc. It also depends somewhat on how quickly players can change direction and velocity, and on how accurately you're able to extrapolate it on the server for the benefit of other players. For the type of games I write, i.e. not shooters, I would probably try 10Hz, or 5Hz.
I'm learning as we go, so it's great to hear invaluable feedback like this. I apologize for calling them packets, I just get messages and packets mixed up and my brain thinks they are synonymous. :P
My game is something like, let's say.. a Maplestory type movement, except top down view.
I'm feeling uneasy with trusting the client. Without even addressing the paragraph containing fireballs: You make sure that people are not speedhacking by taking a delta. OK, fine.
So that means as long as I do not move faster than running speed, I am allowed to walk over water and over chasms. I am allowed to fly and attack my enemies (who cannot reach me with melee) with missle attacks from above, too, as long as I am not moving faster than X.
Having the client do the physics can be OK, but there certainly needs to be a validation for plausibility, or you need a means of making sure that cheating is not that easy and has an overwhelming chance of being detected.
One example how such an offload can be done would for example be to let the client do the collision checking against traps that the player can step on using a Bloom filter (or a spatial hash with enough collisions). Bloom filters have false positives, so the knowledge the client can extract and use to its advantage is limited. When the client reports "hit something (maybe)", the server checks if really something happened. If a client doesn't report so and so often, or if some explicit verification markers aren't reported, it is cheating.
It's hard for the client to selectively drop only the harmful events because it doesn't know what it is that just gave a "positive" result, might be a true positive or false positive. On the other hand, the server only has to do the heavy lifting once every 20 or 30 (or even fewer) steps, not every step.
Yep, I have a secondary loop that does exactly that, infact, it runs at around 2 times a second or so. It checks if the player has overlapped (or ranged into) a coin, or map entity. This then notifies all players in that game to tween that coin towards that player, etc. I could raise that up to run more times per second, but it feels right locally, although I should get my instance server on a VPS and test the latency offsets. I feel like latency is going to bite my ass again.
Does it need to do something? It's perfectly acceptable if it shows "kaboom" when the next tick's server reply comes in (OP says 20 updates per second, so that's not long), is it not? Player will still be standing on the trap then.
Okay, I guess I misunderstood the initial point. I guess what I'm asking is, how would this differ from the standard method of:
(a) move the player locally (or perform other action)
(b) report to server
(c) server checks if new location (or action, state, whatever) is reasonable
(d) server requests correction if new location is slightly bad, or does something more punitive if it's excessively bad
I can see how the bloom filter can save a round trip in certain ways, but if the server requires that the client checks in with the server sufficiently often, this starts to depend a lot on the nature of the feature being checked, and probably is no better than just doing a server-side check anyway. But maybe I'm missing some nuance here?