Sending Messages - Silverfeelin/Starbound-MessageHandling-Demo GitHub Wiki
To send messages to yourself or other entities, use world.sendEntityMessage
.
Remote messages are asynchronous, meaning the result of the message will be available at a later time. Local messages are synchronous, for more information see RpcPromise.
As per the documentation, messages shouldn't be sent on init as things are still being initialized at that point.
The function takes 2 up to an indefinite amount of arguments:
world.sendEntityMessage(entityId, messageType, ...)
- entityId
The entity id. For example, entity.id()
or player.id()
for your own entity. You should have a look at the world.entityQuery
documentation if you don't know how to find other entities.
You can also use the UUID of the entity.
- messageType
The message to send. This message should match the one set up in Receiving Messages.
- args
Zero or more arguments can be added to pass to the message handler.
This can be any serializable data, such as strings and numbers. Tables are also supported as long as they don't contain any non-serializable data such as functions.
world.sendEntityMessage(entityId, messageType, "foo")
world.sendEntityMessage(entityId, messageType, "foo", "bar")
world.sendEntityMessage(entityId, messageType, { foo = "bar" })
- return value
The function returns an RpcPromise
object that can be used to receive the response at a later time. If the message is handled asynchronously, simply checking the result after sending the message won't work.
You can use a PromiseKeeper, or keep track of the promises yourself.
Never busy-wait for a response if you're not absolutely certain the message is only handled locally (i.e.
while not promise:finished() do end
! This will freeze up your script (and possibly your entire game) until the promise finishes.
If your message doesn't expect a response, you may still want to use the promise to ensure the message has been handled. If you don't care about this, you can ignore the return value.
Example
When sendMessage
is called, it will send the message "multiply"
to the player. The promise is stored and checked each frame in the update
function. Once finished, the result will be used to log a message and the promise is discarded.
local promise
function update()
-- Wait for promise to finish without freezing this script up by busy-waiting.
if promise and promise:finished() then
if promise:succeeded() then
sb.logInfo("5 * 10 = %s", promise:result())
else
sb.logWarn("Couldn't multiply 5 by 10")
end
promise = nil
end
end
-- You'd have to call this at some point (not on init!)
function sendMessage()
local id = entity.id()
promise = world.sendEntityMessage(id, "multiply", 5, 10)
end
We now have a problem; if we want to multiply various values, it's hard to keep track of which response belongs to which message. You can figure out how to solve this on your own, but the PromiseKeeper offers a solution out of the box.