I’m working on a roguelite game that essentially allows the player to select abilities or receive temporary debuffs/abilities. Some of these are indefinite while others are active or timed, but ultimately I want to be able to stack an infinite amount of these and even duplicates.
The wall I’m running into is figuring out how to add the timers for the timed ones. How can I build a modular system that allows for creating multiple timed effects? (Basically instanced timers?) I understand the basics of timers by both function and event, but can’t wrap my head around how to achieve this in this instanced format
Basic example:
+20 damage for 20 seconds
+20 damage for 20 seconds
-5 speed for 60 seconds
+10 speed for 30 seconds
I want to be able to have all of these abilities/debuffs and even duplicates of them running at the same time with their own independent timers.
The only way I have kind of come up with is to basically spawn in an instanced blueprint when needed, then have it destroy itself when the effect is up. This just doesn’t feel like the correct way to do it… or am I overthinking it?
this is valid and sometimes needed but a simpler approach is just to have a manager, lets say an actor component that ticks and loops over all effects and updates their state
I would use a string map of floats, where the string is itself a map/dictionary with data relevant to the power-up. The float would be the game time the power up is set to expire. Then, check every x amount of frames or seconds with a single heartbeat/timer to see which of the power ups should be removed/fall off based on the comparison between current game time and the map entry’s float value. For infinite buffs/debuffs, use a value of -1 or 0, since elapsed game time will never be less than or equal to that.
If you use a string as the map key, you can store an arbitrary amount of data in the key like so:
?RowName=default_powerup?CurrentStacks=1
Then you can use ParseOption for the key RowName, to get whatever information you need from your powerups datatable.
If you need actual duplicates, as in multiple map entries (i.e.., for an item inventory) rather than just increasing stacks with no stack limit, you’ll have to add something like ?GUID=0124WXYZ to your map key. You can use the engine’s built-in UUID/GUID functions, or roll your own GUID generator.
I prefer to use a custom solution since it seems like UUIDs are persistent across editor sessions, and with a custom solution, you get greater control over when the GUIDs are released (more important for projects using SaveGame, imo.) Let me know if you need a rundown on how to do this and I’ll post the blueprint function.
This works too; generally speaking, it doesn’t really matter where you do it. Although, If it’s a single-player game and you want the powerups to persist across OpenLevelByName, put it on the game instance.