Pacing pass: unlock ladder, threat rate, economy values

Replace the everything-at--1 test setup with the real progression:
starting set is exactly drone/frigate/railgun_s/salvager; the ladder
runs destroyer+repair+armor at level 0, supports at 1, the quartz gate
(cruiser, railgun_m, afterburner, chip/hardened shortcuts) at 2,
battlecruiser at 4, battleship+railgun_l at 6, dreadnought at 8,
carrier+drone_hangar at 9, with unlock_requires edges cruiser ->
battlecruiser -> battleship -> dreadnought/carrier and railgun_m ->
railgun_l.

world.toml: threat_rate_formula 2*x + 0.15*x*x (below the player's
achievable military output early, crossing at the late boundary,
overwhelming by cycle ~24), starting_building_blocks 1000 -> 200,
expansion cost 200 -> 400 flat (placeholder until action item 4),
artifact_win_count 3 -> 5 (winning means choosing the artifact over a
schematic five times across ~7 cumulative offers).

Bug fix found during the pass: the building_block recipe carried no
unlock_at_station_level, and since building blocks appear in no
schematic's materials, implicit unlocking could never reach it - the
recipe was silently locked at game start. Now explicitly -1.

All values and derivations documented in content_design.md, "Pacing
pass - first values".

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01DyCu8vwChKMbLJQ3xosYEN
This commit is contained in:
2026-07-04 12:49:35 +02:00
parent 27c3a7b65b
commit f62b7bb78e
5 changed files with 92 additions and 22 deletions

View File

@@ -47,7 +47,7 @@ attack_rate_hz = 2.0
[[module]]
id = "railgun_m"
unlock_at_station_level = 1
unlock_at_station_level = 2
surface_mask = [
"OO",
"OO"]
@@ -64,7 +64,7 @@ attack_rate_hz = 1.5
[[module]]
id = "railgun_l"
unlock_at_station_level = 1
unlock_at_station_level = 6
unlock_requires = ["railgun_m"]
surface_mask = [
"OOO",
@@ -101,7 +101,7 @@ collection_rate_hz = 0.5
[[module]]
id = "repair_tool"
unlock_at_station_level = -1
unlock_at_station_level = 0
surface_mask = ["O"]
materials = [{item = "repair_tool_module", amount = 1}]
production_time_seconds = 1
@@ -119,7 +119,7 @@ repair_range_m = 80
[[module]]
id = "afterburner"
unlock_at_station_level = -1
unlock_at_station_level = 2
surface_mask = ["OOO"]
materials = [{item = "afterburner_module", amount = 1}]
production_time_seconds = 1
@@ -133,7 +133,7 @@ added_main_acceleration_mpss = 60
[[module]]
id = "maneuvering_thrusters"
unlock_at_station_level = -1
unlock_at_station_level = 1
surface_mask = ["OO"]
materials = [{item = "maneuvering_thrusters_module", amount = 1}]
production_time_seconds = 1
@@ -150,7 +150,7 @@ added_maneuvering_acceleration_mpss = 10
[[module]]
id = "armor_plates"
unlock_at_station_level = -1
unlock_at_station_level = 0
surface_mask = ["OO"]
materials = [{item = "armor_plates_module", amount = 1}]
production_time_seconds = 1
@@ -163,7 +163,7 @@ added_hp = 1200
[[module]]
id = "sensor_booster"
unlock_at_station_level = -1
unlock_at_station_level = 1
surface_mask = ["OO"]
materials = [{item = "sensor_booster_module", amount = 1}]
production_time_seconds = 1
@@ -179,7 +179,7 @@ added_sensor_range_m = 50
[[module]]
id = "weapon_upgrade"
unlock_at_station_level = -1
unlock_at_station_level = 4
surface_mask = [
"OO",
"OX",
@@ -195,7 +195,7 @@ multiplied_damage = 1.2
[[module]]
id = "weapon_primer"
unlock_at_station_level = -1
unlock_at_station_level = 4
surface_mask = [
"OO",
"OX",
@@ -211,7 +211,7 @@ multiplied_attack_rate_hz = 1.2
[[module]]
id = "weapon_stabilizer"
unlock_at_station_level = -1
unlock_at_station_level = 3
surface_mask = [
"OO",
"OX",
@@ -234,7 +234,7 @@ multiplied_attack_rate_hz = 0.8
[[module]]
id = "drone_bay"
unlock_at_station_level = -1
unlock_at_station_level = 5
surface_mask = [
"OO",
"OO"]
@@ -246,7 +246,7 @@ glyph = "Db"
[[module]]
id = "drone_hangar"
unlock_at_station_level = -1
unlock_at_station_level = 9
surface_mask = [
"OOOOOO",
"OOOOOO"]

View File

@@ -142,8 +142,11 @@ duration_seconds = 1.5
# Depth-3 chain (ore -> ingot -> plate -> block) is the factory's
# doubling-time knob; see the block economy rules in progression_design.md.
# Explicitly unlocked at start (-1): building blocks appear in no
# schematic's materials, so implicit unlocking can never reach this recipe.
[[recipe]]
id = "building_block"
unlock_at_station_level = -1
building = "assembler"
inputs = [{item = "steel_plate", amount = 2}]
outputs = [{item = "building_block", amount = 4}]

View File

@@ -84,7 +84,7 @@ sensor_range_m = 200
# mount medium hardware.
[[ship]]
id = "destroyer"
unlock_at_station_level = -1
unlock_at_station_level = 0
layout = [
"OXOXO",
"OOOOO",
@@ -120,7 +120,7 @@ sensor_range_m = 220
# supports; no 3x3 area exists for an l gun.
[[ship]]
id = "cruiser"
unlock_at_station_level = -1
unlock_at_station_level = 2
layout = [
"XOOX",
"OOOO",
@@ -158,7 +158,8 @@ sensor_range_m = 250
# stern leave no 3x3 area for an l gun and no 2x6 area for a drone hangar.
[[ship]]
id = "battlecruiser"
unlock_at_station_level = -1
unlock_at_station_level = 4
unlock_requires = ["cruiser"]
layout = [
"OOXXOO",
"OOOOOO",
@@ -200,7 +201,8 @@ sensor_range_m = 260
# so no 2x6 drone hangar fits.
[[ship]]
id = "battleship"
unlock_at_station_level = 1
unlock_at_station_level = 6
unlock_requires = ["battlecruiser"]
layout = [
"XOOOOX",
"OOOOOO",
@@ -242,7 +244,7 @@ sensor_range_m = 280
# stay the only hangar hull. Bow and stern strips hold supports.
[[ship]]
id = "dreadnought"
unlock_at_station_level = 2
unlock_at_station_level = 8
unlock_requires = ["battleship"]
layout = [
"XXXOOOOOXXX",
@@ -286,7 +288,8 @@ sensor_range_m = 300
# the lower decks hold supports and 2x2 point-defense m guns.
[[ship]]
id = "carrier"
unlock_at_station_level = -1
unlock_at_station_level = 9
unlock_requires = ["battleship"]
layout = [
"XOOOOOOOOX",
"OOOOOOOOOO",

View File

@@ -1,7 +1,7 @@
[world]
height_tiles = 40
refund_percentage = 100
starting_building_blocks = 1000
starting_building_blocks = 200
scrap_despawn_seconds = 120
scrap_per_threat = 0.25
tile_size_m = 10
@@ -19,7 +19,9 @@ enemy_buffer_width_tiles = 20
[expansion]
columns_per_expansion_tiles = 10
cost_building_blocks = 200
# Flat until the escalating cost formula lands (progression_design.md
# action item 4).
cost_building_blocks = 400
[push]
push_expand_columns_tiles = 10
@@ -32,10 +34,13 @@ target_hysteresis = 0.40 # keep current target unless
[artifacts]
artifact_chance_formula = "0.05 * x" # 5% chance per station level
artifact_win_count = 3
artifact_win_count = 5
[waves]
threat_rate_formula = "x"
# Tuned against the factory-size curve (content_design.md, balancing
# targets): stays below the player's achievable military output early,
# crosses it around the late boundary (~cycle 15), overwhelms by ~24.
threat_rate_formula = "2*x + 0.15*x*x"
gap_min_seconds = 15
gap_max_seconds = 45
spawn_duration_seconds = 10

View File

@@ -580,6 +580,65 @@ breakable). Round-3 knob changes: stabilizer range ×1.5→×1.3, and
per-hull HP trims — battlecruiser 2700→2500, battleship 7500→7000,
dreadnought/carrier 15500→19000.
### Pacing pass — first values
The mapping between station levels and boss cycles: at the intended
push cadence (first set around cycle 23, roughly one per cycle from
mid on), the destroyed set's level is reached around cycle +2. So
level 2 ≈ the mid boundary, level 6 ≈ mid-late, levels 89 ≈ capitals
with enough cycles left to ramp voidsteel production before late.
**Starting set** (`unlock_at_station_level = -1`), per the starting-set
rule (exactly enough to reach the first push): drone, frigate,
railgun_s, salvager. Note: the building_block recipe must carry an
explicit `-1` — building blocks appear in no schematic's materials, so
implicit unlocking can never reach it (fixed in this pass; it was
silently locked).
**Unlock ladder** (level → unlocks; ← marks `unlock_requires`):
| 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, so the first push offers a
full dialog with no artifacts competing. Level 2 is the quartz gate:
cruiser and railgun_m are the first schematics whose chains reach
quartz (the shortcut recipes' outputs only become implicitly unlocked
alongside them, so they cannot drop early).
**Threat rate** `2*x + 0.15*x*x`, tuned against the factory-size curve
with roughly 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 | — |
Below the player early, crossing at the late boundary, overwhelming by
~24 — the endless-race shape from the progression rules. Typical wave
at x=6 (30 s gap): ~520 threat ≈ two cruisers plus escorts; boss at
x=15: ~3800 threat ≈ two and a half dreadnoughts.
**Economy**: `starting_building_blocks` 1000 → 200 (minimal block loop
+ first shipyard ≈ 150, plus beginner slack); expansion cost 200 → 400
flat (placeholder until the escalating formula, action item 4);
`artifact_win_count` 3 → 5 with chance `0.05*x`: ~1518 pushes in a
winning run offer ~7 artifact options cumulatively, so winning takes
choosing the artifact over a schematic five times — a real decision
each time, and the win lands in the cycle 2024 target window.
## Balancing targets (first pass, July 2026)
The six root numbers for the balancing pass. Every derived value (threat