Skip to content

Stage 2: a second queue

Add a bot-spawning event. It’s instant — addbot once per requested bot:

[queues.effects]
ready_after = "applied"
[events.add_bot]
title = "Add a bot"
summary = "Throw hostile bots into the game."
queue = "effects"
[events.add_bot.params_schema]
type = "object"
additionalProperties = false
required = ["count"]
[events.add_bot.params_schema.properties.count]
type = "integer"
minimum = 1
maximum = 4

Each queue dispatches one Invocation at a time; different queues are independent. If add_bot shared the chat queue, a burst of bot redeems would make chat messages wait in line behind them. Separate queues = independent lanes.

def handle_effects_queue(rcon):
def handler(sock, inv_id, event, params):
if event != "add_bot":
failed(sock, inv_id, f"unknown event: {event}")
return
try:
count = int(params["count"])
for _ in range(count):
rcon.command("addbot")
except RconError as e:
failed(sock, inv_id, str(e))
return
applied_done(sock, inv_id, {"count": count})
return handler

Two things change when you add a queue:

  1. Add it to the startup credit grants — one pull per declared queue.
  2. Route on msg["queue"], not on the event name — a dispatch table keeps adding queue N+1 a one-line change:
DECLARED_QUEUES = ["chat", "effects"]
queue_handlers = {
"chat": handle_chat_queue(rcon),
"effects": handle_effects_queue(rcon),
}

Both queues so far are ready_after = "applied" — instant effects. Next: effects that last, and the queue policy built for them.