New atlas_standalone scene/script: attach-or-spawn boot (one REAL
connect_to_sim attempt at SR_PORT-or-9876 — a separate throwaway TCP
probe was proven by live run to kill a pre-accept-loop server via
broken handshake pipe; never abandon a connected socket), else spawn
--port 0 via new ServerProcess.start_with_pipe + LISTENING:{port}
stdout parse, retry against the resolved port. Reader role wired end
to end: protocol.encode_startup_message optional role param (empty
omits the wire key — byte-identical for all existing callers),
sim_bridge.connection_role suppresses the post-handshake
RequestAllSettings auto-send, hud_groups skips AutoPause/AutoResume
sends for readers (all three would otherwise burn Reader violation
strikes per the T-1130 matrix — endorsed by Oscar).
Generic implant host per D-254 SS3: the shell instantiates ALL
registered implant apps; implant_app_manifest gains
available_in_companion (opt-out, default true) and
implant_registry.instantiate_all a standalone filter param (default
preserves hud.gd behavior byte-identically). Boot order is
instantiate_all THEN open_app (reverse renders a permanently black
window — app_changed fires with no listener; matches hud.gd's order).
Owned-server lifecycle: _exit_tree stops a spawned child, attached
servers survive companion close. Known engine limitation documented:
raw SIGTERM bypasses all Godot notifications and orphans a spawned
server; WM close paths verified clean.
Live-verified: spawn-mode (301 systems rendered from systems.db over
the wire), attach-mode, two simultaneous readers, clean shutdown with
zero orphan processes. 14 new gdUnit tests (port/LISTENING parsing).
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
24 lines
1.2 KiB
GDScript
24 lines
1.2 KiB
GDScript
class_name ImplantAppManifest
|
|
extends Resource
|
|
## Manifest resource for an implant app. Each app directory ships one app.tres
|
|
## that declares identity and capabilities (#844, D-191).
|
|
|
|
@export var schema_version: int = 1
|
|
@export var app_path: String = ""
|
|
@export var scene_path: String = ""
|
|
@export var default_mode: String = "fullscreen"
|
|
# TODO: extract to a keybinds manifest when settings-UI remapping lands.
|
|
# KEY_M = 77, KEY_N = 78; -1 = no binding.
|
|
@export var default_key: int = -1
|
|
@export var preserves_state: bool = true
|
|
## D-254 §3 (companion app amendment, 2026-07-17): opt-out flag for the
|
|
## standalone Atlas companion (`make atlas`) — every registered app is hosted
|
|
## in the companion by default; set false only for apps that structurally
|
|
## require a playing character/gameplay context. The IN-GAME implant ignores
|
|
## this field entirely (zero behavior change there) — it exists solely for
|
|
## `atlas_standalone.gd`'s ImplantRegistry.instantiate_all(standalone=true)
|
|
## filter. Naming note: Jeroen's original suggested name was
|
|
## `availableInAtlasApp`; renamed to snake_case + "companion" (not "atlas")
|
|
## because the Atlas is itself one of the hosted apps, not the host.
|
|
@export var available_in_companion: bool = true
|