fix(client): cold-start round 2 — DERIVING TERRAIN state, legend re-fit, release server for make atlas

Item 1: while zero tiles have arrived, the viewer draws a centered
screen-space 'DERIVING TERRAIN…' label (text_dim role, no new hue),
dropping the instant the first tile lands — a cold wait now reads as
loading, not broken. New has_any_tile_arrived() predicate (distinct
from has_pending_tiles(): both true mid-arrival, tested exactly there).

Item 2: legend re-fit root-caused empirically, two plausible fixes
disproven by trace before the real one: a manually-positioned Control's
size NEVER tracks a shrinking minimum in this parenting shape, and
RichTextLabel.fit_content reports degenerate minimums until laid out at
real width once — so reset must be DEFERRED and run after refill, not
inside clear(). ImplantPanel.reset_to_content_size() (call_deferred),
wired into both legend refresh()es. The load-bearing test compares
size.y to get_minimum_size().y — a size-to-size comparison passed
trivially with both numbers equally stuck (caught on first draft).

Item 3: make atlas now builds the RELEASE server and passes
SR_SERVER_BIN (a cold DEBUG server delivers zero tiles for >10s on a
new body — live-measured — vs 210ms warm; release serves cold in well
under a second). atlas_standalone._server_binary_path() honors the env
override per the SR_PORT two-tier precedent, debug path unchanged
when unset.

All fixes revert-verified; nine suites green collateral-checked;
gdlint clean.
This commit is contained in:
2026-07-22 19:51:12 +02:00
parent d4526e51ff
commit dd13760d62
11 changed files with 489 additions and 120 deletions
+20 -2
View File
@@ -263,8 +263,26 @@ func _wait_for_connected(timeout_s: float) -> bool:
return false
func _server_binary_path() -> String:
var project_dir := ProjectSettings.globalize_path("res://")
## Pure function: SR_SERVER_BIN env override, else the debug build path —
## same two-tier shape as _attach_port()'s SR_PORT (D-254 §1). `make atlas`
## now builds the RELEASE server and passes SR_SERVER_BIN so a `_spawn_server()`
## cold-start (this file's own live-repro path — the coordinator's cold-start
## dossier) gets sub-second first-tile derivation instead of a debug build's
## multi-second AnalyzeBody. `override_env`/`override_project_dir` exist ONLY
## for direct-call unit tests (mirrors _attach_port(port_env)'s own param
## shape) — every real caller uses the zero-arg form. Accepts either an
## ABSOLUTE path or one relative to the project root (`res://../`), so
## SR_SERVER_BIN can be given as `server/target/release/settled-reach-server`
## (the Makefile's own shape) without the caller having to know this script's
## `res://` layout.
static func _server_binary_path(override_env: String = "", override_project_dir: String = "") -> String:
var project_dir := (
override_project_dir if not override_project_dir.is_empty()
else ProjectSettings.globalize_path("res://")
)
var env := override_env if not override_env.is_empty() else OS.get_environment("SR_SERVER_BIN")
if not env.is_empty():
return env if env.is_absolute_path() else project_dir.path_join("../" + env)
return project_dir.path_join("../server/target/debug/settled-reach-server")