From f17a6c638c458c65b78709dde36eb487e9517011 Mon Sep 17 00:00:00 2001 From: Jeroen Schweitzer Date: Fri, 10 Apr 2026 13:22:30 +0200 Subject: [PATCH] =?UTF-8?q?feat(ui):=20economics=20debug=20console=20comma?= =?UTF-8?q?nds=20=E2=80=94=20inject,=20param,=20inspect=20(#825)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Three new econ subcommands in the debug console: inject (supply shocks/boosts), param (α/β/friction mutation), inspect (all 7 D-181 signals). Command parsing and validation complete; dispatch wired through existing DebugCommand IPC flow. Server handler ships with #823. Co-Authored-By: Claude Opus 4.6 --- client/ui/debug_console.gd | 170 +++++++++++++++++++++++++++++++++++++ 1 file changed, 170 insertions(+) diff --git a/client/ui/debug_console.gd b/client/ui/debug_console.gd index d030e933b..39306e7e8 100644 --- a/client/ui/debug_console.gd +++ b/client/ui/debug_console.gd @@ -225,10 +225,172 @@ func _dispatch(line: String) -> void: _send_debug("ListPopulation") "status": _send_debug("GetContaminationStatus") + "econ": + _dispatch_econ(parts) _: _append_text("unknown command: '%s' (type 'help')" % cmd, ERROR_COLOR) +# #825: Economics debug console commands (D-178, D-180, D-181). +# Three subcommands: inject (fire EconEvent), param (tweak α/β/friction), inspect (read signals). +# TODO: Server-side DebugCommandKind variants (InjectEconEvent, SetEconParam, GetEconState) +# ship with #823. Until then, _send_debug will transmit the payload but the server will +# respond with an "unknown command" error. Wire format is ready; server handler is not. +func _dispatch_econ(parts: Array) -> void: + if parts.size() < 2: + _append_text( + ( + "usage:\n" + + " econ inject [commodity_id] [ticks]\n" + + " econ param [system_a] [system_b]\n" + + " econ inspect " + ), + ERROR_COLOR, + ) + return + var sub := parts[1].to_lower() + match sub: + "inject": + _econ_inject(parts) + "param": + _econ_param(parts) + "inspect": + _econ_inspect(parts) + _: + _append_text("econ: unknown subcommand '%s'" % sub, ERROR_COLOR) + + +# econ inject [commodity_id] [ticks] +# Minimal form: econ inject Sol shock 0.5 +# Full form: econ inject Sol fusion_fuel boost 1.2 100 +func _econ_inject(parts: Array) -> void: + # parts[0]="econ", parts[1]="inject", rest is args + var args := parts.slice(2) + if args.size() < 3: + _append_text( + "usage: econ inject [commodity_id] [ticks]", + ERROR_COLOR, + ) + return + + # Parse: detect whether commodity_id is present by checking if args[1] is an effect keyword + var system_id: String = args[0] + var commodity_id: String = "" + var effect: String = "" + var magnitude_str: String = "" + var duration_ticks: int = 0 + + var ticks_str := "" + if args[1].to_lower() in ["shock", "boost"]: + # No commodity_id: econ inject [ticks] + effect = args[1].to_lower() + magnitude_str = args[2] + if args.size() >= 4: + ticks_str = args[3] + else: + # With commodity_id: econ inject [ticks] + commodity_id = args[1] + if args.size() < 4: + _append_text( + "usage: econ inject [ticks]", + ERROR_COLOR, + ) + return + effect = args[2].to_lower() + if not effect in ["shock", "boost"]: + _append_text( + "econ inject: effect must be 'shock' or 'boost', got '%s'" % effect, ERROR_COLOR + ) + return + magnitude_str = args[3] + if args.size() >= 5: + ticks_str = args[4] + + if not ticks_str.is_empty(): + if not ticks_str.is_valid_int(): + _append_text("econ inject: invalid ticks '%s'" % ticks_str, ERROR_COLOR) + return + duration_ticks = int(ticks_str) + + if not magnitude_str.is_valid_float(): + _append_text("econ inject: invalid magnitude '%s'" % magnitude_str, ERROR_COLOR) + return + var magnitude: float = float(magnitude_str) + + var payload := { + "system_id": system_id, + "effect": effect, + "magnitude": magnitude, + } + if not commodity_id.is_empty(): + payload["commodity_id"] = commodity_id + if duration_ticks > 0: + payload["duration_ticks"] = duration_ticks + + _append_text( + ( + "injecting %s on %s%s (mag=%.2f, ticks=%d)" + % [ + effect, + system_id, + " / " + commodity_id if not commodity_id.is_empty() else "", + magnitude, + duration_ticks + ] + ), + TEXT_COLOR, + ) + _send_debug({"InjectEconEvent": payload}) + + +# econ param [system_a] [system_b] +func _econ_param(parts: Array) -> void: + var args := parts.slice(2) + if args.size() < 2: + _append_text( + "usage: econ param [system_a] [system_b]", + ERROR_COLOR, + ) + return + + var param_name: String = args[0].to_lower() + if not param_name in ["alpha", "beta", "friction"]: + _append_text( + "econ param: must be alpha, beta, or friction — got '%s'" % param_name, ERROR_COLOR + ) + return + + if not args[1].is_valid_float(): + _append_text("econ param: invalid value '%s'" % args[1], ERROR_COLOR) + return + var value: float = float(args[1]) + + var payload := {"param": param_name, "value": value} + if args.size() >= 3: + payload["system_a"] = args[2] + if args.size() >= 4: + payload["system_b"] = args[3] + + var scope := "global" + if payload.has("system_a") and payload.has("system_b"): + scope = "%s ↔ %s" % [payload["system_a"], payload["system_b"]] + elif payload.has("system_a"): + scope = payload["system_a"] + + _append_text("setting %s = %.4f (%s)" % [param_name, value, scope], TEXT_COLOR) + _send_debug({"SetEconParam": payload}) + + +# econ inspect — request all 7 D-181 signals for a system +func _econ_inspect(parts: Array) -> void: + if parts.size() < 3: + _append_text("usage: econ inspect ", ERROR_COLOR) + return + var system_id: String = parts[2] + _append_text("inspecting economy: %s" % system_id, TEXT_COLOR) + _send_debug({"GetEconState": system_id}) + + func _send_debug(kind: Variant) -> void: var err := ( SimBridge @@ -284,6 +446,14 @@ func _print_help() -> void: + " triangles — list all triangles\n" + " pop — list active NPCs\n" + " status — contamination status\n" + + "\n" + + "Economics (D-178/D-180/D-181):\n" + + " econ inject [commodity] [ticks]\n" + + " — fire an EconEvent at a system\n" + + " econ param [sys_a] [sys_b]\n" + + " — set tâtonnement parameter\n" + + " econ inspect — show all 7 signals for a system\n" + + "\n" + " help — this list" ), TEXT_COLOR