FGameplayAttributeData & UAttributeSet design problem

Hello :slight_smile:

Recently, I work with the GameplayAbilities Module (I know that it on a “use at your own risk” state), and the 4.13 introduce FGameplayAttributeData a new structure to store attribute data inside an UAttributeSet.
Sound cool and it’s really cool, but I have a design problem, I mean a made an inherited struct from FGameplayAttributeData to store EquipmentValue for players, and in other side my mobs don’t need this variable.

Well, if I use it for both of them all mobs will have useless float by Attribute, and this is really ridiculous and I need to use the same because when you create an UGameplayEffect you need to specify the Attribute (and the base structure is part of the name you mention):

The only one workaround I found, it’s to store EquipmentValue inside a TMap, but I would like to know why Epic Staff make it customizable ? Well I would like to know if there is a way to avoid this problem :slight_smile:

Thank you in advance !

Jackblue

Bump ! Any advice will be useful :slight_smile:

Bump !

I have also a question about replication, the AbilitySystemTestAttributeSet.cpp has it’s GetLifetimeReplicatedProps(TArray< FLifetimeProperty > & OutLifetimeProps) content commented, well I would like to know if UAttributeSet uses an another replication system than the normal one for optimization purpose.

Thanks in advance :slight_smile:

Hello!

For some context, FGameplayAttributeData got introduced as a replacement for using floats as attributes directly, as it allows us to explicitly store any extra information that might be necessary for an attribute. Previously if you wanted to know the base value of an attribute on a client, it had to do a ReverseEvaluate to determine what that base value might be, but it wasn’t 100% guaranteed to always be correct, as the reverse evaluate formula couldn’t handle cases such as when a modifier that directly overrides a value is active. By using the struct, we now just store (and can replicate) the base value directly, alleviating the need for the reverse evaluate. You can make an inherited struct and put in game specific logic, but yes, anything you add there will also show up for anyone using that attribute in its attribute set. Depending on how your game is configured, you can also make separate attribute sets and only use the ones you need appropriately on various entities. As an example, in Fortnite, we have an attribute set that has some attributes only our building pieces care about and our players and AI never use those ones.

Re: the replication question, attribute set does use normal replication, but a piece missing from that sample is that for any attribute we want the client to have full knowledge of to possibly run predictive calculations on, we also mark them as ReplicatedUsing and then in the ReplicatedUsing function, we call the GAMEPLAYATTRIBUTE_REPNOTIFY macro that’s inside AttributeSet.h, which makes sure the client’s version of attribute aggregators gets updated. This is a bit clunky and we’d like to clean it up sometime in the future, but it’s not on any of the game team’s radar at the moment. As a usage example, for UI purposes in Fortnite we sometimes have cases where the client wants to perform calculations on an attribute to predict what its value would be if some other modifier were applied, so we need the aggregators to be correct.