How would I handle dynamic modifiers such as cooldowns, damage, defence etc?

Some games have scripts, where certain attacks can increase your damage dealt temporarily, decrease/increase your defence. I was wondering how I would go about implementing this for my own game as I plan on having something very similar.

Idea 1 - Module Script

Have a module script containing the player’s damage, cooldowns for their abilities, and any other dynamic variables(could be a table listing each ability and its cooldown as well as other variables, abilities can be removed if the conditions for the ability are no longer met)

This way I could have a server-script accessing each of these variables in order to temporarily increase them, the server script will clone the module script to ServerStorage on player join and be able to temporarily decrease the variables, the module script will be named after the player i.e “Sxdistical”. Saving can be handled by saving the modules data and then loading by just cloning a template module and then reassigning the data to the cloned module on player join.

I.E

Local PlayerName = "Name of the player here"
req = require(game:getservice("ServerScriptService"))

Idea 2 - Editable variables stored inside ServerStorage(folder & subfolder)

Whereas my 2nd method is having integer variables, bools etc stored inside a folder named after the player I.E “Sxdistical” and then creating a separate subfolder for each power and inside each subfolder I will store their cooldowns, whilst the main folder named after the player will contain damage, defense and so on and these can very easily be altered by a script when needed. For example:

local Playername = NameOfPlayer -- will be assigned through a player join event 
local PlayerStats = game:getservice("SevrerStorage"):WaitForChild(PlayerName) -- A folder stored in ServerStorage
local Damage = PlayerStats.Damage -- A damage integer
local Ability1  = PlayerStats.Ability1 -- The name of the ability is "Ability1", 
-- would be referenced by the ability's script 
local Ability1.Cooldown = Ability1.Cooldown/2 -- Will halve the cooldown 

I’m wondering if anyone can confirm if these ideas would work, are flawed fundamentally, missing some thought or if they have entirely new ways I could implement them.

I do not want a script unless used as an example. I want this to be my own creation. I am looking for ideas.

If anything is not understood here just ask me to elaborate and I’ll elaborate, I tried to be as specific as possible whilst keeping it understandable and concise.

Honestly I’m not 100% sure this is meant to go here and will respectfully move it to the appropriate category if asked (the only one I can think of it being appropriate for is Game Design Support)

3 Likes

I think if you’re doing every player, a ModuleScript is the best idea. You could have a ServerStorage folder for all players and put the ModuleScript in it. : /

2 Likes

Why would modules be better than idea 2? I’m asking even though I personally prefer modules - sounds more fun to create and a lot easier to store as well as the fact that I could also store active buffs/debuffs inside of modules and so on.

1 Like

I’d say because you don’t have to create a ton of instances and values for one folder, and just clone a script with stats. I feel as though both ideas are quite fine, but I’d prefer using module scripts. You can also just add your own values if you’d like to the module script. Either works, I’d just prefer using module scripts as it would probably be more organized feeling and looking. Honestly up to you though. Both would work perfectly fine. The only thing I’d worry about is having a lot of values and cloning them, as it might cause some server lag.

2 Likes

Well both ways are great but for me i handle it a bit differently where i have a class named ActionStates, from the name it basically stores the current action state for each player, it can be more than one state depending on the game, these stats are updated with remote events from the client, the trick here is that you need to check if the remote request being sent from the client is valid or not, for example:

If i have three action stats: attacking, dodging and blocking, then each time the player tries to update any of these stats ill make sure all the other ones are disabled so he can’t enable two or more action stats at once( attacking and blocking at once for example)

There is another simpler way using attributes class where you have a module that adds attributes to player instances each time you want them to have an effect like defense or whatever, this one have a bit less processing time since the server is only updating the attributes for each player and calculating the time left for each effect

2 Likes

100% what I do. The good thing about doing it with attributes is that you don’t have to go back through to reset everything to it’s default. It will all be handled when the character respawns, as the attributes will be reapplied.

I used to store this data in a table, but changed it to attributes when they came out. Looks much cleaner too :slightly_smiling_face:

1 Like

Oh? I know I marked one as a solution but this seems to be solving a current dilemma I’m in. I don’t know why I considered creating one module script per player since I can store it all in one either…nevertheless.

So like this for example:
Module Script

GameRules.ActionStates = {
	["TestPlayer"] = {
		["Attacking"] = {Active = false, Damage = 0, Speed = 0}, 
-- The damage and if necessary effectiveness will be updated
-- Based on the move the player is using, so if the player uses one ability
--it might set the damage to 50 whilst another ability might set it to 20 etc. 
		["Dodging"] = {Active = false, Effectiveness = 10},
		["Blocking"] = {Active = false, Defence = 100}		
	}

Then when I wanted to update it I would update the players entry, each state being triggered by a keypress. The local script would go something(unrefined, I’m sure doing the keybinds this way is going to cause issues down the line with remapping or making it difficult to add new powers but this is a quick hashed together one)
Local Script

local Keys =
	{ 
["Blocking"] = {Primary = "Q", Combo = false}


}

local SelectKeys = {}

print(Keys)



local function InputBegan(input, gameProcessedEvent)
	local Target = script.Parent.Text
	
	if input.KeyCode == Enum.KeyCode[Keys.Special.Primary] and game.Players:FindFirstChild(Target) then 
		print("Printing special", input.KeyCode)
		RemoteEvent:FireServer(Target, input.KeyCode)

end
end

UserInputService.InputBegan:connect(function(input, gameProcessedEvent)
	InputBegan(input, gameProcessedEvent)
end)

Storing different values for each attack, and creating an entry for the player. (TestPlayer would be Mr_Root0 and so on). I’ll handle debuffs/buffs with attributes, I was looking into that recently and I see no issue since buffs/debuffs are not meant to save(and attributes are destroyed once the parent instance is destroyed which works perfectly)

Well, Firstly you seem to have a decent understanding of lua programming but you just lack ideas of how to implement specific systems, i highly encourage you to watch other programmers script and try your best to understand how to implement specific systems, trust me when i tell you that this way you will get way better in shorter time, as the legend say “No problem should be solved twice”.

Secondly from what I understood from your last replies what you are trying to do is to implement buff/debuff system but you are trying so hard to save things that you don’t need to,
Here is an example: instead of saving each buff for each player which is absolutely bot necessary since these buffs are temporary, you Can just make a module that has specific functions that assign different buffs to given players by assigning attributes to their character model like this

CurrentBuff = 50% attack
Expiry = time when the buff was assigned + buff effect time,

I don’t show you code cuz i use a bit complicated methods like OOP and composition but that example would give you a decent idea of what to do,

Each time the player interacts with the game and you want to give the player feedback based on his buff, just let the server check his currentbuff and expiry in case it’s already expired and has no effect

2 Likes

Sorry for the word wall, if you don’t want to read a wall of text skip to the quote at the end as I ask a question that I guess could count as a summary of everything just not a good summary.

I was planning on implementing an attribute-based buff system, I want to keep track of the active buffs the player has on them which means I have to name each buff/debuffs, such as naming an attribute “Corrosion” and then applying X amount of damage over X amount of seconds when corrosion is active. Which I think would be applied through a loop that keeps track of buffs on the player and if a buff exists it’ll apply the damage, and if it no longer detects it it’ll stop.

Regardless, I’ll take your advice regardless and try to find a YouTube video or existing script of how someone’s implemented buffs/debuffs and make it work for my own project as I really should be doing some more research on these scripts before trying to implement them, sure I look for questions that have been asked in regard to it but I don’t watch videos on it which tends to be more detailed and in-depth.

The issue with this is YouTube has really good videos for very specific syntax but not for implementations of different systems so I’m going to try watching Unity YouTubers implement systems and move that over to Roblox.

i highly encourage you to watch other programmers script and try your best to understand how to implement specific systems

Speaking of your advice for learning better implementations, I can’t disagree as my execution isn’t the best because I’m just not that experienced yet.

Would you say it would still be a good application if I were to watch non-lua scripting even if I plan on implementing it in lua as it would teach me the execution but not the process? Such as a video from Unity about how to implement a buff system in C# but converting what they did into lua. It might require some thought on what the closest counterpart would be in Roblox but I could see it as feasible as long as it wasn’t some extremely far-fetched scripting language that shares little similarity to lua.

1 Like

Watching system implementations with different languages will be as beneficial as watching lua, you don’t need the code you just need an idea of how it works,

For the buff thing you want, your saying that you want keep track of a specific buff which I previously mentioned that it’s absolutely not needed but I can’t say for sure since I have no idea about the game your trying to make, but my game had pretty similar systems in case you want some detailed help just contact me via discord Root#2541

1 Like

I’ll definitely start watching content about how to implement in the future then since I don’t have to stick the limited Roblox tutorials on implementing systems(again, not saying Roblox tutorials are bad just a lacking of ones that show how to implement certain systems).

I don’t think I really need specific help as I need to improve at implementing this stuff without handholding though thank you for the offer, I appreciate it.

Though by the buff system I now realize you mean keep track of generic buffs such as a DPS debuff which will control the damage per second and I have a function that alters the attribute to match any changes to it(such as an increase in damage per second being applied if a player hit you with a more powerful DPS debuff) and then a DamageIncrease buff which will control the percentage that outgoing damage is increased by, a healing buff which will control the health regen of the player and so on until I cover all of the generic buff/debuff types that I need.

Either way, I’ll definitely watch a video on this to make sure I better grasp it, I know there’s an overwhelming amount of Unity videos on how to implement buffs.

Note: Is it ethical to change a solution once I’ve already marked an answer as a solution?

1 Like

Allr you are half right there, let me make it so clear so you can get what i mean, You need to check for buff/Debuff only when its going to be applied, here is an example

You have a player with a heavy sword, that player touched a part and got a dmg buff of 50%, this buff will be stored in the system and the server won’t continuously check for it, when will the server check for it you ask?

Lets say that player landed a hit on another player, here is the part where buff information are needed so the server can calculate the total dmg dealt and apply it to enemy, thats simply it,

now you might be wondering what about buff time since you want it to have specific amount of time before you remove the buff from the player?

Well its pretty simple, just store the time that this buff has been assigned to that player (start time) then add the buff time to it (End time) so for example if i have a defense buff and want it to last for 6 seconds, then ill just store the time that this buff has been applied to the player and add to it 6 seconds,

Now you just need to check if the buff is expired or not by just comparing the current time with the stored time,
If the current time is larger than the stored time that means that the buff has expired.

you don’t need to continuously check for it as the player is not continuously landing or receiving hits,
and keep in mind that the connections being created between server and client shouldn’t be long at all since client is very unstable and can encounter errors almost all the time due to connection issues, ping or even low device memory.

Good-luck with your journey