Files
dota_factory/docs/balancing/derived.md
Malte Langkabel 51e45e10a1 Rename scrap-drop entity to "debris" in code and config
Implements the requirements rename in the codebase. The salvageable object
dropped by destroyed ships and defence stations is now the "debris" entity;
the scrap resource it yields (cargo, delivery, smelting, threat,
scrap_drop_formula, scrap_per_threat) is unchanged.

Entity renames: ScrapDataComponent->DebrisComponent, ScrapSystem->DebrisSystem,
ScrapInfo->DebrisInfo, ScrapSelectionChangedEvent->DebrisSelectionChangedEvent
(member scrap->debris), spawnScrap->spawnDebris, getScraps->getDebrisSystem,
getAllScrapInfo->getAllDebrisInfo, scrapAtWorldPos/scrapInBox->debris*,
SalvageScrapBehavior::scrapTarget->debrisTarget, PendingCollection::scrap->debris,
ScrapTest.cpp->DebrisTest.cpp. Config key scrap_despawn_seconds->
debris_despawn_seconds (WorldConfig.scrapDespawnSeconds->debrisDespawnSeconds).
The salvage/deliver behavior classes keep their names (they act on the scrap
resource).

Also implements the new REQ-UI-DEBRIS-PANEL behavior in SelectedBuildingPanel:
a single selected piece of debris shows a "Debris" heading plus a "Scrap" stat
row; a multi/mixed field selection appends "Debris x N" and "Scrap x N" lines.

Updates the four renamed REQ-ID references in comments/docs, plus architecture.md
and derived.md. All 449 test cases pass; app, tests, and balancing targets build.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01Y7N59FsLA5e2kuVdqe4Uhc
2026-07-23 13:10:04 +02:00

7.8 KiB
Raw Blame History

Derived Values (current tuned state)

Everything here is derived from targets.md under the rules in rules.md, and mirrors the config files. Item threats, ship threats, ratios, and belt checks are verified by tools/threat_report.py — re-run it after any recipe or material change and update this file when values move. Combat stats were tuned empirically against the arena suite in bin/balancing/data/balancing.toml (round-by-round record in history.md).

Economy constants

  • scrap_per_threat = 0.25 — 1 scrap per 4 threat destroyed (a cruiser kill drops ~59 scrap); threat(scrap) = 4.
  • Scrap smelting: 1 scrap → 1 iron_ingot, 1 s — deliberately value-losing; reprocessing is the value-preserving path.
  • Reprocessing: 4 scrap per cycle, 4 s; full-pool weights iron_ingot 30 / copper_ingot 30 / silicon 20 / voidsteel 20 → threat(voidsteel) = (4·4 + 4)/0.2 = 100.
  • debris_despawn_seconds = 120 (a capital kill drops hundreds of scrap, collected one per salvage cycle).

Recipes and item threats

(dur in seconds; threat is per output unit)

item recipe dur out threat
iron_ore / copper_ore miner 1 1 1
quartz miner (deposit) 2 1 2
iron_ingot 1 iron_ore 1 1 2
copper_ingot 1 copper_ore 1 1 2
silicon 1 quartz 2 1 4
steel_plate 2 iron_ingot 3 1 7
copper_wire 1 copper_ingot 1 2 1.5
copper_coil 2 copper_wire 1.5 1 4.5
building_block 2 steel_plate 2 4 4
control_chip 1 silicon + 2 copper_wire 5 1 12
capacitor_bank 2 copper_coil + 1 silicon 5 1 18
hardened_steel 3 steel_plate 12 1 33
ceramic_plate 2 quartz 4 1 8
drive_unit 2 steel_plate + 2 copper_coil + 1 control_chip 8 1 43
voidsteel_plate 1 voidsteel + 1 hardened_steel 8 1 141
capital_core 2 voidsteel + 1 capacitor_bank + 1 control_chip 10 1 240

Shortcut recipes (drop-only; item threat stays defined by the base path via the max rule): shortcut_steel_plate 3 iron_ore → 1 plate (2 s, level 1), shortcut_control_chip 2 quartz → 1 chip (4 s, level 2), shortcut_hardened_steel 4 iron_ingot → 1 hardened (8 s, level 2).

Ratio curve realized: t1 all 1:1 (miner:smelter); t2 clean 2:3 (ingot→plate, wire→coil); t3 strange — 2:5 (silicon→chip), 3:5 (coil→capacitor), 3:4 (plate→hardened, plate→drive); t4 inverted 3:2 (hardened→voidsteel_plate). Belt check: worst input demand 1.33 items/s, under the ~2/s single-belt cap everywhere.

Module prefabs

(contribution = item threat + module production time)

module recipe dur mod. time contribution
railgun_s 1 copper_coil 1 1 6.5
salvager 1 steel_plate + 2 copper_wire 2 1 13
repair_tool 1 steel_plate + 2 copper_wire 2 1 13
armor_plates 4 steel_plate 3 1 32
maneuvering_thrusters 1 steel_plate + 1 copper_coil 2 1 14.5
sensor_booster 2 copper_wire + 1 copper_coil 2 1 10.5
afterburner 2 copper_coil + 1 steel_plate 3 1 20
weapon_stabilizer 1 steel_plate + 1 copper_coil 2 1 14.5
weapon_primer 1 capacitor_bank + 1 copper_coil 4 2 28.5
weapon_upgrade 1 control_chip + 1 copper_coil 4 2 22.5
railgun_m 1 capacitor_bank + 2 steel_plate + 1 copper_coil 4 3 43.5
drone_bay 1 control_chip + 2 steel_plate + 1 copper_coil 4 3 37.5
railgun_l 1 capacitor_bank + 2 hardened_steel + 1 ceramic_plate 6 4 102
drone_hangar 1 voidsteel_plate + 2 control_chip + 1 drive_unit 10 6 224

Ships

(fitted = hull item + ship base time + default loadout; the default loadouts are the default_modules used by enemy waves and are geometry-validated against the hull grids)

ship hull recipe dur base default loadout fitted
drone 1 iron_ingot 1 1 railgun_s 10.5
frigate 2 steel_plate + 1 copper_wire 2 2 2× railgun_s, maneuvering_thrusters 47
destroyer 3 steel_plate + 2 copper_coil 4 3 3× railgun_s, armor_plates, sensor_booster 99
cruiser 2 hardened_steel + 2 control_chip 6 4 2× railgun_m, armor_plates, maneuvering_thrusters 233.5
battlecruiser 3 hardened_steel + 2 control_chip + 1 drive_unit 8 5 3× railgun_m, armor_plates, 2× railgun_s 354.5
battleship 3 voidsteel_plate + 1 drive_unit + 2 control_chip 10 6 railgun_l, 2× railgun_m, weapon_stabilizer, 2× railgun_s 722.5
dreadnought 5 voidsteel_plate + 1 capital_core + 2 drive_unit 12 8 3× railgun_l, 4× armor_plates, railgun_s 1491.5
carrier 5 voidsteel_plate + 1 capital_core + 2 drive_unit 12 8 drone_hangar, 2× railgun_m, 2× armor_plates, sensor_booster 1436.5

Combat stats

(arena-converged, 2026-07; see history.md rounds 15)

Weapons: railgun_s 2 dmg × 2.0 Hz (4.0 DPS), range 50 m; railgun_m 14 × 1.5 (21), range 70; railgun_l 52 × 0.8 (41.6), range 100.

Hull HP (15/threat prior + empirical trims): drone 60, frigate 300, destroyer 550, cruiser 1500, battlecruiser 2400, battleship 6300, dreadnought/carrier 24000.

Mobility ladder (speed m/s | main accel | maneuvering | angular | max rot): drone 45|60|30|12|6, frigate 35|45|22|8|4, destroyer 30|35|18|6|3, cruiser 24|25|12|4|2, battlecruiser 20|20|10|3|1.5, battleship 15|14|7|2|1, dreadnought/carrier 10|8|4|1|0.5. Sensors: 150/200/220/250/260/280/300/350 m.

Other modules: armor_plates +1200 HP; repair_tool 9 HP × 1 Hz, range 80; salvager range 60, cargo 20, 0.5 collections/s; afterburner ×1.6 speed +60 accel; maneuvering_thrusters ×1.2 speed +10 maneuvering; sensor_booster +50 m; weapon_upgrade ×1.2 damage; weapon_primer ×1.2 rate; weapon_stabilizer ×1.3 range ×0.8 rate.

Stations: HQ 5000 HP. Player station 3000 HP, 25 dmg × 1 Hz, range 120, scrap 40. Enemy station: 3000+1500x HP, 25+12x dmg, 1.0+0.1x Hz, range 120, scrap 40+30x (x = push level).

Pacing

Unlock ladder (level → unlocks; ← marks unlock_requires; starting set at 1: drone, frigate, railgun_s, salvager, building_block recipe):

level ships modules recipes
0 destroyer repair_tool, armor_plates
1 maneuvering_thrusters, sensor_booster shortcut_steel_plate
2 cruiser railgun_m, afterburner shortcut_control_chip, shortcut_hardened_steel
3 weapon_stabilizer
4 battlecruiser ← cruiser weapon_primer, weapon_upgrade
5 drone_bay
6 battleship ← battlecruiser railgun_l ← railgun_m
8 dreadnought ← battleship
9 carrier ← battleship drone_hangar

Level 0's pool has exactly three entries (a full first dialog). Level 2 is the quartz gate: cruiser and railgun_m are the first schematics whose chains reach quartz; the shortcut outputs only become implicitly unlocked alongside them, so shortcuts cannot drop early.

Threat rate 2*x + 0.15*x*x (x = boss cycle counter), against the factory-size curve with ~half the player's output assumed military:

cycle x rate (threat/s) player military (≈ curve/2)
2 4.6 ~12
6 17.4 ~30
15 63.8 ~60
20 100 ~75
24 134

Economy: starting_building_blocks = 200; expansion cost formula 300 + 50*x + 10*x*x (x = expansions already purchased: ~1 affordable per cycle mid-game at ~1/3 of block income, stretching to 23 cycles late — quadratic so costs outrun the roughly linear block income gradually, never with a hard wall); artifact_win_count = 5 with artifact_chance_formula = 0.05*x. Building costs: belt 2, splitter 3, tunnels 5, miner 15, smelter 20, assembler 35, reprocessing plant 40, salvage bay 25, shipyard 60 — averaging ≈18 blocks per placed building (belts included), which meets the 4-minute doubling target at block threat 4.