local Timer = {}
Timer.__index = Timer
function Timer.new()
local self = setmetatable({}, Timer)
self._finishedEvent = Instance.new("BindableEvent")
self.finished = self._finishedEvent.Event
self._running = false
self._startTime = nil
self._duration = nil
return self
end
function Timer:start(duration)
if not self._running then
local timerThread = coroutine.wrap(function()
self._running = true
self._duration = duration
self._startTime = tick()
while self._running and tick() - self._startTime < duration do
wait()
end
local completed = self._running
self._running = false
self._startTime = nil
self._duration = nil
self._finishedEvent:Fire(completed)
end)
timerThread()
else
warn("Warning: timer could not start again as it is already running.")
end
end
function Timer:getTimeLeft()
if self._running then
local now = tick()
local timeLeft = self._startTime + self._duration - now
if timeLeft < 0 then
timeLeft = 0
end
return timeLeft
else
warn("Warning: could not get remaining time, timer is not running.")
end
end
function Timer:isRunning()
return self._running
end
function Timer:stop()
self._running = false
end
return Timer
Not enough code or context. This is supposed to be in a module and another script is supposed to require this Timer for use - need to see the code that requires this module and uses it. Also need to know what line 18 is referring to in this script.
The Timer class doesn’t look wrong, so it’s more likely the way you’re using it.
That’s not what I’m asking for though. The Timer class itself is fine as I’ve just tested in Studio: what I want is the code you’re using that runs this module. I need to see the code you’re using to require the module understand how you’re using the Timer module, which is what’s causing this problem.
Through my tests and reassessing the error, my bets are on that you called the module the wrong way by not using a colon and instead using a period, because it’s trying to index _running from a number. This means that the timer object is not the first argument.
This is how you’re supposed to call the timer:
local Timer = require(script.Parent.Timer)
local Foobar = Timer.new()
Foobar:start(600)
And I suspect you’re calling it like this:
local Timer = require(script.Parent.Timer)
local Foobar = Timer.new()
Foobar.start(600)
Hence why I need to see the code that requires the Timer module. The class is fine, your code isn’t.
I can attest to your statement. I have just tested it.
Calling it as Foobar.start(600) will throw the exact error.
Using Foobar.start(Foobar, 600) or Foobar:start(600) fixes this.
For the original poster: Colons are for methods that pass self as the 1st parameter. If you want to use a dot instead, just be sure to use whatever is being passed as self to the 1st parameter. (in this case, Timer.new())
local MatchManager = {}
-- Services
local serverStrg = game:GetService("ServerStorage")
-- Module scripts
local folder = serverStrg:WaitForChild("ModuleScripts")
local plrManager = require(folder:WaitForChild("PlayerManager"))
local gameSettings = require(folder:WaitForChild("GameSettings"))
local timer = require(folder:WaitForChild("Timer"))
-- Events
local events = serverStrg:WaitForChild("Events")
local MatchStart = events:WaitForChild("MatchStart")
local MatchEnd = events:WaitForChild("MatchEnd")
-- Timer
local gameTimer = timer.new()
local function timeUp()
print("Time is up!")
end
local function timeStart()
print("Time is started!")
gameTimer.start(gameSettings.Match)
gameTimer.finished:Connect(timeUp)
end
function MatchManager.Prep()
print("Game is starting...")
plrManager.tpToMatch()
MatchStart:Fire()
end
MatchStart.Event:Connect(timeStart)
return MatchManager
This is the script that requires this module. It is a module script.
Took a few hours even though I had already pointed this out, but glad you found your issue. Remember to be wary about how methods are defined and about how you’re calling them. Colon passes the object itself as the first argument to a function.