Networking optimized!

Started by Melssj5, November 01, 2006, 06:00:27 PM

Previous topic - Next topic

Melssj5

My game FM recolects the events from the clients, passes them to the server, the server proces them, and return the state of all the clients to each client. now doing this means, 100% comunication with the server for each iteration, is this too bad?

Is this too heavy to do what I am doing?

   private SimpleVector posicion;
   private Direccion direccion;
   private int vida;//less tha 100
   private String nick;//less than 8 chars
   private int id;//one digit
   public NodoRed sig;//a reference
   public int cambio;//one digit

this are the fields that are being transmited from the server to the client.

I read somewhere that is not a good idea to do this for each iteration, maybe for one every 10 of them to keep a better performance, but I did on this way to avoid people cheating so, all the control is on the server.

Any suggestions? the game runs very very slow maybe 2 or 3 fps when the client is on a remote machine via LAN.
Nada por ahora

Mizuki Takase

Hihi~!! I am still looking at your code and I really do not think that its bad at all... I just feel that there may be some nice optimizations that you can do.. Anyway... I wanted to know how are you testing the networking features? I have been trying your program out and it works fine to me... Really~!!

Lastly.... Consider things like UDP and not TCP, or maybe.. Simplify what you are sending to the server... Since you have static animated ships, I think that you should be sending information regarding to what ship type you are using (short data type), direction of your ship and placement in the world (2 SimpleVectors)?

Off topic~! Why is it that you send the server a lot of serialized objects instead of the serialized classes? I just feel very uncomfortable at using Object rather than the implemented classes... I would think that you would have to do a lot of class cast checking before using them... Also, Java 1.5 rocks! You should try it out sometime...

Melssj5

I wanted to know how are you testing the networking features?


well, running the game. When the client is the same machine than the server then it runs very well, but when the client is on a remote machine then it runs at 1 or 2 fps.
Nada por ahora

manumoi

Hello Melssj. I did something pretty similar to you but with some differences

A message is sent from the client to the server only if the player modifies his position, status... If so, i send the name, position, orientation and status

The server itself is always broadcasting data concerning the whole world.

Client takes these data at the beginning of each game loop.


I use the NIO package for all of that. I think it is set up for TCP by default.


I tried it with 7 clients in a LAN at my university and it was running perfectly (in fact it is too fastand i had to regulate the game loop frequency). I didn t tried on the Internet

So i think if you correctly implemented your option, there should not be problem. Or maybe your server CPU isnt as powerful as it should be... or your network is not efficient...

Good luck

Manu

Melssj5

Hi I tested my app on a 4 intel Xeon procesor with 2 GB of RAM, and the network was just a bit bussy. Anyway I will try to check the nio package but I never have heard about it. Can you please provide me an example.

On my code only on each iterationthe client sends an int array to the server that identifies the events, but when the crafts is not moving the array is empty with 0 length. So it shouldnt be the problem but maybe the information sent from the server to the client. Which information do you send? Would it be a big difference if I replace my ints with shorts or Strings with limited char arrays?
Nada por ahora

raft

Quote from: "Melssj5"My game FM recolects the events from the clients, passes them to the server, the server proces them, and return the state of all the clients to each client. now doing this means, 100% comunication with the server for each iteration, is this too bad?

hello Melssj5,

does this mean you send this data to server at each iteration and wait for server's response to continue iteration ? i dont think so but if it is, it is definitely not a good idea. you shouldnt block your animation loop for anything (other than pause of course)

Quote from: "Melssj5"private SimpleVector posicion;
private Direccion direccion;
private int vida;//less tha 100
private String nick;//less than 8 chars
private int id;//one digit
public NodoRed sig;//a reference
public int cambio;//one digit

and if you send this data to server by serializing it make sure the NodeRed reference does not refer to a big object. as you know, if you serialize an object, all objects that can be reached from it is also serialized. you can make a size check to serializing that object to a ByteArrayOutputStream to determine how much bytes it takes

you may also wish to post your relevant part of code to let us have a look

r a f t

Melssj5

Thanks a lot, I will post it later, the NodoRed is a reference to another NodoRed. Is a linked List.

How can I check the amount of bytes? Of course you said using the ByteArrayOutputStream, but how?

I sent an int array
Now I am going to call my future girlfriend Gaby.
Nada por ahora

raft

mm, if you serialize an element of a linked list, then (depending on implementation of list) either all or on the avarage half of its elements are serialized  :roll:

you can use the following code piece to determine the serialized size of an object

   public static int getSize(Object o) throws IOException {
       ByteArrayOutputStream bos = new ByteArrayOutputStream();
       ObjectOutputStream oos = new ObjectOutputStream(bos);
       
       oos.writeObject(o);
       oos.flush();
       oos.close();
       
       return bos.size();
   }


r a f t

Melssj5

Thanks I was thinking on doing the same but using a FileOutputStream and check the size of the file but I never did because writting a file for each iteration!!!!  :twisted:

Anyway I guess that this may help better.

Does the data type imports a  lost, for example using short instead of int, I mean maybe it transmit some 0 bytes to fill the remaining space if they are only digits on this variables not big numbers
Nada por ahora

raft

Quote from: "Melssj5"Does the data type imports a  lost, for example using short instead of int, I mean maybe it transmit some 0 bytes to fill the remaining space if they are only digits on this variables not big numbers

sure it would help. no matter what you store in a variable of primitive type (like int) serialization stores as much bytes as that type, 4 bytes for an int for example

this helps a little but your problem seems to be something else.

do you wait for server's response before continueing animation loop ? for example do you have any code piece like the one below in your animation loop ?

ObjectInputStream.readObject()

Melssj5

Yeah, this is my mini mini mini mini code.

1.- get the events on a int array.
2.- sent them to the server
3.- make the server interact with all the clients and generate a list with the NodoRed of every client
4.- sent it to the client
5.- move the ships
6.- render the world
Nada por ahora

Melssj5

ok I guess I cant put the render on a separate thread and that will make the game look continous, but it wont solve a bigger problem! the speed of each ship. If the remote client does need more time to move the ship will move slower. In fact that happen now, the remote ship moves very slow. I read somewhere that i could solve that making the interaction with the server almost every 10 local iterations, I mean working 10/11 times locally and just a 1/11 interacting with the server? What do you think?

ABout using UDP I dont think so, because my game cant hold a bad message and I dont trust on the best effort without guaranties or retries.
Nada por ahora

raft

yes, you should remove the blocking code from the rendering thread. with your current way you are consuming your most valuable cpu time by just waiting response from server. using nio or putting blocking code into a seperate thread will both do the job

and your ship's speed isnt determined by how frequently it gets data from server. server should only say your ship's position, direction and maybe speed, accelaration etc. for instance:

frame 1: server said your ship is moving to D direction with S speed
frame1-10: you should move the ship toward that direction
frame 11: server reported some other D and S
frame 11-20 move to that direction
..
and of course you will not receive responses at perfectly regular intervals. the next response may come at 25th frame, the other one at 40th, next one at 41 etc

i see 3 chocies:

* you ship does exactly what your server says at that time, and nothing else. that means your ship will respond after some lag since you wait for server's approval and it also wont move smoothly

* move your ship without waiting for server's response. if server says something different than you expect correct your ship's position accordingly. this will cause your ship jump from here to there during correction

* do the second thing but instead of making your ship jump to corrected position, modify its path to reach the corrected position smoothly. this is a bit complicated but commercial games do it

hope this helps ;)
r a f t

Mizuki Takase

Wow~! This thread is getting really interesting... I know that I have not been helping Melssj5 as I should be (no thanks to World of Warcraft) but atleast raft is! I wanted to say thanks to both raft and Melssj5 since some year, I do plan on continuing my own project, which may include networking...

Melssj5

Well, I can say That you helped me Mizuki, maybe not to solve the problem but giving me some ideas and continuing with the project. I would be glad if you help me with the 3d models you made for the stages and the ships.

I will put the rendre thread and the event handling on different threads instead of on only one. But I guess that modifying the code to fix the ship position would be even harder.

Actually the server calculates everything for each iteration and sends the position and direction of each object3D on the world. That results on a different speed for each ship, syncronizing al the ships is not a good idea because if someone has not a good connection all the players with be lagged.  Anyway I may try raft solutions to check it. But I am afraid it will be an Xtreme change. But it must be done in anyway. but I have so few time on this week.
Nada por ahora