Let’s say I’m building a custom GAS-like system for an RPG. It is meant to be a plugin.
The simplest and most obvious way to handle, for example, attributes (STR, DEX, INT, etc) would be to simply declare them all in the relevant class and hardcode them in an Enum. This way, if I wanna have a weapon that gives +3 STR, for example, I can easily do that in blueprint via dropdown (add new modifier, amount = 3, stat = EStats.STR).
However, this requires you to hardcode what the stats are in the plugin itself. Ideally, I would like to keep the plugin completely agnostic, so that users can declare the stats they’re gonna use by themselves, without touching the plugins code.
GAS itself handles this masterfully, but it requires some very complicated reflection tricks, as well as custom slate code… and I’d really rather not. This “stats in a plugin” is just an example, this is a problem I come across very very often and would like a neat solution to work around it. Basically, something like a dynamic-ish enum, database, thingy?
I’m thinking of a few possibilities using FNames… but that sounds fishy. I could also use TSubclassOf and have each stat be it’s own BP… but that also sounds fishy. Or Instanced + EditInlineNew shenanigans… idk, fishy.
Honestly, just using an FString for the name of the stat is perfectly functional.
You can have a TSet<> of the stats that are allowed, and check argument FString instances against this set if you want to avoid typos.
You can use a TMap<FString, int> for the base stats.
These are very simple to work with in the C++ code, and in Blueprints, and make sense when you print them. No muss, no fuss.
I believe GAS uses Gameplay Tags, maybe you can make use of it too?
They use it for many things, but for attributes/stats you just declare variables inside your AttributeSet class and they show up like this.
Using tags for it could maybe work, but it would be a bit weird inside C++ to do stuff like Target->GetStat(EStats::STR), I think.
Honestly, just using an FString for the name of the stat is perfectly functional.
You can have a TSet<> of the stats that are allowed, and check argument FString instances against this set if you want to avoid typos.
You can use a TMap<FString, int> for the base stats.
These are very simple to work with in the C++ code, and in Blueprints, and make sense when you print them. No muss, no fuss.
I’ll give it a few tests with FStrings! I have a lot of reluctance to rely on strings, but it might just work well haha.