I would like to build from scratch a kind of small (extremely small and simple) MMORPG game with click movements inside a given grid (something like an online Pokemon game). When I click on a cell, the player will move to reach the pointed area (using a pathfinding algorithm such as A*). But, I have no idea about how to build the network protocol of the movement system. And, googling the subject doesn't seem to help me a lot. I need to make a choice: - either I send a message to the server each time I move from one cell to another (which isn't efficient at all because if we are in a 100ms latency network, I can only sens 10movements/sec and if I ask the server to acknowledge the movement it can only do 5moves/sec) - either I send a message each time the player wants to change its direction (it clicks on another cell). The client sends periodically its position to the server and it checks if it's coherent with the destination.
The second solution looks a lot better than the first one and I think that a real game systems must implement that strategy. Am I wrong?
Also, how can we build systems based on that solution that doesn't let a modified (hacked) client be able to send fake positions and teleport anywhere they want? Does real systems implement somethink like a "incoherent sent position" system that will try to try to detect and fix those problems?
Or, is there something simpler to implement? Thank you very much
In a realtime game I would create a panthing mechanic. I would use a formula such as: Speed * time = distance.
now if you run the same logic in the client and the server you only need to send the movement logic at the beginning and the sever can answer with a finish message when the distance is traveled. (compare at the end to prevent cheating. the server always wins)
Now if the client cancels in the movement to go somewhere else, you send a cancelation of panthing and the time that you traveled. The same goes when changing the panthing (in this case you send a new path staring at a new time and place).
Thanks to ScarletMerlin's answers I think there's a simple solution to my problem.
When the player wants to move from one position (for instance 0,0) to another (for instance 10,10), it sends a "MOVE 10 10" message to the server.
Then, only the server will apply the pathfinding algorithm and send after each move the position to the client. (for instance, by message CURRENTLY_ON X Y). Then, the client will update the position of the player.
It's a kind of automatic synchronisation from the server to the client. It also solves the problem of the first solution (one move and one ACK per movement) thanks to pipeling. For instance, if the network has a 1000ms delay and a move is set 50ms, we will just receive messages at time 1000, 1050, 1100, 1150, ... So, we will just feel the lag when the player is changing its direction.
The user will also feel some lag when changing from one direction to another but if we assume that the delay is quite low and symetric (it doesn't seems to be a too strong assumption), it won't be so much percepted (as the change direction will often arrive before the sending of the CURRENTLY_ON message and the server can interrupt its current action (going straight on) to handle the new one).
Related
I’m developing a multiplayer network pong game, my first game ever. The current state is, I’ve running the physic engine with the same configurations on the server and the clients. The own paddle movement is predicted and get just confirmed by the authoritative server. Is a difference detected between them, I correct the position at the client by interpolation. The opponent paddle is also interpolated 200ms to 100ms in the past, because the server is broadcasting snapshots every 100ms to each client.
So far it works very well, but now I have to simulate the ball and have a problem to understanding the procedure.
I’ve read Valve’s (and many other) articles about fast-paced multiplayer several times and understood their approach. Maybe I can compare my ball with their bullets, but their advantage is, the bullets are not visible. When I have to display the ball, and see my paddle in the present, the opponent in the past and the server is somewhere between it, how can I synchronize the ball over all instances and ensure, that the it got ever hit by the paddle even if the paddle is fast moving? Currently my ball’s position is simply set by a server update, so it can happen, that the ball bounces back, even if the paddle is some pixel away (because of a delayed server position).
Until now I’ve got no synced clock over all instances. I’m sending a client step index with each update to the server. If the server did his job, he sends the snapshot with the last step index of each client back to the clients. Now I’m looking for the stored position at the returned step index and compare them. Do I need a common clock to sync the ball?
EDIT:
I've tried to sync a common clock for the server and all clients with a timestamp. But I think it's better to use an own stepping instead of a timestamp (so I don't need to calculate with the ping and so on - and the timestamp will never be exact). The physics are running 60 times per second and now I use this for keeping them synchronized. Is that a good way?
When the ball gets calculated by each client, the angle after bouncing can differ because of the different position of the paddles (the opponent is 200ms in the past). When the server is sending his ball position, velocity and angle (because he knows the position of each paddle and is authoritative), the ball could be in a very different position because of the different angles after bouncing (because the clients receive the server data after 100ms). How is it possible to interpolate such a huge difference?
As you are developing your first game, I think you should try the simplest but brute-force method first. Then you will experience the first exciting result, then you will get courage and try the better methods.
Like Source Engine method, process the game play in one side and send every object state to the other for each 1/30 second. This is a brute method but it works in LAN environment.
Now you will find problems that occur WAN environment where latency is more than 1/30 second.
I am not sure it works actually, but I think that:
Assume that the movement of ball does not change by only player's hit.
Send ball position P, velocity and player A position only when player hits the ball to B.
At B, receive it but process it as if time L is already passed (L=latency between A and B * 2) However, rendered ball should be keep its previous movement until it reaches the ball position P.
Values which never are affected can be masqueraded, even if it is time value. :)
I am developing an java-asterisk application that is calling subscribers to deliver messages. At some moments during the call, I need to monitor whether the subscriber is talking or is silent. I need to monitor that for a fairly long time (1-3 seconds) but don't want to interrupt the flow of the outgoing message.
The way I am doing it now is as below
streamFile(*file A*);
exec("WaitForSilence","300,1,1");
waitStatus=getVariable("WAITSTATUS");
streamFile(*file B*);
This works fine but it is only a 300ms detect and a 1s timeout, so from the subscriber point of view the silence between file A and file B is almost unnoticeable. But if I want to listen for longer (say 3 seconds for example) then the subscriber's experience will be ruined.
What I would need is a function similar to "WaitForSilence" but that:
runs in parallel to the script;
delivers its outcome in a variable channel with a name that I define (as there might be several calls to the function, and I need to get all the results)
I've been looking for more than aweek now and couldn't find a way to do that. Any ideas?
Code you provided will do wait, after that will do playback.
There are no way do that simple in one application.
Posible ways:
1) create c/c++ application(asterisk guru skill required) for that.
2) create enother channel, mix it with ChanSpy and in that channel do silence detect. Complexity - expert in asterisk.
Both are not so short(more then 2-3 screens of code), so can't be described in this site.
You can also try use Background application, but i am afraid it will not work too.
I try to found the best method to do this, considering a turn by turn cross-plateform game on mobile (3G bandwidth) with projectile and falling blocks.
I wonder if one device (the current player turn = server role) can run the physics and send some "key frames" data (position, orientation of blocks) to the other device, which just interpolate from the current state to the "keyframes" received.
With this method I'm quite afraid about the huge amount of data to guarantee the same visual on the other player's device.
Another method should be to send the physics data (force, acceleration ...) and run physics on the other device too, but I'm afraid to never have the same result at all.
My current implementation works like this:
Server manages physics simulation
On any major collision of any object, the object's absolute position, rotation, AND velocity/acceleration/forces are sent to each client.
Client sets each object at the position along with their velocity and applies the necessary forces.
Client calculates latency and advances the physics system to accommodate for the lag time by that amount.
This, for me, works quite well. I have the physics system running over dozens of sub-systems (maps).
Some key things about my implementation:
Completely ignore any object that isn't flagged as "necessary". For instance, dirt and dust particles that respond to player movement or grass and water as it responds to player movement. Basically non-essential stuff.
All of this is sent through UDP by the way. This would be horrendous on TCP.
You will want to send absolute positions and rotations.
You're right, that if you send just forces, it won't work. It's possible to make this work, but it's much harder than just sending positions. You need both devices to do their calculations the same way, so before each frame, you need to wait for the input from the other device, you need to use the same time step, scripts need to either run in the same order or be commutative, and you can only use CPU instructions guaranteed to give the same result on both machines.
that last one is one that makes it particularly problematic, because it means you can't use floating-point numbers (floats/singles, or doubles). you have to use integers, or roll your own number format, so you can't take advantage of many existing tools.
Many games use a client-server model with client-side prediction. if your game is turn based, you might be able to get away with not using client-side prediction. instead, you could have the client lag behind by some amount of time, so that you can be fairly sure that the server's input will already be there when you go to render. client-side prediction is only important if the client can make changes that the server cares about (such as moving).
i am developing a multiplayer roleplaying game, (No, its not a mmorpg. ;)
My current setup is like this.
Client tells the server "I want to move forward"/"I want to move backwards", the server then updates your entity, and informs all clients in the area about the change. The server is also updating each entity every 20ms and sending updates every 100ms to the clients, these updates contains position, velocity, rotation etc.
So far so good, however i have nothing in store for smoothing the movement between the packets on the client side, and i must say, i can not get it working. I have been reading up on prediction, interpolation, deadreackoning but its all a big mess for me.
So right now i am just doing something like "Position = Packet.Position", which causes a very stuttering movement.
So, what i want help with is, how do i get a more smooth movement? Have been looking at the XNA Prediction Sample, but i could not get it right.
Thanks //F
Read Valve's description of their multiplayer protocol. It should be instructive, and gives a very clear example on how you do the prediction/interpolation.
I'd suggest the idea from another question (see the accepted answer)
Here the client calculates its position itself as if its not a network game. Client regularly sends his current position to the server. And if client cheats or can't continue moving in the chosen direction, server just sends the client his correct position.
The same algorithm was used in Ultima Online (at least when I was playing it 10 years ago)
I solved it by running a ghost entity alongside with my main one.
The ghost will get updated every frame aswell, but whenever a packet comes in, his values are set to the values of the packet.
I then gradually tweak the real entity to where the ghost is.
I'm learning about the various networking technologies, specifically the protocols UDP and TCP.
I've read numerous times that games like Quake use UDP because, "it doesn't matter if you miss a position update packet for a missile or the like, because the next packet will put the missile where it needs to be."
This thought process is all well-and-good during the flight path of an object, but it's not good for when the missile reaches it's target. If one computer receives the message that the missile reached it's intended target, but that packet got dropped on a different computer, that would cause some trouble.
Clearly that type of thing doesn't really happen in games like Quake, so what strategy are they using to make sure that everyone is in sync with instantaneous type events, such as a collision?
You've identified two distinct kinds of information:
updates that can be safely missed, because the information they carry will be provided in the next update;
updates that can't be missed, because the information they carry is not part of the next regular update.
You're right - and what the games typically do is to separate out those two kinds of messages within their protocol, and require acknowledgements and retransmissions for the second type, but not for the first type. (If the underlying IP protocol is UDP, then these acknowledgements / retransmissions need to be provided at a higher layer).
When you say that "clearly doesn't happen", you clearly haven't played games on a lossy connection. A popular trick amongst the console crowd is to put a switch on the receive line of your ethernet connection so you can make your console temporarily stop receiving packets, so everybody is nice and still for you to shoot them all.
The reason that could happen is the console that did the shooting decides if it was a hit or not, and relays that information to the opponent. That ensures out of sync or laggy hit data can be deterministically decided. Even if the remote end didn't think that the shot was a hit, it should be close enough that it doesn't seem horribly bad. It works in a reasonable manner, except for what I've mentioned above. Of course, if you assume your players are not cheating, this approach works quite reasonably.
I'm no expert, but there seems to be two approaches you can take. Let the client decide if it's a hit or not (allows for cheating), or let the server decide.
With the former, if you shoot a bullet, and it looks like a hit, it will count as a hit. There may be a bit of a delay before everyone else receives this data though (i.e., you may hit someone, but they'll still be able to play for half a second, and then drop dead).
With the latter, as long as the server receives the information that you shot a bullet, it can use whatever positions it currently has to determine if there was a hit or not, then send that data back for you. This means neither you nor the victim will be aware of you hit or not until that data is sent back to you.
I guess to "smooth" it out you let the client decide for itself, and then if the server pipes in and says "no, that didn't happen" it corrects. Which I suppose could mean players popping back to life, but I reckon it would make more sense just to set their life to 0 and until you get a definitive answer so you don't have weird graphical things going on.
As for ensuring the server/client has received the event... I guess there are two more approaches. Either get the server/client to respond "Yeah, I received the event" or forget about events altogether and just think about everything in terms of state. There is no "hit" event, there's just HP before and after. Sooner or later, it'll receive the most up-to-date state.