From fe7703d5c36d3bca21c5c9531a9574e4f97d81ff Mon Sep 17 00:00:00 2001 From: Malte Langkabel Date: Fri, 3 Jul 2026 15:05:40 +0200 Subject: [PATCH] Add first numbers pass for the v2 production tree content_design.md: full recipe quantities and durations computed with a recursive threat calculator - economy constants (scrap_per_threat 0.25, reprocessing 4 scrap / 4 s, voidsteel at threat 100), per-item threat values, module contributions, and fitted ship threats vs the ladder (96-124%, smooth ~x2-per-class curve). Checks recorded: ratio curve realized (t1 1:1, t2 2:3, t3 strange), belt feasibility under the single-belt cap, block at 4 threat implying ~18 blocks average building cost for the 4-minute doubling target, and a small-end deviation note recommending ladder adjustment over chain thinning. progression_design.md: two new action items - amend REQ-THREAT-ITEM to exclude scrap-consuming recipes from item threat (the max rule would otherwise inflate basic materials via the scrap smelting recipe), and port the calculator to tools/threat_report.py. Co-Authored-By: Claude Fable 5 Claude-Session: https://claude.ai/code/session_01DyCu8vwChKMbLJQ3xosYEN --- docs/content_design.md | 95 ++++++++++++++++++++++++++++++++++++++ docs/progression_design.md | 13 ++++++ 2 files changed, 108 insertions(+) diff --git a/docs/content_design.md b/docs/content_design.md index ee69062..0364ff3 100644 --- a/docs/content_design.md +++ b/docs/content_design.md @@ -339,6 +339,101 @@ first-pass tree. `verify_recipes.py` must be re-run once this lands in recipes.toml; the numbers pass should add a threat-report tool that prints per-item threat values and producer:consumer ratio tables. +### Numbers — first pass + +Computed with a recursive threat calculator (to be ported to +`tools/threat_report.py`, see the action items in +`progression_design.md`); quantities and durations tuned so fitted +ships land on the threat-cost ladder and the ratio curve is realized. + +**Economy constants:** `scrap_per_threat = 0.25` (1 scrap per 4 threat +destroyed — a cruiser kill drops ~59 scrap). 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. +Scrap smelting: 1 scrap → 1 iron_ingot, 1 s — deliberately +value-losing (4 threat of scrap becomes a 2-threat ingot); reprocessing +is the value-preserving path. + +**Recipes** (dur in seconds; threat is per output item): + +| 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 | + +**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 + typical loadout; the +typical loadouts double as the `default_modules` for enemy waves): + +| ship | hull recipe | dur | base | typical loadout | fitted (target) | +|---|---|---|---|---|---| +| drone | 1 iron_ingot | 1 | 1 | railgun_s | 10 (10) | +| frigate | 2 steel_plate + 1 copper_wire | 2 | 2 | 2× railgun_s, maneuvering_thrusters | 47 (40) | +| destroyer | 3 steel_plate + 2 copper_coil | 4 | 3 | 3× railgun_s, armor_plates, sensor_booster | 99 (80) | +| cruiser | 2 hardened_steel + 2 control_chip | 6 | 4 | 2× railgun_m, armor_plates, maneuvering_thrusters | 234 (200) | +| battlecruiser | 3 hardened_steel + 2 control_chip + 1 drive_unit | 8 | 5 | 3× railgun_m, weapon_primer, armor_plates | 370 (350) | +| battleship | 3 voidsteel_plate + 1 drive_unit + 2 control_chip | 10 | 6 | railgun_l, 2× railgun_m, weapon_stabilizer, armor_plates, sensor_booster | 752 (700) | +| dreadnought | 5 voidsteel_plate + 1 capital_core + 2 drive_unit | 12 | 8 | 3× railgun_l, weapon_primer, weapon_upgrade, 2× armor_plates | 1472 (1500) | +| carrier | 5 voidsteel_plate + 1 capital_core + 2 drive_unit | 12 | 8 | drone_hangar, 2× railgun_m, 2× armor_plates, sensor_booster | 1436 (1500) | + +**Checks:** + +- *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 feasibility:* worst input demand is 1.33 items/s (wire→coil, + plate→armor) — under the ~2/s single-belt cap everywhere; no + accidental multi-belt recipes. +- *Block economy:* building_block = 4 threat ⇒ for the 4-minute + doubling at 30% capacity, the average building must cost ≈ 18 blocks + (0.3 × 240 / 4). buildings.toml costs should be set around that mean + (belts cheap, producers ~20–30). +- *Small-end deviation:* frigate–cruiser land 6–24% hot because the + fixed chain overhead dominates small hulls. Recommendation: accept + and adjust the ladder targets to the achieved values (the ~×2-per- + class curve shape is preserved) rather than thinning the early + chains below readability. +- *Rule bug discovered:* the scrap→iron_ingot smelter recipe combined + with REQ-THREAT-ITEM's max-across-recipes rule would set + threat(iron_ingot) to the scrap path (1 + 4 = 5, or more at other + scrap values) instead of 2, inflating every downstream item. Fix + required: exclude scrap-consuming recipes from item threat + computation (see progression_design.md action items). + ## Balancing targets (first pass, July 2026) The six root numbers for the balancing pass. Every derived value (threat diff --git a/docs/progression_design.md b/docs/progression_design.md index 6e9fb17..74ec2d2 100644 --- a/docs/progression_design.md +++ b/docs/progression_design.md @@ -373,3 +373,16 @@ in `requirements.md` and the git history). Still open: one matching deposit tile). Touches REQ-BLD-MINER ("every asteroid tile is equivalent" no longer holds), REQ-GW-ASTEROID-EXPAND / REQ-EXP-*, `world.toml`, and `visuals.toml`. +6. **Exclude scrap-consuming recipes from item threat.** Amend + REQ-THREAT-ITEM: recipes that take scrap as an input do not + participate in an item's threat computation (neither as its value + nor in the max-across-recipes rule). Otherwise the scrap→ingot + smelter recipe inflates the basic materials' threat via the max + rule, poisoning every downstream value. Scrap conversion is already + accounted for by the REQ-THREAT-SCRAP constant. +7. **Threat report tool.** Port the numbers-pass calculator to + `tools/threat_report.py`: per-item threat values, module + contributions, fitted ship threats vs. the ladder targets, + producer:consumer ratio tables, and belt-feasibility checks, read + from the real config files. Re-run after any recipe or material change, like + `verify_recipes.py`.