Inter-Script Communication with Signals in RollingQuest
Learn how to send targeted messages between entities in RollingQuest using the Signals namespace, Signal objects, and the OnSignal hook.
Signals are the primary way for scripts to talk to each other. When one entity needs to notify another — a pressure plate that opens a door, a trigger block that wakes up a sleeping enemy — you emit a signal by name, and every entity whose OnSignal hook matches that name can respond. Signals can carry any Lua value as a payload, so you can pass numbers, strings, tables, or even nothing at all.
To make an entity respond to a signal, define OnSignal in its script. The game calls this function whenever a signal is delivered to that entity.
---@param self Block---@param signal Signalfunction OnSignal(self, signal) if signal.id == "Activate" then self:enable() elseif signal.id == "Deactivate" then self:disable() endend
The Signals namespace provides several functions that let you target signals precisely — from a broadcast to every entity in the level down to a single named entity.
Signals.emitToTypeAndTag(signalId, type, tag [, data])
Sends a signal to all entities that match both a type and a tag — the most precise broadcast filter.
--- @param signalId string--- @param type EntityType--- @param tag string--- @param data any -- optionalSignals.emitToTypeAndTag(signalId, type, tag, data)
-- Only target blocks tagged "trap"Signals.emitToTypeAndTag("Arm", EntityType.Block, "trap")
Sends a signal to every entity for which customFilter returns true. The filter receives the entity and the signal as arguments.
--- @param signalId string--- @param customFilter function--- @param data any -- optionalSignals.emitToCustom(signalId, customFilter, data)
-- Only signal blocks that are currently movingSignals.emitToCustom("Stop", function(entity, signal) if entity.type == EntityType.Block then return entity:asBlock().isMoving end return falseend)
The following two scripts work together. A Side script acts as a pressure plate: when the ball rolls on, it emits a signal. A Block script on a gate block listens for that signal and toggles itself.
-- Side script attached to the pressure-plate tile-- Emits "PressurePlate_On" when the ball rolls on and-- "PressurePlate_Off" when it rolls off.---@param self Side---@param rollIn boolean---@param ball Ballfunction OnBallRoll(self, rollIn, ball) if rollIn then Signals.emitToTag("PressurePlate_On", "gate-block") else Signals.emitToTag("PressurePlate_Off", "gate-block") endend
Use tag-based emission (Signals.emitToTag) when you want to control multiple entities at once without keeping references to each one individually.