Bridge → On & Emit

On & Emit

Register persistent or one-shot listeners on named channels and emit events to all current listeners. Both On and Once return a BridgeConnection — anonymous handlers are always cleanable without holding a function reference.

API

Bridge.On(channel: string, handler: (data: any) → ()) → BridgeConnection
Bridge.Once(channel: string, handler: (data: any) → ()) → BridgeConnection
Bridge.Emit(channel: string, data: any)
Bridge.Clear(channel: string)
Bridge.Has(channel: string) → boolean

On

On registers a persistent listener. It stays active until you call :Disconnect() on the returned connection or call Bridge.Clear on the channel.

-- Module A: emits
Bridge.Emit("player.died", { player = player, killer = killer })

-- Module B: listens
Bridge.On("player.died", function(data)
    updateLeaderboard(data.killer)
end)

Once

Once registers a one-shot listener that automatically disconnects itself after the handler fires once.

Bridge.Once("round.started", function(data)
    initRoundUI(data)
end)

BridgeConnection

Both On and Once return a BridgeConnection — a table with a single :Disconnect() method. This is the same shape as an RBXScriptConnection, so it works directly with Maid.

local conn = Bridge.On("item.purchased", function(data)
    logPurchase(data)
end)

-- Later, when this module is shutting down:
conn:Disconnect()

Pass the connection to a Maid to have it cleaned up automatically:

local maid = RoExpress("Maid")

maid:Add(Bridge.On("round.tick", onTick))
maid:Add(Bridge.On("round.end",  onEnd))

-- end of round: all connections cleaned up at once
maid:Destroy()

Emit

Calls all listeners currently registered on the channel. Pass a single value as data — use a table if you need multiple fields.

-- Single value
Bridge.Emit("player.joined", player)

-- Multiple fields via table
Bridge.Emit("player.died", { player = player, killer = killer, reason = "fall" })

Clear

Removes all listeners on a channel at once. Equivalent to calling :Disconnect() on every connection registered to that channel name.

Bridge.Clear("round.tick")  -- all listeners gone

Has

Returns true if at least one listener is registered on the channel. Does not yield.

if Bridge.Has("player.died") then
    Bridge.Emit("player.died", { player = player, killer = killer })
end

Shop → inventory example

A shop module emits an event; the inventory module reacts without either needing a direct reference to the other:

-- ShopModule.luau
local function Purchase(player, itemId)
    -- ... validate, charge currency ...
    Bridge.Emit("item.purchased", { player = player, itemId = itemId })
end

-- InventoryModule.luau
Bridge.On("item.purchased", function(data)
    addToInventory(data.player, data.itemId)
end)
Bridge is a server-side internal bus. It does not cross the client/server boundary. For server-to-client events use Broadcast; for client-side subscriptions use Listener.

See also

← Bridge  ·  Wait & Query | yield until a channel emits  ·  Maid | bulk-manage Bridge connections  ·  Broadcast | server-to-client events