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 = falserequired = ["count"][events.add_bot.params_schema.properties.count]type = "integer"minimum = 1maximum = 4Why a new queue?
Section titled “Why a new queue?”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.
The handler
Section titled “The handler”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 handlerAdapter bookkeeping
Section titled “Adapter bookkeeping”Two things change when you add a queue:
- Add it to the startup credit grants — one
pullper declared queue. - 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.