127 lines
5.2 KiB
GDScript
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
|