-
Notifications
You must be signed in to change notification settings - Fork 7
How do I create my own?...
Refer to JournalGD.
he "GOAPAction" class and the "GOAPBehavior" class are distinct in that the Action is simply a node that wraps around a reusable Behavior resource. Behavior actually has the logic in it, and is the one that should be overwritten. The names confuse me, too, and may be changed in the future.
Override GOAPBehavior, and override the functions at your discretion.
Prerequisites: What goals must be complete to perform this action. Effects: What goals are changed after this action. Cost: What the cost for this action is. The higher the cost, the less likely it will be chosen for a task. This can be used to have "preferences" for certain actions. Duration: how much time the NPC will wait between target_reached and post_perform. You can use this to simulate the NPC performing the task.
These functions can be overridden to define the logic of the behavior, and is divided into steps. For all of the functions except for is_achievable and is_target_reached, returning false will force a plan recalculation.
This function determines whether an action is currently achievable. For example, a perform_ranged_attack behavior would only be achievable if there is a ranged weapon in the inventory.
What must be done before the NPC performs this action. For our ranged attack example, the NPC would equip a bow.
What must be done once the target is reached, defined by is_target_reached. In our example, shooting the bow.
What must be done once the action is complete. For example, putting away the bow.
Determines whether a target has been reached. The agent is provided under the assumption that the target is a point in physical space, but it can be anything, like waiting until a certain value passes a threshold.
Use this function to clean up anything if the NPC is interrupted by a forced plan recalculation, like putting away the bow.
Instances are a bit like an "Archetype" in a true ECS like Bevy. It stores "default values" for its components, and sets them up at runtime. The InstanceData class has a virtual method func get_archetype_components() -> Array[EntityComponent]
.
To create a new kind of instance data, override this function, and have it return an array of constructed entity components.
To write your own, all you need to do is inherit from EntitComponent, and set the node's name in an init function. That's it! There are some hooks and variables provided to you, which you can see in the in-godot documentation. From there, you're free to go.
AI Modules are, by default, pretty barebones, and open-ended. The built in AI Modules, in addons/skelerealms/scripts/ai/AIModules, should give you a solid idea of how these can be written. It is a good idea to keep different kinds of responses in different modules; for example, dialogue response vs. damage response should be separate.