If you want to go that way, do it loosely (but checking that your FP won’t go wild in those few frames), and re-synch periodically. You can afford e.g. a once-per-second re-synch on the fp stuff
It do not mather how tiny the difference is. Don’t have to be an expert to know that the error will add up very quickly and the game will end up out of synch.
StrictMath might fix it, but then you’ll have to consider if it is fast enough.
If you are not an expert you should probably not say anything at all on this subject. Whether the errors accumulate and how fast depends on the algorithms involved. While some algorithms would diverge rapidly, others can proceed for billions of operations with only tiny differences. In my opinion (as a PhD in mathematics) attempting to avoid floating point is not the correct answer to this problem. After all a great deal of effort was put into the design of the arithmetic used in modern computers (and required by Java) with the intention that the behaviour of floating point is well controlled. Perhaps instead of treating floating point as “here be demons”, more programmers should learn to understand it.
Err, are you seriously suggesting people should use a more complicated and error prone system over a tried and simple secure system?
Floating point rounding errors do add up a lot over time. You either work around it (what I suggest), or make sure it the errors are exactly the same and add up in exactly the same way for everyone (what you seem to suggest).
No, that is what you may get through attempting to use integers.
Again no, what I suggest is to understand what the error bounds are and keep them under control. Accumulated error doesn’t become a problem until it reach perhaps 1 in 1e6, so at that point you need to distribute corrections.
However in the case of Java, the extent of difference is very restricted. For the basic operations (+,-,*,/ etc) even without strictfp the results must be exactly the same unless the range of float/double has been exceeded. A JVM is not allowed to perform computation with any more (or less) precision, it can only use a larger exponent range. So in the case of double if no intermediate value exceeds 1e308, then the results are required to be identical. Java does allow some differences in the case of some of the non StrictMath methods (e.g. sin, cos, etc), but here the permissable difference is very small. Note that methods such as Math.sqrt specify a correctly rounded result — all conforming Java implementations must return exactly the same result for this method.
While doing your own thing in integers may ensure that all clients produce the same answer, it also increases the likelihood that the answer obtained is wrong!
The problem with 0.1 (base 10) doesn’t apply to physics. Using floating point with finance is much more problematic, largely because various authorities specify rounding rules invariably in base 10 while the usual computer floating point is base 2 based.
My point was that there are rounding errors in floating point math unless you happen to only use 2^x numbers, so claiming that floating point math contains fewer errors than integer math is wrong.
0.1 was just a clever example, it’s the 1/3 of binary math. (but please note that 1/3 is not a problem in trinary math)
The errors in floating math are more “hidden”, though, so they often act as time bombs unless the programmer knows what he does. With integer math the error shows up immediately rather than after “billions” of operations.
You still have quantization errors when using integers to represent real world quantities, plus you add in risk, if you scaled the values, that someone will assume the wrong scale factor. In addition many real world quantities have inherent measurement uncertainties (Heisenberg). These uncertainties are much greater than the difference between a base 10 value and its double (base 2) approximation.
Yes it is a damn fun game, especially in multiplayer.
Be sure to check the forum for tools for reading the map format, I know atleast that they make their own cars for the game.
I’ll put in another way. All operations have to be exactly the same or you’ll get out of sync. The tiniest difference in precission can mean the difference between hitting a wall or not. I don’t see how you can “manage the errror” out of the problem. But I’m sure you’ll tell me how, and I’m looking forward to your reply . You could use floating point if you could find out wich operation can differ and replacing those with StrictMath. Maybe it’s only the trig functions. But they are quite important in 3d simulations.
This method is mostly used in RTS games where integer is used anyway. A friend of mine used it in a football game. He started with floating point but found out it did not work and switched to integer.
Now slightly more on topic:
For a car game I would consider the Q3 method of transmitting the difference in state from the last acknowledged timestamp, using udp. There is a limited number of entities that changes every frame so it would work quite well.
All the methods in StrictMath (which are in most cases dentical to those in Math) produce exactly the same results on all platforms.
All floating point operations with +, -, * and / produce exactly the same results on all platforms EXCEPT when numerical overflow occurs.
The strictfp keyword kan be used to make sure that identical results are achieved even when numerical overflow occurs.
Is this correct? Because I guess strictfp operations are slower than nonstrict ones, and it would be very nice to avoid strictfp if the numbers stay within reasonable bounds.
On another issue, since we are talking about games, all we care about is synch. Whether the simulation is realistic (like using Runge-Kutta instead of Euler to stop numerical solutions from diverging from would-be reality) is not essential in most cases. Only the local looks-like-realism is important.
Thank you, Mark Thornton, for your clear response.
By the way, as many of you probably know, most of the Math methods delegate to StrictMath presently. This includes the trig functions. I guess this depends on version number.
You should ignore that apparent delegation of implementation. The JVM can replace the implementation of Math methods with anything it likes subject to meeting the specification.
Okay, Im jumpign in rather later here so forgive me if all this has been said…
Basically, you are trying to do one of the hardest things to do in a WAn networked game.
Car racing invovles objects moving very very fast very very close to eahc other where a tiny difference in position can make ahuge difference in result. When we did Nascar Racing OnLine at TEN we used a special network for gameplay provided by concentric. They ran a star netrowk out of michigan. We put the server there and prioritized packets going to and from that machine to reduce latencies. That was the only environment in which we could gaurantee game-play.
An open-loop client based system is right out because the whole reason that situation works well for many games is because clients are allowed drift a moderate degree apart from each other to cover latencies. Given your situation you will probably need a central server. However that will not solve all your problems. Imagine trying to drive a race with a race-car that has variable lag between when you turn the wheel and when you move the wheels and thats the situation your players will be facing. Its a definite ecipe for disaster. A latency spike might well mean a crash.
You can reduce this somewhat by making this a broadbamnd only game. Analog modems have terrible latency spikes all of their own making. Broadband modems typically dont add much to the problem already existant on the internet. You also might want to consider carefully your communications protocol. Sicne youare pusing the inmternet to the limit ehre this is one of the games Ive seen where the pain of UDP might really be worth it. You also might be able to improve apparent latencies by sending packets both to the server AND P2P. Packets from the server are “correct”, packets from other players are in-between “hints” to help in your prediction. You will probably have to have a TCP channel for really critical information (eg crashes from the server.)
This is really really a bleeding edge thing youare trying to do, I wish you luck!
[quote=“Jeff,post:36,topic:23863”]
Just a related anecdote… In my area (greater Toronto), the cable modems are worse than dialup as far as latency spike go. The latency is so all over the place that you simply can’t play Q3 with someone on a cable modem. That person cannot be hit. They bounce around the screen in a totally spastic way, I assume because the algorithms in the Q3 network code that attempt to compensate for latency get so screwed up from the widely and constantly varying latency. E.g. ping the server and you sill see the latency vary from 70 to 300 ms.
All of the techy folk that I know specifically dumped cable and went with DSL because the issues with cable were so bad.
Id guess your Canadian providers ar trying to put too many people on too little bandwidth and since its a shared conenction between many users, your effectviely getting “swapped out”, but thats just a guess.
One thing to consider, annoying but perhapse better then the alternatives: There are a lot of studies that show that humans deal much better with repdictable latency then with uinpredictable spikes. YOu might try to figure out a 90%+ latency max and actually induce the latency when data arrives sooner. This would at elast even it out though,as someone pointed out, it might start to feel like “lunar buggy racing” if that lag is too big.
Early tests show that a Server-Client model is “good” enough. A ping of 15 can be achieved from birmingham to london with normal broadband connections. Is 15ms low enough? Isn’t that the usual ping in a LAN network? ;D