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
| Pattern | How it's used |
|---|---|
| Reliable push | app:PushAll("round.start") | guaranteed delivery |
| Unreliable broadcast | broadcast:EmitAll("round.tick") | drops ok, next tick follows |
| Bridge decoupling | bridge.Fire("round.began") | SpawnService doesn't import App |
| Token grant | app.TokenBucket:GrantAll(5) | reward tokens on round end |
See also
Server Push · Broadcast · Bridge · TokenBucket · Matchmaking Queue | similar Bridge + push pattern