i have a for loop that handles reducing (or just removing) player effects in general, i store all players and their effects inside a table, and loop through that table every second, firing remote events for clients that have updated effects (which is a lot)
-- Tables;
local playersWithActiveEffects = {
-- example player:
--[[
Player1 = {
effect1 = {
initialDuration = 15,
currentDuration = 8
},
effect2 = {
initialBreakCondition = 25,
currentBreakCondition = 18
}
}
]]
}
-- Functions;
local function DecreaseEffectDurations()
while task.wait(1) do
for player: Player, effects: {string: number} in playersWithActiveEffects do
for effectName: string, effectData: {string: number} in effects do
local properties = effectData.properties
-- effects with durations
if effectData.currentDuration then
effectData.currentDuration -= 1
effectNotif:FireClient(player, effectName, effectData.currentDuration, true)
local character = player.Character
if not character then
print("No character found for " .. player.Name)
playersWithActiveEffects[player] = nil
continue
end
local gameplayValues: Folder = character:FindFirstChild("GameplayValues")
local effectValues: Folder = gameplayValues and gameplayValues:FindFirstChild("effectValues")
local effectValue: BoolValue = effectValues and GetEffectValueOfName(effectValues, effectName)
if effectData.currentDuration <= 0 or not effectValue.Value then
local humanoid = character and character:FindFirstChildOfClass("Humanoid")
if humanoid.Health < 1 then
playersWithActiveEffects[player] = nil
continue
end
effectValue.Value = false
effects[effectName] = nil
effectNotif:FireClient(player, effectName, effectData.currentDuration, false)
if properties then
ApplyEffectProperties(character, gameplayValues, properties, "divide")
end
end
else -- effects without durations
effectNotif:FireClient(player, effectName, nil, true)
local valueToTrack: string = effectData.valueToTrack
if not valueToTrack then continue end
local character = player.Character
if not character then
print("No character found for " .. player.Name)
playersWithActiveEffects[player] = nil
continue
end
local humanoid = character and character:FindFirstChildOfClass("Humanoid")
if humanoid.Health < 1 then
playersWithActiveEffects[player] = nil
continue
end
local gameplayValues: Folder = character:FindFirstChild("GameplayValues")
local effectValues: Folder = gameplayValues and gameplayValues:FindFirstChild("effectValues")
local effectValue: BoolValue = effectValues and GetEffectValueOfName(effectValues, effectName)
if not effectValue.Value then
effectNotif:FireClient(player, effectName, nil, false)
effects[effectName] = nil
end
local trackedValue: NumberValue = nil
for _, value: NumberValue in gameplayValues:GetDescendants() do
if value.Name ~= valueToTrack then continue end
trackedValue = value
end
if not valueToTrack then continue end
local breakCondition: number = effectData.valueConditionForBreak
if not breakCondition then continue end
if trackedValue.Value >= breakCondition then
if effectValue then
effectValue.Value = false
end
effectNotif:FireClient(player, effectName, nil, false)
effects[effectName] = nil
if properties then
ApplyEffectProperties(character, gameplayValues, properties, "divide")
end
end
end
end
-- remove player from tracker if they don't have any more active effects
if next(effects) == nil then
playersWithActiveEffects[player] = nil
end
end
end
end
i’m wondering if this won’t cause any network issues (like large explode from the amount of remotes being fired each second), and if the client won’t absolutely implode when receiving such amount of events
there’s a limit of 5 players in my game, and the effects are limitless (but if i had to guess, the most effects you could have at a time is 9)
the table only includes players that:
- are in the match
- have atleast one active effect
- are not dead and have a character instance
anything else gets ignored