How to Automate Mining Asteroids in EVE Online

Getting back to the problem with EVE Online bots not working:

I just tested the new autopilot bot and uploaded a guide on how to use it: bots/guide/eve-online/how-to-automate-traveling-in-eve-online-using-a-warp-to-0-autopilot.md at 62863c120ee5d063cfc3490bbf6a73e432c70945 · Viir/bots · GitHub

Does this process work for you?

Thanks, something didnt work right. Downloaded the BotEngine via the link in the first bullet and tried to run it in CMD with exactly this command.

C:\EVE\BotEngine\BotEngine.exe start-bot --bot-source=“bots/implement/applications/eve-online/eve-online-warp-to-0-autopilot at 1a1af8ad177a56e006bcf583b3ef98f8b629e83d · Viir/bots · GitHub

The CMD response.

I am recording a log of this session to file ‘C:\bot-session\2019-10-09T00-34-19-A1B322F3920A\session.2019-10-09T00-34-19-A1B322F3920A.jsonl’
This bot source looks like a URL. I try to load the bot from Github
I found 9 files in ‘bots/implement/applications/eve-online/eve-online-warp-to-0-autopilot at 1a1af8ad177a56e006bcf583b3ef98f8b629e83d · Viir/bots · GitHub’.
I loaded bot 6B7CFF19DBC4B095338C0F3831DC92C3C5F65A5C6ADDDAA98B8C0710722240EB.
Starting the bot…

start-bot failed with exception: System.AggregateException: One or more errors occurred. (A task was canceled.)
—> System.Threading.Tasks.TaskCanceledException: A task was canceled.
— End of inner exception stack trace —
at System.Threading.Tasks.Task.ThrowIfExceptional(Boolean includeTaskCanceledExceptions)
at System.Threading.Tasks.Task1.GetResultCore(Boolean waitCompletionNotification) at System.Threading.Tasks.Task1.get_Result()
at Kalmit.BlobLibrary.GetBlobWithSHA256(Byte[] sha256)
at Kalmit.ProcessFromElm019Code.get_GetElmExecutableFile()
at Kalmit.ProcessFromElm019Code.CompileElm(IReadOnlyCollection1 elmCodeFiles, String pathToFileWithElmEntryPoint, String outputFileName) at Kalmit.ProcessFromElm019Code.CompileElmToJavascript(IReadOnlyCollection1 elmCodeFiles, String pathToFileWithElmEntryPoint)
at Kalmit.ProcessFromElm019Code.ProcessFromElmCodeFiles(IReadOnlyCollection1 elmCodeFiles) at Kalmit.PersistentProcess.PersistentProcessWithHistoryOnFileFromElm019Code..ctor(IProcessStoreReader storeReader, Byte[] elmAppFile) at BotEngine.Windows.Console.Bot.RunBotSession(Byte[] kalmitElmApp, Func2 getFileFromHashSHA256, String processStoreDirectory, Action1 logEntry, Action1 logProcessBotEventReport, String botConfiguration, String sessionId, String botSource) in K:\Source\Repos\bots\implement\engine\BotEngine.Windows.Console\Bot.cs:line 38
at BotEngine.Windows.Console.BotEngine.<>c__DisplayClass6_0.b__2() in K:\Source\Repos\bots\implement\engine\BotEngine.Windows.Console\Program.cs:line 270
[2019-10-09T00-36-11] Bot session ended.

Thank you for the feedback.
This looks like a fairly generic error, not specific to the bot, happens already at startup. This error message indicates that some download failed. But I don’t know yet why this happened to you. It could be that some network connection was interrupted.
I can test if I can find such an error when simulating slow internet connection or interruptions. It could also be some kind of firewall, so another test I could run is enabling more firewalls on a Windows and see if I get such an error.

This download where it failed is relatively large, but the engine will cache the downloaded file in the Windows user account. This means that when this download was successful once, it is not necessary anymore for future bot starts from the same Windows user account.

Another measure would be improving the download process to apply some compression, in case that was not done yet.

EDIT:
I ran some experiments here regarding this error you saw. I managed to simulate a scenario with limited internet bandwith.
(Setup in Windows Sandbox. The software ‘NetLimiter 4’ did not work. Using the software ’ TMeter Free’, I could implement the network speed limit. (https://www.howtogeek.com/347711/how-to-limit-any-applications-bandwidth-on-windows/))

In this scenario, I got following error message:

I loaded bot 6B7CFF19DBC4B095338C0F3831DC92C3C5F65A5C6ADDDAA98B8C0710722240EB.
Starting the bot....

start-bot failed with exception: System.AggregateException: One or more errors occurred. (A task was canceled.)
 ---> System.Threading.Tasks.TaskCanceledException: A task was canceled.
   --- End of inner exception stack trace ---
   at System.Threading.Tasks.Task.ThrowIfExceptional(Boolean includeTaskCanceledExceptions)
   at System.Threading.Tasks.Task`1.GetResultCore(Boolean waitCompletionNotification)
   at System.Threading.Tasks.Task`1.get_Result()
   at Kalmit.BlobLibrary.GetBlobWithSHA256(Byte[] sha256)
   at Kalmit.ProcessFromElm019Code.get_GetElmExecutableFile()
   at Kalmit.ProcessFromElm019Code.CompileElm(IReadOnlyCollection`1 elmCodeFiles, String pathToFileWithElmEntryPoint, String outputFileName)
   at Kalmit.ProcessFromElm019Code.CompileElmToJavascript(IReadOnlyCollection`1 elmCodeFiles, String pathToFileWithElmEntryPoint)
   at Kalmit.ProcessFromElm019Code.ProcessFromElmCodeFiles(IReadOnlyCollection`1 elmCodeFiles)
   at Kalmit.PersistentProcess.PersistentProcessWithHistoryOnFileFromElm019Code..ctor(IProcessStoreReader storeReader, Byte[] elmAppFile)
   at BotEngine.Windows.Console.Bot.RunBotSession(Byte[] kalmitElmApp, Func`2 getFileFromHashSHA256, String processStoreDirectory, Action`1 logEntry, Action`1 logProcessBotEventReport, String botConfiguration, String sessionId, String botSource) in K:\Source\Repos\bots\implement\engine\BotEngine.Windows.Console\Bot.cs:line 38
   at BotEngine.Windows.Console.BotEngine.<>c__DisplayClass6_0.<Main>b__2() in K:\Source\Repos\bots\implement\engine\BotEngine.Windows.Console\Program.cs:line 270
[2019-10-09T11-42-21] Bot session ended.

Once I remove the network limit in TMeter, it starts working.

Also, when running the bot a second time, it starts way faster, and does not fail even when the network speed limit is enabled again.

Next step is to find a way to optimize the download process so that it works better in such circumstances.

The problem with the error message has been reported on the .NET Core repository here: https://github.com/dotnet/corefx/issues/20296

Some ideas on how to improve the software can be found at https://thomaslevesque.com/2018/02/25/better-timeout-handling-with-httpclient/

@MutantWizard if you are aware of any process which did compete for internet bandwidth while you started the bot, you could try again after stopping such processes.

Thanks!

I use NetBalancer and tried the BotEngine again with NetBalancer open to monitor bandwidth usage. This is what NetBalancer reports before and during BotEngine runing.

Before:
Bandwidth usage from 0kb to max 5kb coming from Eve exefile.exe and evelauncher.exe. the only other bandwidth users within the same max 5kb prior to starting BotEngine were the system services like Service Traffic, svchost.exe, AODMR.exe, ICM-Service-NET.exe and SearchUI.exe. Nothing else.

During:
Started BotEngine and immediately bandwith went to 247-249kb flat with just about all of it being used by BotEngine for the whole period while it was running. The only other bandwidth users were the same as listed in the before. By the time BotEngine fails with an error it downloads just short of 25MB.

Normally I get 5-6mbps speed and mid 30s ping but for a week now seems my ISP is having some issues resulting in much slower speed than usual and frequent disconnections. Either that or they started throttling me for high usage.

Fortunately a disconnection did not happen during any of the maybe dozen BotEngine trials.

Update:
I tried again in the morning during low internet usage period just to check if I get different results. It came out exactly the same.

@MutantWizard thank you for the detailed report. I will find a solution and post it here.


Regarding the implementation side: I found some reports from other .NET integrators which are interesting for supporting compression:

@MutantWizard, I found a solution. You can avoid that error by using the new BotEngine console app from https://botengine.blob.core.windows.net/blob-library/by-name/2019-10-10.BotEngine.Console.zip

I implemented multiple improvements to help with this scenario:

  • Compression of the downloaded data. The size of the large file which was the bottleneck and led to the crash is now reduced to 13 MB. (This file will again be cached in the file system, so only needs to be downloaded the first time a bot is started on a Windows user account).
  • Increased timeout of the download process to 4 minutes. With the older version of the app, the download failed after 100 seconds, leading to the error message you saw.

It should be sufficient to use the new executable file; the other parts of the guide still apply as before.

I took a very short test trip and it works perfectly! Thanks so much!

Now how do I put the mining bot to do my hard labor?

@MutantWizard, thank you for sharing your results, good to know we have cleared this hurdle.

Now on to the mining bot: At the moment, I am not sure. We could start testing by looking at the activities happening in the asteroid belt. When the bot can do everything in the belt until the ore hold is full, it would already save time compared to not using a bot at all. Another option would be to start with the part of warping to the station and transfer the ore and then travel back to the asteroid belt.

If the ship is in the asteroid belt, what do we do next? I guess, right-click on an asteroid to open the context menu so that we then can click on Approach or Lock Target.

For me the only real benefit to using a bot comes from the bot being able to loop multiple ore loads to the station until interrupted. I would be happy to sacrifice all possible option just for the loop. That way i can take a nap while it works.

To the above effect I can tell you exactly what I do for the complete loop but up to you where to start coding and testing. If you wish you can allow for options but this is supposed to be a beginners bot so I would run it with a standard beginners setup but Im happy to test it whatever you decide.

I think a Standard Beginners Setup would be
System: HS 1.0 (no need to worry about NPC)
Ship: Any with an ore hold
Fitting: 2* Miner I in first two high slots, Thruster in first medium slot (all else optional since bot should not need to use)

Using this kind of a standard setup should make it easy to keep the bot simple, reliable and looping. Anyway up to you, Im happy to test.

Thank you for the clarification, this helps with prioritizing. You are right, skipping all nonessential features makes it a lot easier to program.

Having this information will reduce the time needed to develop this. Prioritizing completion of the loop is fine.

Yes this makes it simpler because the bot does not need to read information about the modules.

Great to do this with you, thoroughly enjoying trying to foresee eventualities and results.

This is the loop please feel free to insert questions for required clicks or data read that I missed to list.

I closed all non essential windows. Keeping open inventory window (list view, full tree) and Overview window (default Eve settings). I keep sort order by name so the order of asteroids and belts doesn’t change when moving from asteroid to asteroid. This way I always know which has been completed and which is next. This sacrifices a bit of travel time between asteroids but still acceptable.

Please note I did not build into this loop moving from depleted asteroid belt to the next asteroid belt coz I didn’t get to this occurrence. This should be built in so if you need me to I can try to simulate this occurrence.

Start Loop
docked with an empty ore hold (remember station to bot variable)
click undock
click Mining tab in overview
right click first asteroid belt and warp to 0
when warp ends scroll down in overview to bring ore asteroids to visible
right click first ore asteroid and approach
when in range right click same ore asteroid and lock target
click first high slot with Mining laser (for reliability wait until ship stopped)
click second high slot with mining laser
click ore hold in inventory window
wait until ore hold full or asteroid depleted (both mining lasers stopped)
if ore asteroid depleted (both mining lasers stopped and ore hold not full) go to start depleted ore asteroid sub-loop
if ore hold full skip sub-loop and continue

start depleted ore asteroid sub-loop
right click first ore asteroid and approach
when in range right click same ore asteroid and lock target
click first high slot with mining laser
click second high slot with mining laser
wait until ore hold full or asteroid depleted (both mining lasers stopped)
if ore hold full exit sub-loop
otherwise go to beginning of sub-loop
end depleted ore asteroid sub-loop

click General tab in overview
right click originating station and dock (retrieve from bot variable)
click and hold to drag ore from ore hold to item hangar
go to beginning of loop
End Loop

This is the basic and simplest loop I could come up with that still works for a single asteroid belt. Even do not need to use afterburner. No exit from loop needed except CTRL + ALT interrupt. i would also suggest for bot to simulate human clicks by inserting a short random time delay between clicks.

1 Like

Think the code might be more efficient this way.

Start Loop
docked with an empty ore hold (remember station to bot variable)
click undock
click Mining tab in overview
right click first asteroid belt and warp to 0
when warp ends scroll down in overview to bring ore asteroids to visible

start sub-loop
right click first ore asteroid and approach
when in range right click same ore asteroid and lock target
click first high slot with mining laser (for reliability wait until ship stopped)
click second high slot with mining laser
wait until ore hold full or asteroid depleted (both mining lasers stopped)
if ore hold full exit sub-loop
otherwise go to beginning of sub-loop
end sub-loop

click General tab in overview
right click originating station and dock (retrieve from bot variable)
click and hold to drag ore from ore hold to item hangar
go to beginning of loop
End Loop

1 Like

I did forget one thing in the above process. There is a real possibility that the above process returns the ship to dock with multiple ore types in the ore hold. so the drag and drop from the ore hold will have to be repeated until the ore hold is empty (another small sub-loop).

I tried to change asteroid belt under assumption that the belt has been depleted. I determine depletion if I warp to the belt and there aren’t any ore asteroids available. Then I just click on the next asteroid belt in the list to find out if any ore asteroids there.

Its easy enough to do it manually but I guess a bit more complex to automate it. The only way I came up with was to keep the overview sort by naming so the order in which they are listed doesn’t change by ship moving around and take a count of the number of asteroid belts. Then I pick the first and warp to 0 then others one by one in the same order in which they are listed in the overview. Adding 1 to the counter each time we visit the next asteroid belt tells the both which belt should be next by counting down the list. Hope this is doable.

1 Like

Thank you for sharing this mining process. Seeing this approach was enlightening. When designing bots, I am used to the more tree-ish structure found in more evolved bots like A-Bot and the mission running bot. The strongly sequential approach shown here makes development more straightforward.

I will use your approach as a check-list in development.

For now, I am not looking at handling belt-depletion. I do not see a problem with considering this after implementing the other parts of the bot.

It looks a lot shorter than the earlier version, so I think it will be easier to understand, which in turn makes it easier to improve.

Not sure how we can identify such a clickable representation of asteroid on the screen. We have clickable objects in the overview window. Some those rows in the overview represent asteroids, but which ones? Can we assume that any row in the overview containing the text “Asteroid” in the Name column is such an asteroid? Or is this not specific enough when we have asteroid belts in the overview too?

Would the “Asteroid” text match be specific enough if we hide the belts from the overview? (For warping, we can use bookmarks (easier to program) or the solar system menu).

Asteroid belt is represented by the line which includes text “Belt”. If the line includes the string “Asteroid” but not the string “Belt” then we can safely assume its an ore asteroid but feel free to do it the easiest way.

1 Like

Im old school from Cobol days and have not done almost any coding since then. Seems logical it would be quite different from what you guys do nowadays. Hope my contribution is useful.

I think we may have to address belt depletion quite quickly. The belts in HS 1.0 systems deplete quite quickly during the day. Very often by the end of the day there is only a few belts left with asteroids that contain ore. None the less you are right, step by step. First without this logic will be easier.

Seeing this example is very helpful, beyond the development of the mining bot. It will also benefit the people who want to learn how to develop bots. I see now many people landing here could be familiar with the sequential/looping approach. As a result, they might have a hard time following the current guides on bot development. Adding a comparison of the different design approaches to the guides should support readers from a more diverse range of previous experience.

I started development on the sensor/seeing side of this mining bot.
I am using this bot description from above, to find out what information the bot needs about the game:

  • Something to initiate undock: → Undock button in station window? Now I remember seeing somewhere you could also undock with a context menu on the active ship in the inventory window. So maybe that would be an alternative.
  • Decide ‘if ore hold full’ → Probably using the capacity gauge in the inventory window.
  • Context menu (for warp, approach, lock target): Seems already covered: The travel bot uses the context menu and the structure should be the same for context menus opened on other objects, such as overview entries.
  • In overview window:
    • Tabs, each with region and title.
    • Entries, each with region, name and distance.
  • Modules in the ship UI. For each module:
    • Indication if it is active.
    • Region (for the click)
  • In the inventory window:
    • Representation of the item hangar (Region)
    • Items in the selected container (Regions)

I think reusing the Sanderling memory reading framework is the fastest way to get all the input we need. I collected samples of what we get from this framework. It looks like two snapshots of the game are sufficient to cover these parts of memory reading. One in station, and one in the belt. I uploaded these samples here:

I am not sure about these parts:

Where would we read this station name from when docked?
Anyway, by using a bookmark instead we can avoid waiting for this.