Countdown timer for Lua script - lua

I am completely new to the Lua programming language, I've only been working with it a few days in total. Although, I do have some experience in Python, C# and Ada.
I am currently trying to make a racing game, one of the aspects of the game I'm trying to include is a countdown timer that ends the game after 90 seconds, then returning to a high score screen, regardless of whether or not the player has eliminated all of their lives already. I haven't a clue what functions to include nor where the place the text in the main script. Some advice would be much appreciated.

When the game starts do:
local startTime = os.time()
local endTime = startTime+90
Then regularely do:
if os.time() >= endTime then
-- exit game
-- return to high score screen
end
until the game ends. Probably this would be in a callback function that gets called regularely. Depending on how your framework works, a loop might also work.

Use timer.performWithDelay to call a specified function after a delay.
Example
local function countdown( event )
print( "listener called" )
end
timer.performWithDelay( 1000, countdown, 90 )

Related

How to make a function wait for some time before executing its second part?

I'm new to LUA and I'm making a simple game where a bunny should bounce after pressing space on the keyboard. So the plan is to make the bunny go up by 30, wait for half a second and then for the bunny to go back to its original position.
That's the code that I've tried so far, and for the looks of it, the love.keypressed function completely ignored the wait function and tried to execute everything at the same time, which means the bunny simply does not move if the spacebar is pressed. (In other words, is there a way to make the bunny stay in the air for 0.5 seconds after pressing the spacebar and then making it go back to its original position?)
function wait(millisecond)
end
function love.keypressed(key)
if key == "space" then
bunny.y = bunny.y - 30
wait(500);
bunny.y = bunny.y + 30
end
end
For love2d this should work -> https://love2d.org/wiki/love.timer.sleep
An a pure lua sleep function would look like this:
(the time is in seconds)
local function sleep(time)
local start = os.clock()
while os.clock() - start <= time do end
end
The best way to do this without blocking the Lua thread (which would cause ALL functions to stop, including graphics and parsing data) is to create a timer. This library does exactly what you're looking for.
In the end, your function would look like this (assuming you've imported the library correctly):
function love.keypressed(key)
if key == "space" then
bunny.y = bunny.y - 30
timer.Simple(0.5, function() -- wait 0.5 seconds, and then run the code
bunny.y = bunny.y + 30
end)
end
end

Can I make my Lua program to sleep for AROUND a day?

I want to make my mydicebot (by seuntje) Lua program sleep AROUND A DAY, after betting for a day... like
function sleep(n)
t = os.clock()
while os.clock() - t <= n do
-- nothing
end
end
function playsleep()
sec = math.random(80000,90000)
sleep(sec) -- around 86400 seconds
end
timestart = os.time()
dur = math.random(70000,80000)
function dobet()
if os.time() - timestart < math.random then
playsleep()
end
timestart = os.time() -- reset the time counter
end
but when I call the playsleep function in the dobet function
it ends up I cannot click anything in my program, cannot move another tab also
and the CPU is not sleeping either, even get busy
and sometimes it stucks even after 90000 seconds
-- THE QUESTIONS --
A. so can I make a function where the sleep is a real sleep?
B. can it sleep until 90000 seconds?
C. or what is the max number of sleep in seconds for the variable "sec" above?
Use the posix module to sleep:
posix = require("posix")
posix.sleep(86400)
But this will still block your program and you won't be able to click anything. You will need to provide more detail about your program in order to receive better advice.
Also os is there.
Why not...
do os.execute('$(type -path sleep) '..(3600*24)) end
...?

Tower-Defense Enemy AI movement roblox

can someone help me on how show i move the NPCs through a path, like in the tds game?. I have tried this
local function move()
-- source is an array with all the positions it has to go to
for i=1,#source,1 do
-- This is in case the MoveTo takes more than 8 seconds
local itreached = false
while itreached == false do
npc.Humanoid:MoveTo(source[i].Position)
wait()
npc.Humanoid.MoveToFinished:Connect(function()
itreached = true
end)
end
end
end
and it works to an extend , that when i approach the npc it somehow falls and lags , otherwise if i just run it without a player it works just fine. Are there other techniques, like lerp or tween? I tried using lerp, but i couldn't move the whole model.
video showing the problem
You are running into an issue with network ownership. The Roblox engine decides who is responsible for calculating the positions of objects based on some calculation around who is closest to the object and who has a strong enough machine to do the calculation. For example, desktop computers and laptops tend to have a wider sphere of influence than mobile devices. Anyways, when you walk close it the NPCs, there is a handoff of ownership, and that is causing the NPCs to fall over. So to fix it, you need to call SetNetworkOwner(nil) on the NPC's PrimaryPart so that the part is owned by the server.
npc.PrimaryPart:SetNetworkOwner(nil)
Also, if you want to clean up your code, you can make it entirely driven by events. Once you tell it to start moving, it will select the next target once it arrives.
local targetPos = 1
local function move()
npc.Humanoid:MoveTo(source[targetPos].Position)
end
-- listen for when the NPC arrives at a position
npc.Humanoid.MoveToFinished:Connect(function(didArrive)
-- check that the NPC was able to arrive at their target location
if not didArrive then
local errMsg = string.format("%s could not arrive at the target location : (%s, %s, %s)", npc.Name, tostring(targetPos.X), tostring(targetPos.Y), tostring(targetPos.Z))
error(errMsg)
-- do something to handle this bad case! Delete the npc?
return
end
-- select the next target
targetPos = targetPos + 1
-- check if there are any more targets to move to
if targetPos <= #source then
move()
else
print("Done moving!")
end
end)

Script stops after a few seconds

I have this exploit for Murder Mystery 2.
It is a tpcoins and esp exploit. When I enable the tpcoins it will turn off after a few seconds. Is there any way of making it so it stays on?
Here's the code:
function enableTpCoin()
if nameMap ~= "" and wp[nameMap] ~= nil then
if lplr.PlayerGui.MainGUI.Game.CashBag:FindFirstChild("Elite") then
tpCoin(10)
elseif lplr.PlayerGui.MainGUI.Game.CashBag:FindFirstChild("Coins") then
tpCoin(15)
end
end
Trigger to start the script is q.
Short answer, you can't. Since this is script related I'll answer your question.
So each round, the player can only earn 10 coins, and 15 if they have purchased the "Elite" gamepass.
This meaning that the game physically doesn't allow you to add anymore per round. You'll have to execute the code at the launch of every round.
The game has FE, so it's most likely that the original developer of the game has specified the remote events to only accept 10 or 15 coins depending on the boolean value whether the user is "Elite" or not.
Even if Universal Link says the truth, here's the solution.
Create a new function. In that function, do a while loop with a interval (use wait(.1)), and in that while loop, call enableTpCoin().
Now, call spawn() and pass the function you created as an argument.
The code should look like this:
function _loop()
while wait(.1) do
enableTpCoin()
end
end
spawn(_loop)

How to end a looping coroutine in Lua?

I'm currently working on a game using Roblox (which uses Lua). It is a basically made up of several minigames. At the beginning of each round, all the players in game are put in a table and teleported to an area. That is where the coroutine comes into play. As the round is in progress, I want a coroutine to start. Every second that coroutine checks if the player's health is below zero, and removes them from the currentPlayer table if it is.
Sorry if I am not describing the problem correctly, but the coroutine will not yield. I haven't used coroutines before, so I am probably trying to yield it the wrong way. I know most of you will not be familiar with Roblox, but the Lua syntax is the same.
Can someone please give me an example of how I would end a looping coroutine?
currentPlayers = {}
roundTime = 60
local lookForWinners = coroutine.create(function()
while coroutine.running do
wait(1)
for i, v in pairs(currentPlayers) do
if v.Character.Humanoid.Health <= 0 then
table.remove(currentPlayers, v)
end
end
end
end)
while wait() do
repeat display("Two or more players need to be in the game.", 1) until #_G.plrs > 1 --Ignore, just checks if two+ players are in game.
display("Picking a map...", 3) pickMap()
teleport(0, 500, 0)
coroutine.resume(lookForWinners)
wait(roundTime)
print("Round over")
coroutine.yield(lookForWinners)
end
Lua is a single-threaded language. Coroutines do not cause functions to execute in parallel.
Coroutines are effectively just a way to make a function that can pause its own execution (using coroutine.yield), that can be resumed from outside (using coroutine.resume). There is no "coroutine.running": there's only one line "running" at any given time.
If Roblox were meant for you to use wait() to jump out of the Lua thread, you would write this as a series of loops that check their condition and then call wait():
local currentPlayers={}
local roundTime = 60
while #_G.plrs > 1 do
display("Two or more players need to be in the game.", 1)
wait()
end
display("Picking a map...", 3) pickMap()
teleport(0, 500, 0)
for i=0, roundTime do
for i, v in pairs(currentPlayers) do
if v.Character.Humanoid.Health <= 0 then
table.remove(currentPlayers, v)
end
end
wait(1)
end
print("Round over")
However, this is bad code. (Whenever you write code, let loops with a "wait" function in them serve to indicate that something is being done incorrectly.) You should be using Roblox's Events to handle your game's logic.
Check to see if the game should start only when the number of players changes.
"Look For Winners" only when a Humanoid's health changes (the HealthChanged event).
Run the timer on some kind of timer or interval (don't forget that you'll probably want to end your game early once somebody has won).
Events have many, many advantages over a busy loop; the most visible one will be that your checks occur when the thing they're checking for happens, and not later.
I suggest you follow Stuart's advice to use events; this is mostly to provide additional information on what coroutines are to help you use them correctly.
Think of coroutines as functions that may return values, but with a twist: while a "normal" function completes when it executes return, when you yield from a coroutine, it saves its state, so that resume can then continue from the point where you yielded as if nothing happened. Note that you only yield from a coroutine and only to the point where the resume of that coroutine was done (this is no different from calling a function and returning from it; the control returns to the point where you called the function).
In addition to that, resume and yield calls allow you to pass values to the coroutine and return (intermediate) values from the coroutine. See this SO answer for an example of how this can be used.
One can still return from a coroutine and it's no different from returning from a function, which completes its execution. If you check the status of the coroutine at that time (coroutine.status), it should be "dead".
So, to answer your question how you can end a looping coroutine: you can return from it, you can yield() from it (and never resume it again), or you can call error(), which you can then catch and check for in the result of the resume call. Having said that, I agree with Stuart that it may be the wrong way to solve your problem.

Resources