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

Wrapped bot throws exception #1

Closed
Cu3PO42 opened this issue Oct 20, 2024 · 11 comments
Closed

Wrapped bot throws exception #1

Cu3PO42 opened this issue Oct 20, 2024 · 11 comments

Comments

@Cu3PO42
Copy link

Cu3PO42 commented Oct 20, 2024

Hi! I'd like to start by thanking you for your continued work on Robocode. I've had a lot of fun with it for almost a decade now.

While evaluating the new Tank Royale platform, I attempted to port some legacy (non-publically-available) bots using the API bridge. They all trigger the same exception at runtime:

dev.robocode.tankroyale.botapi.BotException: StatusEventMapper.map: Could not get robot status from map
	at dev.robocode.tankroyale.bridge.StatusEventMapper.map(StatusEventMapper.java:14)
	at dev.robocode.tankroyale.bridge.AllEventsMapper.lambda$map$0(AllEventsMapper.java:28)
	at java.base/java.util.ArrayList.forEach(ArrayList.java:1596)
	at dev.robocode.tankroyale.bridge.AllEventsMapper.map(AllEventsMapper.java:21)
	at dev.robocode.tankroyale.bridge.BotPeer.getAllEvents(BotPeer.java:535)
	at dev.robocode.tankroyale.bridge.BotPeer.getScannedRobotEvents(BotPeer.java:613)
	at robocode.AdvancedRobot.getScannedRobotEvents(AdvancedRobot.java:889)
	at infovk.repro.TankRoyaleRepro.getScannedRobotEvents_(TankRoyaleRepro.java:34)
	at infovk.repro.TankRoyaleRepro.act(TankRoyaleRepro.java:72)
	at infovk.repro.TankRoyaleRepro.run(TankRoyaleRepro.java:51)
	at dev.robocode.tankroyale.bridge.BotPeer$BotImpl.runRobot(BotPeer.java:732)
	at dev.robocode.tankroyale.bridge.BotPeer$BotImpl.run(BotPeer.java:721)
	at dev.robocode.tankroyale.botapi.internal.BotInternals.lambda$startThread$3(BotInternals.java:118)
	at java.base/java.lang.Thread.run(Thread.java:1583)

I have tried to create a minimal reproducing sample bot that triggers the behavior and am attaching a
packaged jar. You can find the source in this gist. The bot is expected to do nothing except maintain a radar lock in a 1v1, it neither moves nor fires.

The issue seems to stem from requesting the robot's event queue, but not to be related to ScannedRobotEvents specifically. In the "full framework", we handle all event types, but this does not seem to trigger any additional errors.

The reason for the admittedly somewhat odd event handling is that this is the above example is the result of taking a framework and stripping away everything that was not needed to trigger the exception. (Background Info: At my university, the stundents organize a one week introductory programming course for new students before actual classes start. We've found that event handlers were a difficult concept to grasp for many, so we wanted to move everything into the main loop and are storing events in a queue. It's been a few years since I wrote those abstractions, so I unfortunately do not recall why we have our own queue, but also reference AdvancedRobot#getScannedRobotEvent.)

Everything works on legacy Robocode and I'm decently confident we're not violating any laws of Robocode, but I wouldn't guarantee it 100%. I have done my best to strip down everything that is not needed to reproduce the issue.

Thank you in advance for looking into this!

@flemming-n-larsen
Copy link
Contributor

@Cu3PO42

I am happy to hear that you have had a lot of fun with Robocode! 😊

And thank you for both reporting the issue, and providing a lot of details for how to reproduce it, which is crucial for getting the issues fixed. It sounds like a generic bug with the bridge that needs to be fixed.

Regarding not using event handler, and instead using the main loop and reading out events from there is a perfectly legal way to do it in Robocode. You can use the event handlers, if you want, or just extract the current events from the main method or any other method.

I will have a look into this issue and see if I can fix it. 🙂

@flemming-n-larsen
Copy link
Contributor

@Cu3PO42

I have now fixed the issue in the (robocode-api) causing the issue you encountered. And the TankRoyaleRepro you provided seems to run fine with the fixed version. 👍

I have put the new robocode-api-0.2.0.jar for you here into a zip file (GitHub does not allow me to upload jar files directly)
robocode-api-0.2.0.zip

If you encounter more issues, if will be very happy if you raise more tickets about it so we can improve the bridge and be able to support as many legacy robots as possible. 😊

@Cu3PO42
Copy link
Author

Cu3PO42 commented Oct 22, 2024

Thanks for getting to this so quickly! I can confirm the reproduction bot now runs correctly in the first round, and so do other bots based on the same framework.

Unfortunately, they all stop working in the second round due to issues I suspect are related. I'll open another issue when I have the time to do a proper write up for this (probably tomorrow).


The reproduction bot I included fails with the exception

java.util.ConcurrentModificationException
	at java.base/java.util.LinkedList$LLSpliterator.forEachRemaining(LinkedList.java:1253)
	at java.base/java.util.stream.Streams$ConcatSpliterator.forEachRemaining(Streams.java:735)
	at java.base/java.util.stream.AbstractPipeline.copyInto(AbstractPipeline.java:509)
	at java.base/java.util.stream.AbstractPipeline.wrapAndCopyInto(AbstractPipeline.java:499)
	at java.base/java.util.stream.ReduceOps$ReduceOp.evaluateSequential(ReduceOps.java:921)
	at java.base/java.util.stream.AbstractPipeline.evaluate(AbstractPipeline.java:234)
	at java.base/java.util.stream.ReferencePipeline.collect(ReferencePipeline.java:682)
	at infovk.repro.TankRoyaleRepro.getScannedRobotEvents_(TankRoyaleRepro.java:35)
	at infovk.repro.TankRoyaleRepro.run(TankRoyaleRepro.java:49)
	at dev.robocode.tankroyale.bridge.BotPeer$BotImpl.runRobot(BotPeer.java:729)
	at dev.robocode.tankroyale.bridge.BotPeer$BotImpl.run(BotPeer.java:718)
	at dev.robocode.tankroyale.botapi.internal.BotInternals.lambda$startThread$3(BotInternals.java:118)
	at java.base/java.lang.Thread.run(Thread.java:1583)
java.util.ConcurrentModificationException
	at java.base/java.util.LinkedList$LLSpliterator.forEachRemaining(LinkedList.java:1253)
	at java.base/java.util.stream.Streams$ConcatSpliterator.forEachRemaining(Streams.java:735)
	at java.base/java.util.stream.AbstractPipeline.copyInto(AbstractPipeline.java:509)
	at java.base/java.util.stream.AbstractPipeline.wrapAndCopyInto(AbstractPipeline.java:499)
	at java.base/java.util.stream.ReduceOps$ReduceOp.evaluateSequential(ReduceOps.java:921)
	at java.base/java.util.stream.AbstractPipeline.evaluate(AbstractPipeline.java:234)
	at java.base/java.util.stream.ReferencePipeline.collect(ReferencePipeline.java:682)
	at infovk.repro.TankRoyaleRepro.getScannedRobotEvents_(TankRoyaleRepro.java:35)
	at infovk.repro.TankRoyaleRepro.run(TankRoyaleRepro.java:49)
	at dev.robocode.tankroyale.bridge.BotPeer$BotImpl.runRobot(BotPeer.java:729)
	at dev.robocode.tankroyale.bridge.BotPeer$BotImpl.run(BotPeer.java:718)
	at dev.robocode.tankroyale.botapi.internal.BotInternals.lambda$startThread$3(BotInternals.java:118)
	at java.base/java.lang.Thread.run(Thread.java:1583)

Other bots fail with

The thread of the bot could not be interrupted causing the bot to hang.
So the bot was stopped by force.

I assume the thread running the bot for the first round keeps running even after it is complete. This seems to align with the infinite main-loop. Might it be necessary to throw some termination exception? I'll need to look into how that currently work.

@Cu3PO42 Cu3PO42 closed this as completed Oct 22, 2024
@flemming-n-larsen
Copy link
Contributor

@Cu3PO42

Let us continue on this thread with the second issue as well. 🙂

A ConcurrentModificationException should be easy to fix as soon as I figure out where it happens. I will have a look at this as well.

@Cu3PO42
Copy link
Author

Cu3PO42 commented Oct 23, 2024

Sure, if that works better for you I'm happy to continue here! I have been able to create a simple reproduction for the other exception

The thread of the bot could not be interrupted causing the bot to hang.
So the bot was stopped by force.

as well.

Compared to the previous version, I have added basic linear targeting. You can find the source here and a packaged version
in this ZIP.

I suspect that the actual implementation of linear targeting is irrelevant and the different error is simply caused by slightly different timing.

@Cu3PO42 Cu3PO42 reopened this Oct 23, 2024
@flemming-n-larsen
Copy link
Contributor

@Cu3PO42

I have already found several issues that I am trying to solve within the Bot APIs for Java and C#. The most critical one is the one you already mentioned, that it seems that old threads are not stopping in new rounds. And another where the bridged bots cannot be restarted as they disconnect from the WebSocket and exits.

@flemming-n-larsen
Copy link
Contributor

@Cu3PO42
Just a heads up.
I am still working on solving these issues. I have solved some of them, but there are some side-effects I need to get rid of as well.

@Cu3PO42
Copy link
Author

Cu3PO42 commented Nov 3, 2024

I appreciate the update! I didn't mean to convey any urgency. Once you believe you have resolved the problems you are aware of, I'll resume testing!

@flemming-n-larsen
Copy link
Contributor

With Release 0.27.0 lots of bugs has been fixed.

A lot of bugs has also been fixed with the Robocode Bridge. But some still remains.

@Cu3PO42
Copy link
Author

Cu3PO42 commented Dec 3, 2024

Thank you! I can confirm that the bots I tested are now working correctly :-)

I also tested some bots from LiteRumble. DrussGT seems to work perfectly, but BeepBoop crashes immediately:

2024-12-03 21:09:40.493 java[56579:12301144] WARNING: Secure coding is automatically enabled for restorable state! However, not on all supported macOS versions of this application. Opt-in to secure coding explicitly by implementing NSApplicationDelegate.applicationSupportsSecureRestorableState:.
Connected to: ws://localhost:7654
Connection error with ws://localhost:7654
java.lang.NullPointerException: Cannot invoke "java.util.List.add(int, Object)" because "previousStates" is null
	at kc.mega.game.GameState.updateStates(GameState.java:193)
	at kc.mega.game.GameState.updateMyStates(GameState.java:213)
	at kc.mega.game.GameState.updateWithoutScan(GameState.java:70)
	at kc.mega.BeepBoop.onSkippedTurn(BeepBoop.java:205)
	at dev.robocode.tankroyale.bridge.BotPeer$BotImpl.onSkippedTurn(BotPeer.java:875)
	at dev.robocode.tankroyale.botapi.internal.EventHandler.publish(EventHandler.java:26)
	at dev.robocode.tankroyale.botapi.internal.BaseBotInternals$WebSocketListener.handleSkippedTurn(BaseBotInternals.java:953)
	at dev.robocode.tankroyale.botapi.internal.BaseBotInternals$WebSocketListener.onText(BaseBotInternals.java:858)
	at java.net.http/jdk.internal.net.http.websocket.WebSocketImpl$ReceiveTask.processText(WebSocketImpl.java:635)
	at java.net.http/jdk.internal.net.http.websocket.WebSocketImpl$ReceiveTask.run(WebSocketImpl.java:443)
	at java.net.http/jdk.internal.net.http.common.SequentialScheduler$CompleteRestartableTask.run(SequentialScheduler.java:149)
	at java.net.http/jdk.internal.net.http.common.SequentialScheduler$SchedulableTask.run(SequentialScheduler.java:207)
	at java.base/java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1144)
	at java.base/java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:642)
	at java.base/java.lang.Thread.run(Thread.java:1583)

While the stack trace seems to indicate a problem with BeepBoop itself, it does work correctly in legacy Robocode.

I'll see about conducting a more extensive test of all bots in the rumble soon.

@flemming-n-larsen
Copy link
Contributor

@Cu3PO42 Thank you for the confirmation.

There are still some issues I currently hunt down. One of them is that the cannon seems to point in the wrong direction for some bots. So I do expect a bug somewhere in the bridge. But I have had a hard time spotting it.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants