Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Bots receives skipped-turn-event events while dead #83

Closed
SirStone opened this issue Mar 17, 2024 · 14 comments
Closed

Bots receives skipped-turn-event events while dead #83

SirStone opened this issue Mar 17, 2024 · 14 comments
Assignees
Labels
bug Something isn't working that should be fixed

Comments

@SirStone
Copy link
Collaborator

Describe the bug
I've took a while to discover this because I actively started again to work on code only yesterday, but looks like to me that at the death of the robot the server is still giving out the "skipped-turn-event" every turn

Expected behavior
2. stopping receiving the "skipped-turn-event" if the bot is dead

Screenshots
immagine

@flemming-n-larsen flemming-n-larsen added the bug Something isn't working that should be fixed label Mar 17, 2024
@flemming-n-larsen
Copy link
Contributor

@SirStone Thank you for reporting this issue, and also providing the details. I will have a look into this bug.

@flemming-n-larsen
Copy link
Contributor

@SirStone Could you create a minimum bot that can be used for showing this issue? 😊
I have trouble doing this with the sample bots for Java and C#.
I should like you to attach the source code to this issue.

@SirStone
Copy link
Collaborator Author

SirStone commented Mar 18, 2024 via email

@flemming-n-larsen
Copy link
Contributor

I've tried to make a simple bot with the java API but looks like the API itself is stopping to process the events after bot's death, with my API in Nim I'm printing out for test all received events, so I can see that the server is still sending out the after-death skipped-turn events. Sometimes, after several consecutive games where I start a match, stop it, restart it and so on, I find the server using 100% or more CPU, even with no running game. I'm not able to replicate it constantly, that's why I never opened an issue about this but could be that sometime the server keeps talking to dead bots.

I agree with you that something needs to be fixed, and it definitely looks like there is something going on at the server side.
I will try this out with your Nim API to reproduce the issue. 🙂

@SirStone
Copy link
Collaborator Author

SirStone commented Mar 19, 2024 via email

@flemming-n-larsen
Copy link
Contributor

I will wait for the basic bot.

I was able to build and run the Walls NIM 0.1.0 on Ubuntu 22 running on WSL 2 for Windows 11 using Visual Code.
So far, your Walls bot moves around as it should. 😊
But I had to use nim 1.6.18 as I get some {.gcsafe.} issues when using nim 2.0.2.

@SirStone
Copy link
Collaborator Author

SirStone commented Mar 24, 2024

mmm I imagine you used the code on GitHub, that code is year old and is made with NIM 1.6, that's why is not usable with NIM 2.0. Nim 2.0 is not fully compatible with the 1.* versions.

Since 1 year I started the API with NIM 2.0 from scratch but I committed on my personal git repo, the plan was to replace the repo on GitHub with this new one.

Here the zip code with the latest correct sources for Nim2.0, inside you will find the SkipperTester.
RTR_nim_botApi2-master.zip

the "SkipperTester" bot location is in src/RTR_nim_botApi2/OtherBots/SkipperTester
Run it launching it in the terminal with bash, this is required to see the output in the terminal, the SkipperTester bot is never sending the intent to the server so is not able to send messages to it either.

bash src/RTR_nim_botApi2/OtherBots/SkipperTester/SkipperTester.sh

this bash script will try to run the compiled bot in the same directory or the source code (this case). The compiled file is deleted afterwards.
The bot will attempt to connect using the Env variables as standard or can receive indications as arguments for the bash script
Usage: [-u IP:PORT] [-s BOT-SECRET]

In order to be able to see the SkippedTurn events after death, the game cannot end at bot's death, so I suggest to create this kind of match with 3 tanks:

  1. SkipperTester
  2. TrackFire
  3. Walls

With this set of bots there will be high chances that TackFire will kill the SkipperTester bot first and will continue trying to kill Walls, but Walls will be able to stay alive long enough to allow us to watch that the dead SkipperTester is still receiving the SkippedTurn events.

example output:
immagine

In this version of the API I'm printing, by the API themselves and not the bot, a '+' when a Tick arrived, a '-' when an intent is sent and a '!' when a skippedTurn event is received


here is the same source code that can be found in the sources for the SkipperTester bot (SkipperTester.nim)

import os
import ../../../RTR_nim_botApi2    # import the bot api

startBot newBot("SkipperTester.json") # start the bot

var dead = false

method run(bot:Bot) =
  while bot.isRunning(): # <--- we want mantain the bot running to avoid the automatc go()
    sleep(1000) # <--- sleep for 1 second, doing nothing
    # bot.go() <--- not sending go, we want to skip every turn!

method onDeath(bot: Bot, e: BotDeathEvent) =
  echo "I'm dead: " & $e.turnNumber
  dead = true

method onSkippedTurn(bot: Bot, e: SkippedTurnEvent) =
  if not dead: echo "Skipped turn: " & $e.turnNumber
  else: echo "Skipped turn: " & $e.turnNumber & " (dead)"

PS: these API are not usable for complex bots, I just reached a good point of the development but there are bugs that still needs to be fixed.

@flemming-n-larsen
Copy link
Contributor

@SirStone I am looking into the skipping issue, and hope I will get it into the 0.23 release, but no promise.

When creating a Java bot with same behaviour, I am not able to reproduce the issue. But I did not get any skipped turn event with the run() method if go() is never called. So I do expect some issue here. I am looking into it...

@flemming-n-larsen
Copy link
Contributor

@SirStone
I have had a very deep look into the issue and found out that there is no issue with the server or the present bot APIs in Java and C#. They behave as expected.
In order to receive any events with the (official) Bot APIs, the bot is responsible for calling go() at least once somehow in order to receive events.

Hence, the way your SkipperTester is written is not good for testing the SkipTurnsEvent.
As I am not good at Nim, I provided the a Java version I wrote to test it all out and make sure it behaves as expected:

import dev.robocode.tankroyale.botapi.*;
import dev.robocode.tankroyale.botapi.events.*;

public class SkipperTester extends Bot {

    private boolean dead;

    public static void main(String[] args) {
        new SkipperTester().start();
    }

    SkipperTester() {
        super(BotInfo.fromFile("SkipperTester.json"));
    }

    @Override
    public void run() {
        while (isRunning()) {
            int turnTimeOut = getTurnTimeout(); // in microseconds
            try {
                Thread.sleep(turnTimeOut / 1000); // in milliseconds
            } catch (InterruptedException ex) {
                break;
            }
            go(); // skip turn and receive events
        }
    }

    @Override
    public void onDeath(DeathEvent e) {
        System.out.println("I am dead: " + e.getTurnNumber());
        dead = true;
    }

    @Override
    public void onSkippedTurn(SkippedTurnEvent e) {
        System.out.println("Skipped turn: " + e.getTurnNumber() + ", dead: " + dead);
    }
}

The main difference here is happening in the run() method, as we make use of the getTurnTimeout() method to get the turn timeout (is provided in microseconds) and then we wait this exact amount of time to deliberately use all our time to get a Skipped Turn Event.
But we also make sure to call the go() method to "skip" the skip the turn so we will receive events.

I propose you try out the same thing for the Nim version of this bot and see if the behaviour is changing so it will skip almost all turns, and you will receive the SkippedTurnEvents.

@flemming-n-larsen flemming-n-larsen added potential bug Something might not be working and removed bug Something isn't working that should be fixed labels Apr 17, 2024
@SirStone
Copy link
Collaborator Author

I don't think this is the right way for you to replicate the behavior.
The SkippedTurnEvent follows this path:

SERVER -> API -> onSkippedTurn

When the bot is dead, the API can and should stop sending the "onSkippedTurn" to the bot and this is what your and mine API do. But developing the API i noticed that the SERVER is still sending the SkippedTurnEvent after the bot death, I'm talking about the SERVER -> API piece of the path, you can check it only fiddling with the API code and with the socket listener, even before the json message is converted to an usable object.

@flemming-n-larsen
Copy link
Contributor

@SirStone
Hi David. I promise to have another look from the API side of things. 👍

@SirStone
Copy link
Collaborator Author

I've looked in the server code and I found this part that looks like is relevant to this case:
link to server code

I see from the highlighted code that there's no distinction between a 'participant' alive or dead but only if the intent have been received or not, so if a dead bot is still among the participants, is still going to receive the skipped turn event from the server

@flemming-n-larsen flemming-n-larsen added bug Something isn't working that should be fixed and removed potential bug Something might not be working labels Apr 23, 2024
@flemming-n-larsen
Copy link
Contributor

@SirStone The bug should be fixed by now (at the server side), and will be available in release 0.23.0.

@flemming-n-larsen
Copy link
Contributor

Fixed with release 0.23.0

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
bug Something isn't working that should be fixed
Projects
None yet
Development

No branches or pull requests

2 participants