GameplayAbilities and you

Thanks for the feedback. There are a lot of really good points in there and it’s still hard to make a final decision on what to do! But I’ve narrowed it down to a couple different ideas on architecture and can hopefully decide and start implementing it once I get a good block of time (working full time + freelance sucks). Sorry if this reads like a personal dev blog, but I’m possibly someone else might go through a similar issue and might want to see me thought process.

This is for developing an “aggro/threat” table type of mechanic, similar to many RPG games. MMO’s often use this kind of system.

Bad Ideas:
Aggro as a ‘stack’ of an effect - That idea was just dumb.
Ticking like a scrub to check a changed attribute - This is completely outclassed by using “RegisterGameplayAttributeEvent(YourAttribute)” instead.
Using display and gameplay cues - Due to wonky replication, it would be bad to put gameplay related code in here (as mentioned in other places too).
Rolling my own global event system - There seems to be enough things built in to the gameplay abilities module that this isn’t a smart thing to do. I’d rather not start spaghettify my systems and locking them all together. But I might have to do a little bit of this for the contender anyway.

Not so good:
RegisterGameplayAttributeEvent - This seems like a pretty simple and straightforward approach, but it also seems like it would be very limited. I’m assuming that in order to set this system up, I would need to have each AI subscribe multiple different attributes attached on different systems. In the case where I have, say, 2 characters attacking a single NPC, the NPC would be listening for his “health changed” event, and use that to increase the threat for the NPC that caused it. Seems find and dandy… Until I throw healing and buffs into the mix. If player 1 heals player 2, the NPC needs to know that player 2’s health has changed. So I’d need to then make the NPC subscribe to player 2’s “health changed” event, and in the same regard player 1’s event as well. This could get pretty ridiculous if I have, say 6 NPC characters against 5 player characters. A lot of unnecessary subscriptions (in that case, (6 npc * 5) 30 just for the healing case, and then 6 more for their own “damage taken” aggro calculations). If my game had some kind of team wide attack speed buff, or a slow debuff, which deals zero damage, I would have to add a bunch more listeners and it just gets kinda crazy at this point. Does this sound about right? If it is, I’m definitely leaning no for this as my system. I’d be better off just listening for other “ability events” or even “effects resolving” kind of thing.

GameplayEvents - It seems like its OK still, a bit of a workaround and I definitely agree that I wouldn’t want to tie a bunch of abilities to my AI just to get them to “listen” to threat. I definitely could see this working, but seems more like a hack, and just not as good as another option. Still leaning no on this.

The Contender:
GameplayEffectExecution, and publishing those messages - This was suggested by KZJ, and also a user in the Unreal Slackers discord “inside.” And the more I look into it it seems to get better and better. Because everything in a GameplyAbility heavy game is done through effects and attributes, this gives me a solid “entry point” to start throwing some messages around the game and reacting to them in various ways. This also lets me create a complex “threat” calculation, similar to a damage one, which would cover all kinds of different abilities including nukes, AoE, heals, and even 0 damage effects like temporary buffs, taunt-style effects, and the like. Each ability can have a bunch of attributes within which when combined can produce a single float for threat. Something like:


threatToAdd = (TotalAbilityDamage * DamageThreatModifier) + (FlatThreat * FlatThreatModifier) * CharacterThreatModifier;

Or whatever kind of crazy calculation I decide to put on there. So a fireball is flexible, and can deal 300 damage and make 300 threat, and an attack speed buff can deal 0 damage, but still make 500 threat. Heals can be added into the equation super easily. That value can then be broadcast (including source and target data too) to all relevant AI’s and they can then react accordingly.

What makes me pretty happy about this solution is how easy it would be to expand upon it in the future. I could very easily implement a kind of “combat log” by grabbing messages controlled by the player, or even a “what killed you?” kind of popup you often see in MOBA’s showing you what happened moments before you died. Overall I think this is the most elegant solution, and provides me with the least amount of duplicating code for whatever edge cases might appear (if any).

If I do decide to go with GameplayEffectExecution (which I probably will at this point), the next challenge will be incorporating the messaging/events. There doesn’t happen to be any built in messaging system in here, hidden somewhere deep in the GameplayAbility module?

If not, fortunately that’s something which is already clearly documented and has other examples available :).