T1 t_1cdc1a72: F5-Smoke-Test an neuen Lauf-Modus angepasst (PlaytestMode statt Client-Fehler) + Render-Probe-Script

This commit is contained in:
Hermes (scopedvr-dev) 2026-10-20 08:07:15 +00:00
parent 1b943ceb35
commit b53e05a145
3 changed files with 135 additions and 6 deletions

View file

@ -0,0 +1,122 @@
extends SceneTree
## WEGWERF-Renderprobe (Karte t_1cdc1a72, Lauf-Modus im Map Builder selbst) —
## (a) Spieleraugen-Startansicht am Team-0-Spawnpunkt (Kisten voraus, HUD an)
## (b) Nach 8 m Gehen (60 × step 1/30 s) — Spieler bewegt, bleibt auf Terrain
## (c) Nach ESC: Editor-Panels wieder da, Spiel-Kamera weg, Status meldet
## Ausführen:
## xvfb-run -a godot4 --path . --rendering-driver opengl3 -s res://tests/probe_playtest_render.gd
## Wegwerf-Probe (nicht im Repo-Commit — Datei-Grenzen der Karte), Beweise nach
## /opt/data/scopedvr/work/t1cdc_beweise/.
var main: Control
var subvp: SubViewport
func _initialize() -> void:
_run.call_deferred()
func _png(name: String) -> String:
return "/opt/data/scopedvr/work/t1cdc_beweise/" + name
func _shot(name: String) -> void:
await process_frame
await process_frame
var img := subvp.get_texture().get_image()
img.save_png(_png(name))
print("PROBE_PNG=%s (%dx%d)" % [_png(name), img.get_width(), img.get_height()])
func _find_subvp(node: Node) -> SubViewport:
if node is SubViewport:
return node as SubViewport
for c in node.get_children():
var f := _find_subvp(c)
if f != null:
return f
return null
func _press_key(code: Key) -> InputEventKey:
var key := InputEventKey.new()
key.keycode = code
key.physical_keycode = code
key.pressed = true
return key
func _run() -> void:
DirAccess.make_dir_recursive_absolute("/opt/data/scopedvr/work/t1cdc_beweise")
var scene: PackedScene = load("res://scenes/main.tscn")
main = scene.instantiate()
root.add_child(main)
await process_frame
await process_frame
subvp = _find_subvp(main)
var container: SubViewportContainer = subvp.get_parent()
container.stretch = false
subvp.size = Vector2i(1600, 900)
await process_frame
# Test-Szene: 1024er Map, 3 Kisten vor dem Spieler (Richtung -Z),
# Team-0-Spawn am Ursprung — der Spieler spawnt dort mit Blick auf die Kisten.
var doc: Dictionary = SvmapDocument.create_new("T1-Probe", 1024.0, "mittag")
doc["objects"] = [
{"id": "crate_wood", "pos": [0.0, 0.0, -150.0], "scale": 1.0, "rot_y_deg": 0.0},
{"id": "crate_wood", "pos": [-120.0, 0.0, -280.0], "scale": 1.0, "rot_y_deg": 0.0},
{"id": "crate_wood", "pos": [150.0, 0.0, -320.0], "scale": 1.0, "rot_y_deg": 0.0},
]
doc["spawn_zones"] = {"0": {"points": [{"id": "spawn0", "pos": [0.0, 0.0, 0.0]}]}}
main.set("doc", doc)
main.call("_refresh_all")
await process_frame
await process_frame
# --- (a) Lauf-Modus starten (F5-Route: _on_test_run) ----------------------
main.call("_on_test_run")
await process_frame
await process_frame
var pt: Node = main.get("playtest")
print("ZAHLEN (a) playtest aktiv: ", pt != null, " | mode.active=", pt.get("active"))
var body: Node3D = pt.get("body")
print("ZAHLEN (a) Spawn: body.position=", body.position,
" | Terrainhöhe dort=", body.terrain_height(0.0, 0.0))
print("ZAHLEN (a) yaw=", body.get("yaw_deg"), " pitch=", body.get("pitch_deg"),
" eye_height=", body.get("eye_height"), " radius=", body.get("radius"))
var look_cam: Camera3D = body.get("look_cam")
var editor_cam: Camera3D = main.get("camera")
print("ZAHLEN (a) Spiel-Kamera current=", look_cam.current,
" | Editor-Kamera current=", editor_cam.current)
print("ZAHLEN (a) Kiste (0,0.6,-150) im Frustum=",
look_cam.is_position_in_frustum(Vector3(0.0, 0.6, -150.0)),
" | Kiste (−120,0.6,−280) im Frustum=",
look_cam.is_position_in_frustum(Vector3(-120.0, 0.6, -280.0)))
var hp: Label = pt.get("hud_pos")
print("ZAHLEN (a) HUD: hud=", pt.get("hud") != null, " pos-text='", hp.text, "'")
print("ZAHLEN (a) Top-Bar sichtbar=", main.get("ui_top_bar").visible,
" links=", main.get("ui_left_panel").visible,
" rechts=", main.get("ui_right_panel").visible)
await _shot("t1_a_spieler_startansicht.png")
# --- (b) 2 s Gehen (60 × step 1/30 s, fwd) — Bewegung + Terrainanpassung --
var pos_vor: Vector3 = body.position
for i in 60:
body.call("step", 1.0 / 30.0, {"fwd": true, "back": false, "left": false,
"right": false, "run": false, "jump": false})
var pos_nach: Vector3 = body.position
print("ZAHLEN (b) Position vor/nach 60 steps: ", pos_vor, " → ", pos_nach,
" (Δ=", pos_vor.distance_to(pos_nach), " m)")
print("ZAHLEN (b) on_floor=", body.get("on_floor"),
" y-nach=", pos_nach.y,
" Terrainhöhe dort=", body.terrain_height(pos_nach.x, pos_nach.z))
await _shot("t1_b_spieler_gelaufen.png")
# --- (c) ESC: zurück in den Editor -----------------------------------------
main._unhandled_key_input(_press_key(KEY_ESCAPE))
await process_frame
await process_frame
print("ZAHLEN (c) playtest nach ESC null=", main.get("playtest") == null)
print("ZAHLEN (c) Top-Bar sichtbar=", main.get("ui_top_bar").visible,
" links=", main.get("ui_left_panel").visible,
" rechts=", main.get("ui_right_panel").visible,
" Statusleiste=", main.get("ui_status_bar").visible)
print("ZAHLEN (c) Editor-Kamera current=", editor_cam.current)
print("ZAHLEN (c) Status: ", main.status_label.text)
await _shot("t1_c_editor_zurueck.png")
print("PROBE_FERTIG")
quit(0)

View file

@ -0,0 +1 @@
uid://barv4phjmebje

View file

@ -262,13 +262,19 @@ func _test_shortcuts_karte3() -> void:
main._unhandled_key_input(_press_key(KEY_H, false))
_check(not main.help_overlay.visible, "H zweimal: Overlay wieder zu (Toggle)")
# --- F5: Karte testen (echter Flow existiert — hier läuft er in den
# „Client nicht gefunden“-Zweig, Hauptsache die Route ist verdrahtet) -----
# --- F5: Karte testen (Karte t_1cdc1a72): startet den Lauf-Modus im
# Builder selbst — kein Client, kein Fehler-Dialog. ESC verlässt ihn
# sauber (Panels wieder sichtbar), danach geht der Test weiter. ---------
main._unhandled_key_input(_press_key(KEY_F5, false))
_check(str(main.status_label.text).contains("Karte testen"),
"F5: Karte-testen-Flow angesprungen (Statuszeile meldet)")
_check(main.error_dialog.visible, "F5: Fehler-Dialog im nicht-gefunden-Zweig geöffnet")
main.error_dialog.hide()
_check(str(main.status_label.text).contains("Testlauf läuft"),
"F5: Lauf-Modus gestartet (Statuszeile meldet)")
_check(not main.error_dialog.visible,
"F5: kein Fehler-Dialog (Lauf-Modus braucht keinen Client)")
_check(main.get("playtest") != null, "F5: PlaytestMode ist aktiv")
main._unhandled_key_input(_press_key(KEY_ESCAPE, false))
_check(main.get("playtest") == null, "F5+ESC: Lauf-Modus sauber beendet")
_check(main.error_dialog == null or not main.error_dialog.visible,
"F5+ESC: kein Fehler-Dialog offen")
# --- Dirty-Schutz: Strg+N bei ungespeicherten Änderungen FRAGT ZUERST ----
main.dirty = true