25

I'm trying to make a simple script for a game, by changing the time of day, but I want to do it in a fast motion. So this is what I'm talking about:

function disco ( hour, minute)
setTime ( 1, 0 )
SLEEP
setTime ( 2, 0 )
SLEEP
setTime ( 3, 0 )
end

and so on. How would I go about doing this?

Yu Hao
  • 119,891
  • 44
  • 235
  • 294
Donavon Decker
  • 443
  • 2
  • 5
  • 6
  • check also [easiest-way-to-make-lua-script-wait-pause-sleep-block-for-a-few-seconds](http://stackoverflow.com/questions/1034334/easiest-way-to-make-lua-script-wait-pause-sleep-block-for-a-few-seconds) – Bernardo Ramos Jan 21 '17 at 06:54
  • Possible duplicate of [Easiest way to make lua script wait/pause/sleep/block for a few seconds?](http://stackoverflow.com/questions/1034334/easiest-way-to-make-lua-script-wait-pause-sleep-block-for-a-few-seconds) – Nikana Reklawyks Jan 23 '17 at 06:11

12 Answers12

34

Lua doesn't provide a standard sleep function, but there are several ways to implement one, see Sleep Function for detail.

For Linux, this may be the easiest one:

function sleep(n)
  os.execute("sleep " .. tonumber(n))
end

In Windows, you can use ping:

function sleep(n)
  if n > 0 then os.execute("ping -n " .. tonumber(n+1) .. " localhost > NUL") end
end

The one using select deserves some attention because it is the only portable way to get sub-second resolution:

require "socket"

function sleep(sec)
    socket.select(nil, nil, sec)
end

sleep(0.2)
Yu Hao
  • 119,891
  • 44
  • 235
  • 294
  • @DonavonDecker Follow the other approaches in the link then. There are several available for windows. For example, writing a C extension – Yu Hao Aug 01 '13 at 07:41
  • 1
    I understand, but when I try the other method in the link , I get an error saying "attempt to index global 'os' nil value" – Donavon Decker Aug 01 '13 at 07:44
  • @DonavonDecker That's odd, because `os` is a standard Lua library and I tested the one using `ping` under Windows XP myself, and it works fine. What version of Lua are you using? – Yu Hao Aug 01 '13 at 07:49
  • 2
    I think he is using a game engine which doesn't provide the `os` library. If you are, please specify which one, as it is more likely to provide a better solution. – Colonel Thirty Two Aug 08 '13 at 21:33
  • Is this a good solution for a game that's meant to be played on an Android mobile device? – Jeff Zivkovic Nov 27 '18 at 13:31
7

If you have luasocket installed:

local socket = require 'socket'
socket.sleep(0.2)
konrad
  • 3,340
  • 1
  • 27
  • 26
5

This homebrew function have precision down to a 10th of a second or less.

function sleep (a) 
    local sec = tonumber(os.clock() + a); 
    while (os.clock() < sec) do 
    end 
end
2540625
  • 11,022
  • 8
  • 52
  • 58
Mossarelli
  • 319
  • 2
  • 8
  • 6
    don't forget it is a busy wait, consuming processor time – Bernardo Ramos Jan 21 '17 at 06:51
  • If you want a no busy wait for Lua for use in frames for videogames or applications, perhaps wxLua or other libraries may provide less resource craving sleep functions. The sleep function I provide is useful for bugtesting, automation in smaller scripts and less serious projects. – Mossarelli Jan 25 '17 at 10:39
4

wxLua has three sleep functions:

local wx = require 'wx'
wx.wxSleep(12)   -- sleeps for 12 seconds
wx.wxMilliSleep(1200)   -- sleeps for 1200 milliseconds
wx.wxMicroSleep(1200)   -- sleeps for 1200 microseconds (if the system supports such resolution)
2

I know this is a super old question, but I stumbled upon it while I was working on something. Here's some code that's working for me...

time=os.time()
wait=5
newtime=time+wait
while (time<newtime)
do
  time=os.time()
end

And I needed randomization so I added

math.randomseed(os.time())
math.random(); math.random(); math.random()
randwait = math.random(1,30)
time=os.time()
newtime=time+randwait
while (time<newtime)
do
  time=os.time()
end
1

I needed something simple for a polling script, so I tried the os.execute option from Yu Hao's answer. But at least on my machine, I could no longer terminate the script with Ctrl+C. So I tried a very similar function using io.popen instead, and this one does allow early termination.

function wait (s)
    local timer = io.popen("sleep " .. s)
    timer:close()
end
AEM
  • 1,354
  • 8
  • 20
  • 30
1

You should read this: http://lua-users.org/wiki/SleepFunction

There are several solutions and each one has a description, which is important to know.

This is, what I used:

function util.Sleep(s)
    if type(s) ~= "number" then
        error("Unable to wait if parameter 'seconds' isn't a number: " .. type(s))
    end
    -- http://lua-users.org/wiki/SleepFunction
    local ntime = os.clock() + s/10
    repeat until os.clock() > ntime
end
Ismoh
  • 1,074
  • 2
  • 12
  • 35
0

if you're using a MacBook or UNIX based system, use this:

function wait(time)
if tonumber(time) ~= nil then
os.execute("Sleep "..tonumber(time))
else
os.execute("Sleep "..tonumber("0.1"))
end
wait()
  • 1
    Files, and thus commands, are case-sensitive on most Unix systems, except for filesystems in MacOS by default. I.e. you need `sleep` instead of `Sleep`, for most OSes. – aaa Aug 03 '23 at 20:38
0

You can use "os.time" or "os.clock" with "while" loop, i prefer "repeat until" loop because its shorter, but they are expensive because they cost full usage of a single core.

If you need something less demanding, you can use various wrappers like wxLua that i use, but sometimes, some of them also got usage penalty, specially annoying in games, so its best to test them and get what is best for your project.

Or you can relay on OS like Windows to do sleep function, using applications that exist in system32, via Batch or PowerShell, using ">nul" to hide it with "os.execute" or "io.popen", like "ping" (localhost/127.0.0.1) with timeout, "choice" (works with XP, newer versions may be different, i prefer it), "timeout" (/nobreak may be useless because all Windows commands can be canceled with CTRL+C). Downside are limited to given OS and number limitation as well as seconds or miliseconds, running it on eg. Linux may need Wine emulation for Windows (if application are written for it). You can also use "sleep" or "start-sleep" (from PowerShell), but since Lua are standalone, most people prefer pure Lua or wrappers, and you can use what suits your project.

0

The safe function sleep (n) for Lua:

function sleep (n)
    while n > 0 do
        print("Sleeping for ".. tonumber(n) .." seconds...")
        os.execute("ping -n 2 localhost > nul")
        n = n-1
    end
end
darkfrei
  • 122
  • 5
0

Luaposix' unixstd module provides direct access to the sleep function on POSIX systems, i.e. Linux, MacOS and such.

local unistd = require('posix.unistd')
unistd.sleep(5)

sleep only has a second resolution, but posix.time.nanosleep apparently has nanosecond precision:

local time = require('posix.time')
time.nanosleep({tv_sec=5, tv_nsec=500})
aaa
  • 194
  • 1
  • 4
-3
function wait(time)
    local duration = os.time() + time
    while os.time() < duration do end
end

This is probably one of the easiest ways to add a wait/sleep function to your script

zenrae
  • 1
  • 1