Зависит от того, какие средства работы со временем предоставляются средой исполнения (то есть родительским приложением, куда встроен Lua).
Например, если родительское приложение постоянно вызывает глобальную функцию Update(), а также доступна функция os.time(), то можно в самом начале засечь время, а потом периодически его считывать заново внутри Update(). Каждый раз сравниваем новое время с начальным. Как только разница будет больше 3 секунд, значит пора двигаться дальше. Как-то так.