Add one-slot demo snapshot save and load.
This commit is contained in:
@@ -0,0 +1,126 @@
|
||||
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
|
||||
Reference in New Issue
Block a user