moving multiple spaces

I have a real time game on a hex-based map. So far I’ve been lazy and restricted movement to just one hex at a time. This way the server verifies the target hex is empty, and the character occupies both hexes until the walk animation is complete. What are some approaches for allowing movement over multiple hexes? I’m pretty flexible on the rules, but ideally I would like other characters to block movement, and I’d like other characters to be able to attack the moving character as he goes by.

If I extend my current mechanism then the character will walk one hex, pause while it waits for the server to verify the next hex is empty, then walk to the next hex. While this gives me a simple, sure-fire way to deal with movement, I have a feeling that walk-pause-walk-pause-walk will not look good.

Ping on over 3G on a cell phone can be 600ms. This makes the pauses pretty brutal, but also means client-side prediction can get things very wrong. Maybe I could allow prediction of at most one hex? If a character completes the walk animation to the next hex but hasn’t yet gotten server authorization to move there, then it would pause before continuing. For a rollback I guess I could have the character turn around and walk back to where he came from.

Prediction is pretty complex. I’d like to keep it as simple as possible. Just thought of an optimization to the first mechanism… instead of the client moving one square, then requesting to move another, it would tell the server the entire path the character wants to make. The server would then send a “move” command at the proper intervals, cutting the latency in half. Maybe this would work well on WIFI and be good enough for 3G?

I thought about a different approach… when a movement is first chosen, the pathing is done and the server authorizes the entire path. During movement, no further checking is done – the character would just walk through any obstacles that appear. This is kind of lame and means the character doesn’t actually occupy each hex as he moves, so he can’t be attacked or otherwise affected, which doesn’t make much sense.

Any other ideas?

My first ideas was to send the entire path to the server, and the server will ‘ACK’ it (or not.) The server simulates the movement, and will only send ‘BUMP’ back to the client if there is an obstacle, at that moment in time. The client would then have to calculate a new path.

Fantastic idea, Riven! That sounds like it will work very well.

Yeah, I think that would work great.

I was trying to figure out the best way to deal with a similar problem in my now-single-player game Sinuosity and came up with the same conclusion. The client calculates the path, sends it over, the server verifies or rejects it, and if it rejects it tells the client to make a new path.

I ended up implementing a solution in my Dragon project. It is as described, but the server considers the path valid if the first move is valid. Each move in the path is only checked for validity by the server when the unit actually needs to move there. The client goes ahead and blindly moves the whole path. The server sends a correction if a move in the path is invalid when it is time to make that move.

One issue that came up is that, because the client is not authoritative, the client cannot decide to stop a unit from moving just because that client sees the unit is blocked. If the client did stop movement and the server decided there actually was no obstruction, then the server would not know the client is in an incorrect state. As a result, on the client, it has to be possible for two units to occupy the same map location. Without this, if a unit on the client moves on top of another unit (which can happen since the client can’t make the decision to stop), the map location of the other unit gets stomped.

Maybe a better example: units A and B are moving through map location 3,7 in such a way that they just barely miss a collision from the servers point of view. A client with some latency might have the units both occupying the same location briefly, even though there was no collision. Best case is one of the units disappears and then appears again when he moves to the next location. However, if one of the units stopped on the square where a collision was barely missed, he would not reappear. If this was your unit, you’d be unable to click him to move him so he would appear!

Ah cool, that’s a smart way of doing it. Interesting problem you encountered (your explanation of it was very clear).