Put every research branch back in its own lane

#219 deleted the eight-node doctrine lane, which left the ship-lab branch
zigzagging between two lanes with nothing beside it - the same fault #70
fixed for squadron, where a chain that changed lane at depth collided with
somebody else's node. The tree runs as five straight lanes again: supply,
industry, spine, ground, vessels. No two nodes share a lane at one depth,
and every only-child stays in its parent's.

Fleet size is deliberately absent, which is why the widest lane is empty:
#219 moved it out of research and onto the Fleet Office. Said in the code so
the gap reads as a decision rather than as something dropped.

Also corrects wording #216 had made untrue: hubs no longer come with their
own transporters, and the two capacity doctrines buy a BERTH, not the vessel
to fill it.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_019AJMdB7iuHuLFZM1aBu3GD
This commit is contained in:
Loïc Wisniewski 2026-09-05 21:10:35 +02:00
commit 11773a63cf

View file

@ -501,15 +501,30 @@ var buildings: Array = []
# reach a ship crafter and an extractor with zero research points (see the # reach a ship crafter and an extractor with zero research points (see the
# closing comment on #63 for the reasoning); every other node - none of them # closing comment on #63 for the reasoning); every other node - none of them
# required for that opening - costs at least 1. # required for that opening - costs at least 1.
# LANES. A chain keeps one x as it rises, and a branch fans out once, at the
# node it branches from. That rule is why squadron was moved in #70 - it sat
# in someone else's lane at the same depth and the two nodes were drawn on top
# of each other - and #219 broke it again by deleting the whole doctrine lane,
# leaving the ship-lab branch zigzagging between 0.82 and 0.94 with nothing
# beside it.
#
# 0.10 supply logistics -> freight -> freight_yards
# 0.30 industry power_systems -> field_engineering -> drone_bays
# 0.50 spine shipyards -> coordination -> deep_space_scanning
# 0.70 ground forward_bases -> garrison_bays
# 0.90 vessels vessel_science -> logistics_command
#
# Fleet size is deliberately absent: #219 moved it out of research entirely
# and onto the Fleet Office, which is why the widest lane is now empty.
const SKILL_TREE: Array = [ const SKILL_TREE: Array = [
{ {
"id": "shipyards", "name": "Shipyards", "cost": 15, "requires": "", "id": "shipyards", "name": "Shipyards", "cost": 15, "requires": "",
"x": 0.5, "unlocks": BUILDING_SHIP_CRAFTER, "x": 0.50, "unlocks": BUILDING_SHIP_CRAFTER,
"desc": "Build ship crafters, and buy extra vessels at them.", "desc": "Build ship crafters, and buy extra vessels at them.",
}, },
{ {
"id": "logistics", "name": "Logistics", "cost": 25, "requires": "shipyards", "id": "logistics", "name": "Logistics", "cost": 25, "requires": "shipyards",
"x": 0.18, "unlocks": BUILDING_EXTRACTOR, "x": 0.10, "unlocks": BUILDING_EXTRACTOR,
"desc": "Build extractors on planets. They mine ore whether or not you are nearby.", "desc": "Build extractors on planets. They mine ore whether or not you are nearby.",
}, },
{ {
@ -524,7 +539,7 @@ const SKILL_TREE: Array = [
# start being able to hurt them. # start being able to hurt them.
"id": "forward_bases", "name": "Forward Bases", "cost": 30, "requires": "coordination", "id": "forward_bases", "name": "Forward Bases", "cost": 30, "requires": "coordination",
"costs": {"ore": 30, "gas": 12}, "costs": {"ore": 30, "gas": 12},
"x": 0.66, "unlocks": BUILDING_OUTPOST, "research_points": 1, "x": 0.70, "unlocks": BUILDING_OUTPOST, "research_points": 1,
"desc": "Build outposts: forward positions vessels can be stationed at, to hold ground you are not standing on.", "desc": "Build outposts: forward positions vessels can be stationed at, to hold ground you are not standing on.",
}, },
{ {
@ -533,7 +548,7 @@ const SKILL_TREE: Array = [
# researching it never means demolishing and rebuilding. # researching it never means demolishing and rebuilding.
"id": "garrison_bays", "name": "Garrison Bays", "cost": 110, "requires": "forward_bases", "id": "garrison_bays", "name": "Garrison Bays", "cost": 110, "requires": "forward_bases",
"costs": {"ore": 110, "gas": 35}, "costs": {"ore": 110, "gas": 35},
"x": 0.66, "outpost_bonus": 1, "research_points": 2, "x": 0.70, "outpost_bonus": 1, "research_points": 2,
"icon": 40, "icon": 40,
"desc": "Permanent: +1 berth at every outpost, including ones already built.", "desc": "Permanent: +1 berth at every outpost, including ones already built.",
}, },
@ -544,7 +559,7 @@ const SKILL_TREE: Array = [
# manages what shipyards do. # manages what shipyards do.
"id": "logistics_command", "name": "Logistics Command", "cost": 140, "id": "logistics_command", "name": "Logistics Command", "cost": 140,
"costs": {"ore": 140, "gas": 40}, "costs": {"ore": 140, "gas": 40},
"requires": "vessel_science", "x": 0.94, "requires": "vessel_science", "x": 0.90,
"unlocks": BUILDING_PLANNING_CENTER, "research_points": 3, "unlocks": BUILDING_PLANNING_CENTER, "research_points": 3,
"desc": "Build a planning center: set how many of each vessel should always exist, and the crafters are kept working until they do.", "desc": "Build a planning center: set how many of each vessel should always exist, and the crafters are kept working until they do.",
}, },
@ -554,7 +569,7 @@ const SKILL_TREE: Array = [
# arrive after the player has some worth looking after. # arrive after the player has some worth looking after.
"id": "field_engineering", "name": "Field Engineering", "cost": 95, "id": "field_engineering", "name": "Field Engineering", "cost": 95,
"costs": {"ore": 95, "gas": 35, "energy": 20}, "costs": {"ore": 95, "gas": 35, "energy": 20},
"requires": "power_systems", "x": 0.34, "requires": "power_systems", "x": 0.30,
"unlocks": BUILDING_WORKSHOP, "research_points": 2, "unlocks": BUILDING_WORKSHOP, "research_points": 2,
"desc": "Build spacial workshops. Their drones fly out and repair damaged structures, spending ore delivered to the workshop.", "desc": "Build spacial workshops. Their drones fly out and repair damaged structures, spending ore delivered to the workshop.",
}, },
@ -563,40 +578,40 @@ const SKILL_TREE: Array = [
# that reaches workshops already standing. # that reaches workshops already standing.
"id": "drone_bays", "name": "Drone Bays", "cost": 150, "id": "drone_bays", "name": "Drone Bays", "cost": 150,
"costs": {"ore": 150, "gas": 50, "energy": 35}, "costs": {"ore": 150, "gas": 50, "energy": 35},
"requires": "field_engineering", "x": 0.34, "requires": "field_engineering", "x": 0.30,
"workshop_bonus": 1, "research_points": 2, "icon": 43, "workshop_bonus": 1, "research_points": 2, "icon": 43,
"desc": "Permanent: +1 repair drone at every spacial workshop, including ones already built.", "desc": "Permanent: +1 berth at every spacial workshop, including ones already built. The drone to fill it is still yours to build.",
}, },
{ {
"id": "freight", "name": "Freight Handling", "cost": 40, "requires": "logistics", "id": "freight", "name": "Freight Handling", "cost": 40, "requires": "logistics",
"costs": {"ore": 40, "gas": 15}, "costs": {"ore": 40, "gas": 15},
"x": 0.18, "unlocks": BUILDING_TRANSPORT_HUB, "research_points": 1, "x": 0.10, "unlocks": BUILDING_TRANSPORT_HUB, "research_points": 1,
"desc": "Build transport hubs. Each hub includes its own automatic transporters.", "desc": "Build transport hubs. Transporters are built at a ship crafter and assigned to a hub, which then runs its routes without you.",
}, },
{ {
"id": "vessel_science", "name": "Vessel Science", "cost": 35, "requires": "shipyards", "id": "vessel_science", "name": "Vessel Science", "cost": 35, "requires": "shipyards",
"costs": {"ore": 35, "gas": 10}, "costs": {"ore": 35, "gas": 10},
"x": 0.82, "unlocks": BUILDING_SHIP_LAB, "research_points": 1, "x": 0.90, "unlocks": BUILDING_SHIP_LAB, "research_points": 1,
"desc": "Build ship labs, where each vessel type is upgraded and new ones unlocked.", "desc": "Build ship labs, where each vessel type is upgraded and new ones unlocked.",
}, },
{ {
"id": "deep_space_scanning", "name": "Deep-Space Scanning", "cost": 50, "id": "deep_space_scanning", "name": "Deep-Space Scanning", "cost": 50,
"costs": {"ore": 50, "gas": 15}, "costs": {"ore": 50, "gas": 15},
"requires": "coordination", "x": 0.34, "requires": "coordination", "x": 0.50,
"unlocks": BUILDING_PLANET_SCANNER, "research_points": 1, "unlocks": BUILDING_PLANET_SCANNER, "research_points": 1,
"desc": "Build a planet scanner and reveal the nearest world of a chosen type.", "desc": "Build a planet scanner and reveal the nearest world of a chosen type.",
}, },
{ {
"id": "freight_yards", "name": "Freight Yards", "cost": 80, "requires": "freight", "id": "freight_yards", "name": "Freight Yards", "cost": 80, "requires": "freight",
"costs": {"ore": 80, "gas": 30}, "costs": {"ore": 80, "gas": 30},
"x": 0.18, "hub_bonus": 1, "research_points": 2, "x": 0.10, "hub_bonus": 1, "research_points": 2,
"icon": 12, "icon": 12,
"desc": "Permanent: +1 transporter stationed at every hub, including ones already built.", "desc": "Permanent: +1 berth at every hub, including ones already built. The transporter to fill it is still yours to build.",
}, },
{ {
"id": "power_systems", "name": "Power Systems", "cost": 45, "requires": "freight", "id": "power_systems", "name": "Power Systems", "cost": 45, "requires": "freight",
"costs": {"ore": 45, "gas": 35}, "costs": {"ore": 45, "gas": 35},
"x": 0.50, "unlocks": BUILDING_GAS_BURNER, "research_points": 2, "x": 0.30, "unlocks": BUILDING_GAS_BURNER, "research_points": 2,
"desc": "Build gas burners. Each converts gas into energy at its own site - hub transporters keep it stocked and collect what it makes.", "desc": "Build gas burners. Each converts gas into energy at its own site - hub transporters keep it stocked and collect what it makes.",
}, },
] ]