Skip to content

Partial SACU Rebalance#7141

Merged
Rhaelya merged 43 commits into
FAForever:developfrom
lL1l1:balance/partial-sacu-rebalance
Jun 23, 2026
Merged

Partial SACU Rebalance#7141
Rhaelya merged 43 commits into
FAForever:developfrom
lL1l1:balance/partial-sacu-rebalance

Conversation

@lL1l1

@lL1l1 lL1l1 commented Jun 19, 2026

Copy link
Copy Markdown
Contributor

Description of the proposed changes

SACU rebalance has some really simple parts regarding stat/eco numbers, adjacency, and upgrade setup, but also some complex parts regarding presets, removing upgrades, adding new upgrades, and overall identity of SACU statlines. Last SACU rebalance discussion stalled out because I was burnt out rebalancing combat stats to not be so HP-focused, some presets with new support upgrades were weirdly balanced mixes (ex: Aeon chrono + combat, Sera regen + combat), Rhaelya and I also wanted to take a look at combatant presets in general, and identity issues with how Aeon SACUs were changed to be shorter range.

I think the current HP-focused combat + engineering SACUs can be an interesting addition into the current balance as a long-term value type of unit vs T3, they could be a bit stronger vs T4, and the engi upgrades could be more efficient. None of this requires whole identity changes or new upgrades, just changing some numbers.

From this discord post

Summary of changes:

  1. Quantum Gateways
    a. Quantum gateway cost/buildpower buffed to lower barrier of entry into SACU tech.
    b. QG HP reduced since it is a "high tech" structure
    c. QG adjacency massively buffed to allow for long-term SACU production.
  2. General SACU Changes
    1. Base SACU cost reduced by 400 mass
      1. This required shifting around Cybran SACU's mass costs so that SACU with just the dmg/range upgrade is not overpowered.
      2. RAS cost increased by 100 mass so that 5 Aeon SACU sacrifice into GC still.
    2. Buildtime generally reduced to buff QG mass drain from 20-27 mass/s to 30-34
    3. Energy ratios reduced to ~18 for non-combat presets, ~22-26 for combatants, ~32-35 for rambos, and 40 for cloak/shield
    4. Energy upkeeps reduced 30%
    5. Engineer presets heavily buffed in cost to make them a more viable buildpower source. They're still significantly harder to build than even lvl 3 hives, but it's much easier than before. Mainly it is difficult to make the mass/buildtime costs of the base sacu + engi upgrade compete with hives/engis with only 98 buildpower.
      1. Sera TML cost increased by 300 mass to counteract one of the double buffs from engi and base sacu cost buffs. Sera TML preset is quite a powerful tool in the Sera roster already.
  3. Specific SACU Changes:
    1. UEF Bubble Shield prerequisite of the personal shield is removed, buffing the shield preset by 2k mass. Due to the cost decrease, the bubble shield is also rebalanced to be more similar to mobile shields.
    2. Seraphim overcharge upgrade cost reduced to 1k mass, since it needs a massive cost in infrastructure to be supported.
    3. Added RAS to Seraphim on the right arm (OC + tele arm) with a RAS preset, and reduced the base cost and resource production of the SACU to standard values.
    4. Seraphim shield upgrade moved to right arm (OC + tele arm).
      1. This nerfs Seraphim Teleport SACU, which is extremely strong with 59500 HP and 400 DPS being harder to kill than a telemazer before it kills your SMD. Players will have to get used to sending multiple SACU to kill more important targets now. A nano tele SACU is only 19150 mass, and the energy infrastructure needed to build/teleport it is reusable, so for killing a 70-79k mass arty or 220-250k mass game ender, that is a fair price (arguably it is still too powerful, as teleport has no good counters besides spamming shields trying to get them in between the target and the SACU gun).
      2. The Rambo preset was previously useless because it was shield + nano + overcharge, so it had no range from the sensors upgrade to be able to use overcharge. The new Rambo preset is shield + sensors + nano. It is similar to the Nano Combatant in that it only has 400 single-target DPS, but its power/mass relies more on HP than regen, so it does better late-game against concentrated DPS from T4s.

Testing done on the proposed changes

I tested basic functionality by spawning in units and checking the UI but this will need thorough gameplay testing.

Checklist

Summary by CodeRabbit

  • Balance Updates
    • Rebalanced SACU/Support Commander and related economy/defense values across multiple factions, including lower durability, adjusted build costs/cadence, and retuned engineering/shield/resource upgrades
    • Retuned Quantum Gateway performance and supporting adjacency effects
    • Updated Seraphim Rambo preset loadout and right-arm shield generator behavior, including changes that affect teleport-related SACUs
  • Bug Fixes
    • Shield Generator Field now activates immediately (no delayed shield rebuild)
    • Resource Allocation upgrades now correctly apply/revert Death Nuke damage and radius
  • Documentation
    • Updated upgrade tooltips in multiple languages with detailed “resource generation & volatility” stats (including Death Nuke)

lL1l1 added 28 commits June 15, 2026 22:24
"high-tech" structure
Tests:
- Checked upgrade icon in enhancements tab
- Checked preset icon in QG buildables
- Verified all three costs and production are the same as other RAS presets
- No errors when building preset or manually upgrading, and when removing upgrade
1. Mass -400
2. Keep Energy ratios
3. Buildtime adjusted to for 30 mass/s drain from QG
Compensates base SACU cost reduction. Results in QG drain of 34.0-34.1m/s which is similar to 33.9-34.7 drain before rebalance.
Fixes Aeon SACU RAS Sacrifice unit counts (except for nuke, need more energy cost)
prevents double-buffing from base sacu cost buff and engineering cost buff
Cybran has tons of base HP so the range/dmg-only SACU is extremely strong after the base sacu cost reduction.
The costs are moved into the range/dmg upgrade and away from emp/cloak/nano to balance range/dmg-only, combatant, cloak, and rambo presets.
Energy and buildtime will be changed later on a pass over all presets.
Much faster buildtime and lower energy cost so that engi presets can be built somewhat similar to engineering stations.
Lvl 3 hive is 60 bt/bp 21 m/bp, and Cyb/Sera/Aeon are 103.6-100.8 bt/bp 21.9-20.9 m/bp.
UEF is noticeably weaker than others at 110.5 bt/bp 22.9 m/bp because the drone is a flying T3 engi.
Rebalanced to 30-34m/s with more upgraded presets and support presets draining more.
30m/s: sacu
31m/s: range/dmg-only
31.5m/s: stealth
32m/s: combatant
34m/s: rambo, cloak, aa, engi, ras
13.2 e/m: sacu
14.9: engi
17.1: Stealth, AA
18.2: RAS
22: range/dmg-only
25: combatant
32: rambo
40: cloak
More upgraded and support presets drain more.
30m/s: SACU
32m/s: Combatant
33.1m/s: Engi, Intel
34m/s: Rambo, shield
12 e/m: SACU
13.5: engi
18: RAS, Intel
24.5: Combatant
32: Rambo
40: Shield
Majority of cost comes from energy infrastructure, which is not efficient, so really any cost on the OC is excessive, but 1k is just there so that it costs something.
30 m/s: SACU
31.7m/s: Combatant
33.5m/s: Nano Combatant
34.0: RAS, Engi, Adv Combatant, Rambo, TML

Nano is a super heavy part of the overall cost and the SACU's effectiveness so nano combatant ends up that close
12.6 e/m: SACU
14.4: engi
18.0: RAS
22.0: Combatant
25.0: TML
26.0: Nano Combatant
35: Rambo, Adv. Combatant
30.1 m/s: SACU
31.0: Combatant
32.5: Nano Combatant
33.0: Shield Combatant
34.0: Rambo, Engi, RAS
13.9 e/m: SACU
15.4: Engi
18.5: RAS
24.0: Combatant
25.5: Nano Combatant
28.0: Shield Combatant
32.0: Rambo
Adv combatant is extremely energy hungry. This shield + nano + gun range is similar to nano combatant in that it just tanks and deals single-target DPS, but it is better suited late-game since it is HP-tanking instead of regen-tanking.

Translations done using AI
@lL1l1 lL1l1 added the area: balance idea related to suggestions for unit balance label Jun 19, 2026
@coderabbitai

coderabbitai Bot commented Jun 19, 2026

Copy link
Copy Markdown
Contributor

Review Change Stack

Note

Reviews paused

It looks like this branch is under active development. To avoid overwhelming you with review comments due to an influx of new commits, CodeRabbit has automatically paused this review. You can configure this behavior by changing the reviews.auto_review.auto_pause_after_reviewed_commits setting.

Use the following commands to manage reviews:

  • @coderabbitai resume to resume automatic reviews.
  • @coderabbitai review to trigger a single review.

Use the checkboxes below for quick actions:

  • ▶️ Resume reviews
  • 🔍 Trigger review
📝 Walkthrough

Walkthrough

Balance update #7141 reduces SACU and Quantum Gateway costs across all four factions, extends the blueprint schema with death weapon modification fields, reworks the UEF bubble shield (removes personal shield prerequisite, reduces stats, fixes immediate activation), adds a new Seraphim RAS enhancement on the right arm with death weapon modifiers, moves the Seraphim personal shield to the right arm, updates the Seraphim Rambo preset, adjusts adjacency buff coefficients, and updates localization strings in all supported languages.

Changes

SACU Balance Update #7141

Layer / File(s) Summary
Changelog and balance overview
changelog/snippets/balance.7141.md
Adds the #7141 changelog covering SACU cost reductions, Quantum Gateway stat changes, per-faction enhancement tuning, Seraphim right-arm restructure, and Rambo preset swap.
Blueprint schema: death weapon damage/radius fields
engine/Core/Blueprints/UnitBlueprint.lua
Adds DeathWeaponDamageAdd and DeathWeaponRadiusAdd numeric blueprint fields documented as used by RAS SACU enhancements to augment death weapon stats.
Quantum Gateways and adjacency buff coefficients
units/UAB0304/UAB0304_unit.bp, units/UEB0304/UEB0304_unit.bp, units/URB0304/URB0304_unit.bp, units/XSB0304/XSB0304_unit.bp, lua/sim/AdjacencyBuffs.lua
Reduces Health/MaxHealth (10000→7500) and build costs on all four Quantum Gateways, increases BuildRate, and updates SIZE20 EnergyActive/MassActive adjacency buff coefficients for T1/T3 power generators and mass fabricators.
Aeon SACU enhancement rebalance
units/UAL0301/UAL0301_unit.bp, units/UAL0301/UAL0301_script.lua
Reduces Aeon SACU base build cost and build time; adjusts cost/time for EngineeringFocusingModule, ResourceAllocation (with new death weapon modifiers), Shield, ShieldHeavy, StabilitySuppressant, and SystemIntegrityCompensator; updates script to apply/revert death weapon damage/radius mods.
UEF SACU bubble shield script fix and death weapon integration
units/UEL0301/UEL0301_script.lua
Removes delayed forked thread (WaitTicks(1)) from ProcessEnhancementShieldGeneratorField for immediate shield activation; updates ResourceAllocation handlers to apply/revert death weapon damage/radius modifiers alongside production rate changes.
UEF SACU enhancement blueprint rebalance
units/UEL0301/UEL0301_unit.bp
Removes personal Shield prerequisite from BubbleShield preset; substantially nerfs ShieldGeneratorField stats (health, recharge, regen, spillover); narrows ShieldGeneratorFieldRemove to only remove Shield; adjusts costs/times for Personal Shield Generator, RAS, Energy Accelerator (with death weapon modifiers), Plasma Refractor, Engineering Drone, Radar Jammer, and Sensor System.
Cybran SACU enhancement rebalance
units/URL0301/URL0301_unit.bp, units/URL0301/URL0301_script.lua
Reduces Cybran SACU base build costs; adjusts cost/time for CloakingGenerator, EMPCharge, FocusConvertor, NaniteMissileSystem, ResourceAllocation (with new death weapon modifiers), SelfRepairSystem, StealthGenerator (including maintenance), and Switchback; updates script to apply/revert death weapon damage/radius mods.
Seraphim SACU: new RAS enhancement and shield arm reassignment
units/XSL0301/XSL0301_script.lua, units/XSL0301/XSL0301_unit.bp
Adds ProcessEnhancementResourceAllocation/Remove handlers with death weapon modifier support; adds ResourceAllocation/Remove enhancements on right-arm slot with death weapon modifiers; moves personal Shield Generator to right-arm bones; rebalances base production; updates Rambo preset to swap Overcharge for EnhancedSensors; adds new RAS preset; adjusts costs/times for DamageStabilization, EngineeringThroughput, EnhancedSensors, Missile, and Overcharge.
Localization string updates across all languages
loc/CN/strings_db.lua, loc/CZ/strings_db.lua, loc/DE/strings_db.lua, loc/ES/strings_db.lua, loc/FR/strings_db.lua, loc/IT/strings_db.lua, loc/PL/strings_db.lua, loc/RU/strings_db.lua, loc/TW/strings_db.lua, loc/TZM/strings_db.lua, loc/US/strings_db.lua, lua/ui/help/unitdescription.lua
Updates Unit_Description_0019 across all locales with shield regen/recharge stats; expands Unit_Description_0021/0120/0169 to multi-line resource generation/volatility stat blocks including Death Nuke damage/radius; adds Unit_Description_xsl0301_ras with detailed stats; updates xsl0301_Rambo_help to reflect new preset; adds xsl0301_RAS name/desc/help entries; updates all faction RAS UI help descriptions.

Sequence Diagrams

sequenceDiagram
  participant Player
  participant UEL0301
  participant ShieldGeneratorField

  rect rgba(255, 100, 100, 0.5)
    Note over Player,ShieldGeneratorField: Old flow (removed)
    Player->>UEL0301: Apply ShieldGeneratorField
    UEL0301->>UEL0301: DestroyShield()
    UEL0301->>UEL0301: ForkThread (WaitTicks 1)
    UEL0301->>ShieldGeneratorField: CreateEnhancementShield(bp)
  end

  rect rgba(100, 200, 100, 0.5)
    Note over Player,ShieldGeneratorField: New flow (immediate)
    Player->>UEL0301: Apply ShieldGeneratorField
    UEL0301->>UEL0301: AddToggleCap(RULEUTC_ShieldToggle)
    UEL0301->>UEL0301: SetEnergyMaintenanceConsumptionOverride(bp value or 0)
    UEL0301->>UEL0301: SetMaintenanceConsumptionActive(true)
    UEL0301->>ShieldGeneratorField: CreateEnhancementShield(bp)
  end
Loading
sequenceDiagram
  participant Player
  participant SACU as SACU (Aeon/Cybran/Seraphim)
  participant Blueprint_Economy
  participant DeathWeapon

  Player->>SACU: Apply ResourceAllocation
  SACU->>Blueprint_Economy: Read ProductionPerSecondEnergy/Mass
  SACU->>SACU: SetProductionPerSecondEnergy(bp.energy + economy.energy)
  SACU->>SACU: SetProductionPerSecondMass(bp.mass + economy.mass)
  SACU->>DeathWeapon: Apply damage/radius add modifiers
  
  Player->>SACU: Remove ResourceAllocation
  SACU->>Blueprint_Economy: Read base production values
  SACU->>SACU: SetProductionPerSecondEnergy(economy.energy or 0)
  SACU->>SACU: SetProductionPerSecondMass(economy.mass or 0)
  SACU->>DeathWeapon: Revert damage/radius add modifiers
Loading

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~25 minutes

Suggested reviewers

  • Rhaelya

Poem

🐇 Hoppity-hop through the balance patch!
The SACU costs have found their match,
Seraphim's shield hops to the right,
UEF bubble glows instant-bright.
Gateways cheaper, Rambo renewed —
This bunny approves the whole interlude! 🌟

🚥 Pre-merge checks | ✅ 5
✅ Passed checks (5 passed)
Check name Status Explanation
Title check ✅ Passed The title clearly and concisely identifies the main change: a partial rebalance of SACU units with stat/eco adjustments and preset modifications.
Description check ✅ Passed The description comprehensively covers all major changes with detailed explanations, includes testing notes, and provides context from design discussions.
Docstring Coverage ✅ Passed No functions found in the changed files to evaluate docstring coverage. Skipping docstring coverage check.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands.

@lL1l1 lL1l1 requested a review from Rhaelya June 19, 2026 05:26
@lL1l1 lL1l1 marked this pull request as ready for review June 19, 2026 07:15
@hotcheese4444

Copy link
Copy Markdown

I'm partial to moving Sensor system before moving Shield. Sensor system makes Overcharge so much more useful/usable it should be a pre-requisite to OC. It just seems like shield+OC is not ever a viable option currently or with the proposed changes.

@lL1l1 lL1l1 moved this from To Discuss to To Test in 2025 - Balance Iteration I Jun 21, 2026
@lL1l1

lL1l1 commented Jun 21, 2026

Copy link
Copy Markdown
Contributor Author

@hotcheese4444

It just seems like shield+OC is not ever a viable option ... with the proposed changes.

Shield + OC is removed with the proposed changes. The new preset is shield sensors nano which is an extremely tanky single-target DPS option for Sera. It is much more efficient than OC's energy infrastructure costs and doesn't require micromanaging the drain of auto OCs going off at bad times and causing lower damage than desired because of empty storages.

Move sensors to right arm as OC prerequisite

Then we would have range OC nano shield SACUs which seems too powerful compared to advanced nano + gun ACU:

  • 30 vs 35 range
  • 1.7 vs 2.2 speed
  • 33500 +220/s hp vs 29500 +295/s hp 20000 shield
  • 8.4k mass 530k e vs 7.1k mass 300k e + QG 2.55k m 25.5k e
  • 10 T1 BP vs 56 T3 BP + QG 160 BP
  • 200 gun DPS vs 400 gun DPS
  • 5s auto / 3.3s manual oc vs 7.5s oc

You can give the ACU 5.5k +30/s hp with t3 for 3.2k mass 71k e. Definitely still not enough to be anywhere near as effective as proposed preset.

I also want OC to be the AoE SACU upgrade equivalent for Sera, and since it is very powerful against poor pathfinding with its one shot kills I think the OC SACU shouldn't have so much HP as to be unstoppable with that early 11k-14k mass cost rush (this is an estimate including the energy infra mass cost for it to be constantly overcharging bricks and hitting 2 or 1, but this can be even lower because you will have 1-1.5k mass in storages for ACU usage anyway).

I also think you have to consider that the adv combatant preset by itself has huge stat changes:
9850 mass -> 5950 (-3.9k or -40%)
420k e -> 208k e (-50%)
36k bt -> 28k bt (-22%)
This could easily make it viable already. It could snowball with its T3 efficiency and usage of overbuilt energy infrastructure and just win games.

lL1l1 added 7 commits June 21, 2026 18:37
((?:uel0301(_RAS_\w+=.*$\n))(?:uel0301(_RAS_\w+=.*$\n))(?:uel0301(_RAS_\w+=.*$\n))(?:.*[\n])*xsl0301_Rambo_name=.*\n)

Replaced with

$1xsl0301$2xsl0301$3xsl0301$4
In the rebalance mod the T3 fab adjacency for QG started as being equal to factories at 20%. A forum post expressed concerns about it, so I arbitrarily nerfed it to 15%.
3 directions from which to explain the buff:
1. Sandboxing 10 minute builds showed the QG grid to not be better than fab grids.
2. Logically this is explained by the fact that QG adjacency going into RAS SACU is your adjacency's mass investing into inefficient eco, on a 3 minute delay if you maximize your QG discount time.
3. Calculations also show that a QG adjacent to a fab pays itself off in 500s, while a T3 land fac making percies pays off in 342s, and a popular 2 pgen 2 fab template (not the most efficient fab template economically) pays off in 341s.
@lL1l1 lL1l1 force-pushed the balance/partial-sacu-rebalance branch from d9a7dd6 to 9e85a8c Compare June 22, 2026 03:19

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 5

Caution

Some comments are outside the diff and can’t be posted inline due to platform limitations.

⚠️ Outside diff range comments (1)
units/UEL0301/UEL0301_unit.bp (1)

259-268: ⚠️ Potential issue | 🔴 Critical | ⚡ Quick win

Fix death-weapon modifier contract mismatch (wrong enhancement + wrong key).

Line 267/268 adds death-weapon fields to AdvancedCoolingUpgrade, but units/UEL0301/UEL0301_script.lua reads them from ResourceAllocation and expects DeathWeaponRadiusAdd. As written, the add/remove handlers can receive nil and ProcessEnhancementResourceAllocationRemove can crash on unary minus with nil.

Suggested fix
         AdvancedCoolingUpgrade = {
             BuildCostEnergy = 40000,
             BuildCostMass = 1000,
             BuildTime = 5060,
             Icon = "acu",
             Name = "<LOC enhancements_0061>Energy Accelerator",
             NewRateOfFire = 2,
             Slot = "LCH",
             UpgradeUnitAmbientBones = { "UEL0301" },
-            DeathWeaponDamageAdd = 1000,
-            DeathWeaponDamageRadiusAdd = 4,
         },
@@
         ResourceAllocation = {
             BuildCostEnergy = 94400,
             BuildCostMass = 4600,
             BuildTime = 20550,
             Icon = "isb",
             Name = "<LOC enhancements_0069>Resource Allocation System",
             ProductionPerSecondEnergy = 1000,
             ProductionPerSecondMass = 10,
+            DeathWeaponDamageAdd = 1000,
+            DeathWeaponRadiusAdd = 4,
             ShowBones = { "SAM" },
             Slot = "RCH",
             UpgradeEffectBones = { "SAM" },
             UpgradeUnitAmbientBones = { "UEL0301" },
         },

Also applies to: 367-378

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@units/UEL0301/UEL0301_unit.bp` around lines 259 - 268, Remove the
DeathWeaponDamageAdd and DeathWeaponDamageRadiusAdd fields from the
AdvancedCoolingUpgrade enhancement block (around lines 267-268), and instead add
them to the ResourceAllocation enhancement block with the correct key names
DeathWeaponAdd and DeathWeaponRadiusAdd. This correction must be applied in all
occurrences mentioned in the diff, including the section noted at lines 367-378,
to ensure the enhancement fields match what the UEL0301_script.lua file expects
to read from ResourceAllocation, preventing nil value crashes in the add/remove
handlers.
🧹 Nitpick comments (1)
loc/US/strings_db.lua (1)

1933-1934: 🧹 Nitpick | 🔵 Trivial | ⚡ Quick win

Remove the duplicate Unit_Description_xsl0301_ras assignment.

The same key is assigned twice with identical content. It works today, but duplication here is easy to desync later.

🧹 Proposed fix
 Unit_Description_xsl0301_ras="Increases SACU's resource generation and volatility.\n\n+10 mass production per second\n+1000 energy production per second\n+1000 Death Nuke damage\n+4 Death Nuke radius"
-Unit_Description_xsl0301_ras="Increases SACU's resource generation and volatility.\n\n+10 mass production per second\n+1000 energy production per second\n+1000 Death Nuke damage\n+4 Death Nuke radius"
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@loc/US/strings_db.lua` around lines 1933 - 1934, Remove the duplicate
assignment of the Unit_Description_xsl0301_ras key in the strings_db.lua file.
The key appears twice consecutively with identical content, which creates
unnecessary duplication and increases the risk of future desynchronization.
Delete one of the two identical Unit_Description_xsl0301_ras assignments,
keeping only a single definition of this string.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@engine/Core/Blueprints/UnitBlueprint.lua`:
- Around line 955-958: The schema definition in UnitBlueprint.lua declares the
field as DeathWeaponRadiusAdd, but the SACU enhancement blueprints in
UAL0301_unit.bp, URL0301_unit.bp, and XSL0301_unit.bp reference
DeathWeaponDamageRadiusAdd instead. Change the field name from
DeathWeaponRadiusAdd to DeathWeaponDamageRadiusAdd in the schema definition to
match what the consumers are actually using, ensuring the contract is unified
and eliminating nil lookups when scripts attempt to access this radius modifier
field.

In `@loc/US/strings_db.lua`:
- Line 90: The variable `xsl0301_RAS_name` is currently set to an empty string,
but it is referenced in units/XSL0301/XSL0301_unit.bp for the preset UnitName
field without a fallback value, causing a blank label to appear in the UI.
Replace the empty string assignment for `xsl0301_RAS_name` with an appropriate
non-empty string value that describes the unit name.

In `@units/UAL0301/UAL0301_script.lua`:
- Around line 118-120: The AddDamageRadiusMod method call is using the wrong
blueprint key, `DeathWeaponRadiusAdd`, when it should use
`DeathWeaponDamageRadiusAdd` to match the enhancement blueprint contract. Update
the parameter passed to AddDamageRadiusMod from bp.DeathWeaponRadiusAdd to
bp.DeathWeaponDamageRadiusAdd in both occurrences (around lines 120 and 133) to
ensure the radius modification is properly applied and reverted.

In `@units/URL0301/URL0301_script.lua`:
- Around line 206-208: The death weapon radius modifier key in the
AddDamageRadiusMod call references bp.DeathWeaponRadiusAdd, but the blueprint
defines the field as DeathWeaponDamageRadiusAdd. Change the key from
DeathWeaponRadiusAdd to DeathWeaponDamageRadiusAdd in the AddDamageRadiusMod
method call on line 208. Apply the same fix to the remove handler at lines
218-221 where the corresponding RemoveDamageMod call also needs to use the
correct key DeathWeaponDamageRadiusAdd instead of DeathWeaponRadiusAdd.

In `@units/XSL0301/XSL0301_script.lua`:
- Around line 109-111: The deathNuke:AddDamageRadiusMod() method call is using
an incorrect blueprint field name. Change the field reference from
bp.DeathWeaponRadiusAdd to bp.DeathWeaponDamageRadiusAdd to match the actual
field name defined in the blueprint file. This same correction needs to be
applied in two places: once in the initial death nuke setup around line 110, and
again around line 121-124 where the radius modification is reverted.

---

Outside diff comments:
In `@units/UEL0301/UEL0301_unit.bp`:
- Around line 259-268: Remove the DeathWeaponDamageAdd and
DeathWeaponDamageRadiusAdd fields from the AdvancedCoolingUpgrade enhancement
block (around lines 267-268), and instead add them to the ResourceAllocation
enhancement block with the correct key names DeathWeaponAdd and
DeathWeaponRadiusAdd. This correction must be applied in all occurrences
mentioned in the diff, including the section noted at lines 367-378, to ensure
the enhancement fields match what the UEL0301_script.lua file expects to read
from ResourceAllocation, preventing nil value crashes in the add/remove
handlers.

---

Nitpick comments:
In `@loc/US/strings_db.lua`:
- Around line 1933-1934: Remove the duplicate assignment of the
Unit_Description_xsl0301_ras key in the strings_db.lua file. The key appears
twice consecutively with identical content, which creates unnecessary
duplication and increases the risk of future desynchronization. Delete one of
the two identical Unit_Description_xsl0301_ras assignments, keeping only a
single definition of this string.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro

Run ID: 13324298-9303-4a64-ae5e-0538bc581a98

📥 Commits

Reviewing files that changed from the base of the PR and between d0f0330 and d9a7dd6.

📒 Files selected for processing (23)
  • changelog/snippets/balance.7141.md
  • engine/Core/Blueprints/UnitBlueprint.lua
  • loc/CN/strings_db.lua
  • loc/CZ/strings_db.lua
  • loc/DE/strings_db.lua
  • loc/ES/strings_db.lua
  • loc/FR/strings_db.lua
  • loc/IT/strings_db.lua
  • loc/PL/strings_db.lua
  • loc/RU/strings_db.lua
  • loc/TW/strings_db.lua
  • loc/TZM/strings_db.lua
  • loc/US/strings_db.lua
  • lua/sim/AdjacencyBuffs.lua
  • lua/ui/help/unitdescription.lua
  • units/UAL0301/UAL0301_script.lua
  • units/UAL0301/UAL0301_unit.bp
  • units/UEL0301/UEL0301_script.lua
  • units/UEL0301/UEL0301_unit.bp
  • units/URL0301/URL0301_script.lua
  • units/URL0301/URL0301_unit.bp
  • units/XSL0301/XSL0301_script.lua
  • units/XSL0301/XSL0301_unit.bp
✅ Files skipped from review due to trivial changes (2)
  • changelog/snippets/balance.7141.md
  • loc/IT/strings_db.lua
🚧 Files skipped from review as they are similar to previous changes (4)
  • lua/sim/AdjacencyBuffs.lua
  • units/URL0301/URL0301_unit.bp
  • units/UAL0301/UAL0301_unit.bp
  • units/XSL0301/XSL0301_unit.bp
👮 Files not reviewed due to content moderation or server errors (1)
  • loc/TW/strings_db.lua

Comment on lines +955 to +958
--- Used by RAS SACU to add damage to their death weapon
---@field DeathWeaponDamageAdd number
--- Used by RAS SACU to add radius to their death weapon
---@field DeathWeaponRadiusAdd number

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟠 Major | ⚡ Quick win

Unify the death-weapon radius field name across schema and consumers.

The new schema declares DeathWeaponRadiusAdd, but the SACU enhancement blueprints in units/UAL0301/UAL0301_unit.bp:287-305, units/URL0301/URL0301_unit.bp:362-374, and units/XSL0301/XSL0301_unit.bp:427-440 use DeathWeaponDamageRadiusAdd. This contract drift will produce nil lookups in scripts and break radius modifier application/removal.

Suggested schema-side fix
 --- Used by RAS SACU to add radius to their death weapon
----@field DeathWeaponRadiusAdd number
+---@field DeathWeaponDamageRadiusAdd number
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
--- Used by RAS SACU to add damage to their death weapon
---@field DeathWeaponDamageAdd number
--- Used by RAS SACU to add radius to their death weapon
---@field DeathWeaponRadiusAdd number
--- Used by RAS SACU to add damage to their death weapon
---@field DeathWeaponDamageAdd number
--- Used by RAS SACU to add radius to their death weapon
---@field DeathWeaponDamageRadiusAdd number
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@engine/Core/Blueprints/UnitBlueprint.lua` around lines 955 - 958, The schema
definition in UnitBlueprint.lua declares the field as DeathWeaponRadiusAdd, but
the SACU enhancement blueprints in UAL0301_unit.bp, URL0301_unit.bp, and
XSL0301_unit.bp reference DeathWeaponDamageRadiusAdd instead. Change the field
name from DeathWeaponRadiusAdd to DeathWeaponDamageRadiusAdd in the schema
definition to match what the consumers are actually using, ensuring the contract
is unified and eliminating nil lookups when scripts attempt to access this
radius modifier field.

Comment thread loc/US/strings_db.lua
xsl0301_Rambo_help="Enhanced during construction with the enhanced sensor system, personal shield generator, and nano-repair system enhancements."
xsl0301_Rambo_name=""
xsl0301_RAS_desc="SACU (RAS preset)"
xsl0301_RAS_name=""

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟠 Major | ⚡ Quick win

Set xsl0301_RAS_name to a non-empty string.

xsl0301_RAS_name is empty here, but units/XSL0301/XSL0301_unit.bp references <LOC xsl0301_RAS_name> for the preset UnitName without fallback text, so this can surface as a blank preset label in UI.

💡 Proposed fix
-xsl0301_RAS_name=""
+xsl0301_RAS_name="SACU (RAS preset)"
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
xsl0301_RAS_name=""
xsl0301_RAS_name="SACU (RAS preset)"
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@loc/US/strings_db.lua` at line 90, The variable `xsl0301_RAS_name` is
currently set to an empty string, but it is referenced in
units/XSL0301/XSL0301_unit.bp for the preset UnitName field without a fallback
value, causing a blank label to appear in the UI. Replace the empty string
assignment for `xsl0301_RAS_name` with an appropriate non-empty string value
that describes the unit name.

Comment thread units/UAL0301/UAL0301_script.lua Outdated
Comment on lines +118 to +120
local deathNuke = self:GetWeaponByLabel("DeathWeapon") --[[@as SCUDeathWeapon]]
deathNuke:AddDamageMod(bp.DeathWeaponDamageAdd)
deathNuke:AddDamageRadiusMod(bp.DeathWeaponRadiusAdd)

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟠 Major | ⚡ Quick win

ResourceAllocation reads the wrong radius key, so death-nuke radius mod won’t apply/revert correctly.

These handlers use DeathWeaponRadiusAdd, but the enhancement blueprint contract uses DeathWeaponDamageRadiusAdd. This makes radius modification nil-driven and inconsistent between apply/remove.

Suggested fix
-        deathNuke:AddDamageRadiusMod(bp.DeathWeaponRadiusAdd)
+        deathNuke:AddDamageRadiusMod(bp.DeathWeaponDamageRadiusAdd)

-        deathNuke:AddDamageRadiusMod(-baseBp.DeathWeaponRadiusAdd)
+        deathNuke:AddDamageRadiusMod(-baseBp.DeathWeaponDamageRadiusAdd)

Also applies to: 130-133

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@units/UAL0301/UAL0301_script.lua` around lines 118 - 120, The
AddDamageRadiusMod method call is using the wrong blueprint key,
`DeathWeaponRadiusAdd`, when it should use `DeathWeaponDamageRadiusAdd` to match
the enhancement blueprint contract. Update the parameter passed to
AddDamageRadiusMod from bp.DeathWeaponRadiusAdd to bp.DeathWeaponDamageRadiusAdd
in both occurrences (around lines 120 and 133) to ensure the radius modification
is properly applied and reverted.

Comment thread units/URL0301/URL0301_script.lua Outdated
Comment on lines +206 to +208
local deathNuke = self:GetWeaponByLabel("DeathWeapon") --[[@as SCUDeathWeapon]]
deathNuke:AddDamageMod(bp.DeathWeaponDamageAdd)
deathNuke:AddDamageRadiusMod(bp.DeathWeaponRadiusAdd)

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟠 Major | ⚡ Quick win

Cybran RAS death-radius modifier key is mismatched with the blueprint field.

ProcessEnhancementResourceAllocation and its remove handler use DeathWeaponRadiusAdd, while units/URL0301/URL0301_unit.bp:362-374 defines DeathWeaponDamageRadiusAdd. Radius bonus/removal will not resolve correctly.

Suggested fix
-        deathNuke:AddDamageRadiusMod(bp.DeathWeaponRadiusAdd)
+        deathNuke:AddDamageRadiusMod(bp.DeathWeaponDamageRadiusAdd)

-        deathNuke:AddDamageRadiusMod(-baseBp.DeathWeaponRadiusAdd)
+        deathNuke:AddDamageRadiusMod(-baseBp.DeathWeaponDamageRadiusAdd)

Also applies to: 218-221

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@units/URL0301/URL0301_script.lua` around lines 206 - 208, The death weapon
radius modifier key in the AddDamageRadiusMod call references
bp.DeathWeaponRadiusAdd, but the blueprint defines the field as
DeathWeaponDamageRadiusAdd. Change the key from DeathWeaponRadiusAdd to
DeathWeaponDamageRadiusAdd in the AddDamageRadiusMod method call on line 208.
Apply the same fix to the remove handler at lines 218-221 where the
corresponding RemoveDamageMod call also needs to use the correct key
DeathWeaponDamageRadiusAdd instead of DeathWeaponRadiusAdd.

Comment thread units/XSL0301/XSL0301_script.lua Outdated
Comment on lines +109 to +111
local deathNuke = self:GetWeaponByLabel("DeathWeapon") --[[@as SCUDeathWeapon]]
deathNuke:AddDamageMod(bp.DeathWeaponDamageAdd)
deathNuke:AddDamageRadiusMod(bp.DeathWeaponRadiusAdd)

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟠 Major | ⚡ Quick win

Seraphim RAS handler uses a non-matching radius field name.

The script expects DeathWeaponRadiusAdd, but units/XSL0301/XSL0301_unit.bp:427-440 provides DeathWeaponDamageRadiusAdd. This prevents correct application/reversion of death-nuke radius changes.

Suggested fix
-        deathNuke:AddDamageRadiusMod(bp.DeathWeaponRadiusAdd)
+        deathNuke:AddDamageRadiusMod(bp.DeathWeaponDamageRadiusAdd)

-        deathNuke:AddDamageRadiusMod(-baseBp.DeathWeaponRadiusAdd)
+        deathNuke:AddDamageRadiusMod(-baseBp.DeathWeaponDamageRadiusAdd)

Also applies to: 121-124

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@units/XSL0301/XSL0301_script.lua` around lines 109 - 111, The
deathNuke:AddDamageRadiusMod() method call is using an incorrect blueprint field
name. Change the field reference from bp.DeathWeaponRadiusAdd to
bp.DeathWeaponDamageRadiusAdd to match the actual field name defined in the
blueprint file. This same correction needs to be applied in two places: once in
the initial death nuke setup around line 110, and again around line 121-124
where the radius modification is reverted.

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 1

🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@units/UEL0301/UEL0301_unit.bp`:
- Around line 267-268: The DeathWeaponDamageAdd and DeathWeaponRadiusAdd fields
are currently placed in the AdvancedCoolingUpgrade enhancement entry, but the
ProcessEnhancementResourceAllocation function in the script file expects these
death-weapon modifier fields to be in the ResourceAllocation enhancement entry
instead. Move the DeathWeaponDamageAdd and DeathWeaponRadiusAdd fields from the
AdvancedCoolingUpgrade section (lines 267-268) to the ResourceAllocation section
(lines 366 onward) to align the blueprint with the script's expectations for
death-weapon stat modifications.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro

Run ID: d00c0833-477d-4c07-8d8b-b539dd64bd23

📥 Commits

Reviewing files that changed from the base of the PR and between d9a7dd6 and 9e85a8c.

📒 Files selected for processing (22)
  • engine/Core/Blueprints/UnitBlueprint.lua
  • loc/CN/strings_db.lua
  • loc/CZ/strings_db.lua
  • loc/DE/strings_db.lua
  • loc/ES/strings_db.lua
  • loc/FR/strings_db.lua
  • loc/IT/strings_db.lua
  • loc/PL/strings_db.lua
  • loc/RU/strings_db.lua
  • loc/TW/strings_db.lua
  • loc/TZM/strings_db.lua
  • loc/US/strings_db.lua
  • lua/sim/AdjacencyBuffs.lua
  • lua/ui/help/unitdescription.lua
  • units/UAL0301/UAL0301_script.lua
  • units/UAL0301/UAL0301_unit.bp
  • units/UEL0301/UEL0301_script.lua
  • units/UEL0301/UEL0301_unit.bp
  • units/URL0301/URL0301_script.lua
  • units/URL0301/URL0301_unit.bp
  • units/XSL0301/XSL0301_script.lua
  • units/XSL0301/XSL0301_unit.bp
✅ Files skipped from review due to trivial changes (6)
  • lua/ui/help/unitdescription.lua
  • loc/IT/strings_db.lua
  • loc/CZ/strings_db.lua
  • loc/PL/strings_db.lua
  • loc/ES/strings_db.lua
  • loc/FR/strings_db.lua
🚧 Files skipped from review as they are similar to previous changes (15)
  • engine/Core/Blueprints/UnitBlueprint.lua
  • units/URL0301/URL0301_script.lua
  • units/XSL0301/XSL0301_script.lua
  • units/UAL0301/UAL0301_unit.bp
  • units/UAL0301/UAL0301_script.lua
  • units/URL0301/URL0301_unit.bp
  • lua/sim/AdjacencyBuffs.lua
  • units/UEL0301/UEL0301_script.lua
  • loc/TW/strings_db.lua
  • loc/DE/strings_db.lua
  • loc/RU/strings_db.lua
  • units/XSL0301/XSL0301_unit.bp
  • loc/TZM/strings_db.lua
  • loc/CN/strings_db.lua
  • loc/US/strings_db.lua

Comment on lines +267 to +268
DeathWeaponDamageAdd = 1000,
DeathWeaponRadiusAdd = 4,

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟠 Major | ⚡ Quick win

Death-weapon modifier fields are attached to the wrong enhancement entry.

units/UEL0301/UEL0301_script.lua applies death-weapon deltas in ProcessEnhancementResourceAllocation, but ResourceAllocation here has no DeathWeaponDamageAdd/DeathWeaponRadiusAdd fields (Line 366 onward), while those fields are on AdvancedCoolingUpgrade (Line 267-268). This breaks the blueprint/script contract and can skip or mis-handle the intended death-weapon stat changes.

Suggested fix
         AdvancedCoolingUpgrade = {
             BuildCostEnergy = 40000,
             BuildCostMass = 1000,
             BuildTime = 5060,
             Icon = "acu",
             Name = "<LOC enhancements_0061>Energy Accelerator",
             NewRateOfFire = 2,
             Slot = "LCH",
             UpgradeUnitAmbientBones = { "UEL0301" },
-            DeathWeaponDamageAdd = 1000,
-            DeathWeaponRadiusAdd = 4,
         },
@@
         ResourceAllocation = {
             BuildCostEnergy = 94400,
             BuildCostMass = 4600,
             BuildTime = 20550,
             Icon = "isb",
             Name = "<LOC enhancements_0069>Resource Allocation System",
             ProductionPerSecondEnergy = 1000,
             ProductionPerSecondMass = 10,
+            DeathWeaponDamageAdd = 1000,
+            DeathWeaponRadiusAdd = 4,
             ShowBones = { "SAM" },
             Slot = "RCH",
             UpgradeEffectBones = { "SAM" },
             UpgradeUnitAmbientBones = { "UEL0301" },
         },

Also applies to: 366-378

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@units/UEL0301/UEL0301_unit.bp` around lines 267 - 268, The
DeathWeaponDamageAdd and DeathWeaponRadiusAdd fields are currently placed in the
AdvancedCoolingUpgrade enhancement entry, but the
ProcessEnhancementResourceAllocation function in the script file expects these
death-weapon modifier fields to be in the ResourceAllocation enhancement entry
instead. Move the DeathWeaponDamageAdd and DeathWeaponRadiusAdd fields from the
AdvancedCoolingUpgrade section (lines 267-268) to the ResourceAllocation section
(lines 366 onward) to align the blueprint with the script's expectations for
death-weapon stat modifications.

@Rhaelya Rhaelya left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Changes work as intended.

@Rhaelya Rhaelya merged commit e28b0ce into FAForever:develop Jun 23, 2026
5 checks passed
@github-project-automation github-project-automation Bot moved this from To Test to Done in 2025 - Balance Iteration I Jun 23, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

area: balance idea related to suggestions for unit balance

Projects

Status: Done

Development

Successfully merging this pull request may close these issues.

3 participants