I think this is impossible :(

Started by
9 comments, last by iMalc 17 years, 1 month ago
I am currently writing a real-time strategy game, and I'm up against a wall in multiplayer. For various reasons, including replay functionality and bandwidth, I want to send mapped player input instead of player actions. I am trying to emulate the method explained in this article, but that's where I reach the dead-end. Since the input would be applied at a delay, it would completely break the system. If a player made a selection box, those units might be out of the selection box by the time the input was processed. If that doesn't make any sense, it's because I'm probably not explaining it very well. Do you have any suggestions? The only solution that I can think of is to run two simultaneous simulations (with one at a delay) but there must be an easier way.
Advertisement
Quote:
For various reasons, including replay functionality and bandwidth, I want to send mapped player input instead of player actions.


At first glance, this seems like a preposterous design requirement. Even the article you link doesn't do that. It passes commands (not input, nor results).

Why in the world would the server care if the player selects units? The server itself should probably be completely ignorant of how the player gives orders...
Quote:For various reasons, including replay functionality and bandwidth, I want to send mapped player input instead of player actions.

Why? Replays should be easy to do with actions and if you use absolute values (instead of relative values) then your replay would never get out-of-sync. I doubt player actions would be that bandwidth-consumning. Lets say you have 255 different actions, with on average 120 bit of data attached (should be enough for at least two coordinates, probably more depending on the required precision). If a player sends 10 actions per second (remember these are actions like "train unit", "go here", etc.) then we are going to need 1.25 kbps. Compare that to sending 60 mouse positions per second (one position is two 32-bit floats) which takes 3.75kbps.
Why make it unnecessarily hard for yourself? Send player actions, not player input. It won't be less network-efficient - maybe you'd have to send a list of unit IDs instead of the coordinates of a selection box, but it's still a trivial amount of bandwidth and the same amount of latency, and you wouldn't actually have to send anything when the player just selects some units.

For replays, do you really want it to follow precisely the player's camera movements and button clicks, rather than letting the replayer act as an independent observer (with their own camera control, etc, and just no way to interact with the world)? If so, the camera and mouse details could be recorded non-deterministically and independently of the deterministic simulation, and not used to control the world when playing back the replay, so all the network communication would still just be player actions instead of inputs.

I can't think of any reasonable way to make it work when you're sending inputs instead of actions, because the delay would be unbearable - if you click on something, you really want the game to detect that you've clicked on it, and that's not possible if it's delaying a few hundred milliseconds to cope with network latency. That would be why nobody else ever does it that way [smile]
Thanks a lot for your responses.

Excors:

Yeah I realized that this is the exact reason that no one does it this way! :P

When watching a reply you wouldn't have to watch it in "first person" mode if you didn't want to.

However, as a Starcraft player I know that first-person videos (even of lesser-skilled players) are highly sought-after, and the file sizes of a replay like this would be tiny compared to a video. It would also help detect cheating.

Is there a better way besides running to simulations at once?

Telastyn:

I want to do it this way to add the replay functionality I will explain below.

CTar: I wouldn't be sending the mouse position 60 times a second, I would be sending the mouse position with each action, and probably 5 times per second when no actions are being sent.

The reason I want to do it this way is so players can see how other players play. With Starcraft, first-person videos of good players are immensely popular, because it's fun to see how fast they play and it's a great way to see their thought process as they were playing.
Record the replay locally. You can record all the mouse actions without sending anything over the network.
well then, send the commands over the network. In addition separately capture the interface usage. Then when you play a replay you would have the option of watching it 1st or 3rd person.
Quote:Original post by Deyja
Record the replay locally. You can record all the mouse actions without sending anything over the network.


Well if the viewer should be able to switch to see from another players perspective then they would have to exchange their recorded data.

I'd just record the mouse data and the actions. It shouldn't be too expensive or space consumning. Then run the simulation using the recorded actions and paint selection boxes, cursor and everything else which isn't recorded as an action on top of it. I doubt such a file would be over 1MB for an 8 player, 5 hour match.

Quote:I wouldn't be sending the mouse position 60 times a second, I would be sending the mouse position with each action, and probably 5 times per second when no actions are being sent.

When you say action, do you mean moving the mouse or an actual action in the game? If you just mean moving the mouse then fine, but if you mean game action then you're going to be in trouble if you try to show the cursor location to the viewer of the replay. I also assumed you'd do something like this, but you should be ready to handle 60 mouse actions per second since that is going to happen many times. I don't expect the player to do 10 actions every second either, I expect him to do that when he is doing as much as possible (start of game, when training units, attacks, etc.).
Does your game run at a fixed-tick-rate?
i.e. Applying gravity, collision detection and resolution, Position of items, Processing input changes etc all happen at a fixed rate (e.g. 25 times per second)?
You can just hold the state of the world at each of the last (say 50) ticks or so, meaning that you always copy the world state as you update it.
Then send through which tick to apply the input to, apply it to that tick, and then fastforward (process extra ticks without drawing) up to the current tick. At least that's what you could do for an in-game spectator. If you just want to record it, then you do much the same thing, but you would only ever fast-forward if the tick you receive hasn't been processed yet.
Is any of this making sense?
"In order to understand recursion, you must first understand recursion."
My website dedicated to sorting algorithms
Thanks for the responses. :)

Quote:Original post by iMalc
Does your game run at a fixed-tick-rate?
i.e. Applying gravity, collision detection and resolution, Position of items, Processing input changes etc all happen at a fixed rate (e.g. 25 times per second)?
You can just hold the state of the world at each of the last (say 50) ticks or so, meaning that you always copy the world state as you update it.
Then send through which tick to apply the input to, apply it to that tick, and then fastforward (process extra ticks without drawing) up to the current tick. At least that's what you could do for an in-game spectator. If you just want to record it, then you do much the same thing, but you would only ever fast-forward if the tick you receive hasn't been processed yet.
Is any of this making sense?


Yes it is, and that's what I meant by having a second simulation running. It's the only solution that I can think of, but I can imagine it being a load on the processor to be essentially running two copies of the game at once.

My the game will only be running at 20 "ticks" per second, which might make it easier on the cpu.

CTar:

I meant I'll send the mouse coords at every game action (player hits the move hotkey, etc.). Every four game ticks, if there were no actions, the mouse coords will be sent anyways.

To all: I'm sorry if I'm being incredibly dense or newbish with any of this.

edit: typos and clarity... and again

This topic is closed to new replies.

Advertisement