Behavior Context - Lumberyard User Guide

Behavior Context

Open 3D Engine (O3DE), the successor to Lumberyard, is now available in Developer Preview. Download O3DE or visit the AWS Game Tech blog to learn more.

You can use the behavior context to reflect runtime code to make it accessible to scripting languages like Lua or scripting environments like Lumberyard's Script Canvas. The behavior context provides bindings that invoke runtime C++ code.

You can use the behavior context to bind the following C++ constructs for scripting:

In addition to the bindings for C++ constructs, the behavior context provides bindings for Lumberyard's EBus.


Classes that are bound to the behavior context become objects that can be instantiated in a script environment. To reflect a class, you must provide the type that is reflected as a template argument to the class function. The base classes should also be specified, as in the following example:

if (BehaviorContext* behaviorContext = azrtti_cast<BehaviorContext*>(reflection)) { behaviorcontext->Class<MyClass, TheBaseClass>(); }


You can use the built-in attributes described in this section to decorate a class.


Used by the editor to categorize the object in a list.

Type: string

You can use the forward slash (/) separator to nest categories, as in the following example:

Attribute(AZ::Script::Attributes::Category, "Gameplay/Triggers")

A flag that optionally hides this object from specific types of exposure. This flag is primarily used for internal objects that are not intended to be accessible by script.

Type: AZ::Script::Attributes::ExcludeFlags

Possible values: List, Documentation, Preview, All

Value Description
List Hides the object from editor lists.
Documentation Makes the object unavailable for self-documentation.
Preview Excludes this object from appearing in preview builds but can be enabled manually.
All Hides the object from all possible uses.

Specifies the owner of the memory storage for the reflected object.

Type: AZ::Script::Attributes::StorageType

Possible values: ScriptOwn, RuntimeOwn, Value

Value Description
ScriptOwn Specifies that the memory is owned and maintained by the script system (for example, Lua). This is the default value.
RuntimeOwn Specifies that the memory is managed by a native code implementation in C++.
Value Specifies that the object is stored by value in the script system's virtual machine (VM).

Specifies whether the class is constructed by default when nil is provided.

Type: bool

Possible values: true, false


Provides a custom name for script reflection that is different from the behavior context name.

Type: string


Specifies whether the element is used script reflection.

Type: bool

Possible values: true, false


Marks a reflected class, method, EBus, or property as deprecated.

Type: bool

Possible values: true, false


Used by the editor to display additional information in a tool tip.

Type: string

Class Reflection Examples

Classes reflected for scripting become objects that can be instanced in Lua, as in the following example:

local myObj = MyClass()

Classes can also specify custom constructors for scripting purposes. For example, the following constructor enables a custom constructor that specifies an integer:

behaviorContext->Class<MyClass>("MyClass") ->Constructor<int>() ;

This constructor enables the class to be instantiated in Lua in the following way:

-- Constructor in Lua local myClass = MyClass(10)


You can reflect methods either as free functions or as part of classes, as in the following examples:

// This method is reflected as a free function: behaviorContext->Method("AZTestAssert", &AZTestAssert); // This method is reflected as a part of a class: behaviorContext->Class<MyMath>("MyMath") ->Method("Cos", &cosf) ;

As in the previous example, class methods that are reflected for scripting are accessible through the reflected class:

-- Method from a class local math = MyMath() local result = math:Cos(3.14) -- Free method AZTestAssert(ScriptClass ~= nil)

Methods can specify parameters and default values for those parameters, as in the following example:

int globalMethod(int a) { return a + 3; } behaviorContext->Method("globalMethod", &globalMethod, BehaviorMakeDefaultValues(555))

When you bind a method to the behavior context, you can provide an array of strings that contain the method's name and describe its arguments. This is useful when you want to provide friendly names or facilitate documentation.

The following example shows a method whose arguments contain descriptive strings.

// Given this method: bool BoundsCheckMethodWithDefaultValue(float value, float epsilon, float minBounds, float maxBounds) { (void)epsilon; return value >= minBounds && value < maxBounds; } // Bind the given method to the behavior context with friendly argument names. Method("MemberWithDefaultValues", &BehaviorTestClass::BoundsCheckMethodWithDefaultValue, { {{"value", "Value which will be checked to be within the two bounds arguments"}, {"delta", "The epsilon value", BehaviorMakeDefaultValue(0.1f)}, {"minBound", "The minimum bounds value,", BehaviorMakeDefaultValue(0.0f)}, {"maxBound", "The maximum bounds value", BehaviorMakeDefaultValue(1.0f)}} } );

This approach is especially useful in Lumberyard's Script Canvas so that users can understand the meaning of the arguments that they are expected to provide.


You can reflect properties as parts of classes or as global properties. You can reflect properties as write only, read only or read/write. To do this, provide either a getter, a setter, or both for the property.

The following table shows helper macros that you can use to simplify the specification of a property's getter or setter or both.

Operation Helper Macro Code
Setter BehaviorValueSetter
->Property("boolean", nullptr, BehaviorValueSetter(&TestBehaviorContextProperties::m_booleanProp))
Getter BehaviorValueGetter
->Property("boolean", BehaviorValueGetter(&TestBehaviorContextProperties::m_booleanProp), nullptr)
Both BehaviorValueProperty
->Property("isStatic", BehaviorValueProperty(&AZ::TransformConfig::m_isStatic))


You can reflect constants into the behavior context. Constants are by definition read-only. The following examples reflect two constants into the behavior context:

behaviorContext->Constant("SystemEntityId", BehaviorConstant(SystemEntityId)); behaviorContext->Constant("PI", BehaviorConstant(3.14f));


Enums are reflected globally into the behavior context. For this reason, it is important to give them unique names.

The following example reflects the enum GE_VALUE1 and two of its possible values globally into the behavior context.

behaviorContext->Enum<(int)GE_VALUE1>("GE_VALUE1"); behaviorContext->Enum<(int)GlobalClassEnum::Value1>("Value1"); behaviorContext->Enum<(int)GlobalClassEnum::Value2>("Value2");


The ability to bind an EBus to the behavior context enables scripting to become driven and modular. The two main use cases for reflecting EBuses to the behavior context are event handlers and events.

Because EBuses are highly configurable, the features that become available depend on how the EBus was created. For more information, see the Working with the Event Bus (EBus) system.

Event Handlers

By reflecting event handlers, you can enable events to be implemented directly in script.

To implement an event handler

  1. Given the following EBus, reflect an event handler:

    class TestBusMessages : public AZ::EBusTraits { public: virtual void SetSum1(int) = 0; virtual int GetSum1(int) = 0; }; using TestBus = AZ::EBus<TestBusMessages>;
  2. Implement the event handler bindings, as in the following example:

    class TestBusHandler : public TestBus::Handler , public AZ::BehaviorEBusHandler { public: AZ_EBUS_BEHAVIOR_BINDER(TestBusHandler, "{CD26E702-6F40-4FF9-816D-4DCB652D97DF}", AZ::SystemAllocator, SetSum1, GetSum1); void SetSum1(int d1) override { Call(FN_SetSum1, d1); } int GetSum1(int d1) override { int result = 0; CallResult(result, FN_GetSum1, d1); return result; } };

    This handler is what binds a C++ EBus interface to a script language such as Lua.

  3. Tell the behavior context reflection that the event handler is available, as in the following example.

    behaviorContext.EBus<TestBus>("TestBus")-> Handler<TestBusHandler>()-> Event("SetSum1", &TestBus::Events::SetSum1)-> Event("GetSum1", &TestBus::Events::GetSum1)-> ;
  4. Optionally provide the implementation for the EBus handler, as in the following example.

    MyBusHandlerMetaTable1 = { SetSum1 = function(self, _1) -- custom handler code can go here! TestAssert(_1 == 1) end, GetSum1 = function(self, _1) -- custom handler code can go here! return _1 end, } handler = TestBus.Connect(MyBusHandlerMetaTable1)


Events provide a mechanism to broadcast or send an event directly to any object that is connected to the EBus through an ID.

By reflecting events to an EBus, you can broadcast or send the events in scripting, as the following examples show.

behaviorContext.EBus<TestBus>("TestBus")-> Handler<TestBusHandler>()-> Event("SetSum1", &TestBus::Events::SetSum1)-> Event("GetSum1", &TestBus::Events::GetSum1)-> ; -- Lua: local result = TestBus.Broadcast.GetSum1(1)

For information on addressing EBuses, see Working with the Event Bus (EBus) system.

For more information about the behavior context, see Behavior Context in Depth.