Commit graph

73 commits

Author SHA1 Message Date
Hermes (scopedvr-dev)
969e928d74 k1b: Editor-Kamera mit Inhalt ausrichten (Startansicht auf Objekte/Bauteile, Pos1 ganzer Terrain-Klotz, 180-Grad-Schwenk um Inhaltsmitte) 2026-10-20 07:42:50 +00:00
Hermes (scopedvr-dev)
2c5b58f04c t_950fddaa K1: Kamera-Drehen fixen — Drehpunkt unter den Mauszeiger, Map beim Laden passend einpassen
orbit_camera.gd: set_pivot(hit) rechnet aus unveränderter Position/Basis
target/yaw/pitch/distance neu (kein Sprung); MMT-Druck pivoted auf den
Punkt unterm Cursor — Objekt-Treffer zuerst (interaction._pick_object),
sonst Terrain (interaction._ground_point), sonst alter Ziel-Punkt.
ORBIT_DEG_PER_PX = 0.3 gekapselt, Zoom-Minimum DISTANCE_MIN = 5.
fit_to_bounds(mn, mx) ersetzt das tote frame_map(): target = Kartemitte
aus bounds, Abstand über Umkugel-Formel (alle 8 Ecken sicher im Frustum —
reiner Kanten-Faktor 0,65 reicht bei flachen Maps nicht), Mindestabstand
30 m; Pos1/Home = ganze Karte ins Bild (Bounds bleiben gemerkt).
main.gd: Laden/Neu + Resize rufen fit_to_bounds mit den echten doc-Bounds.
Neu: tests/test_orbit_camera.gd (30 checks: kein Sprung, Drehpunkt wandert,
fit, gleichmäßiges Ziehen, Flug-Übergang, Pos1).
2026-10-20 07:09:11 +00:00
Hermes (scopedvr-dev)
dca0947a71 t_1e82f747: Test-Umgebung aufgeraeumt — test_updater Setup robust, test_glb_view auf Pack-Palette (beide Suiten statt immer rot jetzt gruen/SKIP). test_updater: Verzeichnisname war Time.get_ticks_msec (kleine Zahl, kollidierte mit nicht loeschbaren Alt-Laeufen aus read-only git-Packs) → jetzt Unix-Zeit+ticks_usec; Cleanup chmod -R u+w (blocking via OS.execute mit output-Array, 2-Arg-Variante ist async) + include_hidden (.git ist versteckt) + rm -rf-Fallback; git-Fehler geben echten Fehlertext statt roter Zahl. Echte Updater-Pruefungen laufen wieder (75/75, vorher 15/75 FAIL an Setup). test_glb_view: Nachbar-Repos suchen wie tools/sync_objects.sh (Env SCOPEDVR_CLIENT_DIR/SCOPEDVR_MATCH_SERVER_DIR, dann ../+../../-Siblings), Quellen zur Laufzeit in ProjectSettings gesetzt (basis-relativ gerechnet, path_join ketten Absolutpfade); ohne Nachbar klare SKIP-Zeilen+Exit 0 statt 15 FAILs. Camo-Erwartungen entfernt (ueberholt seit d0d4fbd): jetzt Pack-Palette — alle Flaehen albedo_texture != null, Kante 1024², pack_datei_fuer-Zuordnung (military_base→Demonstration_Textures1.png, picture_1/2→Demonstration_picture_N.png 2048²) + Pack-Dateien im Nachbar-Repo (48/48, vorher 4/38 FAIL). Notiz tools/TEST_UMGEBUNG.md (Abhaengigkeiten + test_gui_smoke-F5 vorbestehend rot am 0adb161 via git-stash verifiziert, nicht Teil dieser Karte). 2026-10-20 07:06:48 +00:00
Hermes (scopedvr-dev)
2c10863759 M2 (t_f9eff526): Terrain spiegeln — Höhen UND Boden-Material in allen Live-Pfaden (Spec vc27). terrain_tool: jeder Pinsel-Schritt (Heben/Senken/Glätten/Malen) wendet den Pinsel EINMAL an und kopiert die geänderten Zellen (Snapshot-Vergleich) exakt per SymmetryCore.mirror_cell in die andere Hälfte — Strich-Seite ist Master, Überlappung gewinnt strichnäher, Mitte/Achse wird nicht gedoppelt. demo_stroke läuft über dieselben Schritte. Ohne sym_mode-Feld/Modus AUS: exakt altes Verhalten (byte-identisch zu origin/main, SHA256-Gegenprobe). terrain_mesh unverändert (Live-Pfade tragen Höhe+Schicht bereits, Audit im Handoff). Neu: tests/test_terrain_mirror.gd (105 checks, alle 3 Modi × 4 Pinsel + Mitte/Achse/Rand/Überlapp + Gegenprobe) und tests/probe_terrain_mirror_render.gd (Beweis-Bild Draufsicht). 2026-10-20 06:49:08 +00:00
Hermes (scopedvr-dev)
238ca7bb2f M3 (t_34908425): Objekte spiegeln — Platzieren/Verschieben/Drehen/Löschen/Duplizieren inkl. Partner-Bindung (Spec vc27). ObjectOps: symmetry_place_twin/symmetry_sync_pairs/symmetry_expand_delete (Mathe aus SymmetryCore M1, keine zweite Spiegel-Mathe; Mitte/Achse nicht gedoppelt). interaction: Zwilling in ALLE Objekt-Pfade integriert (Platzieren, Drehen, Löschen, Duplizieren, Pfeiltasten, Ziehen live+Commit, Greifen live+Esc-Rückabwicklung, Spiegeln-Button) — jede Änderung = EIN Undo-Schritt. map_view_builder: schwächere Partner-Markierung über die bestehende Auswahl-Material-Logik (keine zweite Technik). Neu: tests/test_object_mirror.gd (74 checks, alle 3 Modi + Gegenprobe AUS), tests/probe_m3_partner_render.gd (Beweis-Bild). 2026-10-20 06:48:29 +00:00
Hermes (scopedvr-dev)
c15c606311 t_ffa207b1: M4 Bau-Teile + Spawnpunkte spiegeln (Spec vc27)
- BuildOps.place_mirrored / update_mirrored / remove_mirrored /
  inside_match_bounds: pure Statics in build_ops.gd, sym-Kopplung aus M1,
  gleiche Snap-Regeln (Paritaet bleibt), tiefe Kopien (kein Aliasing).
- V9-Grenzen scharf: laege der Zwilling ausserhalb der Match-Grenzen
  (Loader-Regel _inside_bounds ±1 m), wird er NICHT gespeichert und der
  Status meldet V9 im Klartext — auch kein halber sym-Link.
- SpawnTool-Spiegelung im GEGNER-Team (Blau West <-> Rot Ost = faire
  Gegenstelle, Radius 1:1), Partner-Map in design_notes.spawn_mirror
  (Loader-frei, rundtrip-sicher). Auf der Mitte: nicht gedoppelt.
- build_tool.gd: duenne Hooks an den 6 Klick-Mutationen + demo_place —
  EIN Undo-Schritt nimmt Original UND Zwilling zurueck.
- spawn_tool.gd: Hooks in setzen/verschieben/loeschen/demo_place/demo_move;
  _sym_mode() defensiv ueber main.get() (Mock-Mains ohne sym_mode -> OFF,
  statt SCRIPT ERROR — Lektion aus test_shortcuts).
- Neue Suite tests/test_build_spawn_mirror.gd (76 Checks ALL OK) +
  Probe tests/probe_m4_mirror_render.gd (2 Beweis-Bilder).
- Regression: 19/20 Suiten gruen; test_glb_view 15/25 FAIL pre-existing
  (per git-stash gegen 437f6bf verifiziert, Ursache unabhaengig vom Diff).
2026-10-20 06:47:58 +00:00
Hermes (scopedvr-dev)
0adb161386 t_f5935023: M1 Symmetrie-Fundament (Spec vc27, Sly 20.10.) — SymmetryCore (Punkt/Achse X/Achse Z, Zell-Abbildung, Partner-Link sym, alle statisch/pure, headless testbar) + Validator V16 in svmap_io (sym muss String, nicht leer, ≤64 Zeichen, genau 2 pro Kennung) + Toolbar-Schalter + Statuszeile-Anzeige in main.gd (Standard=Punkt, Sly sieht Modus immer) + Suite test_symmetry_core (93 Checks: Modus-Katalog, Kartenmitte aus bounds, zweimal-spiegeln=Identity für alle Modi, Achse/Zentrum-nicht-doppeln, Raster-Zell-Mapping inkl. gerader/ungerader res, Partner-Link-API, V16-Validator, Roundtrip mit sym byte-identisch, Legacy-Karte ohne sym unverändert). 17/19 Suiten grün (test_updater 15/75 FAIL + test_glb_view 15/25 FAIL = PRE-EXISTING per git-stash-Verfahren gegen 437f6bf verifiziert, Ursache unabhängig vom Diff). M1 legt nur Mathe + Anzeige fest — gespiegeltes Bauen selbst kommt mit M2 (Terrain), M3 (Objekte), M4 (Bau-Teile + Spawns). 2026-10-20 06:37:50 +00:00
Hermes (scopedvr-dev)
437f6bf368 Fix Update-Banner hing endlos: git-Warnzeile wurde als Ziel-Commit gelesen (t_50a07d4b-Live-Bug, Meldung Sly 20.10.)
git_run mischt stdout+stderr; bei der HTTP-Umleitung der Forgejo-URL schreibt
git zuerst 'warning: Umleitung nach ...'. Die alte Fassung nahm die ERSTE
Zeile und hielt 'warning' fuer den Remote-SHA -> Banner 'Update verfuegbar:
<sha> -> warning' blieb fuer immer, obwohl der Klon auf origin/main stand
(live auf dem PC belegt: STDOUT korrekt, STDERR Warnung).

Jetzt: sha_aus_ls_remote() liest nur echte '<sha>\t<refs/heads/...>'-Zeilen
(Warnungen/hints/fatal uebersprungen, SHA muss Hex sein), Notnagel = erste
hex-artige Zeile; 'kein Commit in der Ausgabe' gilt als unreachable statt
update_available. Regressionstest: 6 neue Checks in test_updater.gd.
2026-10-20 05:27:02 +00:00
Hermes (scopedvr-dev)
d0d4fbd221 Fix Editor-Live-Texturen: Pack-Original-Zuordnung nach Materialname (t_50a07d4b, aa94bde korrigiert)
aa94bde hat im Live-Pfad die alten Camo-Dateien (desert_multicam_*) verwendet und
zusaetzlich per Inhaltsvergleich auch KORREKTE Texturen wieder durch Camo ersetzt
- das haette die Palette-Arbeit aus t_279df760 im Editor rueckgaengig gemacht.
Jetzt: Zuordnung Materialname -> Pack-Textur (military_base -> Demonstration_Textures1.png,
picture_1/2/3 -> Demonstration_picture_N.png), Pfad ../../../textures/military_desert/
(Client-Repo, dort liegen die Dateien seit 88fded1). Fuer den Inhalt gibt es EINE Quelle:
tools/PACK_TEXTURE_MAPPING.md. Fuer den Inhalt gibt es EINE Quelle: dieselbe Tabelle.
Flaechen mit bereits aufgeloester Textur bleiben unangetastet.
2026-10-20 00:24:54 +00:00
Hermes Agent
aa94bde708 WYSIWYG Camo-Texturen: Live-Viewport lädt Multicam-Texturen (Cache, Warnung bei Fehlen) 2026-10-19 23:26:38 +00:00
Hermes (scopedvr-dev)
967e4dc54a Mehrfachauswahl gemaessigt (t_bceb0965): Gemeinsames Verschieben aller markierten Objekte relativ — Anker-Objekt fuehrt, Abstaende bleiben exakt erhalten (Probe: 3 Objekte, Delta (+4,-2), Distanzen 6.325/5.831/7.616 vor UND nach). Entf loescht die GESAMTE Auswahl (vorher: nur letztes Objekt), mit einem Undo-Schritt fuer die Gruppe. Undo: 1 Schritt stellt ALLE Objekte gemeinsam wieder her (vorher: 3 Einzelschritte); Redo groupen-basiert. Drehung/Scale-Eingabe bei Mehrfachauswahl: '—' eintippen setzt ALLE auf denselben Wert, Position bleibt relativ. Einzelauswahl unveraendert (Gizmo-Zug ist gizmo-gated und nutzt gemeinsam-ziehend-Pfad nicht). Tests: tests/probe_multi_move.gd neu (12 Checks: Positionen, Abstaende, Undo/Redo, Entf), tests/test_inspector.gd 47/47 gruen (T5 erweitert), test_ui_scale 51/0 gruen, --import 0 Parse-Fehler. 2026-10-19 21:57:28 +00:00
Hermes Agent
370917f96e D11 (t_c8748efc): Thumb-Neurender mit Camo-Fix — 292 Thumbs neu gerendert, gen_thumbs.gd lädt Multicam-Texturen manuell (GLTFDocument kann externe URIs in Sibling-Repos nicht laden). 2026-10-19 21:31:57 +00:00
Hermes (scopedvr-dev)
9fa8029910 Farbe je Objekt (t_b0edb807): Inspektor-Abschnitt 'Farbe / Material' mit 7er-Palette (Wüstensand/Oliv/Tarn-Grün/Stahlgrau/Holzbraun/Dunkelbraun/Weiß) + 'Zurücksetzen (Pack-Farbe)'; Mehrfachauswahl = EIN Undo-Schritt; Speichern als OPTIONALES Objekt-Feld tint:[r,g,b] (Anzeige-sRGB, 4 Stellen — Rückwärtskompatibel, Karten ohne Feld unverändert). Neuer Helfer src/svmap/svmap_tint.gd (1:1-Spiegel im Client, gemeinsame Semantik Editor+Spiel): albedo_color-ERSATZ via Surface-Override-Kopien — Original-Materialien bleiben unangetastet, Auswahl-Orange (material_override) gewinnt weiter; set_selected_multi re-synced Tint beim Abwählen, tint_refresh für Inspector-Änderungen ohne Rebuild. Map-View-Bauer wendet tint beim Aufbau an (echte GLBs UND Platzhalter). tests/test_map_tint.gd neu (31 Checks grün), Editor-Gesamtsuite 18/18 (gui_smoke-F5-Artefakt per Gegenprobe entkräftet, updater falsch-rot im Sammel-Filter). Rauheit/Metallisch bewusst weggelassen (Begründung im Handoff/BEWEIS.md). 2026-10-19 20:54:34 +00:00
Hermes (scopedvr-dev)
c8b9c59fda Objekt-Inspektor rechts (t_bb0d11c9): Position/Drehung/Größe tippbar+ziehbar (Godot-Konvention: am Label ziehen), Mehrfachauswahl mit „—“ bei ungleichen Werten, JEDE Änderung = 1 Undo-Schritt (Tippen beim Bestätigen, Ziehen beim Loslassen), live im 3D (Marker-Sync ohne Rebuild, Rescale inkl. Pick-Metas), Auf-Boden-Setzen über vorhandene Logik, Info-Block (Fußpunkt/Kollision/echtes Modell), Kopf mit N von M + Poly. Scale via UIScale (alle 3 Stufen layout-geprüft @2328x1310). Drive-by-Fixes (Vorbestand): Tree.ensure_visible → Tree.scroll_to_item (SCRIPT ERROR bei jeder Auswahl) + sel_label füllt jetzt bei select_object/select_many. tests/test_inspector.gd neu (35 Checks), Suiten grün. 2026-10-19 20:02:14 +00:00
Hermes (scopedvr-dev)
366d482a1a A6-Aufraeum (t_a6a96e4c): Beispiel-Faesser entfernt — Thumbs + .import geloescht, Registry-Sync (345 Objekte, note erhalten), probe_store_a6 auf barrel_001 umgezogen 2026-10-19 20:00:52 +00:00
Hermes (scopedvr-dev)
c8a41c0794 UI-Größe: zentrale Skalierung Klein/Mittel/Groß (t_297221b5) — Top-Bar-Menü, sofort wirksam (Rebuild), gespeichert in user://scopedvr_editor.cfg [ui]; Fenster startet maximiert + merkt Lage; Panel-Min-Maße/Schrift an einen Faktor gekoppelt; Layout-Überlauf-Fixes (Hilfe-Hinweis Umbruch+Grow-up, Statuszeile/Top-Bar-Ellipsis, linkes Panel scrollbar) 2026-10-19 19:21:45 +00:00
Hermes (scopedvr-dev)
43636c840f Bibliothek: 96-px-Kacheln, Kategorie-Gruppen, klappbar + gemerkt, Suche (t_59fc0f21) 2026-10-19 18:49:26 +00:00
Hermes (scopedvr-dev)
90c3c7fdc7 Selbst-Update: lose/geänderte Dateien werden automatisch beiseitegelegt (t_f73a1cc5)
EditorUpdater.pull: vor dem pull --ff-only git stash push -u (erfasst
GEÄNDERT + UNTRACKED — genau die losen .import-Dateien, die am 19.10.
den Update-Knopf blockierten). Nach dem Pull zurückholen (apply+drop);
kollidiert das Zurückholen: reset --hard gegen halb gepoppte Zustände,
Stash bleibt als Sicherung, ehrliche Klartext-Meldung in der Statuszeile
statt roher Git-Zeile. Alte Auto-Stashes gleicher Kennung werden beim
Anlegen verworfen (keine Anhäufung). main.gd zeigt die Klartext-Info.

tests/test_updater.gd: Negativprobe (nackter pull bricht an untracked
vs. getrackt ab), Fix-Probe (läuft durch), geänderte Datei bleibt
erhalten, Konflikt-Fall mit Sicherungs-Stash, Anti-Anhäufung. 69 checks.
2026-10-19 18:41:19 +00:00
Hermes (scopedvr-dev)
3e07e91f5a Revert "Pack-Texturen (t_9675e48d): Editor-Viewport + Thumbs texturiert"
This reverts commit c0cbe4bb0c.
2026-10-19 18:33:15 +00:00
Hermes (godot-vr)
c0cbe4bb0c Pack-Texturen (t_9675e48d): Editor-Viewport + Thumbs texturiert
GlbMeshStore setzt fuer texturlose Military-GLBs die Pack-Palette-Textur
(Atlas per absolutem Pfad aus dem Client-Mesh-Lager, NEAREST + Mipmaps),
gen_thumbs nutzt denselben Helfer → Thumbs zeigen die echten Palette-
Farben statt weisser Silhouetten. 261 Thumbs neu gerendert (317 gesamt).
Beweis: tests/probe_pack_texturen.gd headless — 7/7 Flaechen texturiert.
2026-10-19 18:26:47 +00:00
Hermes (scopedvr-dev)
e1e07e57b0 D6 (t_31e800f2): Editor-Sync — 30 Fahrzeug-Thumbs + Map-Builder-Nachweis
- library/objects.json = 347 Objekte (Merge-Stand Match-Server)
- library/thumbs/: 30 neue Thumbs (tank/apc/air_defense/antenna), in
  Kategorie-Farbe Oliv (D0-Muster) — uebrige 317 Thumbs byte-identisch
- tests/probe_d6_mapbuilder.gd: 3 Fahrzeuge ueber den ECHTEN Map Builder
  platziert (Panzer + Turm exakt auf dem Turm-Ring 1,5929 m + Transportpanzer,
  dazu die Kanone auf 2,1273 m), Kollisionsboxen als Drahtgitter,
  PNG 1600x1000 — PROBE_D6_MAPBUILDER_OK
2026-10-19 18:25:15 +00:00
scopedvr-dev
8f598dc67d Test-Fix (t_03d0f442): test_library-Katalog-Check datengetrieben statt harte 54
Die harte Erwartung lib.size() == 54 (15 Basis + 39 Natur-Update) brach bei
JEDER Kategorie-Karte: schon der A6-Stand hatte 56 (2 Beispiel-Objekte), nach
D1-D5 sind es 317. Der Check ist jetzt datengetrieben:

- Basis-Bestand bleibt garantiert: lib.size() >= 54 (Merge-Fundament A6) —
  der Katalog darf nur wachsen, schrumpfen failt weiterhin.
- Neu: Registry <-> Thumbnails deckungsgleich (je OID ein 128px-Thumb, keine
  verwaisten Thumbs) — fängt vergessene/abgebrochene sync_objects-Läufe.
- Neu: OID-Vergleich gegen die gemergte Match-Server-Registry
  (../scopedvr-match-server, Quelle der Wahrheit aus objects.d/*), wenn das
  Sibling-Repo liegt; ohne Sibling verkürzt sich der Test statt zu failen.
- Testgruppe Registry-Fußpunkt: "alle 54 Objekte" -> dynamische Zahl im Titel.

Suite grün auf main: 95/95 checks (ist 317). Beweis Drift-Erkennung: eine
injizierte Fremd-OID in der MS-Registry failt den neuen Vergleich gezielt.
2026-10-19 18:23:56 +00:00
Hermes (scopedvr-dev)
6572f1e10c D0 (t_47f05319): 317 Thumbs mit Kategorie-Farben neu gerendert + Thumb-Licht entschärft
- gen_thumbs: ambient 0.7->0.35, sun 1.1->0.85 — helle Albedos überstrahlten
  sonst zu Weiss im 128px-Thumb
- alle 317 Thumbs neu (263 Military-Desert-GLBs mit baseColorFactor-Farben)
2026-10-19 18:22:32 +00:00
Hermes (scopedvr-dev)
6c65b13a8f D4 (t_691b51ce): Editor-Sync — 59 neue Prop-Thumbs + Map-Builder-Probe (3 Props mit Kollisionsboxen) 2026-10-19 18:11:07 +00:00
Hermes (scopedvr-dev)
b288e8a1e8 D3 (t_6690c59c): .uid der Render-Probe nachgezogen 2026-10-19 18:09:34 +00:00
Hermes (scopedvr-dev)
c92d35dca2 D3 (t_6690c59c): Render-Probe — Gebaeude in einer Reihe, Kamera naeher (Sichtpruefung Fusspunkt/Groesse) 2026-10-19 18:08:40 +00:00
Hermes (scopedvr-dev)
29b1668f57 D3 (t_6690c59c): Gebaeude in der Editor-Bibliothek (93 Objekte, 37 neue Thumbs) + Map-Builder-Render-Probe 2026-10-19 18:08:05 +00:00
Hermes (scopedvr-dev)
56a808f052 D1 (t_78746c97): Waende in der Editor-Bibliothek (Registry-Kopie + 50 Thumbs) + Render-Probe 2026-10-19 18:07:02 +00:00
Hermes (scopedvr-dev)
c0d426152e D2 (t_33250710): Editor-Bibliothek 83 Objekte + 27 Absperrungs-Thumbs + Renderprobe
- library/objects.json: Editor-Kopie (note behalten), 83 Objekte.
- library/thumbs: 27 neue Thumbs (echte GLB-Meshes), Alt-Thumbs unveraendert.
- tests/probe_d2_barriers_render.gd: Map-Builder-Beweis — 3 Objekte ueber
  map_view_builder platziert, PNG gerendert, Fußpunkt/Groesse gemessen.
2026-10-19 18:06:55 +00:00
Hermes (scopedvr-dev)
310aa695e6 A6 (t_c5a27ca7): Editor loest Kategorie-GLBs aus der Registry auf (GlbMeshStore + gen_thumbs), Thumbs fuer Beispiel-Objekte 2026-10-19 18:02:12 +00:00
Slyphax-Hermes
f99d1e2a28 Fix Selbst-Restart (Live-Befund 17.10.): Update-Restart ging auf den Godot-Editor statt die Map-Editor-APP — self_restart_args ohne --editor (die App startet über main.tscn mit nacktem --path), Kommentar + test_updater angepasst 2026-10-17 21:53:37 +00:00
Hermes (godot-vr)
4c960e2587 test_testrun: Stale-Export-Falle behoben (t_2a90ceab): _cleanup purgt user://testrun KOMPLETT statt nur Testmap.svmap — eine Stale-Export-Datei fremden Owners (Root-Testlauf mit HOME=/home/slyphax erzeugt root-gehoerige Dateien in slyphax-Appdata; ein slyphax-Lauf kann sie nicht ueberschreiben) liess save_to_file still mit Datei-nicht-schreibbar (Fehler 12) scheitern, waehrend Temp-Datei-existiert + Roundtrip dank der alten Datei faelschlich gruen blieben — darum wirkte der 1/14-FAIL pre-existing ohne jeden Code-Bezug. Der Ordner-Owner darf unlinken, der Purge raeumt darum auch root-Dateien weg; zusaetzlich druckt der Export-Check jetzt die save-Fehlerliste (Diagnose ohne Probe-Script). Verifikation: Suite als slyphax UND root je 14/14 ALL OK; Fehlermeldung per Probe als slyphax bestaetigt. 2026-10-17 22:55:05 +02:00
slyphax
73847ed1ce Map-Editor Selbst-Update gehärtet (t_1457e935): KEIN Credential-Dialog mehr — git-Läufe nie interaktiv — Root-Cause: der systemd-User-Manager exportiert SSH_ASKPASS (ksshaskpass); ein nackter git-Spawn im Editor hat damit mitten in der Update-Prüfung das KDE-Login-Fenster geöffnet, und der Credential-Store (~/.git-credentials) war leer (0 Bytes). Fix (Belt AND Braces, EditorUpdater.spawn_argv): JEDE git-Ausführung läuft über /usr/bin/env mit GIT_TERMINAL_PROMPT=0 + GIT_ASKPASS=/bin/true + HOME aus der eigenen Umgebung (kein Hardcode), dazu -c credential.helper= (Helper-Reset, sonst öffnet z. B. der Windows-Credential-Manager sein GUI) + -c credential.helper=store + core.askPass=/bin/true (Askpass-Fallback tot, auch ohne env-Wrapper). Askpass-Präzedenz am PC verifiziert: core.askPass/GIT_ASKPASS schlagen geerbtes SSH_ASKPASS — Fake-Askpass startet nicht, sauberes Authentication failed Exit 128 statt GUI. Neuer Status auth_failed mit klarem UI-Text („Updates nicht prüfbar — Zugangsdaten fehlen (kein Login-Dialog geöffnet)“), Auth-Erkennung pure (looks_like_auth_error: could-not-read-Username / Authentication failed / terminal prompts disabled / Unauthorized — Connection refused ist KEIN Auth-Fehler); pull-Fehler bekommen denselben Zusatz-Hinweis. Credential-Store am PC befüllt (Forgejo-Token für 127.0.0.1:13020, chmod 600) — ls-remote/pull/ls-remote-push laufen stimmlos. Tests: test_updater +10 Checks (auth-Erkennung 4, spawn_argv-Zusammensetzung 6) → 47/47 ALL OK; komplette Suite 12/13 grün (test_testrun: 1/14 FAILED — PRE-EXISTING, per git-stash-Verfahren verifiziert, Ursache unabhängig von diesem Diff, Follow-up-Karte folgt). docs/tasten.md: Abschnitt Updates um „Zugangsdaten fehlen“ ergänzt. 2026-10-17 22:49:42 +02:00
Hermes (godot-vr)
f2b4f6a824 Map-Editor Selbst-Update (t_d95f087a): Start-Check + Banner + Jetzt-updaten + Pruef-Button — EditorUpdater (src/editor/updater.gd): stiller Check beim Start (git ls-remote origin/main vs. lokaler HEAD, keep-alive-leicht), Bernstei-Banner „🔄 Update verfügbar: alt → neu“ mit Knopf „Jetzt updaten“, Datei-Menü-ID 7 „🔄 Updates prüfen“ mit Statuszeilen-Ergebnis (Update verfügbar / auf dem neusten Stand / Nicht erreichbar). Update-Ausführung: Dirty-Schutz via _request_lossy (derselbe deutsche Dialog wie Strg+O/N, Abbrechen bricht ab), dann git pull --ff-only (Tunnel + credential store) → Godot-Import-Lauf (--headless --import) → Neustart. Import-Ausgabe wird geparst: Parse-/SCRIPT-Fehler trotz Exit-Code 0 = Abbruch mit Meldung, KEIN Neustart (Lektion 17.10. class_name-Cache). Restart plattformneutral: cfg [update] restart_command > systemd-User-Unit map-editor auto-erkennung (systemd-run --on-active=3s Kick im eigenen Scope, überlebt den Unit-Neustart) > Selbst-Restart (dieselbe Godot-Binary, --editor --path). Keine Linux-Pfade hartkodiert; git_command aus cfg möglich. Offline: kein Banner, kein Fehler-Geballer. Ein-Hintergrund-Thread je Richtung (check/update) mit Busy-Guard, Thread-join über call_deferred-Ordnung. Tests: neue Suite test_updater (37 Checks: Check divergiert/gleich/unreachable/kein-Repo, Banner-Texte, Pull gegen echte Temp-Klone, Import-Abbruch-Pfad inkl. Exit-0-Falle, Restart-Auflösung), Suite 13/13 ALL OK (997 Checks). docs/tasten.md: Abschnitt „Updates“; H-Overlay-Zeile. 2026-10-17 19:38:07 +00:00
Hermes (godot-vr)
2065ef2252 Map-Editor R3 (t_c863b93b): Kartengröße-Dialog + Menü + Undo-Verdrahtung — neuer Dialog „Kartengröße ändern“ (Datei-Menü, Stil wie new_map_dialog): aktuelle Größe/Auflösung, Freifelder X/Z (256–4096 clamp) + Preset-Buttons 256/512/1024/2048, Live-Preview aus resize_preview (R2): Verlust-Liste beim Verkleinern (Objekte/Bauteile/Spawn-Punkte draußen) mit Entfernen-Schalter, V9-Warnung (Drop aus = Map nicht speicherbar), Spawn-Speicher-Warnung (< 4 Punkte/Team, V11), Warnband beim Vergrößern über ~1024 m (Dichte-Deckel 513 → m/Punkt, Quest-Perf). Ausführen: resize_apply → doc IN-PLACE ersetzt (History-Referenz bleibt gültig) als EINE Undo-Einheit (kompletter doc-Snapshot), Dirty-Flag, Terrain/Viewport-Rebuild + Kamera-Refit. ActionHistory: snapshot/_restore_block vertragen jetzt skalare Ober-Keys (format_version/weather) → Ganz-doc-Snapshots möglich. Tests: neue Suite test_resize_dialog (40 Checks: Dialog-Aufbau/Clamp/Preview-Texte, Menü-Verdrahtung, Undo-Roundtrip BYTE-IDENTISCH, Redo, Drop-aus-Pfad), komplette Suite 12/12 ALL OK (960 Checks). docs/tasten.md: Abschnitt „Kartengröße ändern“. 2026-10-17 19:01:15 +00:00
Hermes (godot-vr)
116acd63ed Map-Editor R2 (t_27ba6c37): Verkleinern + Out-of-Bounds-Liste + Filter — resize_preview() listet je Kategorie (Objekte nach Anker-Regel, Bauteile nach Fußabdruck-"punkte" mit Rotation, Spawn-Punkte nach Punkt-Regel; Kante exakt = drin, Rand-Überlapper bleiben unange tastet), resize_apply(doc, x, z, drop_outside) resampelt wie R1 und entfernt bei Bedarf genau die gelisteten Einträge (Eingabe-doc bleibt rein). Shrink 512→256: Terrain an Weltposition 1:1 (±0.05 m), res bleibt 129 (2 m/Punkt). Tests: 19 neue Checks in test_terrain (Preview/Filter/Roundtrip), 11 Suiten ALL OK (920 Checks). 2026-10-17 18:56:10 +00:00
Hermes (godot-vr)
2d8b9822f0 Map-Editor R1 (t_0d436687): Resize-Kern + Vergrößern — SvmapDocument.resize_terrain(), Anker Mitte/Rand flach, Dichte-Leiter 129→257→513.
Semantik aus PLAN.md „Map-Größe ändern" (17.10., Sly-geankert):
- Anker Mitte: Karte bleibt am Ursprung zentriert, bestehendes Terrain behält
  seine WELTPOSITION (bilinear resampeln, kein Stretch).
- Neue Randzone: flach auf min_height + Material 0 (Gras), wie create_new.
- Dichte-Regel: würde m/Punkt über ~2 sinken, res hoch 129→257→513
  (Format-Limit 513 hart — darüber Warnband, Anzeige in R3).
- size clamp 256–4096 m (MIN_SIZE_M/MAX_SIZE_M), bounds auf neue Größe
  (Y-Grenzen unverändert).
- R1-Schnitt: spawn_zones/objects/gebaeude unverändert übernommen (Filter +
  Out-of-Bounds-Dialog kommen in R2). Reine Funktion — Eingabe-doc bleibt
  unangetastet (Undo-Snapshot), alte Prüfsumme verworfen (save signiert neu).

Tests (test_terrain.gd, 22 neue Checks → Suite 134/134, 11 Suiten ALL OK):
Grow 256→512 — alte Gridpunkte ±0.01 m an Weltposition, Rand flach/Gras,
Material resampelt, res-Bump 129→257 (bei 2048 m gedeckelt auf 513),
spawn/object-Erhalt, svmap-v2-Roundtrip, Clamp.
2026-10-17 18:48:21 +00:00
Hermes godot-vr
b85e3bed52 Map-Editor: Höhenlinien nur im Terrain-Werkzeug (t_89c0ec95)
Sly-Wunsch 17.10.: "die Dauersicht stört" — die Konturen sind genial, aber
nur im Terrain-Werkzeug (F1) gewünscht.

Kopplung am Werkzeug-Wechselpunkt: _set_tool_mode, _after_structure_change
und _recheck_terrain_mode eichen die Konturen NACH (effektiv = Nutzer-Fix
ODER Terrain-Werkzeug). Kein _process-Poll — die Umschaltung passiert
synchron im selben Aufruf, hart ohne Fade (billig und deterministisch).

NEU: Taste L (Action editor_contours_toggle; L war sonst unbesetzt —
Kollisions-Prüfung im Test) und der Button „≈ Höhenlinien" fixieren die
Linien als NUTZER-Wahl dauerhaft in jedem Werkzeug. Default = Fix AUS,
Linien erscheinen also nur bei F1.

Regression aus dem Fundus gefixt: _after_structure_change baute
terrain_view neu OHNE Kontur-Nacheich (das Gitter hatte ihn, die Linien
nicht) — nach jedem Strg+Z kehrte die Dauersicht zurück. Der Rebuild
bekommt jetzt denselben Nacheich wie das Gitter.

Das Relief-Shading (Hillshade + Höhen-Kurve) bleibt davon unberührt und
immer an. Auf flachen Maps (< 2 m Relief) schaltet der Shader weiter
selbst auf aus.

Doku: docs/tasten.md (L-Zeile in Werkzeuge + Kopplungs-Absatz) und
H-Overlay-Zeile (help_text.gd).

Tests: test_shortcuts +5 Checks (Action registriert, physische Taste L,
Kollisions-Freiheit, L ≠ F1/H). test_gui_smoke +21 Checks am ECHTEN main:
Start AUS · Undo/Rebuild bleibt AUS (Root-Cause-Regression) · F1 ein →
F2/F3/F4 aus (synchron, 0 Frames Poll) · L-Fix an/aus inkl. Button-Sync
und Statusmeldungen · Button-Weg ditto.
Suite 11/11 ALL OK: ux 137, shortcuts 203, editor_svmap 31, terrain 112,
library 94, glb_view 28, spawns 52, testrun 14, bauen 87, gui_smoke 89,
rmb_vorrang 32.
2026-10-17 18:24:45 +00:00
Hermes (godot-vr)
d6a0fe2196 Relief-Nachreich (t_3ebe4086): relief_color klammaert Kanaele auf 0..1 — der Mesh-Speicher ARRAY_COLOR/RGBA8 clamp't genauso, der Helfer muss die Render-Wahrheit liefern, sonst liegt der Probe-Vergleich um >0.05 daneben. Live-Material-Test t_55ed041a erwartet jetzt dieselbe relief_color-Formel statt der alten 0.72..1.15-Konstanten. Suite: test_terrain 112/112, 11 Suiten ALL OK. 2026-10-17 18:06:39 +00:00
Hermes (godot-vr)
ffb27645d4 Terrain-Relief lesbar machen (t_3ebe4086) — Sly-Befund 17.10. "Erhoehungen/Vertiefungen kaum erkennbar, alles knallgruen und hell".
1) Hoehen-Faktor kontrastreicher kalibriert: S-Kurve t*t*(3-2t) statt linear, Spanne 0.72..1.15 -> 0.58..1.28 (Senken deutlich dunkler, Huegel deutlich heller).
2) Pseudo-Licht (Hillshade) in den Vertex-Farben: Terrain-Normale x feste Sonnenrichtung RELIEF_SUN=(0.45,0.75,0.5) (seitlich-hinten fuer den Default-Blick), Licht-Faktor 0.62..1.22, Gesamtklemme 0.40..1.35. Formel/Konstanten IDENTISCH zum Match-Client (svmap_terrain.gd im scopedvr-client-Repo) — relief_color() static, Material-Farben unangetastet.
3) Editor-only Extra: Hoehenlinien alle 1 m + kraeftige 5-m-Indexlinie (terrain_contour.gdshader, UV2.x = Vertex-Hoehe, fwidth-stabil, unshaded). Der Quest-3-Vertrag "kein Custom-Shader" gilt fuer das SPIEL — der Editor darf teurer sein (DECISIONS-Konvention); der Match-Client bleibt StandardMaterial3D. Flach-Map-Schutz: Linien erst ab 2 m Gesamtrelief, UI-Toggle "≈ Hoehenlinien" (Default AN, nach jedem Rebuild re-synchronisiert).
Material unshaded: das gebackene Shading ist exakt das sichtbare (kein Doppel-Shading mit dem Viewport-Sonnenlicht), deterministisch fuer die Render-Probe.

Tests: test_terrain +19 Relief-Checks (99 gesamt): Tal/Huegel-Delta > 0.10 UND > 1.2x alte Kalibrierung, Hang-zur-Sonne heller, Stufen-Kanten-Delta > 0.08 UND > 1.2x alt, Materialfarben (Gras/Sand/Fels) unterscheidbar, Alpha=1.0, Kontur-Toggle + Flach-Map-Schutz. Suite 11 Suiten ALL OK: test_ux 137, shortcuts 198, editor_svmap 31, terrain 99, library 94, glb_view 28, spawns 52, testrun 14, bauen 87, gui_smoke 68, rmb_vorrang 32. (Hinweis: gui_smoke-F5 schlug in DIESEM Workspace nur wegen des scopedvr-client-Symlinks neben dem Editor auf — TestRun.find_client findet den Client dann wirklich; ohne Symlink = Standard-Layout: 68/68.)
Renderprobe (xvfb, opengl3): tests/probe_terrain_relief_render.gd — Stufen-Delta 0.149 (>0.10), Hoehenlinien Pixel-Diff 0.167, Huegel/Senke-Fenster-Delta 0.225 — ALL OK 3/3; PNGs im Scratch (terrain_relief_stufe.png, terrain_relief_demo.png).
Housekeeping: fehlende .png.import-Sidecars der M2-Natur-Thumbs nachgereicht.
2026-10-17 18:05:20 +00:00
Hermes (godot-vr)
e1c737df61 Terrain: Material-Farben bleiben LIVE während Heben/Senk-Stroke (t_55ed041a) — Live-Rebuild bekommt die Material-Schicht mit
Sly-Befund: Beim Heben/Senken über gemalten Sand/Fels verschwanden die
Material-Farben live (alles Gras), erst am Stroke-Ende kehrten sie mit
dem Vollrebuild zurück.

Root-Cause: terrain_tool rief im Live-Pfad (Heben/Senken/Glätten)
update_terrain(_heights) OHNE Material-Schicht auf — _mats wurde nur im
Malen-Modus dekodiert — und terrain_mesh fällt bei leerer Schicht auf
alles-Gras zurück (Legacy-Fallback).

Fix (zwei Ebenen):
- terrain_tool._refresh_from_doc dekodiert die Material-Schicht immer,
  der Live-Stroke übergibt sie mit (Heben/Senken/Glätten wie Malen).
- terrain_mesh cached die zuletzt gesehene Schicht: Live-Updates ohne
  mats-Param nutzen denselben Farb-Pfad wie der Idle-Rebuild; Legacy-v1
  (nie gesehene Schicht) bleibt alles Gras — kein Phantom-Cache.

Test: tests/test_terrain.gd neue Gruppe „Live-Material-Farben" —
per-Frame-Check (5 Frames Heben über Sand-Zone, nicht nur Endzustand),
terrain_tool-Integration (Heben-Stroke übergibt Sand-Schicht, Stroke-Ende
= EIN Commit), Legacy-Gras ohne Phantom-Cache. Suite: 99 checks ALL OK;
alle weiteren Headless-Suiten grün (test_glb_view 12/22 FAIL ist
vorbestehend auf origin/main — GLB-Quellen fehlen im Workspace).
2026-10-17 17:51:07 +00:00
Hermes (godot-vr)
db6bcec971 Flugmodus-Tasten: Leertaste=hoch, Shift=runter, Strg=schneller (Sly 17.10., Shooter-Konvention)
- InputMap (shortcut_keys.gd): editor_fly_up=Space, editor_fly_down=Shift,
  editor_fly_fast=Ctrl (vorher E/Q, Shift=fast). E/Q sauber entfernt, keine
  Aliasse (Sly-Freispruch). Alt=langsamer unveraendert, Mausrad bleibt
  Grundtempo.
- Konflikt-Check (verpflichtend): Space/Shift/Ctrl allein triggern KEINE
  Werkzeug-Aktion — neue Testgruppe prueft InputMap-Matches (kein Undo/Save/
  Redo/Pinsel/Freelook-Toggle ohne Combo-Partner) + echtes Terrain-Werkzeug:
  Tasten-Events starten keinen Strich. Strg+LMB-Senken bleibt LMB-gebunden,
  Entf/Strg+Z unangetastet.
- orbit_camera._enter_fly gibt den GUI-Fokus frei, damit Leertaste keinen
  fokussierten Button ausloest (Space=ui_accept, Bibliothek=Platzierung).
- Livetest: Leertaste hebt/Shift senkt die Kamera im Flug (orbit_camera).
- Docs: docs/tasten.md, H-Overlay (help_text.gd), README, Status-/Hilfe-
  Texte der Kamera aktualisiert.
- Test-Hygiene: _test_camera_fly_roundtrip ist jetzt Coroutine (await),
  view_yaw-Orbit-Toleranz 0.01 Grad (float32-Rundtrip-Drift ~2e-4 Grad/Exit).
- Suite: 11 Suiten gruen (test_shortcuts 198 checks).
2026-10-17 17:45:37 +00:00
Hermes (godot-vr)
d6c472603f Build-Tool: ray_pick ohne 500-m-Cap (t_555e33da) — Umschalt+Klick/Baustapel-Pick funktioniert jetzt auch im Default-Framing (~614 m Kamera-Distanz); Workaround-Zoom im RMB-Test entfernt. 2026-10-17 17:39:30 +00:00
Hermes (godot-vr)
7521db7f8d Map-Editor: RMB = Flug mit absolutem Vorrang (t_2470de89) — Terrain-Senken auf Strg+LMB, Hand-Objekt-Abwurf auf Esc.
- Terrain-Pinsel: Rechtsklick startet keinen Strich mehr; Strg+LMB invertiert
  (Heben↔Senken, Blender/Photoshop-Konvention; Malen: Strg+Klick = Gras zurück).
- Platzieren: RMB bricht nicht mehr ab — Objekt bleibt in der Hand, Abwurf nur
  über Esc. build_tool/spawn_tool: RMB-Deselect/Werkzeugwechsel entfernt
  (Auswahl-Deselect = Esc / LMB auf Leere).
- orbit_camera: rmb_filter entfernt — Flug startet in JEDEM Werkzeugzustand.
- docs/tasten.md + H-Overlay + Status-/Paneltexte aktualisiert.
- Neuer Test tests/test_rmb_vorrang.gd (32 Checks, echte Main-UI headless);
  in tools/run_tests.sh aufgenommen. Suite grün (test_glb_view: 12/22 FAIL auch
  auf origin/main — fehlende GLB-Quellen im Scratch-Workspace, umgebungsbedingt).
2026-10-17 17:37:09 +00:00
slyphax
cda6f48b01 GLB-View (t_9b50b231): echte Modelle im Editor-Viewport — Platzhalter nur als Fallback.
- GlbMeshStore (neu): laedt OID+.glb aus konfigurierbaren Quellen
  (ProjectSettings scopedvr/editor/glb_quellen, Voreinstellung =
  Sibling-Repos, wie gen_thumbs; plattformneutral, relative Pfade),
  backt ALLE MeshInstance3D der Szene in EIN normalisiertes ArrayMesh
  (Fusspunkt y=0, XZ zentriert — wie scopedvr_export.normalisiere),
  Materialien/Texturen bleiben je Oberflaeche erhalten.
- Cache pro OID (Parse nur einmal; fehlende Datei ungcached, Parse-Fail
  negativ gecached).
- map_view_builder: echtes GLB vor Platzhalter; kein half_height-Lift
  (schon Fusspunkt-Koordinaten), Scale ueber Node-Scale + AABB-Metas
  mal Scale; Auswahl-Orange nur als Override im Auswahl-Zustand
  (Texturen bleiben sichtbar). fehlende_glbs-Meldung an die Stats-Zeile.
- interaction (Ghost-Preview): nutzt denselben echten Mesh-Pfad;
  Platzier-Status haengt „(Platzhalter — echte GLB fehlt)“ an.
- tests/test_glb_view.gd (neu, in run_tests.sh): Moosfelsen-Probe
  (echtes GLB > Platzhalter-Vertices), stein_mittel_1 1026>>36,
  Normalisierung y=0/XZ-zentriert, Cache-Identitaet, Viewport-Rebuild
  Fusspunkt == Terrainhoehe (b20dff2), Fallback + fehlende_glbs.
  Suite: 773 checks, alle gruen.
2026-10-17 17:23:56 +00:00
Hermes (godot-vr)
afcbda8dd0 Shortcuts 3/3 (t_11b5c25b): Strg+O/N/Umschalt+S + Redo-Wege dokumentiert, F1-F4 Werkzeugwechsel, H-Kurzhilfe-Overlay, F5 Karte testen, Dirty-Schutz vor Neu/Oeffnen, permanente Werkzeug-Anzeige in der Statuszeile. 2026-10-16 17:58:34 +00:00
Hermes (godot-vr)
08a75ac430 Shortcuts 2/3 (t_55257792): R-Drehen + Pfeil-Raster + PgUp/Down + Strg+Bild↑ + Greifen + Terrain-Pinsel-Tasten.
- R = Auswahl 90° drehen (Szene um Auswahl-Mitte, Bauen-Bauteil um Fußpunkt, Gruppe komplett; Umschalt+R = -90°), Mausrad-Feindrehen 15° bleibt
- Pfeiltasten = 2-m-Raster-Verschiebung, Richtung = Kamera-Blickrichtung auf nächste Weltachse gerastet (MoveMath.nudge_delta, pure)
- Bild↑/↓ = ±0,25 m auf der GANZEN Auswahl (EIN Undo), Strg+Bild↑ = Fußpunkt aufs Terrain/Boden absetzen
- G = Greifen (Blender-Semantik): Auswahl hängt an der Maus, LMB setzt mit Raster-Snap, Esc rollt byte-genau zurück (ShortcutPolicy cancel_grab)
- Terrain-Pinsel: [ / ] = Preset-Zyklus Klein/Mittel/Groß (Slider/Label/Preset-Buttons wandern mit), 1-4 = Heben/Senken/Glätten/Malen (PAINT-Clamp-Fix, Palette mit Malen sichtbar); Ziffern NUR im Terrain-Werkzeug
- Strg halten = temporärer Snap-Zwang beim Bewegen/Greifen/Platzieren
- Tests: test_shortcuts.gd 157 Checks (R byte-genau, Pfeil-Raster, Lift-Stufen, Boden-Snap, Greifen+Esc, Pinsel-Zyklus, History-Eintrag pro Operation), test_gui_smoke.gd erweitert (38 Checks) und in run_tests.sh aufgenommen; F-Regression seit Karte 1 damit abgedeckt
- Suite 9/9 grün (696 Checks), Builder-Export 21/0, Parse-Check 11 Dateien grün
2026-10-16 17:53:10 +00:00
Hermes (godot-vr)
095af5ff3c Shortcuts 1/3 (t_c46d31c2): Freelook-Flug + F-Focus + Esc-Policy + Entf-Mehrfachauswahl + Strg+D (+2 m X) + Strg+LMB-Mehrfachauswahl.
- InputMap-Actions mit physischen KEY_*-Codes (shortcut_keys.gd, idempotent) — DE-Layout/Windows-unabhängig
- Freelook: RMT halten = Umsehen+Flug (WASD/EQ, Shift x3, Alt x0.3, Rad = Grundtempo dauerhaft), Shift+F toggle; Orbit bleibt Default, Flug-Exit ohne Kamera-Sprung (FlyMath pure)
- F zentriert Auswahl (SelectionMath.focus_center); Esc = pure Prioritätskette (ShortcutPolicy)
- Strg+LMB + Baum SELECT_MULTI: Mehrfachauswahl synchron Szene↔Baum; Entf/Strg+D wirken auf die ganze Auswahl (EIN Undo-Schritt)
- docs/tasten.md = deutsche Source of truth (Karten 2/3 ergänzen)
- Tests: test_shortcuts.gd NEU 70 Checks, Suite 571 grün, Builder-Export 21/0, Parse-Check grün
2026-10-16 17:43:17 +00:00
Hermes (godot-vr)
b20dff2b5d Terrain C (t_4092e3a0): Objekt-Platzierung == Ghost-Preview — EIN Platzier-Pfad, Fusspunkt auf Terrainhoehe.
Root-Cause: Ghost-Preview und Platzierung nutzten zwei unterschiedliche
Pfade/Strukturen — der Ghost-Root trug den halben Mesh-Lift selbst
(Root=Y+half), das platzierte Objekt hebt nur das Kind-Mesh; die
Platzierung rastete X/Z und hob Y auf terrain_height_at des UNGERASTETEN
Punkts. Bei Raster-Snap und an Haengen wich die platzierte Position von
der Vorschau ab.

Fix — EIN Pfad (ObjectOps.placement_foot): Raster-Snap auf X/Z, dann
Y = Terrainhoehe am GERASTETEN Punkt (SvmapDocument.terrain_height_at).
Ghost-Root = Fusspunkt, Kind-Mesh um half_height gehoben — identische
Struktur wie map_view_builder. Objekt-Cursor trifft jetzt das GELAENDE
(TerrainField.raycast, gleicher Pfad wie Terrain-/Bauen-/Spawn-Werkzeug)
statt der flachen Basis-Ebene; Hoehen-Cache dekodiert einmal pro
Struktur-Aenderung (refresh_terrain_cache aus _after_structure_change).

Tests (test_library 40->94 Checks): Platzier-Fusspunkt (Rampe 0..20 m:
Fusspunkt == Terrainhoehe, Ghost-Pfad == Platzierungs-Pfad, Raster-Snap-Y
am gerasteten Punkt), Registry-Fusspunkt (alle 54 Objekte: Mesh-Unterseite
== pos, kein Schweben/Eingraben), Ghost-Preview == platziertes Objekt mit
simulierter Kamera (Treffer-Zelle == Cursor-Zelle, <5 cm). Editor-Suiten
501 Checks gruen, Builder-Export 21/0, GUI-Smoke 20 gruen.
2026-10-16 17:36:30 +00:00
Hermes (godot-vr)
e505329a42 Terrain B (t_234490cf): Pinsel-Position == Cursor-Position — Ray→Terrain-Mapping gefixt
Root-Cause 1 (Spiegelung): terrain_mesh.gd positionierte die Mesh-Vertices
gespiegelt (+0.5 − index·cell in X UND Z), während ALLE anderen Verbraucher
der Heightmap der Dokument-Konvention folgen (Index 0 = −X/−Z-Ecke):
SvmapDocument.terrain_height_at, TerrainField.height_at/apply_brush und der
Match-Client (svmap_terrain.gd). Der Renderer war der einzige Ausreißer —
der Pinsel-Strahl traf das gerenderte Mesh punktgespiegelt um die Map-Mitte
(Sly-Befund: Erhöhung erschien an ganz anderer Stelle). Fix: Vertices auf
−size*0.5 + index*cell (identisch zum Client), Normalen-Vorzeichen angepasst
(n ∝ (−∂h/∂x, 1, −∂h/∂z)); Winding bleibt gültig (180°-Rotation erhält die
Orientierung, Kreuzprodukt-Normale weiter nach unten = Frontseite).

Root-Cause 2 (Tangenten-Graze): Ein Strahl, der exakt auf eine Hügelkuppe
zielt, grast die gewölbte Oberfläche — f(t) bleibt minimal knapp über 0 und
steigt danach wieder, obwohl weiter hinten (VERDECKT hinter dem Hügel) noch
ein Vorzeichenwechsel an der Basis-Ebene lag. Der March lief durch und der
Pinsel sprang auf den verdeckten Basis-Punkt meterweit weg. Fix in
TerrainField.raycast: Regel 'erster sichtbarer Oberflächen-Kontakt gewinnt' —
kommt f innerhalb des Bandes (½ March-Schritt) an die Oberfläche und entfernt
sich der Strahl wieder, wird das Graze-Minimum lokal per Ternärsuche
verfeinert und als Treffer zurückgegeben. Echter Treffer (f ≤ 0) gewinnt
weiterhin immer; betrifft auch Bauen-Werkzeug und Spawn-Zonen (gleiche
Raycast-Routine).

Tests (test_terrain.gd, 64 → 86 Checks): Neue Gruppe 'Ray→Terrain-Mapping'
mit simulierter Kamera (SubViewport, schief + steil): exakter Screen-Punkt
(unproject) → project_ray → raycast → asserted Treffer-Zelle == Cursor-Zelle
(< 1 Zelle) auf Mitte/Innenraum/Corner/Kanten; Brush-Stroke am Treffer mit
Höhen-Änderungs-Zentrum == erwarteter Zelle; erhabenes Terrain (Strahl trifft
NEUE Oberfläche, y = Hügelhöhe); Mesh-Vertices komplett gegen die
Dokument-Konvention asserted (Root-Cause-Regression). Hügel-Normalen-Checks
auf die korrigierte Konvention umgestellt (lehnt jetzt −X/−Z).

Suite: 7 Editor-Suiten 463 Checks grün + Export 21/0 + GUI-Smoke 20 grün.
2026-10-16 17:27:19 +00:00