Example

Round Manager

Countdown via broadcast ticks, start/end via reliable push, Bridge for internal module coordination.

local ROUND_TIME = 120
local roundActive = false

app:Post("round/start", function(Player, Payload, req, res)
    if roundActive then res:Status(400):Error("Already active"); return end
    roundActive = true
    app:PushAll("round.start", { duration = ROUND_TIME })
    bridge.Fire("round.began", { duration = ROUND_TIME }) -- notify server modules
    task.spawn(function()
        local t = ROUND_TIME
        while t > 0 and roundActive do
            broadcast:EmitAll("round.tick", { timeLeft = t })
            task.wait(1); t -= 1
        end
        if roundActive then
            roundActive = false
            app:PushAll("round.end", { reason = "timeout" })
        end
    end)
    res:Send({ started = true })
end)

app:Post("round/end", function(Player, Payload, req, res)
    roundActive = false
    app:PushAll("round.end", { winner = req.data.winner })
    app.TokenBucket:GrantAll(5)
    res:Send({ ok = true })
end)

-- another module waits for round start without coupling
bridge.Bind("round.began", function(data)
    SpawnService.SpawnAllPlayers()
end)

What this demonstrates

PatternHow it's used
Reliable pushapp:PushAll("round.start") | guaranteed delivery
Unreliable broadcastbroadcast:EmitAll("round.tick") | drops ok, next tick follows
Bridge decouplingbridge.Fire("round.began") | SpawnService doesn't import App
Token grantapp.TokenBucket:GrantAll(5) | reward tokens on round end

See also

Server Push  ·  Broadcast  ·  Bridge  ·  TokenBucket  ·  Matchmaking Queue | similar Bridge + push pattern