Skip to content

Composer

◄hollsteinm► edited this page Jan 31, 2024 · 4 revisions

RPAI Composer is a framework built upon RPAI. The purpose of Composer is to expose a method of configuring RPAI Behavior objects in a data driven manner. It enables the configuration of actions and goals. Composer builds upon RPAI Core by adding several new fundamental resources. These resources are called State Query, Distance, Weight, Mutator, and Action Task. All of these are used by a new data object called a Behavior.

---
title: RPAI Composer Extensions
---
erDiagram
    Action ||--|{ Distance : uses
    Action ||--|{ Mutator : uses
    Action ||--|{ "State Query" : uses
    Action ||--|{ "Action Task" : uses
    Goal ||--|{ "Distance" : uses
    Goal ||--|{ "Weight" : uses
    Goal ||--|{ "State Query" : uses
    Behavior ||--|{ Action : uses
    Behavior ||--|{ Goal : uses
    Behavior ||--|| Reasoner : uses
    Behavior ||--|| Planner : uses
    Behavior ||--|| State : "defines type"
Loading

State Query

Source

A state query is a UObject that enables the configuration of query-able operations upon a state. These functions return an enumeration representing a binary result of the query. It exposes a third state if the evaluation is not possible - assisting in the avoidance of exceptional circumstances or misconfiguration. The query can be overridden to answer any question about an inputed state. By default, the Composer tool exposes comparison based state queries. These comparisons are semantically similar to using the comparison operations: >, <, <=, >=, ==, !=, as well as aggregate queries such as any and all.

Distance

Source

The distance object is defined to return a scalar value. It is expected to be normalized to the inclusive range of 0...1. While C++ and Blueprint programmers can override the base class, various implementations are written to calculate distances between static values and a given state property or two state properties. A Distance object should return values closer to 0 to indicate "less work" to accomplish. To remove any ambiguity in the "direction" of a distance, all values are given as an absolute value.

$d=\|distance(action,state)\|$

Weight

Source

The weight object is functionally similar to the Distance object. It indicates an inverse relationship however. For example, a weight should be high to indicate a more valuable, desirable, outcome. It is used by the Goal to determine which Goal is the most valuable to pursue. A Goal with a Weight ought to return a value in the inclusive normalized range of -1 (not valuable at all) to 1 (the most valuable).

Mutator

Source

A mutator is used to temporarily project the resulting state if a given Action is executed. This is specifically used for planning purposes and in no way interacts with the game world. The mutations that are provided should be treated as heuristic outcomes of performing the action. They should not be used to calculate exact results as that cannot be an accurate description of the game world during runtime. Games are too dynamic despite the possibility of determinism! The simpler the mutation the better.

Take an Action such as Walk to Location for example. In a mutator that "goes too far" the mutator would account for the direction of the character, the bounds of the character and the target destination, and also determine what point would be close enough to the "Target Location" taking all those factors as inputs. Each of those actions is too similar to the actual execution of walking to a location within the game. The better alternative is to simply set the state value of the "Current Actor Location" to the same value as the "Target Location" and be done with it. This evaluates plans faster with less overhead and enables fuzziness in the algorithm. Fuzziness is good and fun and encouraged within the RPAI framework.

Again! It cannot be stressed enough - exactness is the enemy of a mutator. Keep it fuzzy and simple!

Action Task

Source

The Action Task is the game world equivalent of a mutator. An action task does not take any part in planning nor reasoning. This is the actual code that gets executed within the game world. Within the default Action Tasks provided by RPAI Composer you will find 100% feature parity with Tasks provided by Behavior Trees. This means the capability to walk to locations, play animations, play sounds, and more is already built in for the developer. It is 100% data driven by the state object.

This is the primary class most developers will override to integrate their specific game code with RPAI. This is what executes specific actions in the game. In sophisticated projects utilizing Gameplay Tasks, the other integration point is extending the RPAI Action Task Gameplay Task Base. This is by far the best approach to maintain the most decoupling.

Behavior

Source

This is the primary data asset designers will use to build AI using RPAI. It is 100% data driven and automatically includes any new functionality developed using RPAI Core or RPAI Composer base classes. In the following tutorials you will dive deep into the creation and configuration of a Behavior. During execution a Behavior is treated as an immutable service and therefore only acts upon what is configured within the Behavior during development.

Conclusion

This concludes the Composer framework for RPAI. If you have read all the other documentation sections, you are ready to move onto the tutorials.

Clone this wiki locally