Save The Tree implementation and acceptance work in progress
Preserve production code, regression fixtures, audio assets and provenance, test infrastructure, and the original-completion plan and progress ledger. Final game and Windows acceptance remain pending; excluded local artifacts and native experiments are not part of this snapshot.
This commit is contained in:
@@ -28,6 +28,7 @@ func _run() -> void:
|
||||
_test_service_need_effect_schema()
|
||||
_test_path_failure_safe_recovery()
|
||||
_test_exit_persistence_boundary()
|
||||
_test_overdue_departure_snapshot()
|
||||
_test_snapshot_round_trip_and_atomic_rejection()
|
||||
_test_v1_need_migration_and_schema_rejection()
|
||||
_test_deterministic_decision_snapshot()
|
||||
@@ -583,6 +584,32 @@ func _test_exit_persistence_boundary() -> void:
|
||||
_expect(not record.has(&"wallet_gold") and not record.has(&"needs") and not record.has(&"satisfaction_total"), "ordinary transient guest state does not survive despawn")
|
||||
|
||||
|
||||
|
||||
func _test_overdue_departure_snapshot() -> void:
|
||||
for replan: bool in [false, true]:
|
||||
var service := _service_with_definitions()
|
||||
var guest := service.spawn_guest(&"overdue_deadline", &"adventurer", 0, {
|
||||
&"state": GuestRuntimeType.State.DECIDING, &"planned_exit_at": 4,
|
||||
})
|
||||
_expect(guest != null, "overdue deadline fixture spawns through public GuestService")
|
||||
if guest == null: continue
|
||||
if replan:
|
||||
_expect(bool(service.enter_queue(guest.guest_id, &"meal_room", &"overdue_request", 4, 1).get(&"ok", false)), "public queue entry before final patience")
|
||||
_expect(bool(service.tick_queue_patience(guest.guest_id, 5, 0, func(_guest: StringName, _facility: StringName, _request: StringName): return true).get(&"ok", false)), "ordinary patience exhaustion after original deadline")
|
||||
_expect(bool(service.transition_guest(guest.guest_id, GuestRuntimeType.State.DECIDING, 5, &"REPLAN_AFTER_INTERRUPTION").get(&"ok", false)), "public overdue replan retains deadline")
|
||||
else:
|
||||
_expect(bool(service.begin_leaving(guest.guest_id, 5, &"PLANNED_EXIT").get(&"ok", false)), "public leaving can occur after original deadline")
|
||||
_expect(guest.planned_exit_at == 4 and guest.state_entered_at == 5 and guest.is_valid(), "deadline preserved independently of actual later state timestamp")
|
||||
var snapshot := service.create_snapshot()
|
||||
var restored := GuestServiceType.new()
|
||||
_expect(restored.restore_snapshot(snapshot), "overdue ordinary state accepts complete restore")
|
||||
_expect(var_to_bytes(restored.create_snapshot()) == var_to_bytes(snapshot), "overdue entire typed state roundtrip preserves original deadline")
|
||||
for field: StringName in [&"planned_exit_at", &"state_entered_at"]:
|
||||
var corrupt := snapshot.duplicate(true)
|
||||
corrupt[&"guests"][0][field] = -1
|
||||
_expect(not restored.restore_snapshot(corrupt), "negative departure/state timestamp remains rejected " + String(field))
|
||||
_expect(var_to_bytes(restored.create_snapshot()) == var_to_bytes(snapshot), "negative timestamp rejection remains atomic " + String(field))
|
||||
|
||||
func _test_snapshot_round_trip_and_atomic_rejection() -> void:
|
||||
var original := _service_with_definitions()
|
||||
var moving := _moving_guest(original, &"guest_saved_moving")
|
||||
|
||||
@@ -7,6 +7,7 @@ var _state: Variant
|
||||
var _runtime: Variant
|
||||
var _facility_id: StringName
|
||||
var _facility_inventory_id: StringName
|
||||
var _kitchen_fixture_gold := 0
|
||||
|
||||
|
||||
func _initialize() -> void:
|
||||
@@ -36,6 +37,7 @@ func _reset_runtime() -> void:
|
||||
_clock.reset(1, 6, 0)
|
||||
_state.reset()
|
||||
var report: Dictionary = _runtime.initialize(_clock, _state, 3303)
|
||||
_kitchen_fixture_gold = 0
|
||||
_clock.set_paused(true)
|
||||
_expect(report[&"valid"], "runtime initializes S3 actor services")
|
||||
_expect(_runtime.guest_service.get_definitions().size() == 35, "runtime preserves three legacy archetypes and registers 32 MVP catalog archetypes")
|
||||
@@ -69,6 +71,10 @@ func _build_cafeteria() -> void:
|
||||
var facility = _runtime.facility_service.get_instance(_facility_id)
|
||||
_facility_inventory_id = facility.local_inventory_id
|
||||
_expect(facility.state == FacilityInstance.State.NO_STAFF, "unassigned S3 facility starts in NO_STAFF")
|
||||
var kitchen_setup: Dictionary = load("res://tests/fixtures/required_kitchen_setup.gd").ensure(_runtime, _clock, _facility_id)
|
||||
_expect(bool(kitchen_setup.get(&"ok", false)), "public paid kitchen setup/link with actual FLEX shift for S3")
|
||||
_kitchen_fixture_gold = int(kitchen_setup.get(&"gold_cost", -1))
|
||||
_expect(_kitchen_fixture_gold > 0 and _runtime.economy_service.get_balance(&"CONSTRUCTION_EXPENSE") == 800 + _kitchen_fixture_gold and _runtime.economy_service.get_balance(&"PLAYER_CASH") == 4200 - _kitchen_fixture_gold and _state.get_resource(&"gold") == 4200 - _kitchen_fixture_gold, "actual additional paid kitchen/door cost matches both ledger accounts and Gold mirror")
|
||||
|
||||
|
||||
func _register_staff_and_run_task() -> void:
|
||||
@@ -203,7 +209,7 @@ func _run_autonomous_guest_service_with_replay() -> void:
|
||||
_expect(guest != null and guest.satisfaction_samples == 1, "completion records exactly one Guest satisfaction sample")
|
||||
_expect(guest != null and int(guest.needs[&"hunger"]) < 40, "cafeteria completion applies its Need relief")
|
||||
_expect(_runtime.economy_service.get_balance(&"GUEST_WALLET:guest_mio") == 125, "Guest pays the quoted service price once")
|
||||
_expect(_runtime.economy_service.get_balance(&"PLAYER_CASH") == 4225, "service revenue reaches authoritative player cash")
|
||||
_expect(_runtime.economy_service.get_balance(&"PLAYER_CASH") == 4225 - _kitchen_fixture_gold, "service revenue reaches authoritative player cash")
|
||||
_expect(_runtime.inventory_service.total_quantity(_facility_inventory_id, &"ingredient/basic_meal") == 0, "service consumes exactly one reserved recipe input")
|
||||
var final_digest: String = _runtime.latest_digest
|
||||
|
||||
|
||||
@@ -220,7 +220,7 @@ func _test_unreachable_staff_task_is_not_assigned() -> void:
|
||||
|
||||
func _test_shift_end_interrupts_and_fails_service() -> void:
|
||||
_reset_runtime(3314)
|
||||
var facility: FacilityInstance = _build_cafeteria()
|
||||
var facility: FacilityInstance = _build_cafeteria(true)
|
||||
if facility == null:
|
||||
return
|
||||
for staff_id: StringName in [&"short_cook", &"short_server"]:
|
||||
@@ -356,7 +356,7 @@ func _test_corrupt_cross_domain_snapshots_are_atomic() -> void:
|
||||
_expect(SimulationDigest.compute(_runtime.create_snapshot()) == before_digest, "dangling-Reservation rejection preserves the live digest")
|
||||
|
||||
|
||||
func _build_cafeteria() -> FacilityInstance:
|
||||
func _build_cafeteria(physical_kitchen_staff: bool = false) -> FacilityInstance:
|
||||
var build = _runtime.submit_command(
|
||||
&"build_facility",
|
||||
{&"definition_id": &"cafeteria", &"origin": Vector3i(-5, 0, WorldService.LAYER_FRONT)},
|
||||
@@ -371,6 +371,9 @@ func _build_cafeteria() -> FacilityInstance:
|
||||
var facility_id := StringName(facilities[0].get(&"instance_id", ""))
|
||||
var facility: FacilityInstance = _runtime.facility_service.get_instance(facility_id)
|
||||
_expect(facility != null, "completed cafeteria registers with FacilityService")
|
||||
if facility != null:
|
||||
var kitchen_setup: Dictionary = load("res://tests/fixtures/required_kitchen_setup.gd").ensure(_runtime, _clock, facility.instance_id, physical_kitchen_staff)
|
||||
_expect(bool(kitchen_setup.get(&"ok", false)), "public paid kitchen link uses scenario-selected physical or logical attendance")
|
||||
return facility
|
||||
|
||||
|
||||
|
||||
Reference in New Issue
Block a user