AI Planner

The AI Planner was released as a preview package during GDC 2019 and was mentioned in the GDC Talk: Unity AI and Machine Learning Tools for Behavior Creation

The sample project for the planner is located here: GitHub - Unity-Technologies/otto: Otto sample project for the AI Planner

Additionally, you can install the package separately in your project by selecting “Show preview packages” under Advanced drop-down in the Package Manager and searching for “AI Planner”.

Please use this new thread for any questions you have about Otto or the AI Planner. You’re also welcome to start new threads. We will try to monitor this forum as best we can.

10 Likes

I went to create some sort of hello world for this. I just want to create one action with one effect which just displays a Debug.Log(). I don’t get creating the action part.

I created a domain with one trait named Condition, which has a field named Value which is just a bool.
4351252--393448--upload_2019-3-24_0-4-21.png

But in action creation, I couldn’t get Condition.Value to display in either precondition or effect:
4351252--393451--upload_2019-3-24_0-7-18.png

My intent was for the action to have a precondition Agent.Condition.Value = false, then have an effect Agent.Condition.Value = true.

Nevermind. So you have to click Generate Classes for them to be displayed on the editor.

So I generated my TestAction. One thing I didn’t know how to do is how to set the goal. For the TestAction to be invoked, I have to set a goal where Condition.value = true, right? But I can’t find where to do this.

Anyways, so I made a GameObject and attached my agent class (the one deriving from BaseAgent) then set the Plan Definition. However, when I played the scene with just this GameObject, I get the following error:

ArgumentException: SimpleDomain.Condition is an IComponentData, and thus must be blittable (No managed object is allowed on the struct).
Unity.Entities.TypeManager.BuildComponentType (System.Type type, System.Int32* writeGroups, System.Int32 writeGroupCount) (at Library/PackageCache/com.unity.entities@0.0.12-preview.24/Unity.Entities/Types/TypeManager.cs:705)
Unity.Entities.TypeManager.BuildComponentType (System.Type type) (at Library/PackageCache/com.unity.entities@0.0.12-preview.24/Unity.Entities/Types/TypeManager.cs:680)
Unity.Entities.TypeManager.CreateTypeIndexThreadSafe (System.Type type) (at Library/PackageCache/com.unity.entities@0.0.12-preview.24/Unity.Entities/Types/TypeManager.cs:643)
Unity.Entities.TypeManager.GetTypeIndex (System.Type type) (at Library/PackageCache/com.unity.entities@0.0.12-preview.24/Unity.Entities/Types/TypeManager.cs:502)
Unity.Entities.TypeManager.GetTypeIndex[T] () (at Library/PackageCache/com.unity.entities@0.0.12-preview.24/Unity.Entities/Types/TypeManager.cs:493)
Unity.Entities.ComponentType.Create[T] () (at Library/PackageCache/com.unity.entities@0.0.12-preview.24/Unity.Entities/Types/ComponentType.cs:31)
SimpleDomain.SimpleDomainUpdateSystem.OnCreateManager () (at Assets/AI.Planner/Generated/SimpleDomain/SimpleDomain.cs:49)
Unity.Entities.ScriptBehaviourManager.CreateInstance (Unity.Entities.World world) (at Library/PackageCache/com.unity.entities@0.0.12-preview.24/Unity.Entities/ScriptBehaviourManager.cs:40)
Unity.Entities.World.AddManager[T] (T manager) (at Library/PackageCache/com.unity.entities@0.0.12-preview.24/Unity.Entities/Injection/World.cs:244)
Unity.Entities.World.CreateManagerInternal (System.Type type, System.Object[ ] constructorArguments) (at Library/PackageCache/com.unity.entities@0.0.12-preview.24/Unity.Entities/Injection/World.cs:131)
Unity.Entities.World.GetOrCreateManagerInternal (System.Type type) (at Library/PackageCache/com.unity.entities@0.0.12-preview.24/Unity.Entities/Injection/World.cs:147)
Unity.Entities.World.GetOrCreateManager (System.Type type) (at Library/PackageCache/com.unity.entities@0.0.12-preview.24/Unity.Entities/Injection/World.cs:227)
Unity.AI.Planner.PlannerSystem.GetBehaviourManagerAndLogException (Unity.Entities.World world, System.Type type) (at Library/PackageCache/com.unity.ai.planner@0.0.1-preview.2/Runtime/Planner/Planner.cs:549)
UnityEngine.Debug:LogException(Exception)
Unity.AI.Planner.PlannerSystem:GetBehaviourManagerAndLogException(World, Type) (at Library/PackageCache/com.unity.ai.planner@0.0.1-preview.2/Runtime/Planner/Planner.cs:553)
Unity.AI.Planner.PlannerSystem:CreateBehaviourManagersForMatchingTypes(Boolean, IEnumerable1, World) (at Library/PackageCache/com.unity.ai.planner@0.0.1-preview.2/Runtime/Planner/Planner.cs:541) Unity.AI.Planner.PlannerSystem:Initialize(World) (at Library/PackageCache/com.unity.ai.planner@0.0.1-preview.2/Runtime/Planner/Planner.cs:411) UnityEngine.AI.Planner.Agent.BaseAgent1:Start()

The following is my test action:

public class TestAction : SimplePlannerAction {
    public override void BeginExecution(Entity stateEntity, ActionContext action, SimplePlanner agent) {
        Debug.Log("TestAction.Begin");
    }

    public override void ContinueExecution(Entity stateEntity, ActionContext action, SimplePlanner agent) {
        Debug.Log("TestAction.Continue");
    }

    public override void EndExecution(Entity stateEntity, ActionContext action, SimplePlanner agent) {
        Debug.Log("TestAction.End");
    }

    public override OperationalActionStatus Status(Entity stateEntity, ActionContext action, SimplePlanner agent) {
        return OperationalActionStatus.Completed;
    }
}

So I haven’t given up yet and made Condition.Value into an int so that the resulting IComponentData would be blittable. When I played the scene again, I got this error:

ArgumentException: The entity does not exist
Unity.Entities.EntityDataManager.AssertEntityHasComponent (Unity.Entities.Entity entity, Unity.Entities.ComponentType componentType) (at Library/PackageCache/com.unity.entities@0.0.12-preview.24/Unity.Entities/EntityDataManager.cs:369)
Unity.Entities.EntityDataManager.AssertEntityHasComponent (Unity.Entities.Entity entity, System.Int32 componentType) (at Library/PackageCache/com.unity.entities@0.0.12-preview.24/Unity.Entities/EntityDataManager.cs:377)
Unity.Entities.EntityManager.GetBuffer[T] (Unity.Entities.Entity entity) (at Library/PackageCache/com.unity.entities@0.0.12-preview.24/Unity.Entities/EntityManager.cs:831)
SimpleDomain.SimpleDomainUpdateSystem.StateEquals (Unity.Entities.Entity lhsStateEntity, Unity.Entities.Entity rhsStateEntity) (at Assets/AI.Planner/Generated/SimpleDomain/SimpleDomain.cs:87)
Unity.AI.Planner.PolicyGraphUpdateSystem.LookupState (Unity.AI.Planner.HashCode stateHash, Unity.Entities.Entity stateEntity, Unity.Entities.Entity& matchedStateEntity) (at Library/PackageCache/com.unity.ai.planner@0.0.1-preview.2/Runtime/Planner/Planner.cs:711)
Unity.AI.Planner.PolicyGraphContainer.UpdateRoot (Unity.Entities.Entity stateEntity, System.Int32 searchHorizon) (at Library/PackageCache/com.unity.ai.planner@0.0.1-preview.2/Runtime/Planner/Planner.cs:235)
Unity.AI.Planner.PolicyGraphContainer.UpdatePlan (Unity.Entities.Entity stateEntity) (at Library/PackageCache/com.unity.ai.planner@0.0.1-preview.2/Runtime/Planner/Planner.cs:246)
Unity.AI.Planner.Agent.Controller1[TAgent].CompleteAction () (at Library/PackageCache/com.unity.ai.planner@0.0.1-preview.2/Runtime/Agent/Controller.cs:123) Unity.AI.Planner.Agent.Controller1[TAgent].Update () (at Library/PackageCache/com.unity.ai.planner@0.0.1-preview.2/Runtime/Agent/Controller.cs:76)
UnityEngine.AI.Planner.Agent.BaseAgent`1[TAgent].Update () (at Library/PackageCache/com.unity.ai.planner@0.0.1-preview.2/Runtime/Agent/BaseAgent.cs:161)

I tried adding GameObjectEntity to my agent, but it’s still shows the same error. What am I missing?

Did you set up your initial state on your Agent script?
4358359--394279--upload_2019-3-25_18-8-18.png

What do I set it with? I only have one trait so far:
4361137--394732--upload_2019-3-27_1-50-20.png

1 Like

Hmm. Looks okay, but have you tried removing the trait from the state and only having it on the agent?

I know that modding for unity is in general a highly discussed topic, but do you see any opportunity in this AI planner that would allow some kind of AI modding.

I’m just thinking if there would be the possibility of having a “definition language” for “Plan Definition files” that modders could manipulate to add traits, effects, pre-conditions in different combinations which could lead to completely new behavior based on the actions written by the developer?

1 Like

Can you share a bit more about what you’re looking to do? Plan Definition files are currently just a yaml asset, but there’s no reason why we couldn’t serialize that out to a json or other format, too. Or, are you looking for a way to programmatically generate plan definitions at runtime?

Tried removing the Initial State Trait Data. It’s still the same error:

Could you post a small .unitypackage or make it available somewhere with your domain/plan definitions and possibly the sample scene?

  1. an off-topic question: how will AI-Planner work with ml-agents ? seems a bit functionality overlapping?

IMHO, AI-Planner is more suitable for high-level behavior, maybe use it to change ml-agent’s brain?

  1. how do i enable virtual studio interp(syntax highlight) with csc.rsp’s define (like WORKAHOLICDOMAIN_GENERATED in otto demo)?
2 Likes

An example would be that Traits and Enumerations could be defined in XML, that will then be used to generate the actual classes in runtime, for example. Like in the example of the package documentation, a modder could extend the ConsumableType and add new values to it. Instead having Apple and Bottle, it could contain Apple, Bottle and Bread.

Regarding action in an FPS game, I could create the Action “Open Door”. A precondition would be “has Key”, to open the door. Also here, when able to define everything in an external file, a modder could add the precondition “has Weapon”, this way the Agent could only open the door when having a key and a weapon.

These are very basic examples with not such a great use-case, but depending on how much actions you think of for your agent, some other developers could come up with completely new combinations of actions and traits that could lead to brand new behavior.

Also if you think about chaning rewards or costs. You could simply mod a FSP to melee only, because the costs for ranged attacks are too high.

I had the X Series in mind when thinking about that. From what I know they have a lot of AI logic in XML files and there are quite some extensive mods out there that drastically change the behavior and therefor the game.

Of course XML is just an example, but the idea is to have an easily modifiable file format for modders.

1 Like

Do you have a Bitbucket account? I just added my test scenes in Otto project. It’s still big when it’s stripped off. I’ll add you to my Bitbucket repository where I stored my project.

Had a couple of questions to see if this was worth exploring.

First question is how well does it integrate with external data, and can it handle loading/unloading larger (several hundred mb in memory) datasets at runtime?

Second question is how does it perform with a few hundred agents and is the main work done in jobs? I saw at a glance some ECS in there but didn’t dig very deep.

For 1. - You should watch the talk when it is available :slight_smile: I’ll update the main message in this thread to point to it when it becomes available in the vault. I’m not sure if it will be a free talk though. However, to answer your question roughly, yes, it will be suitable for more higher level behavior that is more discrete in nature in terms of decision-making. ML-Agents work particularly well for character control and other problems as you move towards continuous problem domains.

For 2. - I’m not entirely sure as I see the same behavior in Rider. This isn’t likely our final solution for this – it was mainly a convenience, so if I delete the generated directories or the csc.rsp file that the project will still compile correctly and compile out the parts that are dependent on the generated classes. It’s mainly there for when I need to clean and re-generate all files.

2 Likes

Hmm… If you’re using the Otto project, how about just forking it in github and then send me the link to your fork/branch and I can take a look?

To your first question - this is untested currently, but we did experiment at one point with serializing plans / policy graphs that had been pre-computed. I can possibly answer better if you share more about what these larger data sets look like.

Re: your second question - we are currently in the process of jobifying the planner (as of now it runs on the main thread); We’re creating performance tests to verify progress as we jobify. Our plan is to support multiple planners / agents running in a single game with possible caps for memory usage/computation for each planner.

1 Like

We’ll likely support XML and json as formats for import. Our system currently requires code generation for performance reasons and to work well with DOTS/ECS. The idea is that as more people use the system that there can be domain definitions defined that can get shared around and that many people could define plan definitions that operate within those domains to get specific behavior. It is possible currently to modify the reward function. See https://github.com/Unity-Technologies/otto/blob/master/Assets/AI.Planner/WorkaholicDomain-Custom/Work.Extra.cs#L7