Add explicit stairs and measure elevator congestion with real actors

This commit is contained in:
Takeshi
2026-09-09 14:26:38 +09:00
parent e246ce382b
commit fb4ad23190
57 changed files with 3030 additions and 162 deletions
+26 -9
View File
@@ -3,6 +3,7 @@ extends SceneTree
const POST_V2_RUNTIME_KEYS := [
&"kitchen_production",
&"elevators",
&"legacy_stairs",
&"movement_credits",
&"catalog_manifest",
&"progression",
@@ -159,11 +160,22 @@ func _test_congestion_credit_and_alternate_route() -> void:
_reset_runtime(8_103)
for x in range(0, 3):
_runtime.world_service.set_walkable(Vector3i(x, 1, WorldService.LAYER_FRONT), true)
_expect(_runtime.rebuild_path_graph_from_world(), "parallel walkable lane rebuilds into PathService")
var definition_id: StringName = &"guest_corridor" if x == 1 else &"guest_stairs"
var built: CommandResult = _runtime.submit_command(
&"build_facility", {&"definition_id": definition_id, &"origin": Vector3i(x, 1, WorldService.LAYER_FRONT)},
&"manager", &"", 0, -1, StringName("path.parallel.build.%d" % x)
)
_expect(built.is_success(), "parallel lane uses normal %s construction at x=%d" % [definition_id, x])
if not built.is_success():
return
_clock.advance_minutes(10)
_expect(_runtime.construction_service.get_job(built.details[&"job_id"]).state == ConstructionJob.State.COMPLETED, "parallel lane construction completes")
_expect(_runtime.path_service.get_vertical_walk_requires_connector(), "parallel lane retains strict floor policy")
var congested := Vector3i(1, 0, WorldService.LAYER_FRONT)
_runtime.path_service.configure_cell_traffic(congested, 1, 0, false)
for blocker_index in range(4):
# Two 150-cost stairs make the upper route 500; six occupants make the
# direct two-cell lane 575, so the stair detour remains strictly cheaper.
for blocker_index in range(6):
_expect(
_register_idle_staff(StringName("blocker_%d" % blocker_index), congested),
"alternate-route blocker %d registers" % blocker_index
@@ -181,6 +193,9 @@ func _test_congestion_credit_and_alternate_route() -> void:
)
_clock.advance_one_minute()
var picker: GuestRuntime = _runtime.guest_service.get_guest(&"route_picker")
_expect(picker.current_cell == Vector3i(0, 0, 0) and _runtime.get_actor_movement_credit(&"guest:route_picker")[&"credit"] == 1000, "first stair minute preserves incomplete movement credit")
_clock.advance_one_minute()
picker = _runtime.guest_service.get_guest(&"route_picker")
_expect(
picker != null and picker.current_cell == Vector3i(0, 1, 0),
"live congestion makes Runtime choose the cheaper parallel lane (actual %s)" % (
@@ -303,11 +318,11 @@ func _test_current_snapshot_crosslinks_and_legacy_v2() -> void:
_clock.advance_one_minute()
var snapshot: Dictionary = _runtime.create_snapshot()
var runtime_data: Dictionary = snapshot[&"systems"][&"runtime"]
_expect(int(runtime_data[&"runtime_schema_version"]) == 8, "Runtime snapshot advertises schema v8")
_expect(int(runtime_data[&"runtime_schema_version"]) == 9, "Runtime snapshot advertises schema v9")
_expect(not runtime_data[&"movement_credits"].is_empty(), "mid-move snapshot persists fixed-point movement credits")
var digest := SimulationDigest.compute(snapshot)
_expect(_runtime.restore_snapshot(snapshot), "valid mid-move v8 snapshot restores")
_expect(SimulationDigest.compute(_runtime.create_snapshot()) == digest, "mid-move v8 save/load is exact")
_expect(_runtime.restore_snapshot(snapshot), "valid mid-move v9 snapshot restores")
_expect(SimulationDigest.compute(_runtime.create_snapshot()) == digest, "mid-move v9 save/load is exact")
var corruptions: Array[Dictionary] = []
var bad_actor := snapshot.duplicate(true)
@@ -345,6 +360,8 @@ func _test_current_snapshot_crosslinks_and_legacy_v2() -> void:
_strip_post_v2_runtime_state(legacy_data)
legacy_data[&"path"][&"schema_version"] = 3
legacy_data[&"path"].erase(&"vertical_walk_blockers")
legacy_data[&"path"].erase(&"vertical_walk_requires_connector")
legacy_data[&"path"].erase(&"transit_actor_ids")
legacy_data[&"path"][&"actor_cells"] = []
legacy_data[&"path"][&"actor_progress"] = []
for traffic: Dictionary in legacy_data[&"path"][&"cell_traffic"]:
@@ -353,16 +370,16 @@ func _test_current_snapshot_crosslinks_and_legacy_v2() -> void:
traffic[&"temporary_block"] = true
_expect(
_is_true_runtime_v2_shape(legacy_data),
"legacy fixture removes every v3-v8 aggregate and dedicated history instead of relabelling v8"
"legacy fixture removes every v3-v9 aggregate and dedicated history instead of relabelling v9"
)
_expect(_runtime.restore_snapshot(legacy_v2), "legacy Runtime v2 deterministically rebuilds Path actors and credits")
var migrated: Dictionary = _runtime.create_snapshot()
_expect(
int(migrated[&"systems"][&"runtime"][&"runtime_schema_version"]) == 8
int(migrated[&"systems"][&"runtime"][&"runtime_schema_version"]) == 9
and migrated[&"systems"][&"runtime"][&"path"][&"actor_cells"].size() == 2
and migrated[&"systems"][&"runtime"][&"movement_credits"].size() == 2
and bool(_runtime.path_service.get_cell_traffic(origin)[&"temporary_block"]),
"legacy migration emits canonical v8 ownership while preserving blocked traffic state"
"legacy migration emits canonical v9 ownership while preserving blocked traffic state"
)