5
\$\begingroup\$

I have written my first LUA-Script/Function to shut down the Dedicated Server for Don't Starve Together.
I wanted to shut down the server in 2 minutes and inform everyone on the server that the server is shutting down.
The function os.execute is nil in the dedicated server console, so I can't use os.execute("sleep " .. seconds).

Can I improve something on this script? Is it best practice?

function sleep(seconds)
    local t = os.time()
    local diff = 0
    while diff < seconds do
        diff = os.difftime(os.time(), t)
    end
end

local steps = {120,60,30,10,5,4,3,2,1}
local n = table.getn(steps)
for i=1,n-1,1 do
  TheNet:SystemMessage("The server shuts down in " .. steps[i] .. " seconds")
  sleep(steps[i] - steps[i+1])
end
TheNet:SystemMessage("The server shuts down in " .. steps[n] .. " seconds")
sleep(steps[n])
TheNet:SystemMessage("The server is shutting down now")
c_shutdown(true)

Link to the server command list for Don't Starve.

  • TheNet:SystemMessage prints the message into the chat
  • c_shutdown(true) shutdown the server and persist the world
\$\endgroup\$
  • 1
    \$\begingroup\$ I think is correct. Some nit suggestions are: 1) in the for loop, by default increase is '+1' so it's not necessary to type it ('for i=1,n-1 do' works too) 2) instead of 'table.getn(steps)' could simply write '#steps' \$\endgroup\$ – Diego Pino Dec 17 '17 at 14:20
1
\$\begingroup\$
  1. table.getn has been deprecated for more than 2 years now.
  2. Why iterate only until n-1?
  3. I'd prefer using the string.format over plain concatenation. This is just a personal preference, as the strings are easier to read that way.
  4. Although you do not need to pass true to the c_shutdown, do mention in a comment what it does. Maintaining comments is a nice way to recognise engine specific hard-bound parameters; without having to refer the docs again.
  5. Iterate over the table using ipairs

Rewritten, the code would be:

local function sleep(seconds)
    local diff, t = 0, os.time()
    while diff < seconds do
        diff = os.difftime(os.time(), t)
    end
end

local steps = {
  120, 60, 30,
  10, 5, 4, 3,
  2, 1
}
local notice = "The server shuts down in %d seconds"

for _, secs in ipairs(steps) do
  TheNet:SystemMessage(notice:format(secs))
  sleep(secs)
end
TheNet:SystemMessage("The server is shutting down now")
c_shutdown(true)  -- true parameter implies that the game will be saved
\$\endgroup\$
  • \$\begingroup\$ 1. ok 2. only until n-1, because: steps[i+1] 3. cool thing 4. ok 5. this ipairs strategy is not so clear for me. the _ stands for the key and this isn't used. Isn't there anything like foreach? \$\endgroup\$ – Shinigami Dec 21 '17 at 7:50
  • 1
    \$\begingroup\$ @Shinigami ipairs is the same as foreach. I am not using _ because we are not interested in the index of each value. If you want, you can replace secs with steps[_]. foreach loops, AFAIK, also iterate over key => value pairs, and both values are returned in the generators. \$\endgroup\$ – hjpotter92 Dec 21 '17 at 9:47

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.