Async Jobs
async_job lets Lua request named background work without blocking the game loop.
Purpose
Use async_job when a script needs:
- slow I/O
- expensive calculation
- snapshot-based planning
- external API work
Do not use it for direct world mutation from the worker.
API
async_job.run(job_name, request_id, payload)
async_job.try_run(job_name, key, request_id, payload)
run
Schedules a job immediately.
async_job.run("echo", "req-1", {
text = "hello"
})
try_run
Schedules a keyed job only if the same key is not already in flight.
local ok = async_job.try_run("echo", "npc:0x00123456", "req-2", {
text = "scan"
})
If the same key is already running, it returns false.
Callback Convention
Completion returns to Lua through global callbacks on the game loop:
function on_async_job_result(job_name, request_id, result)
end
function on_async_job_error(job_name, request_id, message)
end
result is a plain Lua table reconstructed from the background result payload.
Missing callbacks are ignored safely.
Data Rules
Allowed payload/result value types:
nilbooleannumberstring- nested tables with string keys
- sequential arrays
Not allowed:
- userdata
- functions
- threads
- live world objects
Worker Safety
Background jobs must not mutate:
- mobiles
- items
- sessions
- sectors
- timers
Apply world changes only after the callback returns on the game loop.
Example
function open_echo_demo()
async_job.run("echo", "req-echo", {
text = "hello world"
})
end
function on_async_job_result(job_name, request_id, result)
if job_name ~= "echo" or request_id ~= "req-echo" then
return
end
log.info("Echo result: " .. tostring(result.payload.text))
end
Built-In Jobs
Current built-in job names:
echo
echo is mainly a reference job for testing the plumbing end to end.