The server may or may not be up. If its not hit the local server to try it.

Anyway, I've got the data I need to be sending back and forward happily sending/recieving and just had my first remote internet user log in. Surprise! Its all a bit jumpy.

I'm using TCP. I've turned Nagles off, or rather in Java land I've turned TcpNoDelay on. I'm using NIO for both the buffers and selecting. Its all done on non-blocking streams (apart from the ServerSocket). My client updates the server 5 times a second, and the server updates the appropriate clients 5 times a second. The players own character is maintained their end (and hence looks smooth). Character movement is interpolated on the client to smooth it out. However, the characters still jump around a fair bit.

Ideas so far:

a) Up the update rate (10 a second?). Bit spammy but maybe brute force is the answer.b) Switch to UDP (yes I've read the killer thread at the top), doubt this will help a great deal but I'm willing to give it a go.c) Some clever client manipulation of the data I don't get yet.d) Prevent quick changes of direction at the client.

Have you guys got any pearls of wisdom to divulge, or maybe just some experiences?

You cannot run packets out of a server on the internet at a given rate and expet them to arrive at the other end in anything approaching the same rate unelss you are talking VERY slow ticks (on the order of seconds).

Fact: Internet latencies with broadband modems will spike upwards of 200 ms and easily as high as 400ms or 500ms, thats a 1/5 to 1/2 of a second delay right there. It gets much much worse with analog modems who just love to stop and argue with the modem on the other end about your connection speed right in the middle of your communciation session. (This is called a 'retrain" and can stop all communciation for up to 6 seconds or so.)

So now on ot the advice:

Its sounds to me like you basically have a lock-step game-- the client has to receive a "tick's" data before it can go on. This is not a good model for the internet at all BUt if you are stuck with it then there are some tricks you can use.

One of the basics is called "latency buffering." What you do is build a queue. The length of the queue is the maximum latency time you expect . Lets say you have 20ms ticks (5/sec as yo usaid) and you are designing for up to 300ms of latency. The queue is 300/20 or 15 ticks long. When a tick comes in its added to the end of the queue, as a tick is needed it is taken from the front of the queue.

What you are really doing is effectively making EVERY tick a 300ms latent tick. This will make the controls feel slightly "laggy" but it takes advantage of a basic fundemental in human perception/response which is that people quickly get used to a predictable lag (even one of a suprisingly big size-- think about steering a tug boat) but even the smallest random one drives humans bat-shit.

You can hide the oddity in your game design to make it "make sense". I used this for a tank game (first game ever written for TEN actually.). I locally ramped up volume of the engines for the latency period when someone started a move and ramped them back down when they ended. The result was that it "felt" like you were driving a heavy machine with inertia rather then just using laggy controls and thus it "felt right" to the user.

The way out of this bind completely is to give up on lock-step and use an open loop asynchronous game model. Thats what most modern internet enabled games do. I disucss the diferences in my (too brief I know) chapter on networking in Shawn's book thats coming our soon. Once I finish the Big Thing(tm) I'm working on now I'm hoping to do a whole book on the subejct and discuss WAN gaming in more depth and with a lot more example code.

Got a question about Java and game programming? Just new to the Java Game Development Community? Try my FAQ. Its likely you'll learn something!

Its sounds to me like you basically have a lock-step game-- the client has to receive a "tick's" data before it can go on. This is not a good model for the internet at all BUt if you are stuck with it then there are some tricks you can use.

I'm not sure if I really do. If no data arrives currently then the current state is assumed to be right and the characters all keep moving.

Quote

One of the basics is called "latency buffering." What you do is build a queue. The length of the queue is the maximum latency time you expect . Lets say you have 20ms ticks (5/sec as yo usaid) and you are designing for up to 300ms of latency. The queue is 300/20 or 15 ticks long. When a tick comes in its added to the end of the queue, as a tick is needed it is taken from the front of the queue.

What you are really doing is effectively making EVERY tick a 300ms latent tick. This will make the controls feel slightly "laggy" but it takes advantage of a basic fundemental in human perception/response which is that people quickly get used to a predictable lag (even one of a suprisingly big size-- think about steering a tug boat) but even the smallest random one drives humans bat-shit.

This seems pretty good idea. In my words (just to make sure I understand it), I ensure that the updates coming from the server haven't arrived "too early" in comparison to the last update by keeping them buffered up until they should have arrived. This will smooth out the lag to a constant.

Actually in my case the players controls won't be laggy since the player maintains his/her own state locally.

Quote

The way out of this bind completely is to give up on lock-step and use an open loop asynchronous game model. Thats what most modern internet enabled games do. I disucss the diferences in my (too brief I know) chapter on networking in Shawn's book thats coming our soon. Once I finish the Big Thing(tm) I'm working on now I'm hoping to do a whole book on the subejct and discuss WAN gaming in more depth and with a lot more example code.

Looking forward to this book Is there anywhere I can read about open game loops at the moment?

Finally, after I went to bed last night it came to me in a vision, how about I do this:

* Recieve update from server* Predict where client should be when the next scheduled server update should arrive* Ensure that the movement of the character will get them to the predicted location by the schedule time of the next update

This would have the characters speeding up and slowing down to account for inconsistancies between client and server. Essentially it'd be the same as now but with some visual candy to make it look smoother.

You can hide the oddity in your game design to make it "make sense". I used this for a tank game (first game ever written for TEN actually.). I locally ramped up volume of the engines for the latency period when someone started a move and ramped them back down when they ended. The result was that it "felt" like you were driving a heavy machine with inertia rather then just using laggy controls and thus it "felt right" to the user.

Thanks for that; I usually invent theoretical examples of minor game-design changes to workaround networking problems, but that's a neat little example.

The remote-site smoothing is still missing but actually not a big deal (and good for debugging).

The main difference may be on the sending side. JPilot/HeadQuarter does not work with fixed rate which is artificial regardless how you do it. Either you miss the important moments in motion of you just flood the line.

HeadQuarter handles motion data up to second order (acceleration). The key now is the dead-reckoning, which leads to sending data whenever something significant happens.

Means: if the object doesn't move or moves straight, or has a constant acceleration .... NOTHING is transmitted. But when you press the 'forward' button .... exactly in that moment a message is formed an sent.

Done right and tuned well, only very few messages have to be sent. FlyingGuns e.g. uses 1-3 messages/second (could be less with better tuning).

And with few messages ... the line can be assumed to be free ... now buffered messages still waiting and increasing latency or so.

The code around HeadQuarters dead-reckoning is a bit messy and needs some deeper understanding. But doing it like JPilot does should work quite out-of-the-box.

Sidenote: of course the transfer for HeadQuarter NEEDS to be guaranteed - so it uses TCP only.

Sidenote2: I observed some strange HeadQuarter behaviour on low-latency networks/LAN. Seems to be related to the time manangement. Some research is still needed there.

I may have misunderstood your design. yes what you described in the second post sounds like a basic open loop "dead reckoning" model.

I'll try to sum up as briefly as I can what I talk about in the book.

The basic idea indeed is that you send an update to the other players with your state and a time stamp. When it arrives at the other player, the other player adjusts your position based on that state and the time passed. This often leads to a correction from where it thought you were. Going ahead into the future is predicted from that point given that state and then corrected for when the next packet arrives.

The trick to making this look good is how you handle prediction and correction. The more intelligent you can make the prediction hopefully the smaller the correction will be. But corrections will be inevitable to some degree.

If you do the correction by simply moving the foreign player's location you get a discontinuity that leads to the "warping" effect as described by players. If you view this properly though this is really a point-sampling problem. The solution then is to interpolate between points. Another way of viewing the same phenomenon is an error term. If you apply the error term all at once you get a discontinuity but if you apply it back in in parts you can smooth it out in the same way a dither smoothes out color errors.

A first order interpolation smoothes location but can cause fairly sudden changes in the first derivative (the acceleration). Higher order interpolations can also ramp acceleration in and out.

And yes people usually cheat the velocity to some degree when adding in the error term in order to get the player back to "correct" sooner

Got a question about Java and game programming? Just new to the Java Game Development Community? Try my FAQ. Its likely you'll learn something!

My actors tend towards the location the server indicates. This does cause them to have travel greater than their normally velocity at times but I've introduced a "clamp" so they never move more than 1.1x their velocity (configurable).

This means that they don't catch up to their location as quickly sometimes, although of course that location may be wrong by that point anyway. It does how ever make everything look pretty darn natural.

Now, I'm just trying to think of how I can work Herk's suggestions in without breaking everything else

EDIT: Thanks for the help here, this is the first network system I've implemented that I really happy with the results.

Now, I'm just trying to think of how I can work Herk's suggestions in without breaking everything else

Herk's suggestions are fairly the same as Jeffs, just Jeffs post emphasizes more on the remote side of motion interpolation.

The difficult points there are to introduce and tune some means of damping in order to prevent the thing from swinging around the desired position and at the same time do not introduce a systematic 'fly behind time'.

The latter is hard to recognize for a gamer though .... its more about making the programmer feel he has a clean solution instead of a hack

The next question you are going to run into is, when players interract, whose view is "right"?

Assuming you aren't worried about security there is kind of an art to solving this. It involves picking the most "obvious" viewpoint.

In most situations there is one actor who has the most information abotu the problem. Imagine a FPS for a moment. The person pulling the trigger has a very exact idea of where he is aiming. The others observing him though have an approximate idea at best. Therefor for the most undetectable solution, you let the guy aiming decide whether he hit or not and inform everyone else. This works great as long as you aren't worried about hackers hacking their client to always send "I hit" messages.

There are some other tricks too. If you imagine a game where one-shot kills, then the aim on that one shot is crucial. If you have, say 10 hits to a kill though, then the law of averages has time to work and you get more correct over all results. Finally if a hit doesn't do 1 point always, but a variable of number of damage points, book-keeping on the part of the other players becomes impossible and they can't tell if its screwed up or not

Finally, theres an old adage that applies here: close counts in horse-shoes and handgrenades. Weapons that fire very narrow beams don't have a lot of wiggle room between hit and miss. "Bug guns" though that spray over an area have much greater tolerances for minor errors.

Hope that all gets you thinking. Feel free to post more questions as you have them.

Got a question about Java and game programming? Just new to the Java Game Development Community? Try my FAQ. Its likely you'll learn something!

I've been rolling over the problem in my mind. I don't know if you've looked at what I'm writing at the moment but its a Zeldaeque RPG online. Spell and Ranged combat seem relatively simple. However, hand to hand combat is based on whether the two characters are close enough to allow it.

Now, if I check this on the attackers side it may look right but the defender may see the attack from someone who is out of range. If I do it on the defenders side the attacker may never manage to make an attack because the character will most likely always be out of range (at least if he/she is running away).

I know in JPilot both sides hitting gave feedback but only defender detected hits actually counted. However, thats not going to work here.

Maybe this is one of them cases where I need to come up with a game feat that "works round" the issue.. any ideas?

I'm a little confused now. I thought you were originally having the server tell the client about changes, but found that wasn't good enough performance for moving.

Now when you move on to a completely different action (attacking) you seem to be defaulting to the solution you came up with for movement. Surely you should just use the same system you used originally? It didn't work for movement because of frequency of updates, lag, etc - and there were ways of working around that that are specific to movement....doesn't mean it won't work for attacking?

Jeff's comment that lock-stepping is poor was a brief generalization; if I were to flesh out that point I'd say that lock-stepping is perfect for certain interactions, but poor for others, and that the most obvious one it's used for (movement) is in the "poor" category. Hence, always think twice before lock-stepping.

The movement I currently have looks beautiful to the clients, however it doesn't guarantee (which I suppose is pretty much impossible) that you see the players in the exactly the same location as anyone else.

My original idea for combat was if you're standing near enough to someone you can attack them. However, since you might be seeing a slightly different view of the world to the person you're attacking it may look possible to attack for you (i.e. you're close enough) but impossible to them.

I guess my question is how to resolve the inconsistancy. If player A chooses to attack player B, but from player B's perspective player A is to far away.. what do I do?

I guess my question is how to resolve the inconsistency. If player A chooses to attack player B, but from player B's perspective player A is too far away.. what do I do?

OK, I was probably just being dumb .

Could you describe how combat will work? e.g.

- combat enters a "combat-mode" e.g. with enemy helath bar on screen, or an overlay menu of attack options, etc - combat is automatic attacks - no user interaction - or manual attacks - user has to click / choose a particular kind of attack for each attack to actually happen - turn-based or "as-fast-as-you-can" - ranged? Not just long-distance weapons, but also different minimum separations before you can attack with e.g. dagger and bastard sword - how do you initiate the attack? if it's by clicking on a player, causing you to move towards them and attack all in one motion, then...the server is going to get some advance warning XX ms before the players actually get close enough to each other, and this gives it time to e.g. tell the victim's client info like "you are about to be attacked". This could be used in all sorts of ways. - is there a need to react quickly to an incoming attack? e.g. how many ms does it take for someone to kill you when you could have survived if you'd had time to react? If there is no such need, then perhaps it isn't that important...

However, just becuase you're in combat, doesn't mean your opponent is. Your other option is just to try and move away from the attacker.

Quote

- turn-based or "as-fast-as-you-can"

As fast as the game allowed seems fair.

Quote

- ranged? Not just long-distance weapons, but also different minimum separations before you can attack with e.g. dagger and bastard sword

Now, I'd like this but I think it might be a bit complicated. Plus I'm not quite sure how I could make it "fair" across the network.

Quote

- how do you initiate the attack? if it's by clicking on a player, causing you to move towards them and attack all in one motion, then...the server is going to get some advance warning XX ms before the players actually get close enough to each other, and this gives it time to e.g. tell the victim's client info like "you are about to be attacked". This could be used in all sorts of ways.

Select, and choose attack. Depending on your mode you might run after them aswell.

Quote

- is there a need to react quickly to an incoming attack? e.g. how many ms does it take for someone to kill you when you could have survived if you'd had time to react? If there is no such need, then perhaps it isn't that important...

There might be if you want to go into DEFENSE mode. But then I suppose I could add a "wimp" mode where if you get attacked you automagically go into defense mode. Sorta like the guy that always hides under the table when the fight in the pub breaks out...

Credo: make it believable as possible. Don't even try to make it perfect!

FlyingGuns: me as a player with a immediate-hit weapon (machinegun) - I am the only one who can really tell wether I am aiming and hitting correctly. The defending opponent typically cannot even see me (when looking forward) and for sure cannot judge wether he is hit or not. Due to the bullets speed, he wouldn't be able to avoid the hits anyway.

So the shooting side determines the hit and degrades the remote players health. The health is a distributed, HeadQuarter-property of type Integer which is decremented then. When health crosses 0, the appropriate actions are taken. This works also very fine when more than one player are shooting at the same target!

JPilot: the bullet is flying quite slow and avoiding bullets by cool moves is the games principle. And due to the view from above and being 2D, I as a defender can CLEARLY tell wether I am hit or not.

So, hits are determined locally on any machine, resulting in a visual effect and local destruction of the bullet. DAMAGE is only taken on the machine of the defender/target. So its possible that I can see my bullet hit you ... but you won't die. What NEVER happens is that I see your bullet missing me and suddenly I explode. That would be annoying!

Additionally - this solution work without further network protocol! Sending the bullet is enough.

So its possible that I can see my bullet hit you ... but you won't die. What NEVER happens is that I see your bullet missing me and suddenly I explode. That would be annoying!

Annoying like Quake 3? Quake got this seriously wrong, yet it is arguably the most popular network real-time combat game there is. Yet every time I play (even on a lan) I can't stand how all those 'missing' shots count as hits.

I don't believe it is possible to make a 'twitch' style shooter work over a network without this annoying effect. It will always look like someone got cheated. Like you say, try to make it as believable as possible... it still wont' actually be believable but it's the best you can do.

Quake3/UT is indeed quite suspectible to lag. On the other hand, AmericasArmy, built on top of UT engine, is a lot more forgiving - thanks to the fact that everything is a low slower (people are running slowly, no doublejumps/dodges, etc). You still need to take a small correction in aim to take lag into account, but on the other hand, in real life you would need to take a small correction for moving target due to limited bullet speed. It is absolutely acceptable, as long as people will not get really close to each other

I've been rolling over the problem in my mind. I don't know if you've looked at what I'm writing at the moment but its a Zeldaeque RPG online.

<snip>

Maybe this is one of them cases where I need to come up with a game feat that "works round" the issue.. any ideas?

Kev

Hey kev,

Sorry, I've been INCREDIBLY busy and this was the first time I coudl look back at this. For thsi kidn of game the following kind of approach often works:

When the attacker is clsoe enough on one machine (eithjer player) to initate combat you ddrop into "combat time" on that machine and lock the characters in place. This is annoucned to the other player and combat is then held until the other player brings the two characters together visually.

So, basically, they are really locked in combat when they get close enough on one machine, then the other is allowed to garcefully "catch up".

This works particularly well for turn based combat where you can just delay the start of the first round a few moments. Sicne you mentioend Zelda Im guessing thsi is turn based.

Got a question about Java and game programming? Just new to the Java Game Development Community? Try my FAQ. Its likely you'll learn something!

java-gaming.org is not responsible for the content posted by its members, including references to external websites,
and other references that may or may not have a relation with our primarily
gaming and game production oriented community.
inquiries and complaints can be sent via email to the info‑account of the
company managing the website of java‑gaming.org