Jump to content


Photo

[39dll] Need help optimizating net code


  • This topic is locked This topic is locked
4 replies to this topic

#1 Fellshadow

Fellshadow

    GMC Member

  • GMC Member
  • 136 posts
  • Version:GM:Studio

Posted 13 May 2012 - 10:39 PM

I'm currently working on creating a MOBA-style game for a project, but I'm encountering a lot of lag, even though I'm playing it on a LAN.
If someone could take a look at my code and give me some advice on how to improve it, I'd be very grateful.

Warning: This is fairly long.

Step event for the Host's character
if(global.master == true){
    for(i = 2; i <= MaxPlayers; i += 1){
        
        clearbuffer(0);
        writebyte(myID, 0);
        writeshort(x, 0);
        writeshort(y, 0);
        writeshort(image_angle, 0);
        sendmessage(i, "", 0, 0);
    }
}

Begin Step Event for all other player's characters
if(global.master == false){
            
    clearbuffer(0);
    writebyte(myID, 0);
    writeshort(x, 0);
    writeshort(y, 0);
    writeshort(image_angle, 0);
    sendmessage(1, "", 0, 0);
}

Step Event for the Host's Ghosts
if(global.master == true){
    var size;
    while(true)
    {
      size = receivemessage(myID, 0, 0);
      if(size < 0) break;
      if(size == 0)
      {
        show_message("The other player left the game");
        game_end();
        break;
      }
      messageid = readbyte(0);
        if(messageid == myID){
          x = readshort(0);
          y = readshort(0);
          image_angle = readshort(0);
          break;
        }
    }

    for(i = 2; i <= MaxPlayers; i += 1){
        if(i != myID){
            clearbuffer(0);
            writebyte(myID, 0);
            writeshort(x, 0);
            writeshort(y, 0);
            writeshort(image_angle, 0);
            sendmessage(i, "", 0, 0);
        }
    }
}


End Step Event for Player's Ghosts
if(global.master == false){
    var size;
    while(true)
    {
      size = receivemessage(1, 0, 0);
      if(size < 0) break;
      if(size == 0)
      {
        show_message("The other player left the game");
        game_end();
        break;
      }
      messageid = readbyte(0);
        if(messageid == myID){
          x = readshort(0);
          y = readshort(0);
          image_angle = readshort(0);
          break;
        }
    }
}

I'm also send the time every second.
The Host also spawns 1 minion every 30 seconds from 4 spawn points (So 4 minions total spawned at once) that sends it's x, y and image_angle to all the other players.

I start to encounter lag when:
-I increase the amount of players to 4 or above.
-I increase the amount of minions to 2 or above. (8 Minions total spawned at once - I can't increase it any less than this due to the system)

I realize I shouldn't send the X and Y every step, but I'm not sure how to do it any other way.

Thanks in advance for any help.
  • 0

#2 2DLuis

2DLuis

    Graphic Designer

  • GMC Member
  • 2526 posts
  • Version:GM8

Posted 13 May 2012 - 10:45 PM

I realize I shouldn't send the X and Y every step, but I'm not sure how to do it any other way.


In essence, you're answering your own dilemma with this statement.
If you send position packets every step (30 in one second) that's 30 * your_packet's_size + tcp_header_size bytes that are being sent over the buffer (in one second). This will create unprecedented amounts of networking traffic. I suggest that you only update position on key press and release events.

Edited by 2DLuis, 13 May 2012 - 10:45 PM.

  • 0

#3 Fellshadow

Fellshadow

    GMC Member

  • GMC Member
  • 136 posts
  • Version:GM:Studio

Posted 13 May 2012 - 10:51 PM

Thank you for the quick reply.

The problem is that I'm not sure how to do this in a MOBA game.
On Mouse Click, the character paths to the clicked location. With other objects constantly moving around, the path is always changing.
How would I be able to only send the X/Y on mouse click but still have it display accurately to all other clients?

EDIT: I also have another question.
If I try to read data every step, even if none is being sent, will this cause lag in any way?

Edited by Fellshadow, 13 May 2012 - 11:42 PM.

  • 0

#4 Fellshadow

Fellshadow

    GMC Member

  • GMC Member
  • 136 posts
  • Version:GM:Studio

Posted 25 May 2012 - 10:55 PM

Bump.
I would really appreciate an answer to the edited-in question in my last post.
  • 0

#5 spasbunny

spasbunny

    GMC Member

  • New Member
  • 11 posts

Posted 13 June 2012 - 07:18 AM

On Mouse Click, the character paths to the clicked location. With other objects constantly moving around, the path is always changing.
How would I be able to only send the X/Y on mouse click but still have it display accurately to all other clients?


There are three things I think might help here:

1) If you simply send the position of the click to the other players you only have to send two variables for each user interaction and from there each client can move their version of the character towards whatever position was sent. As you mentioned above, this has a chance to produce fairly large discrepancies between what each player is seeing if the game state is out of sync for each player due to latency.

An example might be that a player has clicked on the other side of a forest patch and the path is calculated to take him along the slightly shorter route to the left of the forest, which all works well for the host. When this is sent to another player there is a minion in a slightly different place, blocking the left route and causing the route to the right to be slightly shorter. Obviously this will cause a fair amount of trouble, so some form of 'path correction' is necessary.

The most obvious method would be that every now and then you send the actual position of the real player object so that everyone else can make sure theirs is on the right track, and recalculate the path from the current position. The path acts as an approximation of what the real player is doing (and is hopefully usually a pretty good approximation), and if the copies of the player happen to stray they can be reset before anything gets too out of sync. Suppose you decide to keep everything relatively tight and send the X/Y coordinates every 3 steps (you could probably get away with a fair bit less than this): you have just cut your network traffic down to a third of its original amount, and if any packets happen to be dropped the copies of the player will keep moving towards the last known goal.

2) Make sure you only send necessary information. While I don't know how you happen to be using image_angle, if it is just facing the object in the direction that it is moving then it doesn't have to be sent through the network, simply get each client to update it based on the new and old position values:

x_old = x;
y_old = y;
x = readshort(0);
y = readshort(0);
image_angle = point_direction(x_old, y_old, x, y);

This solution won't help if you happen to need your objects to face in a different direction to the one they happen to be moving in, but in any case the general idea of 'send as little as possible' is a good start for improving this type of problem.

3) Would I be correct in guessing that you are using TCP connections as opposed to UDP? If so, you should consider moving the constant stream of updates to UDP. TCP is generally more relaible and will perform some error checking to guarantee that the packets you send get to their destination, unlike UDP, however this comes at the cost of extra network traffic. If you are sending the X/Y coordinates regularly then it doesn't matter if the occasional update doesn't make it to its target as the next one in line will correct the problem before the user has much of a chance to notice, so UDP would seem a better choice.

Hope that helps a bit...

If I try to read data every step, even if none is being sent, will this cause lag in any way?


As far as I know checking for incoming packets doesn't produce any network traffic, so it shouldn't contribute significantly to lag...
  • 0




0 user(s) are reading this topic

0 members, 0 guests, 0 anonymous users