Python SignalR multiple calls

Good day,
I realise this isn’t 100% an issue with the game runner but rather with the python implementation for SignalR, but I thought someone else having this issue might find the solution here.

In the Python starter bot a callback is registered for ReceiveGameState, which sets the current gamestate object to the most recently received game state. Sending actions however is decoupled from this callback, and instead works in a busy loop which constantly sends actions. I’d like to send a single action in response to a single gamestate instead, since the function which calculates the action is expensive (a neural network forward pass) and locks up the program while it’s running. When it’s called multiple times, it causes the bot to lag behind the current state and send actions for states in the past.

I’ve tried to add a lock to the send action loop so that it stays locked until the next gamestate is received, but something to do with how SignalR works makes it so that multiple actions get sent even with the lock.

Here are some logs from the python startbot (with print’s added for clarity) illustrating the issue:
Received state #1
Sent Action #1 to Runner
Sent Action #1 to Runner
Sent Action #1 to Runner
Sent Action #1 to Runner
Sent Action #1 to Runner
Sent Action #1 to Runner
Received state #2
Sent Action #2 to Runner
Sent Action #2 to Runner
Sent Action #2 to Runner
Sent Action #2 to Runner
Sent Action #2 to Runner
Sent Action #2 to Runner
Received state #3
Sent Action #3 to Runner
Sent Action #3 to Runner
Sent Action #3 to Runner
Sent Action #3 to Runner
Sent Action #3 to Runner
Sent Action #3 to Runner
Sent Action #3 to Runner

As you can see multiple actions are sent for the same gamestate. I realise this isn’t an issue by itself but when the function for calculating the action to take is expensive (50-60ms) it causes problems when that function is being called multiple times, unncessarily.

I hope my question is clear and that someone can help me with this.

1 Like

Hey @marcin_k,

Did you try to put the part that handles an action right after receiving the gamestate? Thus it should just happen only when a gamestate is received and thus not multiple times. You could also include a check of some kind to prevent an action from being sent to the runner if the previous one was not completed.

Hope this helps.

3 Likes

Another option, just to respond to your question around locking a computation pass with each receiveGameState - check the Javascript starter bot’s implementation. It does that.

The reasoning behind the variance in the way different starter bots do this, was to provide multiple examples of how you can work and interact with the engine - synchronously to the ReceiveGameState, as well as asynchronously with a “busy loop”.

Let us know if you need further info on this