Lua Code Loops
To make code loops in Lua that last more than one frame, you must redefine a function the game already calls every frame, and put the code in that. So far it is known that Tick() from Tick.lua and ProcessDebugKeys() from DebugKeys.lua will loop every frame, starting once the game finishes loading at startup.
Here is a way to do that so you only need to actually redefine an existing function once, and then to manage multiple looping things, you just create/delete tables that define loop functions and their persistent variables:
-- empty table to put all loop tables in
Loops = {}
-- custom function called every frame, which does the function from every loop table in Loops, with the loop table itself as a parameter so they can use their related variables easier
function DoLoops()
for k,v in pairs(Loops) do
v.fun(v)
end
end
-- redefines the existing Tick function, so DoLoops is actually called every frame
function Tick( game, gameTiming, input )
DoLoops()
dofile("TickHook.lua")
--the dofile assumes you are using wolf109909's Python Lua modder to inject code, should change that if using a different filename/method, etc
--also PLEASE REMOVE the dofile if you use this code in a publicly-released mod, I'd rather people at least go to the modding forum and say they consent to modding responsibly before they easily get access to Lua code injection, just in case...
end
This example function works if the code above has been used: whenever you call the function, it checks whether its related loop table is already in Loops, if not then it creates one - that loop's function will display a count that increases every X number of frames, and then deletes itself after looping Y number of times.
--Usage: ExampleFun(10,100) counts upward every 10 frames and stops after it does that 100 times, etc
function ExampleFun(X,Y)
if not Loops["ExampleLoop"] then
Loops["ExampleLoop"] = {
timer = X-1,
delay = X,
count = 0,
limit = Y,
fun = function(my)
--checks if enough frames have passed
my.timer = my.timer + 1
if my.timer == my.delay then
--resets frame timer, increases counter
my.timer = 0
my.count = my.count + 1
--displays counter
local DT = game:gameTiming():GetDT() -- seconds per frame
SpawnEvent{ DisplayText = {
text = my.count,
duration = (my.delay+2)*DT,
fadeTime = DT,
leftJustify = true } }
--deletes itself from Loops when done
if my.count == my.limit then
Loops["ExampleLoop"] = nil
end
end
end
}
end
end