feat(ui): add system population and GDP to star map info panel (#785)

Star map popup now shows POPULATION and GDP rows when data is present.
Generation script updated to compute GDP from population × tier-based
per-capita schedule. 275/301 systems have GDP data (26 uninhabited
correctly omitted).

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
2026-04-10 13:22:10 +02:00
co-authored by Claude Opus 4.6
parent 9d9ea96be1
commit 766da969de
3 changed files with 327 additions and 3 deletions
File diff suppressed because it is too large Load Diff
+6 -3
View File
@@ -507,10 +507,13 @@ func _rebuild_info_panel() -> void:
# Population + GDP
var population: String = node.get("population", "")
if not population.is_empty():
var gdp: String = node.get("gdp", "")
if not population.is_empty() or not gdp.is_empty():
_info_panel.add_component(ImplantDataRow.new("")) # blank line spacer
_info_panel.add_component(ImplantDataRow.new("pop " + population))
_info_panel.add_component(ImplantDataRow.new("GDP —"))
if not population.is_empty():
_info_panel.add_component(ImplantDataRow.new("pop " + population))
var gdp_label: String = "gdp " + (gdp if not gdp.is_empty() else "")
_info_panel.add_component(ImplantDataRow.new(gdp_label))
# ── GTTR excerpt ─────────────────────────────────────────────────────────
var gttr: String = node.get("gttr_excerpt", "")
+46
View File
@@ -106,6 +106,45 @@ def parse_gttr_excerpt(system_id: str) -> str:
return " ".join(paragraph_lines)
GDP_PER_CAPITA: dict = {
5: 75_000,
4: 40_000,
3: 15_000,
2: 5_000,
1: 2_000,
0: 500,
}
def infer_tier_from_population(pop: int) -> int:
"""Infer an economic tier from total population when no explicit tier is set."""
if pop >= 5_000_000_000:
return 5
if pop >= 1_000_000_000:
return 4
if pop >= 200_000_000:
return 3
if pop >= 10_000_000:
return 2
return 1
def compute_gdp(total_pop: int, economic_tier: int | None) -> str:
"""Return a formatted GDP string in Tractus, or empty string if no population."""
if total_pop == 0:
return ""
tier = economic_tier if economic_tier is not None else infer_tier_from_population(total_pop)
per_cap = GDP_PER_CAPITA.get(tier, GDP_PER_CAPITA[1])
value = total_pop * per_cap
if value < 1_000_000_000:
return f"{value / 1_000_000:.1f} MTr"
if value < 1_000_000_000_000:
return f"{value / 1_000_000_000:.1f} BTr"
if value < 1_000_000_000_000_000:
return f"{value / 1_000_000_000_000:.1f} TTr"
return f"{value / 1_000_000_000_000_000:.1f} QTr"
def build_adjacency(edges: list) -> dict:
"""Build a map from system_id to list of adjacent system_ids from edges."""
adj: dict = {}
@@ -162,6 +201,10 @@ def generate() -> dict:
GROUP BY system_id
""")
station_stats = {row["system_id"]: dict(row) for row in cur.fetchall()}
# Economic tier for GDP calculation
cur.execute("SELECT system_id, economic_tier FROM system_economy")
econ_tiers = {row["system_id"]: row["economic_tier"] for row in cur.fetchall()}
conn.close()
adjacency = build_adjacency(star_map["edges"])
@@ -204,6 +247,9 @@ def generate() -> dict:
entry["bodies"] = "%d habitable · %d inhabited" % (hab, inh)
entry["population"] = "{:,}".format(total_pop)
gdp_str = compute_gdp(total_pop, econ_tiers.get(sid))
if gdp_str:
entry["gdp"] = gdp_str
if gttr:
entry["gttr_excerpt"] = gttr
if n.get("is_gateway"):