extends SceneTree
## Probe (user report 2026-10-03): "justify / movement options only work a bit then
## stop". Repeats each control on one face of a real map_flat and prints, per press,
## the stored intent (off_u, rot, ...) AND the row the shader receives (u0 of that
## face's projection-table row), so it shows WHICH layer stops changing.
## HYPERTPS_DAEMON_TCP=127.0.0.1:1 "$HYPER_TPS_GODOT" --headless --path . --script res://scenes/test/_probe_uv_repeat.gd
var _frame := 0
var _map: Node
var _level: Node
var _bid := -1
func _process(_d: float) -> bool:
_frame += 1
if _frame == 1:
_map = (load("res://scenes/maps/map_flat.tscn") as PackedScene).instantiate()
root.add_child(_map)
return false
if _frame < 30:
return false
_run()
quit(0)
return true
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 _row_of_face(f: int) -> Array:
# The face's row index lives in the brush's render projection; read the table row.
var table: PackedFloat32Array = _level.get_projection_table()
var b: Dictionary = _level.get_brush(_bid)
var rp: Variant = b.get("render_proj", null)
var idx := -1
if rp != null and f < (rp as Array).size():
idx = int(rp[f])
if idx <= 0 or idx * 16 + 16 > table.size():
return [idx, "n/a"]
var base := idx * 16
return [idx, "layer %.0f u0 %.4f v0 %.4f U %.3f,%.3f,%.3f" % [table[base], table[base + 1], table[base + 2], table[base + 4], table[base + 5], table[base + 6]]]
func _dump(tag: String) -> void:
var t: Dictionary = (_level.get_brush(_bid).get("face_tex", []) as Array)[2]
var table: PackedFloat32Array = _level.get_projection_table()
var u0s: Array = []
for r in table.size() / 16:
u0s.append(snappedf(table[r * 16 + 1], 0.0001))
print("%-16s off_u %8.4f off_v %8.4f rot %7.2f | table v%d rows %d u0s %s" % [tag, float(t.get("off_u")),
float(t.get("off_v")), float(t.get("rot")), _level.get_projection_table_version(), table.size() / 16, str(u0s)])
func _key(code: int) -> InputEventKey:
var e := InputEventKey.new()
e.physical_keycode = code
e.keycode = code
e.pressed = true
return e
func _run() -> void:
_level = _map.get_node("DCLevel")
var persist: Node = _map.get("_persist")
var keet: Node = root.get_node_or_null("/root/KeetService")
if keet != null:
keet.current_member_id = "probe"
var gs: Node = root.get_node_or_null("/root/GameState")
if gs != null:
gs.route("world:level:*", 1, "peer")
var ft: Array = []
for i in 6:
ft.append({"tex": "kenney-prototype/dark_01", "mode": 1})
var dot: String = persist.record("brush.create", {"planes": _box(Vector3(0, 0, 0), Vector3(3, 2, 1)),
"proj": [], "material_id": 1, "level_id": 0, "sky": false, "face_tex": ft})
persist.refold()
_bid = _level.brush_by_key(dot)
print("brush keys: ", _level.get_brush(_bid).keys())
var keys: PackedStringArray = _level.get_brush(_bid).get("plane_keys", PackedStringArray())
_map.set("_sel_brushes", [_bid] as Array[int])
_map.set("_sel_brush", _bid)
_map.set("_sel_kind", "face")
_map.set("_sel_keys", PackedStringArray([keys[2]]))
root.get_node("/root/GameMode").set_mode("build")
_map._process(0.0)
print("grid step m: ", _map._grid_step(), " snap: ", _map.get("snap_enabled"))
_dump("start")
var panel: Node = _map.get("_face_panel")
for i in 6:
panel.button("+u").pressed.emit()
_dump("panel +u #%d" % (i + 1))
for i in 4:
_map._unhandled_key_input(_key(KEY_RIGHT))
_dump("key Right #%d" % (i + 1))
for i in 3:
panel.button("→").pressed.emit()
_dump("justify → #%d" % (i + 1))
for i in 3:
_map._unhandled_key_input(_key(KEY_PAGEUP))
_dump("key PgUp #%d" % (i + 1))