Python: UDP server is really slow

I created an UDP server which recieves a position of a player in a game. The player sends their coordinates to the server continiously. The server sends this data to all the clients that are in the game so they can see eachother move. It’s kinda working but sometimes there comes a delay (this doesn’t happen all the time tho). So it’s like the other players are moveing in slow motion. Is there anything that I can do to get rid of this delay?
So the game detects when the player presses the w, a, s or d key (which makes the player move) when it detects this it applies the movement to the player.
another function gets the worldposition (coordinates of the player) and sends it to the server.
all the functions on the client side are being run seperately.

The whole project:

The server:
https://hastebin.com/cifamedeho.py

The client:
https://hastebin.com/kozigitume.py

I know it’s a big chunk of code but I am really lost here and don’t really know what might be causing this.

The problem:
[video]https://giphy.com/gifs/YV4sGjmxEzqjEss3Xy/fullscreen[/video]

At what frequency are you sending the data?

I tested out your code (all locally on a single machine) and it seemed to be working perfectly fine. There was no perceivable delay. Is the delay present for you even when testing everything locally?

https://hastebin.com/wonuxubidi.py

You could use something like this to debug your functions.


import tracing

@tracing.trace()
def function_to_trace(meh):
    return meh

Just decorate every function you think could do funny things, and watch in the console how long everything is taking ?

It might be the wifi. The school wifi acts like this for me sometimes.

Also, I think you are using Queues which are good to synchronize data between threads, but with the BGE the best practice is to avoid threads as much as possible.

In your case, I would recommend using https://docs.python.org/3/library/selectors.html#examples

I saw improvements over 10x faster getting rid of threads in a small BGE test using networking.

In the video I was just sending it without a delay so the problem could be shown better normally I set the tick to 2.

I do also have this problem when I am testing locally

Isn’t this for TCP servers? And besides I am not running the server in Blender. The server is being run separately from the game (so just the python file is being runned.

So you’re testing locally. Is everything on a single machine, or on multiple machines on a local network? Are the machine(s) running anything else in the background that could be using a lot of network resources?

When you say you set “tick” to 2, I assume you mean the Skip option on sensors. What does your logic brick setup look like? This is what I tested with and it worked fine.


I know you probably don’t wanna rewrite your code but maby you’d like to have a look at this https://github.com/chr15m/PodSixNet. It’s a perfect fit for the bge and pretty easy to customize.

Yes I was testing everything locally on the same machine. And there are no processes running that might be using a lot of network recourses (at least not to my knowledge)

And you where correct by tick I mean the Skip option.

Might the problem be that I am running it all on the same machine?

you problem could be buffer related.
try add this to your server

self.server.setsockopt(socket.SOL_SOCKET, socket.SO_RCVBUF, 1)

Tried this but it doesn’t seem to solve the problem. It actually kind off seems to make it occur more often

Do you guys also have the lagg when you run it locally? (with multiple instances)
This is the whole project: https://github.com/JerryMotov/tankgame if you are trying it out don’t forget to run the server first & enter the IP at the specified places!

I haven’t looked in detail at this, but a cursory glance of the client file suggests that you’re just calling recvfrom() once per frame. If that is the case, then you will run into gradual buffering when packets do not arrive for every tick. To solve this, you need to process all messages until the message buffer is empty. You don’t have to apply the movements / other inputs as soon as you process the message, just ensure that the socket buffer doesn’t back up.

You are correct about the client calling recfrom() once per frame.
and ‘To solve this, you need to process all messages until the message buffer is empty.’ I am not sure what you mean by this. do you mean that I have to like start a thread if it recieves something? or place the code that handles the message in a different function?

I am just a blender beginner so this is all still a bit new for me :slight_smile:

I mean that you keep calling recvfrom, until it throws an error (you could even check the error code to ensure it’s a “no messages in buffer” error).


def all_messages(sock):
    try:
        while True:
            yield sock.recvfrom()
        
    except socket.error:
        pass




def update():
    for data, addr in all_messages(sock):
        # Do something
        pass

ahh I think I know what you mean.
i’ve tried what you said but this doesn’t make any difference unfortunately & the error it throws is “[WinError 10035] A non-blocking socket operation could not be completed immediately:frowning:
I am really lost now I have no clue why this stuff keeps happening :-/ & it also seems to work pretty shit @ school. What am I doing wrong here the idea/functionality behind the server is not that bad right?

What does your logic brick setup look like? I would take a look at the Render and World properties panels as well. What frame rate is the game running at while testing? It sounds to me like your code isn’t being called frequently enough. Unchecking the Use Framerate option will allow the game to update more frequently. Also try replicating the logic setup I showed you. That’s what I used when testing everything locally on a single machine, and it worked perfectly fine.

My setup used to look like this:


But now i’ve changed it to what you tried. and i’ve unchecked the use framerate option.
But I still have the same issue.
Did you also try moving the players simoultaniously. It mostly occurs when more players are trying to move.