How to use tweakdefs for unit mods in beyond all reason

Your guide to modifying unit stats, cloning units, and working with the tweakdefs system in BAR without breaking your definitions.

Tags: beyond all reason modding, tweakdefs, unitdefs, weapondefs, lua, spring engine, unit cloning

What tweakdefs do in bar

Tweakdefs are the BAR system that lets you modify existing unit definitions without rewriting everything from scratch. Instead of copying a full unitdef table and editing one line, you tell the game which fields to override. This keeps your mod lean and compatible with upstream balance changes.

When you work with BAR units, every unit pulls from tables like unitdefs, weapondefs, and movedefs. Tweakdefs let you target a specific nested value inside those tables. That is the practical advantage over a full clone.

Common tweakdefs mistakes

The errors players hit most often fall into three categories:

Always test one tweakdef change at a time. Apply half a dozen and then something breaks, tracking down which one is slow work.

Cloning units with tweakdefs

When you need a unit that is 90 percent identical to an existing one, start with the original table and mutate. A recursive copy function walks the unitdefs table, duplicates every nested key, and returns a fresh table you can edit without touching the original.

For example, if you want to clone a weapon from one unit onto another through tweakdefs, copy the specific weapondefs entry and remap it under the target unit. Do not rewrite every weapon parameter. Copy the full weapondefs block, then change only what differs.

Keep in mind that Spring.CreateUnit still works for game logic code like spawning unit waves. It is not deprecated for that use. But you cannot use it as a build command in a lobby script. For build orders you need Spring.GiveOrderToUnit with the negative ID of the unitdef, written as -UnitDefNames.armwin.id.

Finding spring api functions

BAR runs on the Spring engine. The Spring API surface is large and not all of it is obvious from a quick search. The key reference files are:

Functions like Spring.GetUnitNearestEnemy(unitID, range) are useful for proximity triggers. The function returns nil when no enemy falls inside the range parameter. A common pattern is reading a custom parameter for range and defaulting it safely:

local triggerRange = tonumber(UnitDefs[unitDefID].customParams.detonaterange) or 64
local targetID = Spring.GetUnitNearestEnemy(unitID, triggerRange)
if targetID then
  -- fire sequence
end

Learn bar modding with a solid team behind you

Picking up BAR modding on your own means staring at Lua tables and engine source code. Doing it inside a community that values patience and clear teaching changes the experience entirely. Creed of Champions runs training sessions and team gameplay for BAR players at every skill level, including modders who want feedback on their work.

[Crd] 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.

Win with skill, teamwork, and respect. Check out the BAR YouTube channel for gameplay content while you learn the ropes.