Skip to main content

Timers & Delays

Need something to happen later, or on a repeating schedule? Here's how to handle time-based logic in HELIX.

One-Shot Delays

Run code after a specified delay:

Blueprint One-Shot Timer
Event BeginPlaySet Timer by EventEventTime3.0LoopingfalseReturn ValueOnDelayCompletePrint StringIn String"Timer fired!"
C++ equivalent (for reference)
// Use "Set Timer by Event" node with Time = 3.0 and Looping = false
// Connect a Custom Event to the delegate pin
// Or use the "Delay" node directly in your execution flow

Repeating Timers

Run code on a regular interval:

Blueprint Repeating Timer
Event BeginPlaySet Timer by EventEventTime1.0LoopingtrueReturn ValueOnTimerTickPrint StringIn String"Tick!"

Use Clear Timer by Handle with the return value from Set Timer by Event to stop a repeating timer.

C++ equivalent (for reference)
// Use "Set Timer by Event" with Looping = true
// Set Time = 1.0 (fires every second)
// To stop: use "Clear Timer by Handle" with the return value

Coroutines in Lua

Lua coroutines let you write sequential-looking code that pauses and resumes across frames:

function M:ReceiveBeginPlay()
-- Start a coroutine
self.SpawnRoutine = coroutine.create(function()
for i = 1, 5 do
self:SpawnEnemy(i)
print("Spawned enemy " .. i .. ", waiting...")
coroutine.yield() -- pause until resumed
end
print("All enemies spawned!")
end)

-- Resume it every 2 seconds
self.TimerHandle = Timer.SetInterval(function()
if coroutine.status(self.SpawnRoutine) ~= "dead" then
coroutine.resume(self.SpawnRoutine)
else
Timer.ClearInterval(self.TimerHandle)
end
end, 2000)
end

Promises in JavaScript

For complex async flows, use Promises or async/await:

function delay(ms) {
return new Promise(resolve => setTimeout(resolve, ms));
}

function waitForPlayers(minPlayers) {
return new Promise((resolve) => {
const handle = setInterval(() => {
// Check connected players (example — adjust to your game logic)
const count = getConnectedPlayerCount();
if (count >= minPlayers) {
clearInterval(handle);
resolve(count);
}
}, 500);
});
}

async function startGame() {
console.log("Waiting for players...");
const count = await waitForPlayers(4);
console.log(`${count} players ready. Starting!`);

await delay(3000); // 3 second countdown
Helix.emit("GameStarted");
}

Tips

  • Timer values in the Lua Timer API use milliseconds (1000 = 1 second). UE's built-in timer nodes use seconds.
  • Always store timer handles and clear them when your actor is destroyed. Orphaned timers cause bugs that are tough to track down.
  • Avoid running heavy logic on fast intervals (< 100ms). If you need per-frame updates, use Tick / ReceiveTick instead.
  • The Blueprint Delay node is convenient but pauses that entire execution thread. For multiple independent delays, use separate timer handles.