BotEngine Devlog

development-of-botengine
#1

This thread is a chronological overview of my work to help you with bot development. I noticed it tends to get chaotic sometimes, so I am trying this as a way to keep organized :thinking:. I guess that ordering by time will be most effective to find things again.

If you have any comments or questions, feel free to post in a new topic.

1 Like
closed #2
#3

People mentioned they have problems getting hash values for files.
Being able to share and identify files is essential when working on bots, so I wrote this guide on how to do that, using hashes:

1 Like
#4

This week brings improvements specific for EVE Online.
As some people had difficulties adapting the memory reading to their use cases, I improved the example code in the Sanderling repository:

It now better shows:

  • Which part of the intermediate results we reuse when reading the UI tree multiple times from the same EVE Online client process. (In the Sanderling app, we reuse the address of the root of the UI tree, because this address does not change. By reusing this part we save time so that subsequent readings of the complete UI tree can be completed in about 200 milliseconds.)
  • Where the transition is between the intermediate representation (partial python objects) of the memory measurement and the representation found in the bot developers API. Observations in the last three years showed this is an important boundary: When we adapted the memory reading to new client versions from CCP, we did that in the part that happens after reading the partial python objects.

You can find the guide on adapting EVE Online memory reading here in the Sanderling repository at ./guide/how-to-adapt-eve-online-memory-reading.md

As always, if you want to learn more about how the memory reading works in EVE Online, don’t hesitate to post your questions on the BotEngine forum.

1 Like
Industry Index Scrape
What is going to be required of Sanderling for the 64 bit client?
#5

While helping @huihui to develop an Industry Index Scraping script, I found some things to improve in the Sanderling App.
I have updated to Sanderling App with a simpler mouse input API: There is a way to Mouse Click on Entry without clicking on info button

The next improvement planned there is to reduce the time to get feedback on experiments and to support easier exploration of the APIs. It looks like there will be a REPL which supports incrementally building up functionality which can be composed into bots. The same interface will also support quick inspection of results from memory reading.

1 Like
#6

I published the first version of this tool today, along with a guide on how to use it at A Simpler Way to Make EVE Online Bots

1 Like
#7

An update regarding EVE Online:
I merged an update of the memory reading based on an observation shared by Kaboonus:

This was to adapt to changed in-memory symbols of the missions info panel.
You can download the compiled binary of version 2019-04-05 from https://ci.appveyor.com/api/buildjobs/0ereo9umi7suqbo4/artifacts/src%2FSanderling%2FSanderling.Exe%2Fbin%2FDebug%2FSanderling.Exe.exe

I also updated this EVE Online bot development guide accordingly: A Simpler Way to Make EVE Online Bots

2 Likes
#8

I recently worked more on the design to solve the issues of bot operation interrupted sporadically by script bugs which are hard to spot:

1 Like
#9

As mentioned earlier, I am working on a new version of the EVE Online bot framework, to solve the issues with understanding bot code and bad surprises at runtime, and recording and inspection of bot operation.

This is a report on the recent progress with developing this framework:
I explored possible solutions using the example of a warp to 0km autopilot bot. Today I uploaded a rough draft of how this framework could be used. This draft concentrates on static parts, framework API and programming language. Other aspects are not presented in there. The programming language part is already well demonstrated as this draft contains said autopilot bot, I copied the bot code below:

module Main exposing (botStep)

{-| This is a warp to 0km auto-pilot, making your travels faster and thus safer by directly warping to gates/stations.
The bot follows the route set in the in-game autopilot and uses the context menu to initiate warp and dock commands.
To use the bot, set the in-game autopilot route before starting the bot.
Make sure you are undocked before starting the bot because the bot does not undock.
-}

import SimplifiedSanderling
    exposing
        ( BotEvent(..)
        , BotEventAtTime
        , BotRequest(..)
        , InfoPanelRouteRouteElementMarker
        , MemoryMeasurement
        , MouseButtonType(..)
        , centerFromRegion
        , mouseClickAtLocation
        )


-- This implementation is modeled after the script from https://github.com/Arcitectus/Sanderling/blob/5cdd9f42759b40dc9f39084ec91beac70aef4134/src/Sanderling/Sanderling.Exe/sample/script/beginners-autopilot.cs


{-| We need no state for the autopilot bot
-}
type alias State =
    ()


init : ( State, List BotRequest )
init =
    ( initialState, [] )


initialState : State
initialState =
    ()


botStep : BotEventAtTime -> State -> ( State, List BotRequest )
botStep eventAtTime stateBefore =
    case eventAtTime.event of
        MemoryMeasurementCompleted memoryMeasurement ->
            ( initialState, botRequests ( eventAtTime.timeInMilliseconds, memoryMeasurement ) )

botRequests : ( Int, MemoryMeasurement ) -> List BotRequest
botRequests ( currentTimeInMilliseconds, memoryMeasurement ) =
    case memoryMeasurement |> infoPanelRouteFirstMarkerFromMemoryMeasurement of
        Nothing ->
            [ ReportStatus "I see no route in the info panel. I will start when a route is set."
            , TakeMemoryMeasurementAtTime (currentTimeInMilliseconds + 4000)
            ]

        Just infoPanelRouteFirstMarker ->
            case memoryMeasurement |> isShipWarpingOrJumping of
                Nothing ->
                    [ ReportStatus "I cannot see whether the ship is warping or jumping."
                    , TakeMemoryMeasurementAtTime (currentTimeInMilliseconds + 4000)
                    ]

                Just True ->
                    [ ReportStatus "I see the ship is warping or jumping, so I wait."
                    , TakeMemoryMeasurementAtTime (currentTimeInMilliseconds + 4000)
                    ]

                Just False ->
                    botRequestsWhenNotWaitingForShipManeuver
                        memoryMeasurement
                        infoPanelRouteFirstMarker
                        ++ [ TakeMemoryMeasurementAtTime (currentTimeInMilliseconds + 2000) ]

botRequestsWhenNotWaitingForShipManeuver : MemoryMeasurement -> InfoPanelRouteRouteElementMarker -> List BotRequest
botRequestsWhenNotWaitingForShipManeuver memoryMeasurement infoPanelRouteFirstMarker =
    let
        announceAndEffectToOpenMenu =
            [ ReportStatus "I click on the route marker to open the menu."
            , mouseClickAtLocation
                (infoPanelRouteFirstMarker.uiElement.region |> centerFromRegion)
                MouseButtonRight
                |> Effect
            ]
    in
    case memoryMeasurement.menus |> List.head of
        Nothing ->
            [ ReportStatus "No menu is open."
            ]
                ++ announceAndEffectToOpenMenu

        Just firstMenu ->
            let
                maybeMenuEntryToClick =
                    firstMenu.entries
                        |> List.filter
                            (\menuEntry ->
                                let
                                    textLowercase =
                                        menuEntry.text |> String.toLower
                                in
                                (textLowercase |> String.contains "dock")
                                    || (textLowercase |> String.contains "jump")
                            )
                        |> List.head
            in
            case maybeMenuEntryToClick of
                Nothing ->
                    [ ReportStatus "A menu was open, but it did not contain a matching entry." ]
                        ++ announceAndEffectToOpenMenu

                Just menuEntryToClick ->
                    [ ReportStatus ("I click on the menu entry '" ++ menuEntryToClick.text ++ "' to start the next ship maneuver.")
                    , mouseClickAtLocation (menuEntryToClick.uiElement.region |> centerFromRegion) MouseButtonLeft |> Effect
                    ]


infoPanelRouteFirstMarkerFromMemoryMeasurement : MemoryMeasurement -> Maybe InfoPanelRouteRouteElementMarker
infoPanelRouteFirstMarkerFromMemoryMeasurement =
    .infoPanelRoute
        >> Maybe.map .routeElementMarker
        >> Maybe.map (List.sortBy (\routeMarker -> routeMarker.uiElement.region.left + routeMarker.uiElement.region.top))
        >> Maybe.andThen List.head


isShipWarpingOrJumping : MemoryMeasurement -> Maybe Bool
isShipWarpingOrJumping =
    .shipUi
        >> Maybe.andThen .indication
        >> Maybe.andThen .maneuverType
        >> Maybe.map (\maneuverType -> [ SimplifiedSanderling.Warp, SimplifiedSanderling.Jump ] |> List.member maneuverType)

Upload with all the details is on github:

1 Like
MARVEL script, ratting at a new level
#10

Today I worked on removing a bottleneck from EVE Online bot development. In the past, adapting the memory measurement parsing code required a developer to set up Visual Studio and use a .NET build. To remove this friction, the parsing code is moved into the bot scope, where it can be changed as easily as your own bot code.
The commit in the Sanderling repository adds an example of how to write the serialized memory measurements to files, so these can be easily imported when experimenting with changes to the parsing code:

After running this new derivation code on a process sample, you will find the files partial-python.json, sanderling-memory-measurement.json and sanderling-memory-measurement-parsed.json in a subdirectory named after the process.

Edit:
I improved the names for the derivations to:

  • Avoid having two different kinds of ‘memory measurement’.
  • Clarify that the reduction happens from partial python to get the other versions.

The names of derivations are now:

  • partial-python
  • reduced-with-named-nodes
  • reduced-with-named-nodes-parsed-further

3 Likes
#11

Design of the EVE Online bot framework continues:

I continued the design based on the draft from last week.

The linked commit adds the following parts:

  • Sample files containing derivations from EVE Online memory measurements, to use as a reference for automated testing of parsing code.
  • Example bot (Main.elm) to ensure fundamental functionality is covered in the first release.
  • Bot-side code for the interface of EVE Online bots to the hosting app (Sanderling_Interface_20190513.elm).
  • EVE Online specific functionality (Sanderling.elm). This also contains code to parse the contents of memory measurements from Sanderling.
  • Automated tests for the interface functions and memory measurement parsing functions.

With this version, the new framework is almost ready for the first release.

1 Like
#12

Did some fine-tuning for the EVE Online bot framework today:

1 Like
#13

The new EVE Online bot framework has landed! :tada:

Besides releasing the software to run EVE Online bots, I also uploaded this guide which explains how it works:https://github.com/Viir/bots/blob/56fd088fb5c7c52fe08ada90f75acc0f652e753c/guide/how-to-use-eve-online-bots.md

Edit:
Updated guide to fix a problem in the example of how to start a bot:

Thanks @Kaboonus for pointing out that problem!

Next step is writing guides on how to develop EVE Online bots.

3 Likes
MARVEL script, ratting at a new level
#14

Today I started the guide on developing EVE Online bots, describing how to set up the programming tools to efficiently work on EVE Online bots. You can find it here:

As questions come up, I will expand this.

1 Like
#15

An update regarding EVE Online:

I published a new version of the bot framework and updated the download links in the guide accordingly:

With the new software, a generic interface between bot and host is introduced, which offers more flexibility in the functionality integrated into a bot.

One concrete example of how this flexible interface improves over the old Sanderling app: This allows coding custom logic to choose a windows process in case there are multiple instances of the game client process present.

Most developers won’t need to use this new interface directly but will use it indirectly over libraries encapsulating these low-level functionalities for easier use.

An example of such a library is the one for EVE Online, contained in the warp-to-0 auto pilot bot, in the file Sanderling.elm: