-
-
Notifications
You must be signed in to change notification settings - Fork 77
Description
Summary
Currently, executing code asynchronously or with a delay requires complex workarounds using MP.CreateEventTimer and MP.RegisterEvent. This proposal adds simple, intuitive functions for async execution:
- MP.SetTimeout(ms, func) - Execute a function after a delay
- MP.CreateThread(func) - Execute a function asynchronously
Current Workaround (Complex)
To achieve async execution today, developers must:
-- Current: 15+ lines of boilerplate for a simple delayed execution
local threadId = 0
function createAsyncTask(func)
threadId = threadId + 1
local id = "__thread_" .. threadId
local handlerName = "__thread_handler_" .. threadId
_G[handlerName] = function()
func()
MP.CancelEventTimer(id)
_G[handlerName] = nil
end
MP.RegisterEvent(id, handlerName)
MP.CreateEventTimer(id, 100)
end
-- Just to do this:
createAsyncTask(function()
Wait(5000)
print("5 seconds later")
end)Proposed Solution (Simple)
-- SetTimeout: Execute after delay (like JavaScript)
MP.SetTimeout(5000, function()
print("5 seconds later")
end)
-- CreateThread: Async execution
MP.CreateThread(function()
print("This runs asynchronously")
Wait(1000)
print("Non-blocking code")
end)Real-World Use Cases
Auto-restart warning system
function scheduleRestart(minutes)
MP.SetTimeout(minutes * 60000, function()
shutdownServer()
end)
-- Warning messages
MP.SetTimeout((minutes - 5) * 60000, function()
MP.SendChatMessage(-1, "^6[SERVER]^r Restart in 5 minutes!")
end)
MP.SetTimeout((minutes - 1) * 60000, function()
MP.SendChatMessage(-1, "^4[SERVER]^r Restart in 1 minute!")
end)
endDelayed kick after warning
MP.RegisterEvent("onCheatDetected", function(playerID)
MP.SendChatMessage(playerID, "^4[AntiCheat]^r Suspicious activity detected. You will be kicked in 10 seconds.")
MP.SetTimeout(10000, function()
MP.DropPlayer(playerID, "Kicked by AntiCheat")
end)
end)Non-blocking database operations
MP.RegisterEvent("onPlayerJoin", function(playerID)
-- Don't block the main thread while loading data
MP.CreateThread(function()
local data = loadPlayerDataFromDB(playerID)
applyPlayerData(playerID, data)
print("Player data loaded for " .. playerID)
end)
end)Welcome sequence with delays
MP.RegisterEvent("onPlayerJoin", function(playerID, playerName)
MP.SendChatMessage(playerID, "^2Welcome " .. playerName .. "!^r")
MP.SetTimeout(3000, function()
MP.SendChatMessage(playerID, "^3Type /help for available commands^r")
end)
MP.SetTimeout(6000, function()
MP.SendChatMessage(playerID, "^3Join our Discord: discord.gg/example^r")
end)
end)Benefits
| Current Approach | Proposed Approach |
|---|---|
| 15+ lines of boilerplate | 1 function call |
| Manual cleanup required | Automatic cleanup |
| Error-prone | Simple and reliable |
| Hard to read | Intuitive syntax |
| Must manage event timers manually | Native implementation |
Technical Notes
- Backward compatible: Does not affect existing MP.CreateEventTimer functionality
- Familiar pattern: Same syntax as JavaScript setTimeout - millions of developers already know it
- Performance: Native C++ implementation would be faster than Lua workarounds
- Memory safe: Automatic cleanup of handlers after execution
Additional Context
I've implemented this as a Lua wrapper in my framework (https://github.com/Kipstz/Tree-BeamMP-Plugin/blob/main/_tree/threads.lua), but a native C++ implementation would be cleaner, more performant, and benefit all plugin developers without requiring external dependencies.
I'm willing to implement this feature and submit a PR if the approach is approved.