.NET is a platform upon which EyeAuras is built. It affects all the tiny bits - startup, memory allocation, data management, literally every small bit of the program is affected by this change.
NET8 is not the latest version (there is already a preview of .NET 10), but platform upgrade is not something you do "just because", there must be a reason. I've picked .NET8 (and not .NET9/.NET10) because only for that specific version there is a prototype of a new memory management mechanism, which, from the current tests, just blows out of the water literally everything else that we had in .NET since its inception.
That is one of the primary characteristics of this new mechanism in comparison to what we have now ("workstation-sustainedlowlatency"). Basically this is the duration of those "hiccups" which tend to happen and are in worst cases become noticeable.
Traditionally, there is always a tradeoff when you're developing a system - you can spend less CPU time, but it will cost you some extra memory OR you can save some memory, but it will increase CPU consumption. EyeAuras has almost always been picking the first option - memory is cheap and cpu cycles are expensive in consumer PCs (purely my opinion). But, aligning to that strategy also means that any improvements in the very core of memory management system should affect us greatly and that memory management mechanism seems to be a perfect fit. We'll see how it goes, but I am expecting to achieve a measurable performance jump in the nearest future.
ScriptContainerExtension
prototype - there will be a separate article on this later. For now it is in alpha-stage.That feature allows you to Link from BT/Macro another aura containing C# Script
action - this is equivalent of you "referencing" another project in programming.
All the classes and types defined in that script will become available to you for use in BTs.
Referencing has existed for many months by now, but was "hidden" from a public eye as it was not fully complete and was not working in a way I wanted it to.
Now you can have C# class, which will analyze the game - be it via Computer Vision triggers or by directly reading values from memory - and provide BehaviorTree with a data necessary for making a decision.
Instead of cluttering the tree with all the checks and having 50 different Variables, you can now have a single class, e.g. TheGame
, which will be wrapping up ways of getting the info.
This is a bot which under the hood uses that same approach which I will be outlining below.
First, lets take a look at "Shared" aura and files which it has.
public sealed class TheGame {
public TheGame(IFluentLog log){
Log = log;
}
public IFluentLog Log {get;}
public int IntValue { get; private set; }
public void Refresh()
{
IntValue++; //in real-world apps, this could be the code reading values from Memory or calling Refresh on Triggers
Log.Info($"Refreshed the state, value: {IntValue}");
}
}
In that class we have all the scaffolding done and prepared - we initialize triggers OR prepare everything for memory-reading, maybe create some OSD - basically prepare to do the actual work.
Whenever Refresh
method gets called, the actual data refresh happens. In the example which I am showing, this is happening as a part of a ticking BT. In real-world scenarios this could be on timer, from BT, manually OR even all the methods combined - you're not restricted by anything here, do whatever you want.
[Inject] IAuraTreeScriptingApi AuraTree {get; init;}
Log.Info("Bot is being started!");
var tree = AuraTree.GetBehaviorTreeByPath("./New tree");
var game = GetService<TheGame>(); //create TheGame
tree["TheGame"] = game; //save instance to Variables, making it possible to access it from BTs/Macros
This is how we're propagating TheGame to BT - via Variables. This is the key part that was missing before. From now on, objects passed via Variables should be fully accessible and there are no restrictions on values that are being passed around.
Now getting to BT. Here is an example structure which you could use.
var game = Variables.Get<CheatCrescendo.TheGame>("TheGame").Value;
game.Refresh();
In the first node, we call Refresh
, which is expected to refresh game state, actualize it and make it possible to consume in further nodes.
Keep in mind, that variable "TheGame" by that point is already filled and points to an instance of TheGame we've created before. Surely you can just have another node in the tree creating that on the first run, but that is up to you to decide. Somehow, you have to create "TheGame" before accessing it here.
return Run();
public IEnumerator<NodeStatus> Run(){
using var osd = GetService<IOnScreenCanvasScriptingApi>().Create();
var game = Variables.Get<CheatCrescendo.TheGame>("TheGame").Value;
var textOsd = osd.AddHtmlObject();
while (!cancellationToken.IsCancellationRequested){
textOsd.Html = $"{game.IntValue}";
yield return NodeStatus.Success;
}
}
That is an example of EyeAuras-driven OnScreenDisplay, which can draw whatever you want on the screen. You do not really need it, it is just an example of what you could have. It uses recently-added IEnumerator<NodeStatus>
approach, which allows you to "split" node lifecycle in parts.
In that case, we're creating OSD on the first run of the node and then simply update it on all consequent runs. As this always happens right after Refresh
has been called, your OSD will be tightly in sync with that bot "sees".
That is an example of how you can utilize OSD to better "visualize" decision-making of the bot. Note those colored lines and figures - all of them mean something and having that drawn on the screen immensely happens with debugging. Also it looks cool.
And under that selector you can have however many nodes, checking the actual state of the game. Considering all those nodes have access to TheGame
object and its methods, you can do whatever you want here. Expose HP as a number that is read directly from memory ? No problem, write that logic in TheGame, call that method from BT Node and you're good to go. Or you can have that same method reading the value from ColorSearch trigger doing color analysis check. Or you can use TextSearch to get that value from UI.
What is also cool is the fact that you can have methods doing something, i.e. you expose a method which uses a bunch of operations to get you from Town A to town B - opens portal, selects and option, clicks on it, etc. Then you simply call that method from BT and it takes you wherever you wanted.
A whole bunch of performance-related changes. Please report any problems you will notice.
PoeShared.Blazor.Controls
that contains default EyeAuras controls is now exposed to scripts by defaultAll action nodes (Wait, MouseMove, KeyPres, etc. - all of them) now have Outputs as well. Logic is exactly the same as it was with other nodes - linked node gets executed only if current node succeeded.
Done some major changes in how Macros are rendered, the overall UX should be better. Please, report any inconsistentices you may notice. There will be more changes in the following weeks, trying to address initial (first) rendering performance.
Probably it will be easier to show, lets take, for example a very basic Razor component created via :
That is what we get as a result
@namespace GameGrind
@inherits BlazorReactiveComponent
<!-- your Razor/HTML markup here -->
namespace GameGrind;
public partial class UserComponent : BlazorReactiveComponent {
//some code here
}
Note that random namespace (GameGrind
, in this case) which previously was automatically inserted whenever you added a new Razor Component.
This is minor, but very inconvenient technical requirement that the scripting system had.
One of such inconveniences would be the fact that such code could not be easily copy-pasted to another EyeAuras script - you either had to change the namespace OR had to deal with the fact that you have multiple different non-related namespaces in your code. None of those are good thing to have.
From now on, namespace declaration is not a requirement anymore - you can omit namespace declaration in BOTH .razor
and .cs
files and EyeAuras will automatically insert them during compilation. Less code = less headache = better life.
In one of the latest changes in 1.6 I've introduced a bug, which made switching between BTs/Macros excruciatingly slow in some cases. Especially if you had multiple macros with a large number of nodes in them.
This patch fixes this. I'll be closely monitoring the situation.
Please report any kind of UI slowness you notice.
Major addition to our library of tools. More details here.
Following the feedback, this patch fixes a problem which was found in auto-update system - with Security Measures
option enabled, the app was not updating properly and reverted to the previous version upon restart.
Unfortunately, for obvious reasons I cannot just release an update which will fix that. There are two solutions:
Security Measures
in Settings
, update the app and enable it again.Please keep reporting found problems!
A lot of work was done on making Behavior Trees and scripting system overall more flexible - we can finally create bots using ONLY Macros and Behavior Trees, without falling back to Auras. Having to combine multiple complex systems together (Auras and Behavior Trees) made things much harder to understand. But, of course, we're not still done yet - there will be many more changes in new computer-vision based nodes in the nearest future.
For years, Target Window
was a prerequisite in all Capture
triggers (Image/Color/Text/ML) - EyeAuras worked only with windows.
Starting from this version, we'll try a different approach:
Target Window
is not set, EA will start capturing Primary ScreenTarget Window
basically stopped Triggers from working. From now on, this will only switch the mode to Primary Screen capture and I would suggest to use Enabling Conditions to control the capture. This is very important! Check your old triggers to ensure that there are no "test" or "leftover" triggers as they will start eating up CPU.Target Window
in many cases is not really required if you're playing games in Borderless Windowed
or other similar modes where the game occupies the entire screenIMPORTANT! Multi-monitor setups are not supported yet. Only the primary screen will be captured. I'll extend support in the future
Major Macros changes: Greatly enhanced flexibility of Macros
New CV-Based Nodes: new computer-vision nodes which are equivalent of Triggers. No triggers needed any more for simple bots! -- MLSearch paired with MLFindClass - works with ML models and allows to filter ML search results. Combine that with MouseMove enhancments and you can build point'n'click bot in no time! -- PixelSearch - finds a pixel of a specific color -- ImageSearch - finds an image -- ColorCheck - checks whether the color of pixel/region matches with expected
New Logic Nodes: added new nodes which allow you to control execution flow
-- Interrupter - allows to conditionally interrupt already running nodes
-- Timeout - allows you to put a maximum time which you "allow" the child node to Run (stay in Running
state)
-- CheckKeyState - very simple node, which checks the current state of the specific key
-- IfThenElse - allows to write if..then..else
condition in BT form - useful for those who are new to BTs infrastructure
BT Undo/Redo: You can now undo/redo node additions/removals using Ctrl+Z
/ Ctrl+Y
.
Hotkey Activation: BTs and Macros can now activate directly via hotkeys.
Login Widget: Added a simple widget which you can use in your mini-apps to implenent EyeAuras-based login
PopOut View: View a real-time, read-only version of a BT/Macro in a floating window for testing/debugging.
BT Variables Support: Nodes like MouseMove
can use CvLastFoundRegion
from CV-based searches.
.css
, .js
, .md
, .dll
) directly using IScriptFileProvider
.[Keybind]
attributes for hotkey-triggered methods.[Dependency]
attributes or init properties for services like SendInput
.AppStarted
, allowing automation without showing EA UI.R
and G
color channels were swappedIBlazorWindow
now has a new property TitleBarViewType` which allows to fully replace window title bar with whatever you wantClear()
method to MiniProfilerWorldToWindow
transformation matrix to WindowImageProcessedEventArgs - this allows to very easily calculate in-window coordinates after Refresh()
Percentage
which could be used to denote that the value is in %
(e.g. 0.1
= 10%
)Opacity
LoginWidget
not working properlySendInputUnstableScriptingApi
to SendInputScriptingApi
- there were no changes for almost a year, looks stable enough@Rowenor
for finding this out!Move To Parent
option to Aura TreeEvent Log
The new option is available only in those nodes which work with image capture right now - pixel color checks, ML, image search, etc. It is very simple and semantically equivalent to Inverter node, but built in. The reason is BTs tend to grow very-very quickly and reducing overall amount of nodes should help keeping them structured.
p.s. I know these have been quiet few weeks, internally I am working on a new large feature, which will be available to public later this year. I'll keep you posted.