extends SceneTree ## Identitäts-Probe-Map (Karte t_1da96275): deterministische Testkarte, die ## BOTH WORLDS — Editor-Playtest UND Quest-Client — mit EXAKT denselben ## Daten fährt (Identitäts-Vertrag: gleiche Map → gleiche Block/Walk- ## Entscheidungen). ## ## Layout (Höhenfeld res 33 = 2-m-Zellen, 64 × 64 m): ## x < 0 → Höhe 0.0 (flach) ## 0 ≤ x < 8 → Höhe 0.3 (Stufe 0.3 m — erklimmbar, Step-Up) ## x ≥ 8 → Höhe 1.1 (Stufe 0.8 m darüber — blockt) ## Objekte (alle auf FLACHEM Terrain, damit die Proben sauber sind): ## building_001 bei (−16, 0, −16) → Tür-Probe (Azimut 202.5°, Befund ## Karte t_f9adf97c: freie Breite 1.10 m) ## barracks_001 bei ( 20, 0, 12) → Wand-Probe (Trimesh blockt) ## box_006 bei (−16, 0, 8) → Kisten-Stufe 0.334 m (Step-Up) ## Run: godot4 --headless --path . -s res://tests/gen_identitaet_map.gd ## Schreibt: ${SVR_IDENTITAET_MAP:-/tmp/svr_identitaet_probe.svmap} (JSON). const STEP_KLEIN := 0.3 const STUFE_GROSS := 1.1 func _initialize() -> void: var res := 33 var size := 64.0 var heights := PackedFloat32Array() heights.resize(res * res) for zi in res: for xi in res: # Platzierungs-Konvention: (0,0) liegt bei (−size/2, −size/2); # Höhe hängt nur von x ab (Spalten). var x := float(xi) / float(res - 1) * size - size * 0.5 var h := 0.0 if x >= 0.0: h = STEP_KLEIN if x >= 8.0: h = STUFE_GROSS heights[zi * res + xi] = h var raw_b64 := TerrainField.encode(heights, 0.0, STUFE_GROSS) var doc: Dictionary = { "format_version": 1, "info": {"name": "Identitaets-Probe", "author": "Karte t_1da96275", "version": 1}, "terrain": { "type": "heightmap", "resolution": res, "size_x_m": size, "size_z_m": size, "min_height_m": 0.0, "max_height_m": STUFE_GROSS, "heightmap_r16_b64": raw_b64, }, "objects": [ {"id": "building_001", "pos": [-16.0, 0.0, -16.0], "rot_y_deg": 0.0, "scale": 1.0}, {"id": "barracks_001", "pos": [20.0, 0.0, 12.0], "rot_y_deg": 0.0, "scale": 1.0}, {"id": "box_006", "pos": [-16.0, 0.0, 8.0], "rot_y_deg": 0.0, "scale": 1.0}, # Wand-Ersatz für die „Stufe 0.8 m blockt"-Probe: 0.85 m hoch — # über der Step-Up-Grenze (0.45 m) → muss blocken. Steht AUF der # 0.3-Ebene (Terrain bei x=2 ist 0.3), Fußpunkt-Konvention. {"id": "barrel_001", "pos": [2.0, 0.3, 20.0], "rot_y_deg": 0.0, "scale": 1.0}, ], "spawn_zones": { "0": {"points": [ {"id": "A1", "pos": [-30.0, 0.0, -30.0]}, {"id": "A2", "pos": [-28.0, 0.0, -20.0]}, {"id": "A3", "pos": [-26.0, 0.0, 20.0]}, {"id": "A4", "pos": [-24.0, 0.0, 10.0]}, ]}, "1": {"points": [ {"id": "B1", "pos": [30.0, 0.0, -30.0]}, {"id": "B2", "pos": [28.0, 0.0, -20.0]}, {"id": "B3", "pos": [26.0, 0.0, 20.0]}, {"id": "B4", "pos": [24.0, 0.0, 10.0]}, ]}, }, "bounds": {"min": [-32.0, -5.0, -32.0], "max": [32.0, 20.0, 32.0]}, "weather": "mittag", } var path := OS.get_environment("SVR_IDENTITAET_MAP") if path.is_empty(): path = "/tmp/svr_identitaet_probe.svmap" var fa := FileAccess.open(path, FileAccess.WRITE) if fa == null: printerr("IDENT_GEN FAIL: kann nicht schreiben: " + path) quit(1) return fa.store_string(JSON.stringify(doc)) fa.close() print("IDENT_MAP=%s" % path) quit(0)