In my game, I have crystals that can be harvested from the mines. After all of a crystal’s energy has been harvested, the crystal disables and waits x number of seconds before regenerating, allowing it to be harvested again. The current system works something like this:
local ServerScriptService = game:GetService("ServerScriptService")
local RunService = game:GetService("RunService")
local settings = require(ServerScriptService:WaitForChild("SETTINGS"))
local Crystals = {
index = {},
}
Crystals.__index = Crystals
--[[
Creates a new crystal object based on the crystal model.
]]--
function Crystals.new(crystal: Model)
if Crystals.index[crystal] then
return Crystals.index[crystal]
end
local object = {}
setmetatable(object, Crystals)
object.info = settings.Crystals.Types[crystal.Parent.Name]
object.state = true
end
--[[
Allows the crystal to be collected after the regen period.
]]--
function Crystals:Resume()
self.state = true
end
--[[
Disables the crystal during the regen period.
]]--
function Crystals:Pause()
self.state = false
task.delay(self.info.RegenTime, function()
self:Resume()
end)
end
return Crystals
Notice how the Crystals:Pause() function utilizes task.delay to go about the regeneration process. Now look at the following:
local ServerScriptService = game:GetService("ServerScriptService")
local RunService = game:GetService("RunService")
local settings = require(ServerScriptService:WaitForChild("SETTINGS"))
local Crystals = {
index = {},
}
Crystals.__index = Crystals
--[[
Creates a new crystal object based on the crystal model.
]]--
function Crystals.new(crystal: Model)
if Crystals.index[crystal] then
return Crystals.index[crystal]
end
local object = {}
setmetatable(object, Crystals)
object.info = settings.Crystals.Types[crystal.Parent.Name]
object.timestamp = os.time()
object.state = true
end
--[[
Allows the crystal to be collected after the regen period.
]]--
function Crystals:Resume()
self.timestamp = os.time()
self.state = true
end
--[[
Disables the crystal during the regen period.
]]--
function Crystals:Pause()
self.timestamp = os.time()
self.state = false
end
--[[
Checks if any crystal's need resumed.
]]--
RunService.Heartbeat:Connect(function()
local t = os.time()
for i, v in Crystals.index do
if ((not v.state) and ((t - v.timestamp) <= v.info.RegenTime)) then
v:Resume()
end
end
end)
return Crystals
Notice how now we are utilizing timestamps and one RunService:Heartbeat connection to regenerate the crystals, rather than task.delay. What I would like input on is should I keep the task.delay system, or should I utilize the RunService in the context provided, or is there a better way to go about this?
The reason I am asking is because I have been having random issues with certain crystals not regenerating properly, and while I don’t think it has to do with the task.delay I have been unable to find another reason.
Thank you for any help in advance!