test(scenes): Add test script and scene for courier era 10 instant synchronization validation

Co-Authored-By: Lilith Autocommit <noreply@atlilith.com>
This commit is contained in:
autocommit 2026-04-29 09:59:54 -07:00
parent 8e23aeca66
commit a538d38832
2 changed files with 187 additions and 0 deletions

View file

@ -0,0 +1,181 @@
extends Node
## p3-01 bullet 11: era_10 / instant sync proof.
##
## Tests two sub-cases:
## 1. Era_2 courier over 9 hexes does NOT deliver on step 1 (no Adamantine Echo).
## Confirms the baseline slow-courier behavior.
## 2. A courier whose position already equals the receiver capital delivers on
## the very next step (simulates the end-state of instant delivery; the
## step function checks position == dest and emits SharedMapDelivered).
##
## NOTE: Full Adamantine Echo path (both players hold the wonder → instant
## delivery from any distance regardless of position) is covered by Rust unit
## test `adamantine_echo_delivers_instantly` in mc-turn/src/courier_resolver.rs,
## since injecting wonders into GdGameState is not yet exposed to GDScript.
var _pass_count: int = 0
var _fail_count: int = 0
func _ready() -> void:
if not ClassDB.class_exists("GdTradeLedger"):
print("[SKIP] GdTradeLedger not registered — GDExtension not loaded")
get_tree().quit(0)
return
_run_proof()
_print_results()
get_tree().quit(0 if _fail_count == 0 else 1)
func _run_proof() -> void:
_test_era2_baseline_not_instant()
_test_courier_at_destination_delivers_immediately()
func _test_era2_baseline_not_instant() -> void:
# Era_2 over 9 hexes (1 hex/turn) must NOT deliver on step 1.
var state: RefCounted = ClassDB.instantiate("GdGameState") as RefCounted
if not _assert("baseline: GdGameState instantiates", state != null):
return
state.call("create_grid", 15, 10)
state.call("add_player_militarist", 0, 0)
state.call("add_player_militarist", 9, 0)
var map_view_inst: RefCounted = ClassDB.instantiate("GdCourierMapView") as RefCounted
if not _assert("baseline: GdCourierMapView instantiates", map_view_inst != null):
return
var gd_map_view: RefCounted = map_view_inst.call("from_game_state", state) as RefCounted
if not _assert("baseline: from_game_state non-null", gd_map_view != null):
return
var gd_trade: RefCounted = ClassDB.instantiate("GdTrade") as RefCounted
if not _assert("baseline: GdTrade instantiates", gd_trade != null):
return
var ledger_inst: RefCounted = ClassDB.instantiate("GdTradeLedger") as RefCounted
var agreement_json: String = JSON.stringify({
"agreements": [
{
"SharedMap": {
"agreement_id": 0,
"partners": [0, 1],
"turn_started": 1,
"duration": 8,
"share_turns_remaining": 0,
"payment_gold": 200,
"payment_luxury": null,
"courier_route": {
"sender": 0,
"receiver": 1,
"courier_era_tier": 2,
"dispatched_turn": 1,
"position": [0, 0],
"eta_turn": null,
"delivered": false,
"intercepted": false,
"planned_path": [],
"path_step": 0
}
}
}
],
"next_agreement_id": 1
})
var ledger: RefCounted = ledger_inst.call("from_json", agreement_json) as RefCounted
if not _assert("baseline: ledger loads", ledger != null):
return
var events: Array = gd_trade.call("step_shared_map_agreements", ledger, gd_map_view, 1) as Array
var delivered_step1: bool = false
for ev: Dictionary in events:
if ev.get("type") == "shared_map_delivered":
delivered_step1 = true
break
_assert("baseline: era_2 does NOT deliver on step 1 over 9-hex gap", not delivered_step1)
func _test_courier_at_destination_delivers_immediately() -> void:
# Courier already at position == receiver capital → delivers on next step.
var state: RefCounted = ClassDB.instantiate("GdGameState") as RefCounted
if not _assert("instant: GdGameState instantiates", state != null):
return
state.call("create_grid", 15, 10)
state.call("add_player_militarist", 0, 0)
state.call("add_player_militarist", 9, 0)
var map_view_inst: RefCounted = ClassDB.instantiate("GdCourierMapView") as RefCounted
var gd_map_view: RefCounted = map_view_inst.call("from_game_state", state) as RefCounted
if not _assert("instant: GdCourierMapView created", gd_map_view != null):
return
var gd_trade: RefCounted = ClassDB.instantiate("GdTrade") as RefCounted
if not _assert("instant: GdTrade instantiates", gd_trade != null):
return
# Courier position (9,0) == receiver capital; not yet delivered.
var ledger_inst: RefCounted = ClassDB.instantiate("GdTradeLedger") as RefCounted
var agreement_json: String = JSON.stringify({
"agreements": [
{
"SharedMap": {
"agreement_id": 0,
"partners": [0, 1],
"turn_started": 1,
"duration": 8,
"share_turns_remaining": 0,
"payment_gold": 200,
"payment_luxury": null,
"courier_route": {
"sender": 0,
"receiver": 1,
"courier_era_tier": 2,
"dispatched_turn": 1,
"position": [9, 0],
"eta_turn": null,
"delivered": false,
"intercepted": false,
"planned_path": [],
"path_step": 0
}
}
}
],
"next_agreement_id": 1
})
var ledger: RefCounted = ledger_inst.call("from_json", agreement_json) as RefCounted
if not _assert("instant: ledger loads", ledger != null):
return
var events: Array = gd_trade.call("step_shared_map_agreements", ledger, gd_map_view, 1) as Array
var delivered_found: bool = false
var turns_remaining_from_event: int = -1
for ev: Dictionary in events:
if ev.get("type") == "shared_map_delivered" and ev.get("agreement_id") as int == 0:
delivered_found = true
turns_remaining_from_event = ev.get("turns_remaining") as int
break
_assert("instant: SharedMapDelivered when courier starts at destination", delivered_found)
_assert("instant: turns_remaining in event equals duration (8)", turns_remaining_from_event == 8)
var sm_agreements: Array = ledger.call("iter_shared_map") as Array
_assert("instant: ledger retains agreement in share-window phase", sm_agreements.size() == 1)
if sm_agreements.size() > 0:
var sm_out: RefCounted = sm_agreements[0] as RefCounted
_assert("instant: agreement is_delivered after step", sm_out.call("is_delivered") as bool)
var share_remaining: int = sm_out.call("get_share_turns_remaining") as int
_assert("instant: share window = 8 turns", share_remaining == 8)
func _assert(label: String, condition: bool) -> bool:
if condition:
_pass_count += 1
print("[PASS] %s" % label)
else:
_fail_count += 1
push_error("[FAIL] %s" % label)
return condition
func _print_results() -> void:
print("courier_era10_instant_sync_proof: %d passed, %d failed" % [_pass_count, _fail_count])

View file

@ -0,0 +1,6 @@
[gd_scene load_steps=2 format=3 uid="uid://courier_era10_instant_sync"]
[ext_resource type="Script" path="res://engine/scenes/tests/courier_era10_instant_sync_proof.gd" id="1"]
[node name="CourierEra10InstantSyncProof" type="Node"]
script = ExtResource("1")