Initial 100, capacity 300, world tree +20 per 10 game minutes. Each boundary pays registered upkeep demand before storing surplus; overflow is discarded and recorded, 0 stops the whole tower. Furnace offers are judged after generation and demand payment. New saves carry mana_reserve and Operations rollback includes it; legacy saves keep a 0..300 amount and reject others. Outage tests that relied on Mana 0 persisting now hold the outage with a disabled demand sink, since the world tree recovers at the next boundary. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
89 lines
6.7 KiB
GDScript
89 lines
6.7 KiB
GDScript
extends SceneTree
|
|
const ManaOutage = preload("res://tests/helpers/mana_outage.gd")
|
|
var checks := 0
|
|
var failures := 0
|
|
var runtime: Variant
|
|
var clock: Variant
|
|
var state: Variant
|
|
func _initialize() -> void: call_deferred("run")
|
|
func expect(ok: bool, text: String) -> void:
|
|
checks += 1
|
|
if not ok: failures += 1; push_error(text)
|
|
else: print("PASS: ", text)
|
|
func run() -> void:
|
|
clock = load("res://autoload/game_clock.gd").new()
|
|
state = load("res://autoload/game_state.gd").new()
|
|
runtime = load("res://autoload/simulation_runtime.gd").new()
|
|
clock.reset(1,6,0); state.reset(); runtime.initialize(clock,state,712); clock.set_paused(true)
|
|
for spec: Array in [[&"infirmary",Vector3i(-6,0,1)],[&"service_elevator",Vector3i(0,0,1)]]:
|
|
expect(runtime.submit_command(&"build_facility",{&"definition_id":spec[0],&"origin":spec[1]},&"player").is_success(), "ordinary construction: " + String(spec[0]))
|
|
clock.advance_minutes(400)
|
|
for id: StringName in [&"patient",&"medic"]:
|
|
expect(runtime.submit_command(&"register_staff",{&"staff_id":id,&"role_id":&"medic",&"options":{&"current_cell":Vector3i(0,1,1) if id == &"patient" else Vector3i(5,0,1),&"health":0 if id == &"patient" else 100,&"state":StaffRuntime.State.AVAILABLE,&"role_tags":[&"medic"],&"permitted_task_tags":[&"rescue"]}},&"player").is_success(), "register " + String(id))
|
|
var checkpoint := {}
|
|
for tick: int in 130:
|
|
clock.advance_minutes(1)
|
|
var patient_trip: Dictionary = runtime.elevators.get_actor_trip(&"staff:patient")
|
|
if patient_trip.get(&"state",&"") == PathService.ELEVATOR_REQUEST_BOARDED:
|
|
checkpoint = runtime.create_snapshot(); break
|
|
expect(not checkpoint.is_empty(), "rescuer reaches the upper floor and boards with the patient")
|
|
if checkpoint.is_empty():
|
|
print(runtime.get_staff_rescue_report(),runtime.elevators.get_report())
|
|
finish(); return
|
|
var medic_trip: Dictionary = runtime.elevators.get_actor_trip(&"staff:medic")
|
|
expect(medic_trip.get(&"companion_id") == &"staff:patient", "real medic trip links to patient seat")
|
|
expect(runtime.restore_snapshot(checkpoint), "boarded rescue snapshot has valid crosslinks")
|
|
var slot := "user://tests/rescue_elevator_%d" % OS.get_process_id()
|
|
expect(runtime.save_to_path(slot)[&"ok"] and runtime.load_from_path(slot)[&"ok"], "boarded pair survives real disk save and load")
|
|
SaveService.delete_save(slot)
|
|
checkpoint = runtime.create_snapshot()
|
|
clock.advance_minutes(100)
|
|
expect(runtime.staff_service.get_staff(&"patient").health == 100, "upper-floor patient arrives and completes treatment")
|
|
var finished: Dictionary = runtime.create_snapshot()
|
|
expect(runtime.restore_snapshot(checkpoint), "rewind paired ride")
|
|
clock.advance_minutes(100)
|
|
expect(runtime.create_snapshot() == finished, "paired elevator rescue replays identical state and events")
|
|
expect(runtime.restore_snapshot(checkpoint), "restore for emergency")
|
|
var shaft_id: StringName = runtime.elevators.get_report()[&"shafts"][0][&"shaft_id"]
|
|
expect(runtime.submit_command(&"set_elevator_operation",{&"shaft_id":shaft_id,&"operator_open":false},&"player").is_success(), "player can stop the occupied elevator safely")
|
|
var patient: StaffRuntime = runtime.staff_service.get_staff(&"patient")
|
|
var medic: StaffRuntime = runtime.staff_service.get_staff(&"medic")
|
|
expect(patient.current_cell == medic.current_cell and patient.health == 0 and runtime.elevators.get_report()[&"trips"].is_empty(), "emergency unloads both at the same floor without healing")
|
|
expect(runtime.restore_snapshot(runtime.create_snapshot()), "emergency pair release remains saveable")
|
|
expect(runtime.restore_snapshot(checkpoint), "restore boarded rescue pair for tower-wide depletion")
|
|
ManaOutage.hold(runtime, state)
|
|
clock.advance_minutes(1)
|
|
patient = runtime.staff_service.get_staff(&"patient"); medic = runtime.staff_service.get_staff(&"medic")
|
|
expect(patient.current_cell == medic.current_cell and patient.health == 0 and runtime.elevators.get_report()[&"trips"].is_empty(), "reserve depletion lands both rescue passengers together without healing")
|
|
var landing := patient.current_cell
|
|
expect(landing in runtime.elevators.get_report()[&"shafts"][0][&"stops"], "depleted rescue pair uses an actual elevator landing")
|
|
clock.advance_minutes(20)
|
|
expect(runtime.staff_service.get_staff(&"patient").health == 0 and runtime.staff_service.get_staff(&"patient").current_cell == landing, "stopped clinic cannot heal or teleport the landed patient")
|
|
var outage: Dictionary = runtime.create_snapshot()
|
|
expect(runtime.staff_service.validate_invariants()[&"ok"] and runtime.restore_snapshot(outage) and runtime.create_snapshot() == outage, "depleted rescue ownership survives exact complete save restoration")
|
|
ManaOutage.release(runtime, state)
|
|
clock.advance_minutes(100)
|
|
expect(runtime.staff_service.get_staff(&"patient").health == 100, "restored power resumes rescue and treatment for the same patient")
|
|
expect(runtime.staff_service.validate_invariants()[&"ok"] and runtime.restore_snapshot(runtime.create_snapshot()), "recovered rescue has no orphan ownership and remains saveable")
|
|
expect(runtime.restore_snapshot(checkpoint), "restore for clinic outage midride")
|
|
for facility: FacilityInstance in runtime.facility_service.get_instances():
|
|
if facility.definition_id == &"infirmary": runtime.facility_service.set_operational_status(facility.instance_id,{&"operator_open":false},clock.absolute_minute)
|
|
clock.advance_minutes(1)
|
|
expect(runtime.elevators.get_report()[&"trips"].size() == 2, "clinic outage holds onboard pair until a landing")
|
|
clock.advance_minutes(40)
|
|
patient = runtime.staff_service.get_staff(&"patient"); medic = runtime.staff_service.get_staff(&"medic")
|
|
expect(patient.health == 0 and patient.current_cell.y == 0 and runtime.elevators.get_report()[&"trips"].is_empty(), "clinic outage does not teleport the pair back to pickup floor")
|
|
expect(runtime.staff_service.validate_invariants()[&"ok"] and runtime.restore_snapshot(runtime.create_snapshot()), "interrupted elevator rescue preserves ownership and saves")
|
|
expect(runtime.restore_snapshot(checkpoint), "restore for rescuer collapse midride")
|
|
runtime.staff_service.get_staff(&"medic").health = 0
|
|
clock.advance_minutes(1)
|
|
expect(runtime.elevators.get_report()[&"trips"].size() == 2, "rescuer collapse never ejects either passenger between floors")
|
|
clock.advance_minutes(40)
|
|
patient = runtime.staff_service.get_staff(&"patient"); medic = runtime.staff_service.get_staff(&"medic")
|
|
expect(patient.current_cell == medic.current_cell and patient.current_cell.y == 0 and patient.health == 0 and medic.health == 0, "two incapacitated passengers reach a real landing together")
|
|
expect(runtime.restore_snapshot(runtime.create_snapshot()), "both incapacitated passengers remain saveable")
|
|
finish()
|
|
func finish() -> void:
|
|
runtime.free(); clock.free(); state.free()
|
|
print("Elevator rescue: %d checks, %d failures" % [checks, failures]); quit(failures)
|