Multiplayer Pong Woes (need some help)

Hey everyone,

I've recently taken up Java programming and decided to write an internet multiplayer pong game as a learning tool. I've gotten as far as writing a simple pong game and connecting multiple clients to my server.

The problem is lag. I don't know how to handle it. When playing two clients at the same time on my computer, naturally, game play is nearly flawless. But once I connect a client across the net or even on my lan, bad things happen. I've been tossing around various ideas around in my head on how to handle lag, but I just can't come up with a solution.

I have one client designated as the 'sender'. This client constantly sends ball updates to the other player who is the 'reciever'. On the sender's end, everything is smooth and happy. On the reciever's end, the ball is constantly being updated and is jumping across the playfield in a very annoying fashion (this because of the latency).

The biggest problem is predicting where the ball will be because depending on how the ball hits the paddle, it can be deflected off at a different angle (so the player can 'aim' the ball sort of). The sender recieves the updated ball position too late, and it jumps whenever it hits the opponent's paddle. On the reciever's end, it's much much worse.

How can I smooth out gameplay on both sides?

Thanks!

EvilDingo

[1392 byte] By [EvilDingo] at [2007-9-27 19:04:18]
# 1

I've never done this before, but it seems like all you really need to send over the network are updates to the paddle position based on the user's input. The ball's movement can be calculated separately at each end based on the location of the paddles.

This might lead to other problems.. I don't know. It would cut down on the amount of stuff you have to send over the network though.

Jetset_Willy at 2007-7-6 21:15:55 > top of Java-index,Other Topics,Java Game Development...
# 2

Right. I've just updated it so the clients predict the ball and only send a message to the other player when the ball strikes their paddle (because this can change it's course unpredictiably). Using this method with two clients on the same machine, the gameplay is pretty much perfect. Although, the ball appears to pass through the opponent's paddle before it's tradjectory gets updated.

This is only with 2-5ms latency tops. Imagine that situation with 300ms or so. The ball will pass through the paddle and be half way back to the player's paddle when it gets updated and 'jumps' back.

I've tested this method over the internet and it's extremely confusing gameplay. :)

I've noticed that my clients lag slightly behind each other when the game starts. After a bounce or two, they're pretty much back on track but the faster the ball goes, the more jumping the ball makes when it strikes a remote paddle.

I just can't think of a solution.

EvilDingo

EvilDingo at 2007-7-6 21:15:55 > top of Java-index,Other Topics,Java Game Development...
# 3

lol, what a coincidence, I just wrote a pong game as well :p

I'll add networking 2 it 2night, and c what I come up with...

Latency prediction is 1 possibility (rather like the timenudge function in the Q3 engine) where what you see on screen is a prediction Xms into the future. However, if your doing collision detection on the client not the server, there is little point in doing this.

1 important fact though...with a game such as pong, that requires such precision and timing, it will be impossible to play over high lag, however you structure your code.

Abuse at 2007-7-6 21:15:55 > top of Java-index,Other Topics,Java Game Development...
# 4

Definitely let me know how it goes with your multiplayer code. My latest unsuccessful method is to update the ball not all at once, but in small increments. Basically, player one makes a correction based on the packet information it recieved from player two. Then it's player two's turn to make a correction based on player one's ball position.

This goes back and forth sending updated locations every 130ms or so. I was attempting to syncronize the two games this way, but it doesn't work. For some reason yet unknown, the games refuse to remain in sync. Even though they plot the EXACT same ball course using the EXACT same velocity and vectors.

I put a timer on the ball packets and the maximum ping was 13ms. I guess this adds up over time, but ****, it's driving me crazy. If you can play Quake on the net, you HAVE to be able to play pong! :)

The funny thing is, if I would just bite the bullet and take out the paddle aiming code, both clients would predict the exact same ball path and everything would be fine. But aiming gives pong added gameplay... without it you're just deflecting a shot instead of taking one.

I thought of running the game a few ms in the future or possibly lagging the clients and buffering the commands, but it seems so complex. The sync code would be more complex than the entire game! Heh heh.

EvilDingo

EvilDingo at 2007-7-6 21:15:55 > top of Java-index,Other Topics,Java Game Development...
# 5

> I thought of running the game a few ms in the future

> or possibly lagging the clients and buffering the

> commands, but it seems so complex. The sync code would

> be more complex than the entire game! Heh heh.

hehe, and I bet the netcode in Q3 is the most complex part :P

Abuse at 2007-7-6 21:15:55 > top of Java-index,Other Topics,Java Game Development...
# 6

I wrote somthing simmilar some time ago.

The same code was running on the 2 computers, in one computers the left side was the other computer, and on the other machine the right side was the other computer, the only info on the net was 'changes' in the movment direction of the paddle (4 directions and stop).

Noah

noah.w at 2007-7-6 21:15:55 > top of Java-index,Other Topics,Java Game Development...
# 7

The problem is the balls in my pong game can travel at differen't angles as well as speeds. Most of the pong game's I've seen, the balls always bounce at a 45 degree angle and only reverse their horizonal or vertical position. My game has the balls travelling at any angle and they can be sort of aimed by where the ball lands on the paddle. If the ball hits the paddle at the edge, it will shoot off at a shallow angle and higher speed than if it hit the paddle in the center.

It looks like I'm going to have to scrap all that to make it playable via the net though.

EvilDingo

EvilDingo at 2007-7-6 21:15:55 > top of Java-index,Other Topics,Java Game Development...
# 8

I am not sure that it makes a big diff.(the speed and angle),

The program is in a loop moving the ball, checking the paddle movements and calculate hits. the point is to send minimun data on the net, i use to send just changes in the paddle direction.

How is the paddle moves in you game ?

Noah

noah.w at 2007-7-6 21:15:55 > top of Java-index,Other Topics,Java Game Development...
# 9
If the loop is faster than the trasmission, it can cause problems.Noah
noah.w at 2007-7-6 21:15:55 > top of Java-index,Other Topics,Java Game Development...
# 10
My loop is 13ms. That's the animation. I have no delay on my communication thread. Would that have anything to do with it? The threads competing?EvilDingo
EvilDingo at 2007-7-6 21:15:55 > top of Java-index,Other Topics,Java Game Development...
# 11

Are you using TCP or UDP?

I've never written a network game, but I did write an application

where you drew on a canvas, and it had to update an identical canvas

on the receiving program on the network.

Switching to UDP caused much less lag, I found, for obvious reasons.

Of course, I only tried this on a LAN, so I've never seen the repercussions of using UDP over the Internet.

On the LAN, there's obviously much less chance of bad things happening to the packets on their journey. :)

carmichaelbaby at 2007-7-6 21:15:55 > top of Java-index,Other Topics,Java Game Development...
# 12
jsdt has an example
mchan0 at 2007-7-6 21:15:55 > top of Java-index,Other Topics,Java Game Development...
# 13

Oh yeah, having no delay on the communication thread

caused horrible things to happen to me, but again that

was with UDP, so it didn't have to wait for any

acknowledgements, so it just chucked the packets as quick

as possible, and probably some poor buffer got overloaded!

carmichaelbaby at 2007-7-6 21:15:55 > top of Java-index,Other Topics,Java Game Development...
# 14

I've learned a lot over these past few days. I had quit the project many times in frustration, only to come back and try to work it out one last time.

I don't know how I worked though it. My code had so many subtle problems that it all seemed like it wasn't working due to a single bug. It turned out I had multiple bugs and misconceptions all throughout the code.

First thing I did was .setTcpNoDelay(true) on my clients' socket. It's set to false by default and this means that TCP/IP clumps together similar packets to save bandwidth. Good for stability, BAD for games. So if you're having trouble with late/sporatic TCP/IP updates, make sure you turn the delay off.

Next was a frame rate issue. You absolutely MUST syncronize your clients. But the catch is, you can't do this with tread.sleep(delay). None of the operating systems that Java supports gives any reliable millisecond timer. I stumbled on an excellent timer in the forums at www.javagaming.org.

Those two out of the way, I started seeing a remarkable change in net play. Pong was VERY playable and very smooth, but still a little screwed up. FINALLY, after hours and hours of looking over the same small snippet of code, I found an elusive error and fixed it.

BINGO! Pong has netplay!

I now have to fix a few lingering bugs in my server application and finish up a few more features before I'm satisfied. I'm so relieved that I was able to pin point the problem (after days of research) and fix it.

Interpong lives!

EvilDingo

EvilDingo at 2007-7-6 21:15:55 > top of Java-index,Other Topics,Java Game Development...