Files
dota_factory/docs/balancing
Malte Langkabel 9c275e283c give every recipe one shape: a list of output groups
Implements REQ-MAT-OUTPUT-GROUP. A recipe had two shapes -- outputs produced
together, or outputs of which exactly one happened -- and every rule over them
was written twice, selected by `building == ReprocessingPlant`: sizing a
buffer, deciding whether a cycle fits, resolving what a cycle makes, costing an
item. RecipeDef now holds output groups, each a weight and a list of items, and
a cycle yields exactly one group. One group is the ordinary recipe, so the old
two cases are the same shape with one and with several, and all four rules
collapse to one expression apiece with no building-type test left.

rollReprocessingOutput becomes rollOutputGroup, where a single group returns
without drawing or testing eligibility. That early-out is load-bearing twice
over. Drawing there would consume entropy for every ordinary recipe and shift
every later random outcome; and eligibility must not apply either, since
implicit unlocking is demand-derived, so an ordinary recipe's output can be
producible while nothing yet calls for it -- testing it would stop the building
producing rather than gate a drop. Past the early-out a group is eligible only
when all of its items are unlocked, being produced whole.

Threat follows the recipe's shape rather than the building, and the per-unit
value now divides by the group's amount as well as its odds. That moves no
number today: every item resolved through this path has amount 1, which is why
the threat expectations are untouched.

Config keeps `outputs = [...]` as the single-group form, so only the two
reprocessing recipes change shape. The recipe summary gains "/" between groups
and keeps "+" within one, which also fixes the plant reading as though a cycle
produced all of its items at once.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01Ne3mejABZoLWKLh8fgpM3x
2026-08-17 12:47:09 +02:00
..

Balancing Documentation

Everything about balancing Dota Factory, separated by role:

  • rules.md — the design rules and principles. Timeless; changes only when the design changes.
  • targets.md — the base numbers (roots/anchors) chosen by design. Change these first; everything else re-derives.
  • derived.md — the current tuned state of all derived numbers, mirroring the configs. Updated whenever configs change.
  • process.md — how balancing is done: the pass order, tuning discipline, tools, and the checklist for the next round.
  • history.md — chronological record of decisions, findings, bugs, and arena rounds.

Related: game content (hull grids, footprint gating, tree design and fiction) in ../content_design.md; rules with REQ-* ids in ../requirements.md.

Status

First full balancing round complete (2026-07-06): targets → tree → numbers → threat-calculator parity → combat stats (arena-converged) → pacing. Next step: full-game playtests against the run-shape targets in targets.md.

Open action items

Agreed changes that require edits to requirements.md, the code, or the configs. Completed items are removed (their outcomes live in requirements.md, history.md, and the git history).

  1. Fill unfillable schematic slots with artifacts. With duplicates removed, the schematic drop pool can run dry — previously unreachable. Decision: every slot in the choice dialog that cannot be filled with a schematic because the eligible pool is exhausted is filled with an artifact option instead (in addition to any artifact option granted by the regular artifact roll). A push therefore always awards a full dialog. Update REQ-DEF-SCHEMATIC-DROP.
  2. Confirm wave scaling in playtests. threat_rate_formula is the only time-scaling axis; verify the tuned curve (see derived.md) produces the intended difficulty race in real runs.
  3. Gate shortcut-recipe drops on their inputs. Extend the assembler recipe schematic pool eligibility in REQ-DEF-SCHEMATIC-DROP: in addition to the existing station-level and output-item checks, all of the recipe's input item types must be implicitly unlocked as well.
  4. Resource deposits. Add a terrain deposit layer per the Resource deposits rules (rules.md): deposit patches generated in expansion columns (deterministic content per expansion, randomized placement within the new columns), deposit rendering, and a miner condition (a resource recipe is selectable only if the miner's footprint overlaps at least 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. Until this lands, quartz mines anywhere and the mid-game is knowledge-gated only.