Files
magic-factorio/tests/snapshot_smoke.gd
T

127 lines
5.2 KiB
GDScript

extends SceneTree
const WorldSimulation = preload("res://src/simulation/world_simulation.gd")
const DemoSnapshot = preload("res://src/persistence/demo_snapshot.gd")
const TEST_PATH := "user://mana_foundry_snapshot_test.json"
func _initialize() -> void:
DemoSnapshot.path_override = TEST_PATH
if FileAccess.file_exists(TEST_PATH):
DirAccess.remove_absolute(ProjectSettings.globalize_path(TEST_PATH))
var failures: Array[String] = []
var live := _make_two_stage()
for _tick in range(400):
live.step()
var before := live.state_fingerprint()
var charged_before := live.get_charged_count()
var snapshot := live.to_snapshot()
var restored := WorldSimulation.new()
if not restored.apply_snapshot(snapshot):
failures.append("apply_snapshot rejected a live two-stage snapshot.")
elif restored.state_fingerprint() != before:
failures.append("Restored simulation fingerprint did not match the live factory.")
elif restored.get_charged_count() != charged_before:
failures.append("Restored charged count did not match.")
if failures.is_empty():
for _tick in range(200):
live.step()
restored.step()
if live.state_fingerprint() != restored.state_fingerprint():
failures.append("Live and restored factories diverged after more ticks.")
if not DemoSnapshot.save_payload({"schema": DemoSnapshot.SCHEMA, "simulation": snapshot}):
failures.append("DemoSnapshot could not write the test slot.")
else:
var loaded := DemoSnapshot.load_payload()
var from_disk := WorldSimulation.new()
if not from_disk.apply_snapshot(loaded.get("simulation", {})):
failures.append("Disk snapshot failed to apply.")
elif from_disk.state_fingerprint() != before:
failures.append("Disk snapshot fingerprint did not match the pre-save factory.")
var empty := WorldSimulation.new()
if empty.is_demo_complete():
failures.append("Empty factory reported demo complete.")
var first_item := _make_two_stage()
var saw_item := false
for _tick in range(2000):
first_item.step()
if first_item.get_charged_count() >= 1:
saw_item = true
break
if not saw_item:
failures.append("Two-stage factory never produced a charged crystal for the one-item check.")
elif first_item.is_demo_complete():
failures.append("Demo completed after a single charged crystal.")
else:
var mid := WorldSimulation.new()
if not mid.apply_snapshot(first_item.to_snapshot()):
failures.append("Could not restore the one-item factory.")
elif mid.is_demo_complete():
failures.append("Loaded one-item factory reported complete.")
var packed := load("res://scenes/main.tscn") as PackedScene
var demo := packed.instantiate()
root.add_child.call_deferred(demo)
await process_frame
await process_frame
demo.call("_start_new_game")
var sim: WorldSimulation = demo.get("simulation")
for x in range(-5, -1):
sim.place_building(WorldSimulation.KIND_BELT, Vector2i(x, 0), 0)
sim.place_building(WorldSimulation.KIND_BELT, Vector2i(0, 0), 0)
for x in range(2, 6):
sim.place_building(WorldSimulation.KIND_BELT, Vector2i(x, 0), 0)
for z in range(1, 5):
sim.place_building(WorldSimulation.KIND_MANA_PIPE, Vector2i(0, z), 1)
sim.configure_machine_bridge(int(demo.get("anchor_machine_id")), Vector2i(-2, 0), Vector2i(0, 0))
sim.configure_machine_bridge(int(demo.get("charger_machine_id")), Vector2i(0, 0), Vector2i(2, 0))
for _tick in range(240):
sim.step()
var scene_before := sim.state_fingerprint()
var payload: Dictionary = demo.call("collect_demo_snapshot")
if not bool(demo.call("_save_demo_snapshot")):
failures.append("Scene save helper failed.")
demo.call("_reset_demo")
if sim.state_fingerprint() == scene_before:
failures.append("Reset after save did not change simulation state.")
if not bool(demo.call("_load_demo_snapshot")):
failures.append("Scene load helper failed.")
elif sim.state_fingerprint() != scene_before:
failures.append("Scene save/load did not restore the simulation fingerprint.")
if FileAccess.file_exists(TEST_PATH):
DirAccess.remove_absolute(ProjectSettings.globalize_path(TEST_PATH))
DemoSnapshot.path_override = ""
if failures.is_empty():
print("SNAPSHOT_SMOKE_OK charged=%d fingerprint=%s" % [charged_before, before])
quit(0)
else:
for failure in failures:
push_error(failure)
quit(1)
func _make_two_stage() -> WorldSimulation:
var simulation := WorldSimulation.new()
simulation.place_building(WorldSimulation.KIND_SOURCE, Vector2i(-6, 0), 0)
for x in range(-5, -1):
simulation.place_building(WorldSimulation.KIND_BELT, Vector2i(x, 0), 0)
simulation.place_building(WorldSimulation.KIND_BELT, Vector2i(0, 0), 0)
for x in range(2, 6):
simulation.place_building(WorldSimulation.KIND_BELT, Vector2i(x, 0), 0)
simulation.place_building(WorldSimulation.KIND_SINK, Vector2i(6, 0), 0)
var refine_id := simulation.place_building(WorldSimulation.KIND_MACHINE, Vector2i(-1, 1), 0)
var charger_id := simulation.place_building(WorldSimulation.KIND_CHARGER, Vector2i(1, 1), 0)
simulation.place_building(WorldSimulation.KIND_MANA_SOURCE, Vector2i(0, 5), 1)
for z in range(1, 5):
simulation.place_building(WorldSimulation.KIND_MANA_PIPE, Vector2i(0, z), 1)
simulation.configure_machine_bridge(refine_id, Vector2i(-2, 0), Vector2i(0, 0))
simulation.configure_machine_bridge(charger_id, Vector2i(0, 0), Vector2i(2, 0))
return simulation