OverviewFilesCommitsIssuesDocsReleasesPeers

hyper-tps / scenes / test / gate_room_state_seed.gd

69 lines · gd ref:
extends SceneTree
## GATE — A TIMED-OUT ROOM-STATE LOAD NEVER RESEEDS THE ROOM (hyper-games #131).
##
## 2026-10-20: a headless `--daemon-only --room-id` peer joined a room whose StateBase took
## 16.4 s to open; the game gave up after 8 s, and _restore_saved_map, finding no
## world:settings:current_map (it had not LOADED, not "is absent"), SEEDED map_server into
## the room as admin — for everyone. Timed out is UNKNOWN, not absent.
##   R1  a room selected, state NOT loaded: no seed (the bug)
##   R2  a room selected, state loaded: seeding allowed (a truly fresh room)
##   R3  no room (offline): unchanged — local state, nothing shared to overwrite
##   R4  _restore_saved_map asks _may_seed_world before it writes the setting
##   R5  the wait clears the last state error first (the timeout reported a STALE one)
##   R6  a timed-out wait still restores once the state arrives (late restore)
##
## RUN: "$HYPER_TPS_GODOT" --headless --path . --script res://scenes/test/gate_room_state_seed.gd

var ok := true
var _ran := false


func _p(c: bool, m: String) -> void:
	print(("ok   " if c else "FAIL: ") + m)
	if not c:
		ok = false


func _process(_delta: float) -> bool:
	if _ran:
		return true
	_ran = true
	_run()
	print("GATE room_state_seed: %s" % ("PASS" if ok else "FAIL"))
	quit(0 if ok else 1)
	return true


## The body of `fn` in `src` (to the next top-level func).
static func _body(src: String, fn: String) -> String:
	var at := src.find("func %s(" % fn)
	if at < 0:
		return ""
	var nxt := src.find("\nfunc ", at + 5)
	return src.substr(at, (nxt if nxt > 0 else src.length()) - at)


func _run() -> void:
	var script: GDScript = load("res://scenes/game/game.gd")
	_p(script != null, "game.gd compiles")
	if script == null:
		return
	var has := false
	for m: Dictionary in script.get_script_method_list():
		if String(m.get("name", "")) == "_may_seed_world":
			has = true
	_p(has, "R0 Game._may_seed_world exists")
	if has:
		_p(script.call("_may_seed_world", true, false) == false, "R1 room selected + state NOT loaded: no seed")
		_p(script.call("_may_seed_world", true, true) == true, "R2 room selected + state loaded: seed allowed")
		_p(script.call("_may_seed_world", false, false) == true, "R3 no room (offline): unchanged")
	var src := FileAccess.get_file_as_string("res://scenes/game/game.gd")
	var rb := _body(src, "_restore_saved_map")
	var ask := rb.find("_may_seed_world(")
	var write := rb.find("set_state(\"world:settings:current_map\"")
	_p(ask >= 0 and write > ask, "R4 _restore_saved_map asks _may_seed_world before writing the setting")
	var wb := _body(src, "_await_room_state")
	_p(wb.find("_last_state_error = \"\"") >= 0, "R5 the wait clears the last state error first")
	_p(src.find("func _restore_when_loaded(") >= 0 and _body(src, "_restore_when_loaded").find("_restore_saved_map()") >= 0,
		"R6 a timed-out wait restores once the state arrives (_restore_when_loaded)")