extends SceneTree
## Gate: the player's own carve reaches the terrain as INTERACTIVE, once.
##
## TerrainEditManager.apply_sphere / apply_edit / apply_mesh_stamp / apply_convex
## wrote the record FIRST:
##
## GameState.set_state(key, data) # emits state_changed synchronously ->
## # _on_state_changed -> _apply_edit_local(.., false)
## _apply_edit_local(edit_id, data) # interactive -- but already applied: skipped
##
## so every local carve was applied NON-interactive: no worker priority lane, no
## priority collision rebuild, no DC_EDITLAT stamp. Measured 2026-09-30 in
## scripts/mountain-bench.sh with DC_EDITLAT=1: 16 carves applied, 0 priority
## collision builds, 0 EDITLAT stamps (hyper-games #88 carve latency).
var ok := true
var _started := false
var _done := false
class FakeTerrain extends Node:
var calls: Array = [] # [kind, interactive]
func clear_edits() -> void:
pass
func edit_terrain(_p: Vector3, _r: float, _s: float, _op: int, interactive: bool) -> void:
calls.append(["sphere", interactive])
func edit_terrain_box(_p: Vector3, _e: Vector3, _s: float, interactive: bool) -> void:
calls.append(["box", interactive])
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 not _started:
_started = true
_run()
if _done:
print("GATE local_carve_interactive: %s" % ("PASS" if ok else "FAIL"))
quit(0 if ok else 1)
return false
func _frames(n: int) -> void:
for i in n:
await process_frame
func _run() -> void:
var gs: Node = root.get_node_or_null("GameState")
_p(gs != null, "GameState autoload present")
if gs == null:
_done = true
return
gs.install_routes()
gs.current_map_id = "gate_interactive_map"
var fake := FakeTerrain.new()
root.add_child(fake)
# load(), not the class name: naming it compiles it before GameState exists.
var tem: Node = (load("res://scenes/game/terrain_edit_manager.gd") as GDScript).new()
root.add_child(tem)
tem._terrain_node = fake
tem._retry_timer.stop() # its 1 s re-search would drop the fake (not a DCTerrain)
await _frames(2)
fake.calls.clear()
tem.apply_sphere(Vector3(1, 2, 3), 1.5, -3.0, 1)
_p(fake.calls.size() == 1, "one sphere carve reaches the terrain once (calls %s)" % str(fake.calls))
_p(fake.calls.size() >= 1 and fake.calls[0] == ["sphere", true],
"and it is INTERACTIVE (got %s)" % str(fake.calls))
fake.calls.clear()
tem.apply_edit(Vector3(4, 5, 6), Vector3(1, 1, 1), -3.0)
_p(fake.calls.size() == 1 and fake.calls[0] == ["box", true],
"a box carve is applied once, interactive (got %s)" % str(fake.calls))
_p(gs.keys_with_prefix("world:terrain:edit:").size() == 2, "both records were written")
_done = true