• Announcements

    • khawk

      Download the Game Design and Indie Game Marketing Freebook   07/19/17

      GameDev.net and CRC Press have teamed up to bring a free ebook of content curated from top titles published by CRC Press. The freebook, Practices of Game Design & Indie Game Marketing, includes chapters from The Art of Game Design: A Book of Lenses, A Practical Guide to Indie Game Marketing, and An Architectural Approach to Level Design. The GameDev.net FreeBook is relevant to game designers, developers, and those interested in learning more about the challenges in game development. We know game development can be a tough discipline and business, so we picked several chapters from CRC Press titles that we thought would be of interest to you, the GameDev.net audience, in your journey to design, develop, and market your next game. The free ebook is available through CRC Press by clicking here. The Curated Books The Art of Game Design: A Book of Lenses, Second Edition, by Jesse Schell Presents 100+ sets of questions, or different lenses, for viewing a game’s design, encompassing diverse fields such as psychology, architecture, music, film, software engineering, theme park design, mathematics, anthropology, and more. Written by one of the world's top game designers, this book describes the deepest and most fundamental principles of game design, demonstrating how tactics used in board, card, and athletic games also work in video games. It provides practical instruction on creating world-class games that will be played again and again. View it here. A Practical Guide to Indie Game Marketing, by Joel Dreskin Marketing is an essential but too frequently overlooked or minimized component of the release plan for indie games. A Practical Guide to Indie Game Marketing provides you with the tools needed to build visibility and sell your indie games. With special focus on those developers with small budgets and limited staff and resources, this book is packed with tangible recommendations and techniques that you can put to use immediately. As a seasoned professional of the indie game arena, author Joel Dreskin gives you insight into practical, real-world experiences of marketing numerous successful games and also provides stories of the failures. View it here. An Architectural Approach to Level Design This is one of the first books to integrate architectural and spatial design theory with the field of level design. The book presents architectural techniques and theories for level designers to use in their own work. It connects architecture and level design in different ways that address the practical elements of how designers construct space and the experiential elements of how and why humans interact with this space. Throughout the text, readers learn skills for spatial layout, evoking emotion through gamespaces, and creating better levels through architectural theory. View it here. Learn more and download the ebook by clicking here. Did you know? GameDev.net and CRC Press also recently teamed up to bring GDNet+ Members up to a 20% discount on all CRC Press books. Learn more about this and other benefits here.
Sign in to follow this  
Followers 0
miicchhii

Networking to Slow - Java Multiplayer Pong

12 posts in this topic

Hey all!
I created a Pong Game in Java and added Networking,
but it seems to slow the whole game down signifficantly.

I use a thread for the networking routine, on both server and the two clients.
The conversion is as follows:

send a marker (so the receiver knows which value will be sent next)
send the value
send the next marker, etc...

This is the Code for the Server:

[CODE]
/**
*
* Klasse (Thread) welche die Netzwerkfunktionen abhandelt
*
*/
class Network implements Runnable {
Network() {
}
public void run() {
// mit Host verbinden und Kommunizieren
try {
ServerSocket server = new ServerSocket(8888);
System.out.println("Warte auf Verbindung auf Port 8888");
Socket Client1 = server.accept();
System.out.println("Server: Client1 verbunden");
Socket Client2 = server.accept();
System.out.println("Server: Client2 verbunden");

//Client1 einrichten
OutputStream out1 = Client1.getOutputStream();
PrintStream ps1 = new PrintStream(out1, true); // Second param: auto-flush on write = true
InputStream in1 = Client1.getInputStream();
BufferedReader br1 = new BufferedReader(new InputStreamReader(in1));
//Client2 einrichten
OutputStream out2 = Client2.getOutputStream();
PrintStream ps2 = new PrintStream(out2, true); // Second param: auto-flush on write = true
InputStream in2 = Client2.getInputStream();
BufferedReader br2 = new BufferedReader(new InputStreamReader(in2));

String line="";
ps1.println("run");
ps2.println("run");

while(true){

//Einlesen Client1
for(int i=0;i<1;i++){
line = br1.readLine();

if(line!=null){
if(line.contains("v1")){
line = br1.readLine();
player1Y=Integer.parseInt(line);
}
}
}//end Einlesen for-Schleife

//Einlesen Client2
for(int i=0;i<1;i++){
line = br2.readLine();

if(line!=null){
if(line.contains("v1")){
line = br2.readLine();
player2Y=Integer.parseInt(line);
}
}
}//end Einlesen for-Schleife

//Ausgabe an Client1
ps1.println("v2");
ps1.println(""+player2Y);

ps1.println("v4");
ps1.println(""+ballY);

ps1.println("v3");
ps1.println(""+ballX);

ps1.println("v5");
ps1.println(""+player1Score);

ps1.println("v6");
ps1.println(""+player2Score);

//Ausgabe an Client2
ps2.println("v2"); //gespiegelt für Player 2
ps2.println(""+player1Y);

ps2.println("v4");
ps2.println(""+ballY);

ps2.println("v3");
ball2X=MAXX-ballX; //gespiegelt für Player2
ps2.println(""+ball2X);

ps2.println("v5"); //gespiegelt für Player2
ps2.println(""+player2Score);

ps2.println("v6"); //gespiegelt für Player2
ps2.println(""+player1Score);

}


} catch (IOException e) {
// TODO Auto-generated catch block
//e.printStackTrace();
System.out.println("Verbindungsfehler aufgetreten");
}
}
}
[/CODE]

And the Client:

[CODE]
/**
*
* Klasse (Thread) welche die Netzwerkfunktionen abhandelt
*
*/
class Network implements Runnable {
String hostAdress;
Network(String adress) {
this.hostAdress = adress;
}
public void run() {
try {

Socket connectionToTheServer = new Socket(hostAdress, 8888);
System.out.println("Client: Verbindung zu Server hergestellt");
InputStream in = connectionToTheServer.getInputStream();
BufferedReader br = new BufferedReader(new InputStreamReader(in));
OutputStream out = connectionToTheServer.getOutputStream();
PrintStream ps = new PrintStream(out, true);
String line="";
while(!(line.equals("run"))){line=br.readLine();}//warten auf Start des Spiels

while(true){

//Ausgeben

ps.println("v1");
ps.println(""+player1Y);

//Einlesen
for(int i=0;i<5;i++){
line = br.readLine();
if(line!=null){
if(line.contains("v2")){
line = br.readLine();
player2Y=Integer.parseInt(line);
}else
if(line.equals("v3")){
line = br.readLine();
ballX=Double.parseDouble(line);
}else
if(line.equals("v4")){
line = br.readLine();
ballY=Double.parseDouble(line);
}else
if(line.contains("v5")){
line = br.readLine();
player1Score=Integer.parseInt(line);
}else
if(line.contains("v6")){
line = br.readLine();
player2Score=Integer.parseInt(line);
}

}
}//end Einlesen for-Schleife
}


} catch (UnknownHostException e) {
// TODO Auto-generated catch block
//e.printStackTrace();
System.out.println("Verbindungsfehler aufgetreten");
} catch (IOException e) {
// TODO Auto-generated catch block
//e.printStackTrace();
System.out.println("Verbindungsfehler aufgetreten");
}

}
[/CODE]

Logically everything works fine, but its very slow.

I would appreciate some recommendations on how to improve the speed!

Thanks in advance!
0

Share this post


Link to post
Share on other sites
Have you tried [url=http://docs.oracle.com/javase/1.5.0/docs/api/java/net/Socket.html#setTcpNoDelay(boolean)]setTcpNoDelay[/url]?
1

Share this post


Link to post
Share on other sites
[quote name='BitMaster' timestamp='1355390153' post='5010112']
Have you tried setTcpNoDelay?
[/quote]
Thank you so much!
I added it and its much better now :)
Is there anything else i can do?
0

Share this post


Link to post
Share on other sites
[quote name='miicchhii' timestamp='1355391198' post='5010118']
[Thank you so much!
I added it and its much better now [img]http://public.gamedev.net//public/style_emoticons/default/smile.png[/img]
Is there anything else i can do?
[/quote]

- UDP
- Better network/packet structure
0

Share this post


Link to post
Share on other sites
For the issue at hand the choice between TCP and UDP are irrelevant, especially in any local test.
1

Share this post


Link to post
Share on other sites
[quote name='alexc95' timestamp='1355392369' post='5010125']
- Better network/packet structure
[/quote]
You mean not to send single lines with auto-flush?
0

Share this post


Link to post
Share on other sites
ideally, your code should handle 250-500ms lag, and thus you'll need to interpolate between the data sent to you from another player
this is a game where lag will affect gameplay, and we don't care about cheating, so, i would just do very simple interpolation in between updates
and not worry so much about the actual amount of latency or updates..
the biggest problem you will face is "invariance," here being desynchs, but since you have a centralized server that makes all the decisions
this problem is already solved =)

i would implement fast interpolation pad_y = (0.9 * pad_y + 0.1 * pad_last_y); pad_last_y = pad_y;

nodelay is good in high-speed games (disabling nagle algo), but it might not always be enabled..
the drivers are free to do nothing, after all, and never tell you otherwise
udp isn't really any faster, it's just potentially smaller packets, and widely used for "positioning" that are high-frequent updates
when working with networking, you will never have a cpu bottleneck compared to high latency
high latency is measured in hundreds of milliseconds, and there isn't much you can do about it
increasing the amount of updates you are doing by too much will just cause the socket to throttle (and die) because its write buffer would be exceeded
the normal latency for local loopback is 0ms, LAN is 1ms+ and internet is at least 60ms
60ms is alot considering 30fps is 33ms, 60ms is ~16fps
that's why you'll always _always_ need to interpolate between moving visuals with high-frequency updates
Edited by Kaptein
1

Share this post


Link to post
Share on other sites
[quote name='Kaptein' timestamp='1355399101' post='5010161']
ideally, your code should handle 250-500ms lag, and thus you'll need to interpolate between the data sent to you from another player
this is a game where lag will affect gameplay, and we don't care about cheating, so, i would just do very simple interpolation in between updates
and not worry so much about the actual amount of latency or updates..
the biggest problem you will face is "invariance," here being desynchs, but since you have a centralized server that makes all the decisions
this problem is already solved =)

i would implement fast interpolation pad_y = (0.9 * pad_y + 0.1 * pad_last_y); pad_last_y = pad_y;
[/quote]

So i should let the Clients kinda estimate where the ball will be on the next update?
Or insert an interpolated point between two of the updates?
0

Share this post


Link to post
Share on other sites
[quote name='miicchhii' timestamp='1355399423' post='5010163']
[quote name='Kaptein' timestamp='1355399101' post='5010161']
ideally, your code should handle 250-500ms lag, and thus you'll need to interpolate between the data sent to you from another player
this is a game where lag will affect gameplay, and we don't care about cheating, so, i would just do very simple interpolation in between updates
and not worry so much about the actual amount of latency or updates..
the biggest problem you will face is "invariance," here being desynchs, but since you have a centralized server that makes all the decisions
this problem is already solved =)

i would implement fast interpolation pad_y = (0.9 * pad_y + 0.1 * pad_last_y); pad_last_y = pad_y;
[/quote]

So i should let the Clients kinda estimate where the ball will be on the next update?
Or insert an interpolated point between two of the updates?
[/quote]

yep, you have to. it's not a decision or design choice.. i updated my post and added some context as to why we have to do this and make do
i used 60ms in my example, but i've never had such a low latency on my connection :) it's usually in the 90's (97ms for example)
what this means is usually only that the response from me to the server will be delayed by 97ms, and that the movement will STILL be fluid
but ANY point in between me and the server could delay data unreliably before sending it
which means that it won't always be fluid, especially if the nodes wait too long to send and just gather your incoming data,
then send it in one bigger package (causing the server to get 10-20 updates in a single read())

Note: i didn't speak about advantages of UDP, such as congestion controls, but i'm sure you can read about it on your own
TCP has delayed ACK (which can be delayed a long time, even 200ms) and nagle algorithm isn't reliably disabled (and you shouldn't want to disable it either)
in short: use UDP for your game if you want the fastest throughput of small updates
but, personally i wouldn't go that far :) Edited by Kaptein
0

Share this post


Link to post
Share on other sites
You could also send/receive a byte array instead of using character stream as you seems to be only sending Numbers. I know it prolly won't improve a lot the speed but
optimization is always good. Go read about java object serialization/deserialization. You will save time by not creating a String and parsing it as you just want to send numbers. Edited by PsychotikRabbit
0

Share this post


Link to post
Share on other sites
Ok, I will try to implement that. :)
Kaptein, Thank you for your advices and all the informations!

PsychoticRabbit: But it will only affect the CPU time, not network itself that much i guess?
0

Share this post


Link to post
Share on other sites
I didn't test it but I'm pretty sure it would improve the network time. You won't need to open an output stream on the socket to write a string and to open an input stream on the socket to read a string. It would improve both CPU and network time. You could write a small unit test to test out the time sending and receiving a string by streams and another test for the time sending deserialized object and receiving the byte array.
0

Share this post


Link to post
Share on other sites
any packets that are smaller sized than the maximum packet size won't have an effect on throughput or latency at all
think of packetsize in GPU terms, if you draw very little with the gpu, the gpu will spend a measurable time "working on working with" the data
all packets that are <= the max size of the what the links on the route allows, will pass through intact
using as big as possible packetsize, but <= the correct packet size gives you the best throughput
for windows a MTU (frame) defaults to 1500 bytes (i think) over broadband, but that does not affect TCP packet size!
i imagine that tcp packetsize is at least 8kb, perhaps 16kb by now
i don't think you will be sending anything close to 8kb of data in one go, and it will most likely be alot less than the MTU size
in short: wether or not you use string stream, bit stream or serialized objects, it doesn't matter
java is a long-standing framework for JVM that most likely sends any kind of data just as effective as another

what really matters is how fast you try to send the tcp packets, and that they don't get split up (doubling the queue)
edit: and don't disable nagle
if you need the data to pass through immediately, use UDP, but it's not a recommended protocol
many firewalls block it.. among other things, UDP doesn't guarantee the order of packages arrive in the same order it was sent
Edited by Kaptein
0

Share this post


Link to post
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!


Register a new account

Sign in

Already have an account? Sign in here.


Sign In Now
Sign in to follow this  
Followers 0