Dynamic Attribute System

The documentation of Generic Game Framework.

通用库存系统.封面
罗传月武(YueWu)

Author

罗传月武(YueWu)

专注游戏开发和Web技术。

Created: Jun 24, 2025Updated: Sep 15, 2026

Table of contents

Introduction

Inspired by Lyra's GameplayTagStack, this mechanism tracks and manages dynamic attribute through a GameplayTag-to-Integer mapping. In GIS, this concept has been further expanded and is referred to as the Tag Attribute Container.

For C++ User only

This article is intended only for C++ users who wish to develop other game systems using this system; Blueprint users need not read this article.

Tag Attribute Container

GIS encapsulates 2 approaches to implement a dynamic attribute system, which are as follows:

  • GameplayTagIntegerContainer: Contains a list of GameplayTagInteger entries, each representing a Tag-to-Int32 key-value pair.
  • GameplayTagFloatContainer: Contains a list of GameplayTagFloat entries, each representing a Tag-to-float key-value pair.

These containers are implemented using FastArraySerializer, ensuring efficient network replication and simplified callbacks for data change notifications. Each entry in the container is also marked with SaveGame, facilitating data serialization for single-player games or server-side operations.

Steps to Use Attribute Containers

Taking ItemInstance as an example:

Add a Container to your class.

cpp
1 /**
2 * Container for integer attributes of the item instance.
3 * 道具实例的整数属性容器。
4 */
5 UPROPERTY(VisibleAnywhere, Replicated, Category="ItemInstance", SaveGame, meta=(DisplayName="Attributes (Integer)", ShowOnlyInnerProperties))
6 FGIS_GameplayTagIntegerContainer IntegerAttributes;
7
8 /**
9 * Container for float attributes of the item instance.
10 * 道具实例的浮点属性容器。
11 */
12 UPROPERTY(VisibleAnywhere, Replicated, Category="ItemInstance", SaveGame, meta=(DisplayName="Attributes (Float)", ShowOnlyInnerProperties))
13 FGIS_GameplayTagFloatContainer FloatAttributes;

In the constructor, set the current object as the ContainerOwner of the container. (Do it inside initialize component if you are using actor component as owner.)

cpp
1UGIS_ItemInstance::UGIS_ItemInstance(const FObjectInitializer& ObjectInitializer): Super(ObjectInitializer), IntegerAttributes(this), FloatAttributes(this)

Ensure that the field is properly replicated over the network, with replication conditions customized based on your project requirements.

cpp
1void UGIS_ItemInstance::GetLifetimeReplicatedProps(TArray<FLifetimeProperty>& OutLifetimeProps) const
2{
3 Super::GetLifetimeReplicatedProps(OutLifetimeProps);
4
5
6 // FastArray don't need push model.
7 DOREPLIFETIME(ThisClass, IntegerAttributes);
8 DOREPLIFETIME(ThisClass, FloatAttributes);
9}
10

Ensure that your class implements the IGIS_GameplayTagIntegerContainerOwner and IGIS_GameplayTagFloatContainerOwnerinterface.

cpp
1class GENERICINVENTORYSYSTEM_API UGIS_ItemInstance : public UObject, public IGameplayTagAssetInterface, public IGIS_MixinOwnerInterface, public IGIS_GameplayTagFloatContainerOwner,
2 public IGIS_GameplayTagIntegerContainerOwner

Implement the OnTagFloatUpdate and OnTagIntegerUpdatemethod from the interface, which allows you to respond to attribute changes.

cpp
1 /**
2 * Called when a float attribute is updated.
3 * 浮点型属性更新时调用。
4 * @param Tag The gameplay tag identifying the attribute. 标识属性的游戏标签。
5 * @param OldValue The previous value of the attribute. 属性之前的值。
6 * @param NewValue The new value of the attribute. 属性的新值。
7 */
8 virtual void OnTagFloatUpdate(const FGameplayTag& Tag, float OldValue, float NewValue) override final;
9
10 /**
11 * Called when an integer attribute is updated.
12 * 整型属性更新时调用。
13 * @param Tag The gameplay tag identifying the attribute. 标识属性的游戏标签。
14 * @param OldValue The previous value of the attribute. 属性之前的值。
15 * @param NewValue The new value of the attribute. 属性的新值。
16 */
17 virtual void OnTagIntegerUpdate(const FGameplayTag& Tag, int32 OldValue, int32 NewValue) override final;

OnTagFloatUpdate and OnTagIntegerUpdateis called whenever an attribute is changed, on both the server and client sides.

Application Cases

This feature is designed to simplify the implementation of dynamic attributes, with reusable code.

Item instance utilize this dynamic attributes feature. Naturally, you may also apply this to other systems beyond just inventory management.