Java-Gaming.org    
Featured games (81)
games approved by the League of Dukes
Games in Showcase (498)
Games in Android Showcase (115)
games submitted by our members
Games in WIP (562)
games currently in development
News: Read the Java Gaming Resources, or peek at the official Java tutorials
 
    Home     Help   Search   Login   Register   
Pages: [1]
  ignore  |  Print  
  3D Networking trials.  (Read 793 times)
0 Members and 1 Guest are viewing this topic.
Offline GabrielBailey74
« Posted 2013-10-06 22:58:47 »

Hello JGO, it's been a while since I've made a post here :3

Last night I created a trial 3D networking app, it's laid out like so:
1  
2  
3  
     [server]
    |        |
[client] [client]

Everything seemed fine until I decided to start taking in players "Coordinate packets" (line containing x, y, x & ID) and shipping them to another player:
1  
2  
3  
   public void sendPosition(Player p) {
      p.session.writeObject(~[Client[" + id + "]: packed-location: "+x+", "+y+", "+z+"]~);
   }

Issues:
Looks like severe lag. (Player movements are super jittery)
If the players x or z is updated, occasionally the y value will go crazy? (X & Y != z so why's the z value being updated client sided?)


Features relative to this post:
Each player is represented in the game world by a box.
Both players render properly @ their x, y, z in the game world.

Questions:
Is the reason for the lag because I'm sending strings instead of another data type?

Notes:
Stream types are both ObjectStreams (ObjectInputStream -> ObjectOutputStream)
Thanks for any feedback guys =D

Offline opiop65

JGO Kernel


Medals: 154
Projects: 7
Exp: 3 years


JumpButton Studios


« Reply #1 - Posted 2013-10-06 23:05:15 »

I've never really done networking, but in all the tutorials I've read everything is sent in bytes. Maybe thats the cause? Also, how many times per second do you send that packet? Dont send it every frame, only send it a few times a second and interpolate the movement between the spaces where you don't send them.

Offline GabrielBailey74
« Reply #2 - Posted 2013-10-06 23:13:32 »

only send it a few times a second and interpolate the movement between the spaces where you don't send them.

Sounds great, I will try implementing =D

At the moment the only time the players x / y / z is sent over the network is if it has changed:
(Code: Client-sided)
1  
2  
3  
4  
5  
6  
7  
8  
9  
10  
11  
12  
13  
14  
15  
16  
17  
18  
19  
20  
21  
22  
23  
24  
25  
26  
27  
28  
29  
30  
31  
32  
33  
34  
35  
36  
37  
38  
39  
40  
41  
   // This method is called by 'player.update(tpf)' which is called from the games update loop.
  private void updateLoc(double tpf) {

      // cam.getLocation() until physics are implemented.
     Vector3f loc = cam.getLocation();
      x = loc.x;
      y = loc.y;
      z = loc.z;
      boolean newX = false;
      boolean newY = false;
      boolean newZ = false;
      if (lastX != x) {
         newX = true;
      }
      if (lastY != y) {
         newY = true;
      }
      if (lastZ != z) {
         newZ = true;
      }
      lastX = x;
      lastY = y;
      lastZ = z;
      if (newX && newY && newZ) {
         sendValue("x");
         sendValue("y");
         sendValue("z");

         // we've updated the x, y, z no need to continue.
        return;
      }
      if (newX) {
         sendValue("x");
      }
      if (newY) {
         sendValue("y");
      }
      if (newZ) {
         sendValue("z");
      }
   }

This is called every 10ms to send the positions on the fly:
(Code: Server-sided)
1  
2  
3  
4  
5  
6  
7  
8  
9  
10  
11  
12  
   for (Player p1 : players) {
      for (Player p2 : players) {
         if (p1 != p2) {

            // Send player 2 player 1's position
           p1.sendPositionPacked(p2);

            // Send player 1 player 2's position.
           p2.sendPositionPacked(p1);
         }
      }
   }

All code criticism is welcome lol, I know I'm probably doing multiple things wrong.

Games published by our own members! Check 'em out!
Legends of Yore - The Casual Retro Roguelike
Offline Troncoso

JGO Coder


Medals: 20



« Reply #3 - Posted 2013-10-06 23:22:24 »

You've got two kinds of packets you can send: UDP and TCP. UDP is what you should use for inconsequential things like position and speed and stuff as it is much faster. TCP is for more secure data.
Offline GabrielBailey74
« Reply #4 - Posted 2013-10-06 23:27:28 »

You've got two kinds of packets you can send: UDP and TCP. UDP is what you should use for inconsequential things like position and speed and stuff as it is much faster. TCP is for more secure data.

@Troncoso:
TCP Is default I believe.
UDP with java would require use of a DatagramPacket not raw strings =D

I will try switching to UDP/DatagramPacket and apply some benchmarking tonight Smiley

Thanks Troncoso, feedback's still welcome guys =D

Offline Jeremy
« Reply #5 - Posted 2013-10-06 23:58:12 »

You've got two kinds of packets you can send: UDP and TCP. UDP is what you should use for inconsequential things like position and speed and stuff as it is much faster. TCP is for more secure data.

@Troncoso:
TCP Is default I believe.
UDP with java would require use of a DatagramPacket not raw strings =D

I will try switching to UDP/DatagramPacket and apply some benchmarking tonight Smiley

Thanks Troncoso, feedback's still welcome guys =D

Before you do that, try disabling Nagle's Algorithm first (with interpolation and client-side prediction.) In today's world, a lot of very successful FPS games are written over TCP and it is very likely you can pull it off too. It will make your life a lot easier.

http://stackoverflow.com/questions/12094583/can-nagles-algorithm-be-disabled-when-using-httpurlconnection

JevaEngine, Latest Playthrough (This demo is networked with a centralized server model)

http://www.youtube.com/watch?v=rWA8bajpVXg
Offline GabrielBailey74
« Reply #6 - Posted 2013-10-07 00:33:35 »

Before you do that, try disabling Nagle's Algorithm.

@Jeremy:
No difference, just tried with it on / off.
Thanks though ^_^

I'm going to try using UDP with DataGramSockets & DataGramPackets I guess ^_^
Already wrote a simple client/server now to implement the 'player system' for sending / storing coordinates.

If you think about it, is that alot of data to send every 10ms?
int bytes2Send = 98 * onlineClients;


Quote
INCOMING DATA: ~[Client[2]: packed-location: 4.33860469818115, 0.0340594636558, 9.76801013946533]~

Offline Jeremy
« Reply #7 - Posted 2013-10-07 00:36:34 »

Before you do that, try disabling Nagle's Algorithm.

@Jeremy:
No difference, just tried with it on / off.
Thanks though ^_^

I'm going to try using UDP with DataGramSockets & DataGramPackets I guess ^_^
Already wrote a simple client/server now to implement the 'player system' for sending / storing coordinates.

If you think about it, is that alot of data to send every 10ms?
int bytes2Send = 98 * onlineClients;


Quote
INCOMING DATA: ~[Client[2]: packed-location: 4.33860469818115, 0.0340594636558, 9.76801013946533]~

You aren't going to get smooth gameplay if you are literally just sending player coordinates. No matter which protocol you use.

JevaEngine, Latest Playthrough (This demo is networked with a centralized server model)

http://www.youtube.com/watch?v=rWA8bajpVXg
Offline GabrielBailey74
« Reply #8 - Posted 2013-10-07 00:44:55 »

You aren't going to get smooth gameplay if you are literally just sending player coordinates.
Thanks ^_^, I'm not familiar with interpolation / client side prediction yet.
Is that what you mean by your quote above?

Below is 2 code snippets, would both of them have the same effect on sending/receiving players positions?
Meaning: would both snippets below send the data in the same amount of time, and not cause the players position to be updated slightly later due to snippet #2's length?

1  
2  
3  
4  
// shortest possible IMO
byte[] bytes = (id + "," + x + "," + y + "," + z).getBytes();
DatagramPacket packet = new DatagramPacket(bytes, bytes.length, HOST, PORT);
socket.send(packet);


1  
2  
// way too much unnecessary data xD
clientObjectOutputStream.writeObject("~[Client[" + id + "]: packed-location: "+x+", "+y+", "+z+"]~");

(I don't know why player movement is so choppy :/ - Is it due to too much string parsing?)

Offline HeroesGraveDev

JGO Kernel


Medals: 254
Projects: 11
Exp: 2 years


┬─┬ノ(ಠ_ಠノ)(╯°□°)╯︵ ┻━┻


« Reply #9 - Posted 2013-10-07 02:14:08 »

You've got two kinds of packets you can send: UDP and TCP. UDP is what you should use for inconsequential things like position and speed and stuff as it is much faster. TCP is for more secure data.

Not neccessarily the best advice.

Using TCP and UDP over the same router increases UDP packet loss.

Also, packet loss with UDP causes more inconvience for the users, and if you end up trying to implement your own version of TCP on top of UDP... well, you have a serious flaw.

If you need TCP, use TCP.
If you think you need UDP, use TCP.
If you know you need UDP, and can explain why it suits your situation better than TCP, then use UDP.

Games published by our own members! Check 'em out!
Legends of Yore - The Casual Retro Roguelike
Offline GabrielBailey74
« Reply #10 - Posted 2013-10-07 02:24:14 »

Could it be because I'm sending the data at such a fast rate? o.O

I made a benchmarking test using a for loop:
(I'm now sending raw bytes ^_^ no more raw strings)
1  
2  
3  
4  
5  
6  
   // I/O has just been initialized.
  for (int i = 0; i < 500; i++) {

      // send the client the time this message was sent.
     client.write(new String("TimeStamp: " + System.currentTimeMillis()).getBytes());
   }

Client output:
(Longest delay for message @ server -> client: 420ms)
http://pastebin.com/B84RW0hT

From the output it looks like the more and more messages that get sent in that for loop cause a build up in server -> client messaging delays?

Offline GabrielBailey74
« Reply #11 - Posted 2013-10-07 02:29:39 »

Wow...

It was because I was sending the data so fast xD
1  
2  
3  
4  
5  
6  
7  
8  
9  
10  
11  
12  
         new Timer(10, new ActionListener() {
            @Override
            public void actionPerformed(ActionEvent e) {
               try {

                  // write the time every 10ms vs. for loop(500)
                 write();
               } catch (IOException e1) {
                  e1.printStackTrace();
               }
            }
         }).start();


Message gets to the client in 0ms.
(Highest being the occasional 10ms)

But I already wrapped my code to update the players position in a timer @ 10ms intervals, I'm guessing if I increased the delay it wouldn't be good soo? Sad

Offline KudoDEV

Senior Newbie





« Reply #12 - Posted 2013-10-08 22:48:56 »

Games like this shoudl be like so:

You connect to server > server sends other player's positions to you and sends your position to others players.

when a client moves send move to server > server updates client's position server side and sends move to others.

that's how I do it for tile based movement.
Offline GabrielBailey74
« Reply #13 - Posted 2013-10-09 03:50:41 »

Games like this shoudl be like so:

You connect to server > server sends other player's positions to you and sends your position to others players.

when a client moves send move to server > server updates client's position server side and sends move to others.

that's how I do it for tile based movement.

Thanks ^_^

That's exactly what's going on.

Player connects to server > position and ID are sent to the server.
When a client moves > send his new position to the server which is than broadcasted to all other clients.

The main issue is how choppy the movement is :/

Offline KudoDEV

Senior Newbie





« Reply #14 - Posted 2013-10-09 04:03:38 »

Oh, I had the same issue.

Create a movement class that keeps track of each movement packet received.

Every time the game updates use delta to calculate how far the player should move.

So say you receive a left movement packet > create a movement instance set it in the players instance

> gameloop checks if players have queued movement

> movement updates (position.x -= delta * ( u * v ))     meaning: u = speed and v = factor to make u*v = pixels per seconds wanted.

> if movement reaches pixels wanted per packet null it.

> game loop checks for movements if the movement is now null there is no movement.

That worked wonders for me.
Offline xsvenson
« Reply #15 - Posted 2013-10-09 08:19:51 »

The source engine network model: https://developer.valvesoftware.com/wiki/Source_Multiplayer_Networking
Also latency compensation and stuff: https://developer.valvesoftware.com/wiki/Latency_Compensating_Methods_in_Client/Server_In-game_Protocol_Design_and_Optimization

Also, once You have worked with the network  long enough, I suggest You take a look at Kyronet: https://code.google.com/p/kryonet/

“The First Rule of Program Optimization: Don't do it. The Second Rule of Program Optimization (for experts only!): Don't do it yet.” - Michael A. Jackson
Pages: [1]
  ignore  |  Print  
 
 
You cannot reply to this message, because it is very, very old.

 

Add your game by posting it in the WIP section,
or publish it in Showcase.

The first screenshot will be displayed as a thumbnail.

radar3301 (9 views)
2014-09-21 23:33:17

BurntPizza (28 views)
2014-09-21 02:42:18

BurntPizza (18 views)
2014-09-21 01:30:30

moogie (20 views)
2014-09-21 00:26:15

UprightPath (27 views)
2014-09-20 20:14:06

BurntPizza (29 views)
2014-09-19 03:14:18

Dwinin (46 views)
2014-09-12 09:08:26

Norakomi (74 views)
2014-09-10 13:57:51

TehJavaDev (102 views)
2014-09-10 06:39:09

Tekkerue (50 views)
2014-09-09 02:24:56
List of Learning Resources
by Longor1996
2014-08-16 10:40:00

List of Learning Resources
by SilverTiger
2014-08-05 19:33:27

Resources for WIP games
by CogWheelz
2014-08-01 16:20:17

Resources for WIP games
by CogWheelz
2014-08-01 16:19:50

List of Learning Resources
by SilverTiger
2014-07-31 16:29:50

List of Learning Resources
by SilverTiger
2014-07-31 16:26:06

List of Learning Resources
by SilverTiger
2014-07-31 11:54:12

HotSpot Options
by dleskov
2014-07-08 01:59:08
java-gaming.org is not responsible for the content posted by its members, including references to external websites, and other references that may or may not have a relation with our primarily gaming and game production oriented community. inquiries and complaints can be sent via email to the info‑account of the company managing the website of java‑gaming.org
Powered by MySQL Powered by PHP Powered by SMF 1.1.18 | SMF © 2013, Simple Machines | Managed by Enhanced Four Valid XHTML 1.0! Valid CSS!