BAR Widgets for Idle Builders and Factory Queue Events

Practical widget patterns for spotting idle builders, handling unitDestroyed events on partially built units, and decoding base64 widget payloads in Beyond All Reason.

Tags: BAR widgets, idle builder detection, queue management, Spring engine events, lua modding

Idle builder visibility

The factory queue manager widget in BAR handles production flow, surfacing to build stop commands. A builder sitting idle wastes economy. The widget approach hooks into widgetHandler:UnitIdle(unitID) and checks factory commands with Spring.GetFactoryCommands(unitID, 0). When the return drops to zero, the builder has nothing queued.

Stopping production cleanly requires spGiveOrderToUnit(unitID, -buildDefID) with the correct build definition ID. Getting this wrong leaves the factory in a half-stopped state where the widget reports idle but the game still thinks the unit is producing.

UnitDestroyed and mid-build cancellations

The unitDestroyed event fires when a building takes damage and collapses. The problem surfaces when that unit was in the middle of construction and the queue manager needs to react. Cancelling a queue before the next unit is built fails if the previous unit walks off the production pad first.

The unitFinished hook has the same timing issue. A factory finishes one unit and starts another before the widget gets the cleanup signal, leaving the queue manager out of sync with actual production state. The correct approach checks both the command queue and the physical state of the factory pad rather than relying on a single event.

This means watching Spring.GetFactoryCommands for empty returns, verifying the builder has not moved away from the construction site, and confirming no other widget has already claimed the idle unit.

Base64 encoded widgets in the client

Some BAR mods distribute widget code as base64 encoded strings to avoid parsing issues during lobby distribution. Splitting these on the client means decoding the full payload first, then extracting individual widget files by their Lua wrapper markers. The decoding happens once at load time, and each widget registers itself through standard Spring widgetHandler hooks.

If the encoded payload contains multiple widgets, each one carries a section header that the loader splits on. The pattern mirrors how Spring handles compressed mod packages: one container, multiple components, decoded at initialization.

Finding the right Spring commands

New Lua writers in BAR often struggle with the SpringRTS wiki, which documents the engine at a level that does not always map cleanly to BAR-specific implementations. The BAR source repository on GitHub fills the gap. Reading cmd_factoryqmanager.lua and cmd_factory_stop_production.lua shows exactly how the game handles production events, idle detection, and queue manipulation.

The wiki gives you the function signatures. The BAR source shows you how experienced modders string those functions together into working widgets.

Creed of Champions

"The removal of toxicity, the goal of fun and learning, makes for a refreshing spot to play and spend time. It has also made a game with plenty of complexity a bit less daunting to dive into." — Crd-005