Python and Signal response time issues

Hello team

My friend (definitely not me) has been having a lot of issues with his Python bot not responding to the game in a timely fashion. At first he was doubting his abilities to optimize his program which led him on a witch-hunt for the part of his code causing this delay.

He traced it back to this part of the code:

StarterBot.py

def get_next_player_action(args) -> None: 
    try:
        ...
        hub_connection.send("SendPlayerCommand", [player_command])
        ...
    except Exception as e:
        ...

This command alone takes an average of 30ms with highs of 100ms even when sending empty commands.

Anyone know of a way to speed up sending his response back to the game faster? Asking for a friend.

It is as if the Signal library for python has been written to handle calls in series. This is understandable, but because the library itself takes more than 50ms of computation time, the bot basically never sends a command to the game. Even when the game is done, the bot keeps sending commands to the game as it is working through its backlog of requests.

Any ideas? Anyone else having this issue?

Funny, I also have a friend with a similar issue!

Huge backlogs/delays in signals to/from the engine, it seems. I’m still trying to make sense of it. Measuring the time between updates from the game engine, I sometimes have huge delays (multiple seconds!).
By the time I respond with an action, the engine is already loads of ticks in the future. This is with a small toy bot with pretty limited logic.

Not sure how to make sure that you’re in sync with the game engine when using the python bot. My friend has given up on it for now, and is seeing if there are similar issues with the other starter bots. So far it seems like the javascript reference bot doesn’t suffer from the same thing.

What I found when looking at the StarterBots is that the connections are different.

JavaBot - Synchronous
JavascriptBot - Asynchronous
KotlinBot - Synchronous
NETCoreBot - Asynchronous
PythonBot - Synchronous

From my limited knowledge, I would think this game would favor a Async connection. It’s even shown as the standard in the documentation.

Is your friend :wink: also using Python? Anyone else using Python, Kotlin or Java having issues?

Anyone else using JavascriptBot or NETCoreBot having a similar issue, or do you all have fiber fast connections to the engine?

Using .net i don’t really suffer from any noticeable issues, my bot plays a solid strategy due to the async nature, any delays I get from my own logic is compensated by taking a snapshot of the gamestate before I do my calculations.

I havent really tested the delay since I dont have much issues

I know a friend building JavaScript.

He also has a constant 4 round delay on bots.

The delay is pretty constant though, almost always 3 - 4 rounds.
So it might not be the connection itself.

My exact thoughts now is:
No wonder my Genetic AI last year just fell through at the end.

I was always turning just too late, making a near perfect bot almost useless because of the same issues here.

At least this year theres no future simulations (At least not the way i did last year).
So its manageable.

Unfortunately, the delay for the PythonBot is constantly growing.

Gif below is for a game at 50ms Tickrate and 500 rounds. The bot is the included StarterBot for python, with the addition of only showing the currentTick. As you can see, when the game is finished, the Bot is only registering the current tick of ± 200. There is no way of making an AI of any sorts if the SignalR overheads for Python is more than 50ms to begin with.

Animation

Can the EC team please assist with this?

This is strange,

The generic Referencebit runs pretty smooth.

I dont know python well, but will something like this signalr-async · PyPI not help make it more async?

@gatkramp I’m just giving up on the python bot (I also see increasing delays). After spending a lot of time trying to fix it, I’ve played with the other bots and am having much more success.

The javascript one works ok. It does sometimes get delayed updates though.
I tried a workaround where I measure the time since the last update from the engine, and if it’s been too long (or too short, which usually means it’s recovering from a late one) i ignore the update and immediately return.
That seems to work nicely, recovering from “bursty” updates at the cost of ignoring an update every now and then. But at least you stay in sync with the engine, and can be sure that your received state is fresh.

The C# one works great.
(once you get it working, which was a bit of a faff for me. what I ended up doing was changing the TargetFramework to .netcore 5.0).
It is properly asynchronous, updates come in consistently in a separate thread, independent of your turn logic.

So my advice is, don’t bother with the python bot, the python bot will only bring you tears.

I’m going to use c# this year (or possibly c++, if entelect/myself/someone else updates the starter bot to work with this year’s engine)

Thanks @Kortgat. I also saw it but to be honest, Async programming is a bit of a new concept to me. I will try to implement and see if it works.

Good afternoon everyone,

I would just like to assure you the team has seen the complaints about the Python signals and are investigating. We can unfortunately not ensure a solution as this might be an issue with a component outside of our control but we will let you know as soon as we have concluded our investigations.

Jip, the Python one is a bit of a mess. Even the Dockerfile is not working. If you have any other libraries in the requirements.txt file, it usually fails to build. Tried just adding numpy, which failed. I see this was an issue in 2021 which basically got ignored.

I fixed it by changing the base image to a more reputable source which fixed all the issues.

So my advice is, don’t bother with the python bot, the python bot will only bring you tears.

I like crying when I code :sweat_smile:. But in all honesty, I am doing the challenge to learn new techniques, and increase my knowledge base. Not ideal spending time on non-strategy related issues, but at least I am learning something.

Win-Win

1 Like

This seems to be a working solution. I had to use the signalrcore_async library. Bot now keeping up with the ticks. For some or other reason, it does not send back its command. Will fix it hopefully before the first round.

Awesome, I think in future events Entelect should add this to their python starter bot by default.

there will still be the small delay of 1 or 2 ticks due to the overheads of signalR in python but at least it wont compound the time .

Just be sure to watch out for doing calculations on the game state while you receive new game states, when using async processes that tries to modify the same variable/object at the same time can cause it to crash, I tend to extract the information I need into a separate variables and work with that so new states don’t mess with my current calculation

2 Likes

I think I fixed at lot of the PythonBot issues. I had to modify the signalrcore-async library to get it working as the library was outdated and did not send the invocationId to the SignalR server, which meant that commands sent to the server was never accepted.

I tested it a bit and it was working way better. I have posted the StarterBot to the portal and I am just waiting for the game to finish.

I have also created a pull request on the EC main repository for the Python Starterbot. It might not be implemented in time for the first tournament, but anyone can access the pull request to update their bot.

What a journey it has been so far. Now I can get back to strategy…

2 Likes

Evening, we’re currently looking at the starterbots :face_in_clouds: Thanks for contributing! :rocket: @JeanBoguo is gonna have a look :mag_right: