extends Node
## PROBE (not a gate): a COLD map load with a large journal already in the room state
## — the user's Home (2026-10-05: "very big hitch on starter map load", 8.9 s of script
## time; ~2460 records making ~3500 brushes). Puts PROBE_N brush.create records into
## GameState first (as a room-state load would), then instantiates map_test and times
## every frame until the journal has been folded, plus the rebuild's phases.
##
## Run: "$HYPER_TPS_GODOT" --headless --path . res://scenes/test/_probe_load_scale.tscn
var _t_last := 0
var _frames: Array = []
var _map: Node = null
var _n := 3500
var _t0 := 0
func _box(lo: Vector3, hi: Vector3) -> Array:
return [1, 0, 0, hi.x, -1, 0, 0, -lo.x, 0, 1, 0, hi.y, 0, -1, 0, -lo.y, 0, 0, 1, hi.z, 0, 0, -1, -lo.z]
func _ready() -> void:
if OS.get_environment("PROBE_N") != "":
_n = int(OS.get_environment("PROBE_N"))
var gs: Node = get_tree().root.get_node("/root/GameState")
gs.route("world:level:*", 1, "peer")
var keet: Node = get_tree().root.get_node_or_null("/root/KeetService")
if keet != null:
keet.current_member_id = "probe-author"
for i in _n:
var x := 60.0 + float(i % 50) * 1.2
var z := float(i / 50) * 1.2
gs.set_state("world:level:probe-author:op:%d" % (1791000000 + i), {"v": 2, "kind": "brush.create",
"undone": false, "g": "probe-author:1791000000", "planes": _box(Vector3(x, 0, z), Vector3(x + 1, 1, z + 1)),
"proj": [], "material_id": 0, "level_id": 0, "sky": false})
_t0 = Time.get_ticks_usec()
_map = (load("res://scenes/maps/map_test.tscn") as PackedScene).instantiate()
add_child(_map)
_t_last = Time.get_ticks_usec()
print("PROBE instantiate+add_child %.1f ms" % ((_t_last - _t0) / 1000.0))
func _process(_d: float) -> void:
var now := Time.get_ticks_usec()
_frames.append((now - _t_last) / 1000.0)
_t_last = now
var lv: Node = _map.get("level")
var live: int = (lv.get_live_brush_ids() as PackedInt32Array).size() if lv != null else 0
if live >= _n or _frames.size() > 600:
var worst := 0.0
var total := 0.0
for f: float in _frames:
worst = maxf(worst, f)
total += f
var st: Dictionary = lv.get_stats() if lv != null else {}
var ph := {}
for k: String in st:
if k.begins_with("ms_") or k == "build_ms":
ph[k] = snappedf(float(st[k]), 0.1)
print("PROBE %d brushes live after %d frames: worst frame %.1f ms, total %.1f ms (from add_child %.1f ms)" % [
live, _frames.size(), worst, total, (now - _t0) / 1000.0])
print("PROBE last rebuild phases %s" % str(ph))
print("PROBE index %s" % str(_map.get("_persist").index_stats()))
# NAVSPLIT: where nav_rebuild's time goes.
var c := PackedVector3Array()
var h := PackedVector3Array()
var ta := Time.get_ticks_usec()
_map._collect_nav_boxes(_map, c, h)
var tb := Time.get_ticks_usec()
_map._collect_brush_boxes(c, h)
var tc := Time.get_ticks_usec()
var region: AABB = _map._nav_region(c, h)
var v: Node = _map._ensure_nav()
v.set_boxes(c, h)
var td := Time.get_ticks_usec()
v.rebuild_box(region, 16.0, 16, 0.4, 1.8)
var te := Time.get_ticks_usec()
print("PROBE nav split: node boxes %.1f ms, brush boxes %.1f ms (%d), set_boxes %.1f ms, rebuild_box %.1f ms" % [
(tb - ta) / 1000.0, (tc - tb) / 1000.0, c.size(), (td - tc) / 1000.0, (te - td) / 1000.0])
get_tree().quit(0)