Real Lua patterns from active BAR modders working with unitdefs, buildoptions, and nested tables. Skip the guesswork.
The single most common mistake new BAR modders make involves buildoptions. Direct assignment to def.buildOptions or def.buildoptions creates malformed menus when the nested table structure is wrong. The fix requires iterating through the existing buildOptions array and removing bad entries rather than replacing the whole table.
The working pattern loops through unitDefs, checks each entry for a buildOptions table, collects invalid indices, and removes them in reverse order to avoid index shifting:
for name, def in pairs(unitDefs) do
local badOptions = {}
local buildOptions = def.buildOptions or def.buildoptions
if buildOptions then
for i, option in ipairs(buildOptions) do
if unitDefs[option] == nil then
table.insert(badOptions, i)
end
end
if #badOptions > 0 then
local removed = 0
for _, badIndex in ipairs(badOptions) do
table.remove(buildOptions, badIndex - removed)
removed = removed + 1
end
end
end
end
This keeps the build menu intact while stripping out references to units that do not exist in the current game state.
A recurring pain point involves widget performance. Updating the entire widget from scratch on every mouse click creates visible stutter, especially on larger unit rosters. The solution spreads updates across multiple frames and only changes what actually needs changing.
Instead of recreating all tables on each interaction, modders should track state deltas. Only the units that changed between frames require table rebuilds. This reduces CPU load and keeps the interface responsive during matches. Players requesting this approach consistently report smoother performance after refactoring their update loops.
Hardcoded chains like if name=="armmex" or name=="armflea" or name=="armck" grow unmanageable fast. A cleaner approach uses a dedicated lookup table:
local targetUnits = {
armmex = true,
armflea = true,
armck = true,
}
for name, ud in pairs(UnitDefs) do
if targetUnits[name] then
-- apply changes
end
end
This pattern scales to dozens of units without turning into an unreadable wall of string comparisons. Adding or removing a unit requires a single line change in the table definition.
Three durable lessons emerge from these discussions. Use code blocks when asking for help. Raw inline code gets mangled and wastes everyone time. Update incrementally instead of rebuilding from scratch on every interaction. Spreading work across frames produces smoother results. Replace chained conditionals with lookup tables. Readability matters when code gets complex.
BAR modding rewards clean code and clean communication. Teams that share well-formatted snippets and fix problems without blame move faster and learn more. The community that practices this stays fun and productive for everyone.
Crd is the first really comfortable community I have been a part of. Everyone is nice and kind, the atmosphere is relaxed, and I am not getting yelled at for not being optimal.