Scripting Helpers is winding down operations and is now read-only. More info→
Ad
Log in to vote
0

Time Script Keeps On Timing Out And Freezing The Game?

Asked by 5 years ago

The script that records how long a user is in the game is here:

_G.timePlayed = {}
local minutes = 0
local seconds = 0

game.Players.PlayerAdded:Connect(function(player)
while true do
        if minutes >= 1 and seconds <= 0  then
        seconds = seconds + 1
        _G.timePlayed[player] = minutes .. " Minutes and " .. seconds .. " Seconds"
        elseif minutes == 0 and seconds <= 59 then
            seconds = seconds + 1
            _G.timePlayed[player] = seconds .. " Seconds"
        print(_G.timePlayed[player])
    wait(1)
    end
    end
end)


Basically, it just sets the amount of time a player has been in the game to _G.timePlayed and then another script sends that data from _G.timePlayed to a webhook on PlayerRemoving. Issue is, the script above works until it gets to more than 59 seconds which then the game freezes for a few seconds and then this appears in the Developer Console: http://prntscr.com/lefooq

I have tried fixing this by editing my script a lot but it still persists and I don't know why.

1 answer

Log in to vote
0
Answered by 5 years ago
Edited 5 years ago

Loops and Why They're Dangerous

Loops run a piece of code over and over again, hence their name. Running code uses some processing power. If you make an infinite loop or a really large loop (like a while do loop) and there are no delays, the script will run the same code over and over again an infinite amount of times with no breaks. Your processor will have too many tasks to do and won't be able to handle all the stress it is under.


Solution

Add a wait, yield or delay of any kind. The reason why your code was working up until the 1 minute mark is because of the second half of your script:

elseif minutes == 0 and seconds <= 59 then
    seconds = seconds + 1
    _G.timePlayed[player] = seconds .. " Seconds"
    print(_G.timePlayed[player])
    wait(1) --This is important!!
end

This wait is giving your processor time to rest. Your game runs fine. Unlike:

if minutes >= 1 and seconds <= 0  then
    seconds = seconds + 1
    _G.timePlayed[player] = minutes .. " Minutes and " .. seconds .. " Seconds"
elseif...

No wait in sight. Your code will loop and run the same code with 0 breaks. It's processing the math of adding 1 to the variable seconds, processing _G and changing the value the timeplayed table's key of player to the string and... You get the idea. A lot of work with no time for your computer to rest. Add a wait!

if minutes >= 1 and seconds <= 0  then
    seconds = seconds + 1
    _G.timePlayed[player] = minutes .. " Minutes and " .. seconds .. " Seconds"
    wait(1) --Script saved!
elseif...

_G

_G is the global table, but it's not used much anymore because it's over shadowed by ModuleScripts. Instead of using _G, use a module script instead.

--Regular script
local module = require(script.ModuleScript)
--Replace "script.ModuleScript" with your real module script, wherever it may be
local minutes = 0
local seconds = 0

game.Players.PlayerAdded:Connect(function(player)
    while wait(1) do
        module:UpdateTime(player) --Modules make code a lot less crowded
    end
end)

Module Script:

local module = {}
module.timePlayed = {}

function module:UpdateTime(player)
    module.timePlayed[player] = module.timePlayed[player]+1
end

return module

Other script:

--Another script that wants the time, this script will also decode the seconds into minutes and numbers
local module = require(game:GetService("ServerScriptService").Script.ModuleScript)

function decodeTime(player) --Lets say this script somehow gets a hold of player
    local seconds = module.timePlayed[player]
    if seconds < 60 then
        print(tostring(seconds).." Seconds")
    else
        print(tostring(math.floor(seconds/60)).." Minutes and "..tostring(seconds%60).." Seconds")
    end
end

tostring turns everything into a string. Booleans, numbers, nil and etc. math.floor rounds the number down to the nearest whole number and % is modulus. Basically, it gets the remainder of a number/number2.



Hope it helps!

Ad

Answer this question