Java: Network Game Lag
Hello all, I have created a multiplayer pong game and so far so good. However, I've come across a small problem... lag. The game is perfectly in-sync, however, the game lags way too much. I've tried using non-blocking sockets but that doesn't work either (same results). The game is set at 30 FPS (Frames Per Second), which is set using the tradional Thread.sleep(1000/fps); Here is my source-code if you need to take a look: http://www.jamisongames.info/MultiPong/MultiPong.java I would appreciate any help that you guys can give me. Thanks and regards, Jamison
I'm no expert, but i'll have a go anyway.
First thing - The java implementation of sockets is, in my opinion, slightly buggy. First, if you use it wrong it can go REALLY slowly. Second, there would seem to be some incompatibilities when using sockets to communicate with non-java programs.
Basically, If I remember right, the answer is - Only use socket programming if you're communicating java to non-java, otherwise use RMI - remote method invocation
First thing - The java implementation of sockets is, in my opinion, slightly buggy. First, if you use it wrong it can go REALLY slowly. Second, there would seem to be some incompatibilities when using sockets to communicate with non-java programs.
Basically, If I remember right, the answer is - Only use socket programming if you're communicating java to non-java, otherwise use RMI - remote method invocation
DaBookshah, I agree with the anonymous poster. I've worked with sockets only for a short time, and before I got into trying to make a multiplayer RTS with them, they've worked flawless. And even making a multiplayer RTS they should work flawless (I've seen it done), I just know I'm doing something wrong.
Anonymous poster, thanks for all of that great information. I saw something about using the Socket.setTcpNoDelay(true) when using sockets for a multiplayer RTS, and I tried it but it had no effect on blocking sockets. Maybe it should be used with non-blocking sockets?
I'll take a look at the DataOutputStream class.
Oh, and wouldn't Datagram Packets be a bad idea for a multiplayer RTS? Would the positions tend to jump around since the packets aren't guaranteed to arrive in the same order they were sent out? For example:
Frame 0 - Server - ballX = 0; ballY = 0;
Frame 0 - Client - ballX = 0; ballY = 0;
Frame 1 - Server - ballX = 5; ballY = 5;
Frame 1 - Client - ballX = 0; ballY = 0;
Frame 2 - Server - ballX = 10; ballY = 10;
Frame 2 - Client - ballX = 5; ballY = 5;
Frame 3 - Server - ballX = 15; ballY = 15;
Frame 3 - Client - ballX = 15; ballY = 15;
Frame 4 - Server - ballX = 20; ballY = 20;
Frame 4 - Client - ballX = 20; ballY = 20;
Notice how the ball would skip a position in Frame 0 and Frame 1 and then in Frame 2 it would appear to jump from Position 0 to 10.
I'm going to rewrite my run() method, and change my sockets back to non-blocking again. And I'll also try and repaint the screen whenever possible (I'll see if I can find that tutorial on how to do that).
Anonymous poster, thanks for all of that great information. I saw something about using the Socket.setTcpNoDelay(true) when using sockets for a multiplayer RTS, and I tried it but it had no effect on blocking sockets. Maybe it should be used with non-blocking sockets?
I'll take a look at the DataOutputStream class.
Oh, and wouldn't Datagram Packets be a bad idea for a multiplayer RTS? Would the positions tend to jump around since the packets aren't guaranteed to arrive in the same order they were sent out? For example:
Frame 0 - Server - ballX = 0; ballY = 0;
Frame 0 - Client - ballX = 0; ballY = 0;
Frame 1 - Server - ballX = 5; ballY = 5;
Frame 1 - Client - ballX = 0; ballY = 0;
Frame 2 - Server - ballX = 10; ballY = 10;
Frame 2 - Client - ballX = 5; ballY = 5;
Frame 3 - Server - ballX = 15; ballY = 15;
Frame 3 - Client - ballX = 15; ballY = 15;
Frame 4 - Server - ballX = 20; ballY = 20;
Frame 4 - Client - ballX = 20; ballY = 20;
Notice how the ball would skip a position in Frame 0 and Frame 1 and then in Frame 2 it would appear to jump from Position 0 to 10.
I'm going to rewrite my run() method, and change my sockets back to non-blocking again. And I'll also try and repaint the screen whenever possible (I'll see if I can find that tutorial on how to do that).
Okay, I've changed my code and I've completely rewrote my run() method. I changed the FPS to 10 and I'm now using non-blocking sockets. The lag is completely gone now, however, now the game is completely out of sync (synchronization). When I test it on my localhost (with myself), it seems to work without lag and it's almost perfectly in-sync. But when I upload it and test it (with myself), it's completely out of sync. What can I do?
Take a look at my changed source-code:
http://www.jamisongames.info/MultiPong/MultiPong.java
Oh and I couldn't find anything even about Java on gaffer.org.
Maybe I should try and rewrite my code to use Packets?
Take a look at my changed source-code:
http://www.jamisongames.info/MultiPong/MultiPong.java
Oh and I couldn't find anything even about Java on gaffer.org.
Maybe I should try and rewrite my code to use Packets?
Is it out of sync by the latency you have to that host (your 'ping')? If so, there's not a lot you can do. (Test it by typing 'ping www.myhost.com' in your command line.)
UDP is generally faster than TCP under Internet conditions, because dropped packets just disappear instead of lagging.
You include a time (or a frame number, which does the same job) in the packet, and discard it if the object it refers to (or the entire game state if it's all in one packet) has been updated by a packet with a later timestamp.
UDP is generally faster than TCP under Internet conditions, because dropped packets just disappear instead of lagging.
Quote:
Oh, and wouldn't Datagram Packets be a bad idea for a multiplayer RTS? Would the positions tend to jump around since the packets aren't guaranteed to arrive in the same order they were sent out?
You include a time (or a frame number, which does the same job) in the packet, and discard it if the object it refers to (or the entire game state if it's all in one packet) has been updated by a packet with a later timestamp.
Hey. I admit that RMI is something that I have had no experience with - When searching for answers to similar questions, I always found posters(experts) on the java.sun.com forums saying that RMI was the way to go unless sockets were absolutely required(java to non-java). Ok, given, that wasn't about game programming, maybe its wrong.
I can't back my comments about java sockets being buggy with a concrete example (can't be bothered dragging out the code) BUT from personal experience I have had severe problems with them(I only used them once ok). Basically, when writing a program to connect with a server, I was unable to come up with one which didn't take 50 connection attempts to actually successfully connect. Other programs in different languages doing an identical job didn't have such problems. I eventually found a document on the sun site which mentioned this problem, as far as I could gather theres a problem with the implementation in some ways.
[Edited by - DaBookshah on March 18, 2006 6:40:12 AM]
I can't back my comments about java sockets being buggy with a concrete example (can't be bothered dragging out the code) BUT from personal experience I have had severe problems with them(I only used them once ok). Basically, when writing a program to connect with a server, I was unable to come up with one which didn't take 50 connection attempts to actually successfully connect. Other programs in different languages doing an identical job didn't have such problems. I eventually found a document on the sun site which mentioned this problem, as far as I could gather theres a problem with the implementation in some ways.
[Edited by - DaBookshah on March 18, 2006 6:40:12 AM]
I've been working with Sockets for about three weeks, and I haven't come across a single connection problem with them. Only lag and out-of-sync problems (in games).
Anyway, back on topic... it can't be latency. I had my friend ping me (through my router) and the time it took was between 100-105ms (milliseconds). And he lives in New York, so it's not like he's next door ;).
I tried using Datagram Sockets but those are much more confusing than TCP Sockets. I couldn't figure out how to use them to make an RTS.
I know there has gotta be some way to fix this...
Anyway, back on topic... it can't be latency. I had my friend ping me (through my router) and the time it took was between 100-105ms (milliseconds). And he lives in New York, so it's not like he's next door ;).
I tried using Datagram Sockets but those are much more confusing than TCP Sockets. I couldn't figure out how to use them to make an RTS.
I know there has gotta be some way to fix this...
This topic is closed to new replies.
Advertisement
Popular Topics
Advertisement
Recommended Tutorials
Advertisement