OverviewFilesCommitsIssuesDocsReleasesPeers

hyper-tps / scenes / test / _probe_load_scale.gd

80 lines · gd ref:
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)