What's new
  • Visit Rebornbuddy
  • Visit Resources
  • Visit API Documentation
  • Visit Downloads
  • Visit Portal
  • Visit Panda Profiles
  • Visit LLamamMagic

[OLD] Exilebuddy Ascendancy Major API/Bot Changes

Status
Not open for further replies.

pushedx

Well-Known Member
Joined
Sep 24, 2013
Messages
4,252
Reaction score
290
With the release of Ascendancy, Exilebuddy has undergone several major API design updates. These were done to keep us up with the current state of the game, and should greatly help improve Exilebuddy in the future. Please note, this post covers API related stuff, and not the bot implementation related stuff (that is in the next post!).

Unchanged

Pathfinding

The current pathfinding library is an old copy of ours, from 2012-2013. We have a new updated version to use, but it was not possible to switch to it. The current system works decently, but the design of code that uses it, ExilePather, is in need of some major updates. For example, all pathfinding is done synchronously, so when many pathfinding operations are done, the bot will stop and wait for them to complete. Furthermore, support is limited for being able to correctly handle the terrain nuances of this game, which results in the bot getting stuck tying to go though narrow areas and the like.

Components/Object Manager/Objects

These things need a modernization update. This was partly done at the last big expansion with the simplification of the Item API, which has helped a lot. Further changes will help remove API bloat from over the years, and help improve performance in some places. However, for the time being, they are staying as-is.

Changed

GUI API

Please see the An Overview of Exilebuddy's GUI API Design thread for the new GUI related changes. This is the biggest set of API changes Exilebuddy has seen.

Input

Input has seen some major changes to offer better compatibility with the client and finally provide the expected behavior. The old implementation modeled input events on a global level, meaning if you just performed a mouse click, you'd have to wait the input event delay (default was around 100ms) before another input action was processed. This proved problematic, since you're able to perform mouse input and keyboard inputs at the same time. In addition, you can use multiple keys simultaneously, which is important for using flasks.

The new implementation now sets an input event delay of around 200-250ms each event, but each event is separately tracked. So for example, if you press the 1 key, there is a 200-250ms delay between when you can press the 1 key again, but, you can press any other key or event right away, as long as it too was not already on a cooldown. This design models more human like behavior, as the typical person can only click 4-5 times per second (there's a lot of sites that let you test reaction speed that were used to come up with this value).

In the old design, the average input events per second were 10, which translated into 600 input events per minute. With the new design, the max value (barring the user changing the values) is half that for each event type. However, additional changes have been made to how the Input API is being used by the bot/routine implementation to help greatly reduce this, yet makes things feel more fluid and fast compared to before.

API wise, a new function, SimulateKeyEvent replaces the previous key related functions (PressKey, ReleaseKey). This is to more accurately model keyboard messages, as sometimes you want to only send a down, or down/char/up, or only a up. In any case though, you want to do it all at once, as opposed to across multiple frames, which would happen in the old implementation.

The purpose of these changes is to make the bot play the game more human-like in terms of performing actions, while attempting to avoid looking like a bot due to high input actions per second/minute. We hope these will make a big difference moving forward, as users will definitely notice these changes when they run the bot.

Terrain Data

The implementation of terrain data has changed a bit. In the previous version, the API would cache terrain data per-area, then expose a set of raw data to anyone who wanted it. The new design now exposes the current terrain data, and a new cache class has been added to help avoid the overhead of reading all the terrain data multiple times per-area.

TerrainData.Cache (A CachedTerrainData object) tracks the current terrain data per-area. This data is reloaded on area change, to reduce memory usage as before multiple copies would exist in memory. This does increase some processing time on area-changes back to the old area, but is the first set of changes moving towards a better implementation (which falls under the Pathfinding stuff that didn't make it in).

A new class, WalkabilityGrid, has also been added. This is a wrapper class that operates directly on arrays of pathfinding data. In the old design, a similar class existed to store the walkablity status of a position, but it used a lot of memory and processing as it was a part of the old pathfinding library and never updated. This change should further help to reduce memory use and processing overhead.

Finally, a new function, UnblockTriggerableBlockages has been added to update pathfinding data that has been blocked off by triggerable blockages. For example, if pathfinding data is requested (non-cached) near a closed door, the door blocks off the two adjacent areas, and pathfinding operations would fail, which means the bot could not pathfinding though the area at all. To get around this, the triggerable blockage is "unblocked" in the data so the pathfinding data models what the terrain would look like if it was already opened. This functionality used to be internally applied to pathfinding data but is now exposed.

ExilePather

ExilePather has seen some changes in regards to the set of functions that calculate a walkable position for an object. In the old code, a rather bruteforce algo was used to find walkable locations near an object. These were commonly 30x30 grids at most, but some were much smaller. The problem with this implementation was that a pathfind was done for each point, so if the user was really far away, 100s of really long, time consuming pathfinds were done, which caused the bot to stop and wait since pathfinding is synchronous.

This is why the bot would randomly stop at times in towns when a new area transition came into view. Another problem with the implementation was that it had to code around several area transitions which had very specific nuances. For example, Catacombs has a stairwell that you need to travel down into before being able to interact with the area transition. Without the special handling, a location on the side could be chosen, and the bot would fail taking the area transition.

The new design removed all those functions in favor of a much simpler, smarter algorithm, that should help fix all area transition interactions. So far in testing, things look great, but tweaks will be added as needed if any new issues come up.
 
Last edited by a moderator:
With the release of Ascendancy, Exilebuddy has undergone several major bot design updates. These were done to keep us up with the current state of the game, and should greatly help improve Exilebuddy in the future. Please note, this post covers the bot implementation related stuff, and not the API related stuff (that is in the previous post!).

Unchanged

Grind Bot

The "grind bot" design of OldGrindBot is still the same and has not changed. This implementation is in need of some modernization work, but due to major API updates it was not possible to improve a lot of aspects of this.

Corrupted areas have known issues with completion if you die near the end. In addition, Vaal Vessel opening seems broken in certain cases, as the chest state for them is no longer consistent (client doesn't know if it can open it or not). These things will be looked into later, as it takes a while to find and test new logic for them.

For users who wish to bot in Perandus challenge leagues, Perandus chests get treated as normal chests when it comes to opening them outside of your grind zone. In other words, if the current grind zone isn't the area you're in, the bot will not go out of its way to open these chests. This is just how the chest logic opening works for now, and no changes will be made for now.

In addition, the Perandus league pack mechanics will burst DPS down most builds using OldRoutine. The respawning mechanic requires a routine that will fall back and kite to avoid the league design. Changes to OldRoutine for this league will not be made.

Targeting

The Combat Targeting system is one of the main contributors to high frame time. More specifically, the underlying Stats system is really expensive to access per object, and constantly accessing the stats of all objects in range start to add up. These checks are required to a degree, but a better implementation is needed to help reduce the load. It was originally planned to rewrite this system, but due to the API changes, this has been postponed.

Changed

3rdParty Content Loading

The new 3rd party content loading system has now replaced the old system. Please read the Overview of the new upcoming 3rd party content loading system for more information if you are unfamiliar with it.

Code Compiler Changes

The code compiler has changed for 3rd party content. Before, we used CodeDOM (the DevTab still does) but it is rather old now and does not support a lot of new C# features. The Rosyln compiler services are now used to compile modern C# for 3rd party content. This doesn't change anything for devs, other than that they can use new modern C# features!

AreaStateCache

Some performance related changes were made to AreaStateCache. This class is now obsolete and will be removed in the future, but for now is required by OldGrindBot as everything is designed around it. Items and Chests are now added in batches, in an attempt to lower long update spikes in areas with a lot of objects. For example, up to 10 chests/items are processed per AreaStateCache update of the respective system. Pathfinding checks for chests have been updated as well. Breakable chests no longer get pathfinding checks used on them, as it was causing long pauses in crypt-like areas with a ton of urns/gold pots. This has helped reduce some unnecessary overhead, but is only a small band-aid for the design.

Coroutines

A lot of the coroutines have had some updates to account for latency and reaction times. The bot should now look and feel more natural and fast compared to before, since a lot of artificial delays have been removed. Delays are now mostly based on latency and a reaction time to make sure things don't work too fast.

Interaction coroutines have been updated to hopefully get rid of the clunky look and feel they have had in the past. Looting is much faster now, with a much smaller artificial delay, as without it, things look too much like a bot is performing the actions. The artificial delays after chest opening have been removed, so users should be able to move away from strongboxes more easily now than before. There are still some delays based on latency and the like, but users can implement their own chest opening coroutines without them if they really want to.

Various coroutines for the Stash have been updated to support the new currency tabs. The currency tabs work differently than normal stash tabs, so devs will need to update their logic to handle them correctly. The WithdrawItemsCoroutine will not currently withdraw from currency tabs, but Stashing or Iding coroutines will.

PlayerMover

There is a new DefaultPlayerMover implementation that replaces the old ones. This one has two notable changes compared to previous implementations. The first is the experimental anti-wall hugging logic used in City of Sarn is now applied outside of towns. This should help quite a bit in places that were having issues with paths running too close to walls. The second is the method of movement has changed. In the old implementations, a move action was performed with a mouse click, in a click-to-move fashion. While this worked and was as precise as possible given client limitations, it ran into two main issues. First, it required an input action per move, so when input events were throttled to 100ms, only 10 move actions could be performed per second. The client can handle much more, but when the bot tried it, too many actions were being generated. The second issue is fast moving characters would stutter quite a lot as the delay between the bot running and the client finishing the action grew.

In the new implementation, one move action is started, then the bot will continuously move as a normal player would. This allows the client to move as fast as possible, while exponentially reducing the number of input events sent to the client. There is a downside to this approach, but so far it seems insignificant in most cases. If there are client performance issues (more like when), it's possible for the bot to overshoot it's destination. This isn't an issue when coded around, but it's possible the bot does some glitchy things at times as a result. On the plus side, limited frame rate setups should now behave almost exactly the same as normal ones, and require no additional changes (the experimental, non-supported LowFPS mechanic has been removed).

An Execute function has been added to the interface to allow users more flexibility with interacting with them. The following example gives a simple illustration of how this can be used.

The implementation for the player mover is as follows for devs who want to use the new design in their own code: https://gist.github.com/pushedx/c1dd3692afe369b3fc61ba72f341b6cf

OldRoutine

The primary/secondary skill casting of OldRoutine has been updated to use the same skill use mechanics as the DefaultPlayerMover. With this design, the bot is able to make the character attack as fast as possible, without spamming the client with new input events which otherwise would trigger the Too Many Actions disconnection. As a result, the default CR will attack much faster and more fluid than before. It is highly recommended all CR devs update their routines to make use of the BeginUseXXX functions as well, as it makes a huge difference.

The other aspects of OldRoutine have not been changed, as it's an old routine that needs to be replaced, but unfortunately was not possible due to the API updates. For now, it's still the default routine we provide.
 
Last edited:
Status
Not open for further replies.
Back
Top