Doloro GDK 22 .1.0 Beta
by Tauri Interactive
Execution logic & Practices

Following section clarify you how the Brain executes the DAIProject using a logical graph. Also here you'll find the best development practices for Doloro AI Core-based projects.

Logic Cores Root

Doloro.AI.LogicCoresRoot it's a single Order implemented within the Doloro AI Core itself. The instance of the nodes creates by Brain component during instantiation of the DAIProject source.

The node implements core behavior logic in meter of call all your root layer action\scripts.

  • Calls all the child nodes in parallel way.
  • Restarts the branch execution as soon as it has been computed.
  • Holds the branch while it has InProgress result.

Actions using

Action is a final state logical block the represents leaf of the branch. It has no children and stops in-depth hierarchy navigation on itself.

State Meaning
Success Execution of an action has been competed with an expected result.\nIn case of conditional actions Success result should mean true.
Fail Execution of an action has been failed.\nIn case of conditional actions Success result should mean false.
In progress Execution of action has not been finished yet.\nThe node will be called on the next tic as soon as be reached in execution queue.

Orders using

Order is an Action derived class. The difference is the Order can receive other Action instances as child. By using orders, you are creating in-depth hierarchy of logic that allows to make you conditional branching of AI instance behavior.

By global logical concept orders splits on following ideas:

Concept Idea
Sequencer Executes child logical nodes in some sequence following a straight algorithm.
Multi-task Executes child logical nodes independently providing you with fake or real multi-threading operations.
Randomizer Executes children logical node in some randomly way to simulate flexible behavior in the cases with the same entry conditions.
Listener Not makes a choice by any internal rules and leaves the choice to some external handler.\nHandler could be located both:
- in some different part of the AI graph and conduct its choice implicitly or explicitly via the Virtual memory
- outside of the AI and operate the choice via messages \ delegates \ events.

An order should operate output result according with results of its children execution results. Return of unmanaged predefined result could damage concept of conditional flow control using in regular AI development process.

Virtual memory using

Every AI instance represented with the Brain component has its own virtual memory that can store runtime AI data for continue used during the session.

via Action

You can operate the memory via the following nodes supplied with the Doloro Core Nodes module or them custom analogs:

Operation type Node Default editor menu path
set SetBool Actions \ Set \ Set Bool
SetFloat Actions \ Set \ Set Float
SetInt Actions \ Set \ Set Int
SetRect Actions \ Set \ Set Rect
SetString Actions \ Set \ Set String
SetVector2 Actions \ Set \ Set Vector2
SetVector3 Actions \ Set \ Set Vector3
SetVector4 Actions \ Set \ Set Vector4
SetVariable Actions \ Set \ Set Variable
compare CompareBool Actions \ Compare \ Compare Bool
CompareFloat Actions \ Compare \ Compare Float
CompareInt Actions \ Compare \ Compare Int
CompareObjectRef Actions \ Compare \ Compare Object Ref
CompareString Actions \ Compare \ Compare String
operator FloatOperation Actions \ Operators \ Float Operation
IntOperation Actions \ Operators \ Int Operation
RectOperation Actions \ Operators \ Rect Operation
StringOperation Actions \ Operators \ String Operation
system Copy Actions \ Memory \ Copy
Exists Actions \ Memory \ Exists
Remove Actions \ Memory \ Remove
RemoveByType Actions \ Memory \ Remove By Type

More details you may find by following link: Actions

via code

During Doloro.AI.Action or Doloro.AI.Order development or managing process of an Doloro.AI.Brain instace from the external tools and components you may interact with the Virtual Memory of the AI instance.

Writing

Following example demonstrates how to set variable to the Doloro.AI.Core.Memory instance allocated over a Doloro.AI.Brain component.

// Creating new `Variable` instance.
var VAR_INSTANCE = new Variable(VAR_NAME, VAR_VALUE);
// Sending the variable to the memory.
AI_INSTANCE.memory.Write(WRITE_AGENT_REF, ref VAR_INSTANCE);
Member Type Description
VAR_NAME string Name of the variable in Virtual Memory pool.
VAR_VALUE object Object to variable set.
VAR_INSTANCE Doloro.AI.Variable Reference to Virtual Memory entry.
AI_INSTANCE Doloro.AI.Brain Instance of an AI that holds the memory pool.
WRITE_AGENT_REF object Reference to object initiated the operation.

The Doloro.AI.Variable always sending by using ref because variable itself is a container. To proof references integrity the memory may change the container on other related to the variable that already using by internal services or other agents.

Reading

Following example demonstrates how to get variable from the Doloro.AI.Core.Memory instance. This example goes for a case when you are calling the memory from within a Doloro.AI.Action.

// Checking that the var exists in the memory pool.
if (!AI_INSTANCE.memory.Exists(VAR_NAME))
{
// Variable not found.
// Considering `Action` execution as failed.
return Result.Fail;
}
// Reading variable from the memory.
var VAR_INSTANCE = AI_INSTANCE.memory.Read(VAR_NAME);
// Validating received var by its type.
if(!(VAR_INSTANCE.value is EXPECTED_TYPE castedVar))
{
// Variable has unexpected type.
// Considering `Action` execution as failed.
return Result.Fail;
}
// Variable is received and valid to use.
// Handle the value here by referring the `castedVar` member.
Member Type Description
VAR_NAME string Name of the variable in Virtual Memory pool.
VAR_INSTANCE Doloro.AI.Variable Reference to Virtual Memory entry.
AI_INSTANCE Doloro.AI.Brain Instance of an AI that holds the memory pool.
EXPECTED_TYPE System.Type Type expecting from the Variable stored value.

In case of a trusted variable that always exists and has the same type you should use unsafe way to access data to prevent extra CPU time usage. Save way for such tasks could be critical for AI performance and should be reduced if possible.

EXPECTED_TYPE value = (EXPECTED_TYPE) AI_INSTANCE.memory.Read(VAR_NAME).value

Session data

Normally any Action which behavior based on its internal data should release this entire temporal data as soon as its active session is ended.

To handle this you need to override Doloro.AI.Action.End handler and dispatch the entire session data within.

Such a data must be set back to parameters considering default to the node along with its definition made by AI developer or default values defied within the source itself. Otherwise, it could cause unexpected behavior during the next session

Example

Following example shows a good practice of work with session data that dully modifies an Action instance from inside.

public class CUSTOM_ACTION : Action
{
// Variables defined by user \ developer via public interface.
public int USER_DEFINED_VAR0;
public float USER_DEFINED_VAR1;
// Internal system variables defined from within the script.
protected int SOURCE_DEFINED_VAR0;
protected float SOURCE_DEFINED_VAR1;
// Variables that will store our backed up data.
// You may use any other more advanced way to backup settings,
// current examples shows the simplest one.
private int USER_DEFINED_VAR0_BACKUP;
private float USER_DEFINED_VAR1_BACKUP;
// Occurs when the action instance loaded to the virtual machine.
public override void Init(Brain ai)
{
// Making backup of settings defied by AI developer.
MakeUserSettingsBackup();
}
// Executive logic for the node.
public override Result Pass(Brain ai)
{
// Executing logical node with effect over internal values.
....
// ------------------------------------------------------
// Concluding a result.
return Result.Success;
}
// Handler calling when an Action/Order get
// and explicit result like a Success or Fail.
public override void End(Brain ai)
{
// Restoring default state of the node.
SetDefaults();
}
// Records user defined settings for continue backup.
protected virtual void MakeUserSettingsBackup()
{
USER_DEFINED_VAR0_BACKUP = USER_DEFINED_VAR0;
USER_DEFINED_VAR1_BACKUP = USER_DEFINED_VAR1;
}
// Writes back saved user defined data.
protected virtual void RestoreUserSettingsBackup()
{
USER_DEFINED_VAR0 = USER_DEFINED_VAR0_BACKUP;
USER_DEFINED_VAR1 = USER_DEFINED_VAR1_BACKUP;
}
// Drops the action to default state.
protected virtual void SetDefaults()
{
// Restoring user defined values.
RestoreUserSettingsBackup();
// Restoring script defined values.
SOURCE_DEFINED_VAR0 = 1;
SOURCE_DEFINED_VAR1 = 1f;
}
}

Best practice

Instead of creating such complex schemas mentioned in previous paragraph, we recommend you avoid overriding of initial setting members and separate your permanent and temporal data.

Just make you choose in conditional logic using initial members and reinitialize temporal members according to it.

This will allow you to avoid unnecessary operations of backing up and restoring of the values. Remember that an AI should be as fast as possible and anything that could be reduced must be reduced.

Warning
The practice applicable only to management of memory allocated within the Action instance. Any external data should be handled using the previous concept.

Flow control

Manual

Any AI makes decisions of which branch within the behavior graph to select basing on results gained on other stages. Doloro AI Core implements it in a way when each logical node returns some Doloro.AI.Core.Result that literally divided on 2 logical states:

Incomplete
(Implicit)
Complete
(Explicit)
None Success
InProgress Fail

Complete stages using by sequence orders as input value that allows to make decision where its has to go next in branch.

The other way for Doloro.AI.Order derived classes to make a choice is make it according with a data shared via Virtual memory using or own internal specific logic.

Each Doloro.AI.Order implements different algorithm, but the concept itself staying still.

Core auto-controlled

To addition of custom logic implemented with orders Doloro.AI.Brain also has a built-in flow control system. That system allows you to create logical loop for certain order \ action until it reach a certain expected explicit result.

This loop can be managed by definition the condition via the Doloro.AI.Core.PipelineItem.LoopUntil property or via any AI IDE like a Doloro AI Studio.