Commit graph

148 commits

Author SHA1 Message Date
slyphax
5a70824dd5 Malen mit Symmetrie: Überlappung beider Seiten nimmt den stärkeren Anteil (stetig statt Mittelsenkrechten-Kante)
Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
2026-10-25 00:55:18 +02:00
slyphax
7f06e28472 Malen mit Symmetrie: nur wirklich bemalte Punkte spiegeln (harte gerade Kanten weg)
Sly 25.10.: „teilweise sehr harte Kanten in den Übergängen“. Ursache: bei
aktiver Symmetrie kopierte jeder Mal-Schritt das GANZE Snapshot-Quadrat um
den Pinsel auf die Gegenseite — dort vorhandene weiche Verläufe wurden an
den Quadratkanten gerade abgeschnitten. Jetzt werden nur Punkte gespiegelt,
die der Schritt verändert hat; überlappen beide Seiten, gewinnt wie bisher
der näher am Strichpunkt liegende Wert.
Test: test_terrain_mirror 109/109 (neuer Fall schlägt mit altem Code fehl).

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
2026-10-25 00:50:09 +02:00
slyphax
4e973795f6 Malen: echter weicher Übergang am Pinselrand (Misch-Schicht statt Streuung)
Sly 25.10.: „weich“ soll ein Textur-Verlauf am Pinselrand sein, nicht fleckig;
gerade Strichkanten wirkten weiter hart (1-m-Übergang).
- Format (optional, alte Karten gültig): materials_b_r8_b64 (zweites Material
  je Punkt) + materials_w_r8_b64 (Anteil 0–255); ohne Mischung fallen die
  Felder weg. V15 prüft Länge/IDs/Paarigkeit.
- TerrainField.apply_material_brush_mix: innen voll, außen Smoothstep-Anteil;
  nur verstärken, nie abschwächen; Gras drübermalen mischt zurück.
- Shader: Top-2 aus 4 Nachbarpunkten × (a, b) mit Anteilen → nur noch 2
  Albedo-Fetches; Warp bleibt.
- Pinsel/Live-Vorschau, Spiegeln, Symmetrie-Analyse/-Anwenden, Resize,
  Anheben, Undo (terrain-Snapshot) tragen die Misch-Schicht mit.
- Streu-Rand (vorheriger Commit) entfernt.
- Tests: test_mal_fein 30/30 (Verlauf fällt weich, nie abschwächen,
  zurückmischen, Kodierung), Editor-Suite unverändert grün bis auf die
  bekannten Umgebungs-Tests; Kette Editor → Server → Client per
  run_map_download_e2e 15/15 mit gemischter Karte.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
2026-10-25 00:43:26 +02:00
slyphax
4a7b99ee3e Malen: Regler „Kante hart ↔ weich“ + Pinsel ab 1 m
Sly 25.10.: harte Kanten an Strichrändern, Pinsel auf 1 m, Regler für die
Kantenschärfe.
- apply_material_brush(…, weichheit): im äußeren Anteil des Radius wird
  gestreut ausgedünnt (fester Hash je Punkt → deterministisch, Nachmalen
  füllt nicht auf); der Shader macht daraus einen ausfransenden Übergang.
  Kein Formatwechsel (ein Material je Punkt bleibt).
- Panel: Regler 0–100 % (Default 40 %), nur im Malen-Modus; Pinselgröße ab 1 m.
- test_mal_fein 26/26 (Dichte fällt nach außen, deterministisch, 1-m-Pinsel),
  test_terrain_mirror an die Tool-Weichheit angepasst.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
2026-10-25 00:30:16 +02:00
slyphax
40ca5ab6ba Terrain-Malen: weiche, organische Kanten statt 1-m-Pixelblöcke
Sly 25.10.: „immer noch harte Kanten beim Malen“. Ursache: die Splat-Textur
hatte beim feinen 1-m-Raster genau einen Texel je Materialpunkt und wird
nearest gesampelt → jede Zelle ein harter Block.

- Shader liest die Material-ID-Karte (R8, ein Texel je Punkt, texelFetch)
  und mischt PRO PIXEL bilinear über die 4 Nachbarpunkte.
- Leichter Domain-Warp (Value-Noise in Rasterzellen, eine Oktave) verwackelt
  die Abtaststelle → keine Rastertreppen, natürliche Kante.
- Malen aktualisiert nur noch die Bytes der Karte (kein Splat-Neuberechnen).
- TerrainArrays.material_image (Spiegel-Datei, identisch im Client).
- Render-Probe tests/probe_mal_weich_render.gd (vorher/nachher geprüft).

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
2026-10-25 00:23:18 +02:00
slyphax
69668eb250 Feines Material-Raster: Malen auf ~1 m statt Höhenraster (bei 1024 m vorher 8 m)
Sly: „feiner malen“. Die Material-Schicht bekommt ein eigenes Raster
(terrain.material_resolution, optional; Default = resolution → alte Karten
unverändert gültig): ~1 m pro Punkt, auf dem Höhenraster ausgerichtet,
max. 1025 (1024 m → 1025, 256 m → 257, 2048 m → 1025 = 2 m).

- SvmapIO: material_resolution / material_resolution_for / resample /
  upgrade_material_layer / material_at_height_point; V15 prüft Raster + Länge.
- Neue Karten starten fein; beim Öffnen werden alte Karten optisch identisch
  angehoben (Datei ändert sich erst beim Speichern); Resize rechnet die
  Schicht auf ihrem eigenen Raster an der Weltposition um.
- Pinsel, Spiegeln (Symmetrie live + „Symmetrie anwenden“) und Live-Splat
  arbeiten auf dem Material-Raster; Vertex-Farben lesen den passenden Punkt.
- Malen-Hinweis zeigt die echte feinste Einheit.
- Tests: test_mal_fein 22/22 (Raster, Anheben, 2-m-Pinsel ≈ 13 Punkte,
  V15, Roundtrip, Resize); test_terrain/test_terrain_mirror/
  test_symmetry_onclick auf das neue Raster nachgezogen; Identitäts-Runner OK.
  Kette Editor → Server (Prüfsumme) → Client per run_map_download_e2e 15/15.

Format-Spiegel: Match-Server svmap_loader (V15) + Client svmap_terrain.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
2026-10-25 00:07:25 +02:00
slyphax
66df3bdc1e Editor: Klick wählt das exakt getroffene Objekt (Mauer statt Nachbar-Gebäude) + Malen-Hinweis statt Stärke-Regler
- _pick_object: Kugel-Näherung nur noch Vorfilter, entschieden wird über den
  echten Mesh-Treffer (SelectionMath.ray_mesh_distance, Faces gecacht).
  Ohne Mesh-Treffer bleibt die alte Kugel-Wahl als Fallback.
- Terrain-Panel: im Malen-Modus ist der Stärke-Regler weg (Malen setzt das
  Material zellenweise, Stärke hatte nie eine Wirkung); stattdessen steht die
  feinste Mal-Einheit der Karte da (size / (resolution - 1)).
- Tests: test_klick_exakt 6/6 (reproduziert Gebäude-Kugel vor Mauer),
  test_mal_hinweis 4/4. Vorhandene Suiten unverändert (4 schon vorher rote
  Umgebungs-Tests: assets_panel, identitaet_client, model_sources,
  playtest_identitaet).

Ersetzt die nie gepushten Arbeitskopie-Änderungen der Karten t_12feca66 /
t_c487a430 / t_271a77bd (Material-IDs per lerp gemischt, Sub-Zellen ohne
Client/Server-Unterstützung).

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
2026-10-24 23:27:48 +02:00
Hermes (scopedvr-dev)
1d8763b881 Karte t_5c94d098 Terrain-Blending v2: Splat-Texel-Dichte folgt der KARTENGROESSE
Gleiche Ursache wie im Client (BEWEISE.md in work/terrain_blending_v2_t_5c94d098_bilder/):
splat_side_for(129) = 512 px = 2 m/Texel auf der 1024-m-Standardmap (8 m/Zelle)
-> Gewichtsrampe in 2-m-Stufen, sichtbar als Baender/Stufen an der Materialgrenze.

Aenderung Editor:
- library/terrain_arrays.gd (Spiegel-Datei, byte-identisch zum Client):
  splat_side_for(res, map_size_m = 0.0) = MAX(4 Texel/Zelle, 1 m/Texel aus der
  Karten-Kantenlaenge), Zweierpotenz, geklemmt [256, 1024]; build_splat_bytes
  ohne Allokation je Texel + Schnellpfad (gleiche ID in allen vier Nachbarzellen)
  -> unveraenderte Bytes, deutlich schneller.
- src/viewport/terrain_mesh.gd: _build_splat bekommt size_x/size_z und gibt sie an
  splat_side_for; der Live-Sub-Rect-Pfad greift nur noch, wenn auch die
  Kantengroesse stimmt (Size-Aenderung ohne res-Aenderung baut die Splat neu).
- tests/test_terrain_splat.gd (Spiegel, identisch im Client): +6 Kartenmass-Checks
  (31/31).

Suiten (frischer Forgejo-Klon): test_terrain_splat 31/31, test_terrain 155/155,
test_terrain_mirror 106/106.
2026-10-22 19:37:30 +00:00
Hermes (scopedvr-dev)
04c6c67ba8 Karte t_7a0a6b79 Terrain-Qualitaet: Splat-Top-2-Blend (weiche Uebergaenge), Live-Sub-Rect beim Malen, Ausbrennen-Fix (Shading-Normalisierung) 2026-10-21 22:12:04 +00:00
Hermes (scopedvr-dev)
f5a4ab54d0 Wasser pro Map (t_28fdef03): V20-Validator, Panel-Regler, Vorschau-Renderer
- src/svmap/svmap_io.gd: _validate_wasser (V20) — optional, endliche Zahl,
  Terrain-Hoehenbereich +/-10 m; identisch zum Match-Server
- src/ui/panels/map_panel.gd: Regler 'Wasserhoehe' mit Sofort-Rebuild;
  ganz links (-10) = Feld ENTFERNEN (Legacy-sauber, keine Migration)
- src/viewport/map_view_builder.gd: _build_wasser nach _build_terrain
  (Senken fuellen sich); Legacy ohne Feld = kein Wasser-Node
- src/viewport/terrain_mesh.gd: Matsch-Ring in relief_color (Ufer-Faktor,
  dieselbe Formel wie der Client)
- library/svmap_wasser.gd + src/viewport/wasser.gdshader: Spiegel-Modul,
  byteidentisch zum Client (Identitaets-Vertrag der Vorschau)
- tests/test_wasser.gd: 33 Checks (W1 V20, W2 Panel, W3 Vorschau + Matsch-Mathe, W4 Spiegel)

Verifiziert: Editor-Suite 33/33, test_editor_svmap 31, test_terrain 155,
test_gui_smoke 92, test_skybox 23 — alle OK
2026-10-21 06:13:59 +00:00
Hermes (scopedvr-dev)
8468b89456 Terrain-Textur-Panel + Editor-Spiegel (t_ab408127): Terrain-Panel zeigt die 20 CC0-Materialien; terrain_mesh bindet terrain_arrays.res (Spiegel aus Client via tools/sync_terrain_tex.sh, Ordner OHNE .gdignore — ResourceLoader braucht den Index); TerrainArrays-Klasse spiegelgleich in library/ (identischer Pfad wie im Client — .res-Script-Pfad löst in beiden Repos auf); Kontur-Shader bekommt Textur-Sampling + Höhenlinien; V15-Test auf neue Palette (ID 20 abgelehnt, 3 gültig); test_terrain 155/155 2026-10-21 00:48:41 +00:00
Hermes (scopedvr-dev)
338e7152a0 ALLES Trimesh (t_ff7fc919): Registry + 250 Kollisions-Suppen synchron; KolliderBau.hindernis_aabb aus der Suppe (Spiegel Client/Server); Identitäts-Probe um Trimesh-Fälle erweitert (12 IDENT-Zeilen, ALL OK) 2026-10-20 22:58:42 +00:00
Hermes (scopedvr-dev)
42a205b6ff Platzierungsfreiheit (t_e166e656): Scale-Zeile entfernt (Groesse fix), Kippen X/Z (rot-Feld, Strg+R/Alt+R, Ghost + Platzierung), Versenken unter Terrain erlaubt + Tiefe-Anzeige, Spiegel-Mathe 3 Achsen, KolliderBau rot + hindernis_aabb, Suiten + Identitaets-Runner 2026-10-20 22:32:10 +00:00
Hermes (scopedvr-dev)
78d311c75f Atmosphaere & Skybox (t_f72913d4): Render-Probe Editor-Vorschau (Panorama vs. Prozedural, xvfb/opengl3) 2026-10-20 22:11:30 +00:00
Hermes (scopedvr-dev)
0505463ace Atmosphaere & Skybox (t_f72913d4): Map-Option „Himmel: Pack-Skybox“ (weather_sky=sky_panorama, checksum-neutral), Vorschau = 1:1-Spiegel Client-Wetter (ACES/Fog/sun_deg/Panorama via Nachbar-Klon), V17-Validator; Suite test_skybox 23/23 2026-10-20 22:10:36 +00:00
Hermes (scopedvr-dev)
35a1d80d3e svmap: Prüfsummen-Repair-Dialog „Trotzdem laden“ (t_9814f18f) 2026-10-20 22:05:53 +00:00
Hermes (scopedvr-dev)
65b33a207a svmap: Prüfsummen-Schema v2 (t_9814f18f)
- sign_map schreibt schema=v2, Hash über die quantisierte Payload
  (12 signifikante Stellen, Snap über die Godot-Textform → idempotent)
- save_to_file quantisiert VOR dem Schreiben → Dateien ohne Rausch-Floats
- Laden: schema=v2 → v2-Hash; fehlt → Legacy-Fallback (Bestandskarten)
- FirstFight-Fall: Python-repr-Floats (15+ sig) hashen formatunabhängig
- Beweise: tests/test_svmap_checksum_v2.gd (18 Checks, ALL OK);
  echte FirstFight.svmap lädt nach v2-Resave, cross-validiert im Server
2026-10-20 21:33:28 +00:00
Hermes (scopedvr-dev)
7a1b5037e7 Playtest: Splitter-Lagen bleiben erhalten (Sly-Befund 20.10.)
Beim Start des Test-Modus versteckt der Editor die Panels — Godot
klappt dabei die Splitter zusammen (Lage springt z. B. [-320,0] →
[160]), beim Wiedereinblenden baut er die Trenner mit Defaults wieder
auf → die fein gezogenen Seitenbereiche waren weg („riesen groß").

Fix in main.gd (besitzt die UI, überlebt den Playtest-Node): beim
Start alle split_offsets von MainSplit/BottomSplit sichern, im
Exit-Handler deferred UND im nächsten Frame zurücksetzen (das Layout
muss die Panels erst neu vermessen haben). Suite test_playtest 52/52
(mit Splitter-Regression: merken → verbiegen → Exit → unverändert),
test_ui_layout 79, test_gui_smoke 92 grün.
2026-10-20 21:21:05 +00:00
Hermes (scopedvr-dev)
812da1a261 Playtest-Avatar (t_17a35c59): Kommentar-Harmonisierung nach Rebase auf 52919b3
Beide WASD-Yaw-Fixes koexistieren (52919b3: Bewegung aus yaw_deg;
t_17a35c59: Koerper-Rotation fuer Avatar-Front + Third-Person-Kamera).
Die Kommentare behaupteten gegensaetzliche Fakten — jetzt konsistent.
Suiten: test_playtest_avatar 84/84, test_playtest 39/39.
2026-10-20 21:19:20 +00:00
Hermes (scopedvr-dev)
6f00737dd3 Playtest-Avatar (t_17a35c59): Spieler-Modell = Bot-Rig + First/Third-Person (Taste V)
- playtest_avatar.gd (NEU): Spiegel-Modul des Bot-Avatars (Quelle
  bot_avatar.gd/MatchRemoteAvatar) — UAL-GLB + m40-Rifle aus dem
  Nachbar-Klon ../scopedvr-client (GLTFDocument, kein Duplikat),
  AnimationTree-Pipeline 1:1 (BlendSpace1D Idle/Walk/Jog auf den
  Clip-Naturgeschwindigkeiten 0/0,979/2,620 m/s, sync, TimeScale-Kadenz
  nach BOT2: Schrittlängen 0,95/0,85 m, Klammern 1,0–4,5 / 0,6–2,0,
  Blend-Glättung 0,25 s), Gait-Schwellen 0,3/2,6 m/s aus der ECHTEN
  PlaytestBody-Geschwindigkeit, Frontachse +Z → MODEL_YAW_OFFSET = PI.
  Importer-Semantik nachgebildet: "_loop"-Endungen gestrichen +
  LOOP_LINEAR (GLTFDocument liefert rohe GLTF-Namen).
- playtest_body.gd: Körper trägt den Blick-Yaw (1:1 TestmapPlayer
  rotate_y — vorher weltachsen-fixierte WASD-Bewegung, Beweis-Probe),
  Avatar-Halterung (Kopf-Anker 1,65 m, GLB-Füße am Boden), Third-Person-
  SpringArm3D (3,5 m + 0,3 m Margin, eigener Body ausgeschlossen),
  toggle_perspektive/set_perspektive, horizontale_geschwindigkeit().
- playtest_settings.gd: persistenter Eintrag dritte_person (Default First).
- playtest_mode.gd: Avatar-Bau in enter() (graceful ohne Client-Klon:
  First Person + Klartext-HUD-Hinweis), Taste V, Gait-Speisung pro Frame,
  HUD-Hinweis + F1-Hilfe erweitert.
- settings_panel.gd: Perspektive-Auswahl (Erste/Dritte) im Einstellungen-
  Panel, live wirksam + persistiert.
- tests/test_playtest_avatar.gd (NEU, 84 checks): Identitäts-Vertrag gegen
  die Client-Quelle (Konstanten aus bot_avatar/match_remote_avatar/
  testmap_player gelesen), GLB-Ladung, Anim-Pipeline, Kadenz-Mathe,
  Modellhöhe == Kapsel == Client (1,83 m), Rifle-Mount, V-Umschalter +
  Persistenz, SpringArm (Blick zum Körper, kein Clipping durch Wand),
  Blickrichtung == Bewegungsrichtung, Playtest-Integration (enter + Gait).
2026-10-20 21:18:25 +00:00
Hermes (scopedvr-dev)
52919b36b4 Playtest: WASD folgt der Blickrichtung (Sly-Befund 20.10.)
Bug: Die Laufrichtung kam aus transform.basis des Körperknotens — die
Kamera-Drehung steckt aber im look_cam-Kindknoten, der Körper rotiert
nicht → WASD lief stur in eine Himmelsrichtung. Auf der Quest rotiert
der ganze Origin mit dem Kopf, dort trat der Bug nicht auf.

Fix: forward/right aus yaw_deg bauen (identisch zu view_direction(),
identisch zum Kopf-Yaw des Clients). Regression in test_playtest:
yaw 0° + W → -Z, yaw 90° + W → -X. Suite 39/39 grün.
2026-10-20 21:10:09 +00:00
Hermes (scopedvr-dev)
0cdf68622c Playtest-Physik = Quest 3 identisch (t_1da96275): CharacterBody3D + echte Kollider statt AABB-Blocking — KolliderBau (1:1-Spiegel svmap_world), Testmap-Player-Parameter (Kapsel 0.35x1.8, 6/14 m/s, Jump 4.5, Step-Up 0.45), Bauteil-Trimeshe (Treppe/Tür), Identitäts-Vertrag Suite (Editor vs. Client, 8 Entscheidungen identisch), FPS-Probe (Physik-Overhead 7%) 2026-10-20 21:01:37 +00:00
Hermes (scopedvr-dev)
fabbbcce20 Playtest-Kollision: echter Registry-Fußabdruck statt Pick-Radius-Kugel
Sly-Befund 20.10.: Im Editor-Testmodus hing man an unsichtbaren Wänden weit
VOR den Gebäuden. Ursache: _collect_obstacles nutzte die Viewport-Metas
pick_radius (Kugel-Näherung = volle Raumdiagonale + Zuschlag) — bei der
Kaserne (17×35 m) blockte das ~40×40 m. Die Trimesh-Fixes aus t_9558038d
wirken nur im Spiel-Client, der Editor-Playtest baut seine Blockierung
selbst (keine Physik-Welt, nur AABBs).

Fix: Hindernis-AABB aus der Registry (collision.size × scale, um rot_y_deg
konservativ gedreht, Y vom Fußpunkt bis Fußpunkt + Höhe — gleiche
Konvention wie der Client-Kollider). Fallback: Kugel-Näherung bleibt für
Objekte ohne Registry-Eintrag.

Regression in test_playtest.gd: gedreht/ungedreht, Scale, Fallback
(20 checks, alle grün). Suiten: playtest_comfort 51, playtest_spawn 56,
resize_dialog 44, terrain 153 — ALL OK.
2026-10-20 20:11:11 +00:00
Hermes (scopedvr-dev)
1f1a413065 Begehbare Gebäude (t_9558038d): Registry + Kollisionsdateien gezogen
- library/objects.json vom Match-Server (dc9432b): 37 Gebäude jetzt
  shape=trimesh mit collision.quelle -> library/kollisions/<oid>.json
  (36 038 Dreiecke gesamt, objects.json bleibt klein).
- library/kollisions/ (37 Dateien) im Editor-Repo. Editor-Platzhalter nutzt
  weiterhin collision.size — Optik/Anzeige unverändert.
- Suiten nach dem Sync grün: test_library 101, test_object_mirror 74,
  test_library_browser_ui 30, test_editor_svmap 31, test_map_tint 31/0.
2026-10-20 19:50:36 +00:00
Hermes (scopedvr-dev)
d637314b82 Update-Check: sichtbares Ergebnis-Fenster für „🔄 Updates prüfen“ (Sly-Wunsch 20.10.).
Befund: der Check funktionierte die ganze Zeit — die Rückmeldung kam aber
NUR in der Statuszeile („Du bist auf dem neusten Stand (…).“) und verblasst
dort schnell → las sich wie „tut nichts“. Probe (echter Menü-Klick): Check
läuft, ls-remote ok, Status korrekt.

Fix: nach dem MANUELLEN Check (report=true) öffnet ein kleines AcceptDialog
„Update-Check“ mit Klartext-Ergebnis (Stil wie Map-Check-Dialog):
- up_to_date: „Du bist auf dem neusten Stand (<sha>).“
- update_available: Zusätzlich zum Banner das Fenster mit local → remote
  und Hinweis auf „Jetzt updaten“.
- unreachable / auth_failed / error: gleicher Klartext wie Statuszeile.
Der Still-Start-Check (report=false) zeigt bewusst KEIN Fenster (nur Banner
bei „Update verfügbar“) — Probe belegt: Popup sichtbar=false.
Probe: probe_update_check (echter Menü-Klick → Popup sichtbar + Text).
Suiten: test_updater 75 OK, test_resize_dialog 44 OK, test_theme 35 OK,
test_gui_smoke 92 OK, test_ux 137 OK, test_ui_layout 79 OK.
2026-10-20 18:37:38 +00:00
Hermes (scopedvr-dev)
ae551f387a Fix: Resize-Dialog 5930 px hoch + OK/Abbrechen unterhalb des Bildschirms (Sly-Befund 20.10. „viel zu lang, kann nichts bestätigen").
Ursache (Proben im Container, xvfb): autowrap-Labels OHNE Mindestbreite
melden VOR dem ersten Layout eine explosionsartige Mindesthöhe (Wrap bei
~1 px → jedes Wort eine Zeile). popup_centered() übernimmt genau diesen
Wert als Fensterhöhe: Resize-Dialog 5930 px statt ~470, Neue-Map-Dialog
4781 px statt ~390 — beide waren betroffen. Nach dem Layout fällt der
Mindestwert zurück, die Fenstergröße bleibt aber.
Zusatz-Befund: wächst die Live-Vorschau NACH dem Öffnen (Preset 256 →
Warnband), bleibt das Fenster oben hängen → Buttons bei y≈940 in einem
900-px-Sichtbereich = unerreichbar.

Fix:
- resize_map_dialog + new_map_dialog: autowrap-Labels bekommen
  Mindestbreite ~ Dialogbreite → Umbruch rechnet mit echter Breite,
  Fenster normal hoch (Probe: 481 px).
- resize_map_dialog: Inhalt in ScrollContainer (horizontal aus), Höhe
  dynamisch = min(Inhalt, sichtbarer Platz); nach jeder Vorschau-Änderung
  wird das Fenster gedeckelt und neu zentriert (_fit_dialog/
  _fit_after_layout) → OK/Abbrechen IMMER erreichbar. unresizable.
- tests: test_resize_dialog prüft jetzt Mindesthöhe VOR dem Popup
  (absolut, < 1500 px) für beide Dialoge + echten Menü-Klick;
  Preset-Button-Suche robust über find_children.
Proben (xvfb): Dialog 662×481, nach Preset 256 → 662×631, unten 765 < 900,
Buttons sichtbar (Beweisbild work/dialog_beweis/resize_dialog_fix.png).
Suiten: test_resize_dialog 44 OK, test_theme 35 OK, test_gui_smoke 92 OK,
test_ux 137 OK, test_ui_layout 79 OK.
2026-10-20 18:33:07 +00:00
Hermes (scopedvr-dev)
f4cfe17594 Fix: Datei-Menü komplett tot — id_pressed landete als Argument VOR dem Methodennamen (Sly-Befund 20.10. „Kartengröße ändern tut nichts“).
popup.id_pressed.connect(main.call.bind("_on_menu_action")) rief effektiv
call(6, "_on_menu_action") → „Cannot convert argument 1 from int to
StringName“ (map-builder.log 20.10., 2 Treffer) — KEIN Menü-Eintrag tat
etwas (Neue Map/Öffnen/Speichern/Kartengröße/Updates). Alle anderen
.call.bind-Stellen hängen an arg-losen Signalen (pressed/timeout) und
waren unbeeinträchtigt. Fix: Lambda mit expliziter Reihenfolge
(Stil wie grid_btn/contours_btn). Regression: test_resize_dialog stellt
jetzt den echten Klick nach (id_pressed.emit(6) am Datei-Popup) — vorher
rief die Suite _open_resize_dialog() direkt auf und sah den Bruch nicht.
Suiten: test_resize_dialog 42 OK, test_theme 35 OK, test_gui_smoke 92 OK, test_ux 137 OK.
2026-10-20 18:19:42 +00:00
Hermes (scopedvr-dev)
f6c754115a U7 (t_2336c58e): Feinschliff — Theme konsequent (Disabled/Fokus/Hover, LineEdit, Tab-Hover, Splitter-Anfassen, Scrollbars, Farb-Token warning/badge_outline), Abstands-Raster 4/8 über UIScale, Typografie-Raster (heading/body/small via ui_scale.gd), Tooltips für alle Knöpfe inkl. Dialoge, Leerzustand in der Bibliothek, Fenstertitel mit „(ungespeichert)“. Neue Suite tests/test_theme.gd (35 Checks). Keine Funktionsänderung. 2026-10-20 12:08:10 +00:00
Slyphax
0e1406a63e M5 (t_60014669): Ein-Klick „Karte symmetrisch machen“ + Symmetrie-Check mit Klartext-Bericht (Spec vc27). Neu: symmetry_ops.gd (analyze/apply/check — Paarung über Spiegel-Position + sym-Links, Ergänzen ohne Löschen, Widersprüche zählen und der gewählten Quelle zusprechen, Terrain zellgenau Höhen+Material, Spawn-Zwillinge im Gegner-Team via M4-Mechanik, frische sym-Kopplungen ohne V16-Waisen) + Symmetrie-Panel über Panel-Registry (main.gd unberührt; Widerspruchs-Dialog nennt die Zahlen VOR dem Anwenden, Quell-Hälfte links/rechts bzw. vorn/hinten, EIN Undo-Schritt). Suite test_symmetry_onclick (66 Checks: 0 Abweichungen nach Klick, Zellgleichheit, Quell-Flip, Legacy ohne sym, EIN Undo stellt alles her, Modus AUS no-op) + Renderprobe probe_m5_symmetry_render (Vorher/Nachher). 2026-10-20 10:55:06 +00:00
Hermes (scopedvr-dev)
835a7f7363 U3 t_a4bf9b8c: Objekt-Gruppen — GroupState (group_state.gd, fuell-/datei-agnostisch ueber get_meta/set_meta), scene_tree_panel: Gruppen-Ebene im Baum (Name + (N Objekte), eingerueckte Mitglieder, Klick waehlt alle Mitglieder, Gruppen-Knoten markiert wenn alle Mitglieder gewaehlt), zwei-Wege mit Auswahl, Rendering bleibt Gruppen-unabhaengig. Neue Suite tests/test_scene_groups.gd + Renderprobe probe_u3_groups_render.gd. 2026-10-20 10:36:04 +00:00
Hermes (scopedvr-dev)
5dca5513da U6 t_639135dd: dezente Auswahl — Kontur statt Vollorange (Textur bleibt sichtbar).
Neu shaders/selection_outline.gdshader: Inverted-Hull-Außenhülle (unshaded,
cull_front, Grow entlang der Normalen; Streifen-Uniform für den Zwilling).

Markierung jetzt über Outline-Kind am Mesh (Auswahl/Hover/Partner); Farben +
Breiten aus theme/editor_theme.tres (selection_outline*, *_width_mm) — eine
Quelle. material_override wird von der Markierung nicht mehr angefasst:
GLB-Texturen bleiben im Auswahl-Zustand voll sichtbar, der Tint bleibt beim
Markieren sichtbar (kein "Orange gewinnt" mehr).

Spawn-Zonen: konstante Disc-Deckkraft + dezenter Kontur-Ring (Torus) statt
Aufhellung/Emission; Label-Farbe aus dem Theme statt hartkodiertem Gelb.
Bau-Teile: Kontur um das Bauteil-Mesh statt halbtransparenter Vollbox.
Neu: set_hover()-API (schwächste Stufe) — Anschluss an die Mausbewegung
liegt in interaction.gd (Grenze dieser Karte) und folgt als eigene Karte.

Suite tests/test_selection_look.gd (41 checks: Theme-Quelle, Grundmaterial
unangetastet, Outline nur bei Markierung, restlos weg bei Abwahl, Zwilling
dünner+gestrichelt, Spawn-Ring, Bau-Teil-Kontur). Altsuiten an die neue
Semantik angepasst (test_glb_view: GLB-Auswahl ohne Override; test_map_tint
T3: Kontur statt Orange-gewinnt; test_object_mirror: Partner per Kontur).

Beweise: 4 Renderproben (fass, echtes GLB — vorher Vollorange / nachher
Kontur, je auf Sand und Fels) in /opt/data/scopedvr/work/u6_auswahl_beweise/.
Voll-Batterie 32/32 grün (EXIT 0) inkl. der drei angepassten Suiten.
2026-10-20 10:33:04 +00:00
Hermes (scopedvr-dev)
f16b9c8fb6 U5 t_5e3e97c9: Platzieren EINMAL — ein Klick setzt, Werkzeug beendet sich, neues Objekt ausgewählt (Baum+Inspektor), Klartext-Status; Shift = Serienmodus (weiter setzen, Status nennt ESC); Ghost/Panel-Kachel nach dem Setzen zurück; eine Platzierung = ein Undo-Schritt. Abbruch via ESC (ShortcutPolicy) — Rechtsklick bleibt Flug-Vorrang (t_2470de89, test_rmb_vorrang). Neue Suite tests/test_place_once.gd (52 checks) + Renderprobe. 2026-10-20 10:15:01 +00:00
Hermes (scopedvr-dev)
403895b743 t_a7d15717: run_suites.py False-Positive gefixt — Fehler-Regex nur noch auf ^SCRIPT ERROR: / ^Parse Error: am Zeilenanfang (re.MULTILINE). Vorher matchte die Phrase-Regex das eigene Check-Label der Suite ("ok: Parse Error wird erkannt ...", test_updater.gd Zeile 73) -> SCRIPT_ERROR obwohl ALL OK: 75. Zusaetzlich \n zwischen stdout+stderr (sonst verkleben die Streams und der ^-Anker verliert die erste stderr-Zeile). Abnahme: Voll-Batterie SUITEN_TOTAL=30 GRUEN=30 ROT=0, test_updater sauber OK. 2026-10-20 10:12:14 +00:00
Hermes (scopedvr-dev)
60b09bfb74 U2 t_e3c0310a: Szenen-Baum links mit Kategorie-Ebene + Zwei-Wege-Auswahl — scene_tree_panel: Objekte unter Kategorie-Knoten (LibraryBrowser.group_of + Label-Mapping), Spawn-Zonen Team A/B, Bau-Teile, Gruppen-Ebene (GroupOps; Klick auf Gruppe waehlt alle Mitglieder), Kopf mit Zaehlern (Objekte (N)), Auge-Praefix je Eintrag (nur Anzeige, keine Doc-Aenderung), leerer Zustand mit Klartext-Hinweis, Zwei-Wege-Kopplung ueber _obj_index_map (O(1) Markieren + scroll_to_item). Neue Suite tests/test_scene_tree.gd (24 checks: Baum fuellt sich, Klick->3D, 3D->Baum, Mehrfach, Gruppen-Klick, leerer Hinweis, UIScale). Renderprobe probe_u2_scene_tree_render.gd. main.gd NICHT angefasst. 2026-10-20 10:03:34 +00:00
scopedvr-operator
3d7ba993d5 glb_mesh_store: verschachtelte Pack-Modelle auch in models/ finden
Operator-Befund aus dem Eigenstaendigkeits-Beweis auf dem PC (20.10.):

Die App baute den Registry-Pfad nur als <quelle>/<rel-pfad-mit-Praefix
'assets/objekte/'>. Der mitgelieferte models/-Ordner NEBEN der App enthaelt die
Pack-Struktur aber DIREKT (models/military_desert/props/box_010.glb). Ergebnis:
291 von 334 Modellen (alle verschachtelten Pack-Objekte — genau die, mit denen
die Karten gebaut werden) wurden in der eigenstaendigen App nicht gefunden.

Fix: zusaetzlicher Kandidat <quelle>/<rel-pfad OHNE 'assets/objekte/'> — der
flache Alt-Pfad bleibt unveraendert.

Belegt (exportierte App, nacktes Umfeld, frisches HOME):
  box_010       -> models/military_desert/props/box_010.glb   (vorher: leer)
  baum_kiefer_1 -> models/baum_kiefer_1.glb
  fehlende_glbs=0   PROBE ERGEBNIS: OK
Suiten: gui_smoke 92 OK, Import 0 Fehler.
2026-10-20 10:01:57 +00:00
scopedvr-operator
a62357dad8 tools/probe_gen_map.gd: OIDs per --oid= waehlbar
Damit lassen sich auch VERSCHACHTELTE Pack-Modelle pruefen
(models/military_desert/<kategorie>/<oid>.glb) — noetig, weil der erste
Eigenstaendigkeits-Beweis nur flache Modelle abdeckte.
2026-10-20 10:00:29 +00:00
scopedvr-operator
e317706df0 tools/sync_models.sh: Pack-Referenzordner als Textur-Quelle
Operator-Befund auf dem PC (20.10.): die Original-Texturen liegen NICHT im
Client-Klon, sondern in einem eigenen Pack-Ordner:
  ~/godot-projects/ithappy_pack_ref/ithappy/military_desert/textures/
Deshalb sucht das Skript jetzt zusaetzlich dort (<clone>/../ithappy_pack_ref/...)
und als letzte Instanz per find -maxdepth 6 unter <clone>/.. und <client>/..
(also neben dem Projekt). Belegt mit einem nachgebauten PC-Aufbau: Palette wird
gefunden, landet FLACH in models/textures/, --check danach Exit 0.
2026-10-20 09:58:47 +00:00
scopedvr-operator
8c97d00871 tools/sync_models.sh: Texturen suchen + flach spiegeln + Textur-Ordner nicht mehr loeschen
Operator-Nachbesserung nach dem Eigenstaendigkeits-Beweis (exportierte App,
kein Client/Godot im Dateisystem):

- SRC_TEX wird GESUCHT statt fest verdrahtet: SCOPEDVR_TEX_DIR ->
  assets/textures/military_desert -> assets/textures -> Ordner der
  Demonstration_Textures*.png unter assets/. Findet er nichts, gibt es einen
  HINWEIS samt Loesung (SCOPEDVR_TEX_DIR=/pfad).
- Texturen werden FLACH nach models/textures/<name>.png gespiegelt — die App
  sucht sie dort; im Client liegen sie verschachtelt.
- Modell-Spiegel schliesst den Unterordner textures/ aus (skip_top): vorher
  galt er als 'ueberfluessig' und wurde bei JEDEM Lauf geloescht, der
  Textur-Spiegel legte ihn neu an -> Endlosschleife, --check nie sauber.

Belegt: 2. Lauf 0 Aenderungen, --check Exit 0; exportierte App findet
baum_kiefer_1/stein_mittel_1 aus models/, fehlende_glbs=0, ERGEBNIS: OK.
2026-10-20 09:55:05 +00:00
Hermes (scopedvr-dev)
7c7dc38566 U-Nachlauf t_efb3d022: assets_panel _library_load_open_states robuster Typ-Check
bool(cfg.get_value()) warf SCRIPT ERROR "Nonexistent bool constructor" bei
Nicht-Bool-Eintraegen in [library] (Array-Eintraege neben zuletzt_benutzt) —
die Klapp-Zustaende luden dann gar nicht (STATES leer).

Fix: nur echte Bool-Werte uebernehmen, String/Int/Array auf Fallback true,
kein Crash mehr.

Beweis-Probe tests/probe_t_efb3d022_repro.gd:
  vorher: 2x SCRIPT ERROR "Invalid call. Nonexistent 'bool' constructor",
          STATES leer
  nachher: 0 Fehler, 3 Zustaende geladen (Array-Eintrag -> Fallback true)

Suite test_assets_panel.gd erweitert um Testgruppe 0
"Klapp-Zustaende aus kaputter cfg" (6 neue Checks, 75 -> 81, ALL OK):
Array/String/Int-Eintraege + save->load-Rundtrip.

test_inspector 47/47, test_gui_smoke 92/92, --import 0 Parse-Errors.
2026-10-20 09:52:26 +00:00
Hermes (scopedvr-dev)
4fb883a44c T3 t_aaff5dcc: Komfort im Testlauf — Fliegen/God-Mode (G, Noclip+Blickrichtung), Spawn-Sprung 1-4 (exakt, Terrain-Hoehe), HUD-Toggle H + Blick/Hoehe, Achsen-Linien X, Hilfe F1, Maus-Empfindlichkeit (PlaytestSettings + Einstellungen-Panel via Registry, main.gd unangetastet); Suite tests/test_playtest_comfort (51 Checks), test_ui_layout Tabs registry-getrieben 2026-10-20 09:47:28 +00:00
scopedvr-operator
ab173ac8aa T2 Ueberall installierbar (Operator-Push): Modelle aus mitgeliefertem models/-Ordner
Worker hatte die Arbeit fertig, aber NICHT committet/gepusht (3. Fall heute) —
aus dem Karten-Arbeitsordner gerettet und hier gepusht.

- GlbMeshStore.quellen(): Reihenfolge EINE Stelle — Setting -> Sibling-Repos ->
  mitgelieferter Ordner models/ direkt neben der App (dedupliziert, typisiert)
- Klartext-Meldung FEHLT_TEXT statt stillem Platzhalter; Notfall-Modus: Terrain
  und Bauteile laufen ohne GLBs
- neu: tools/sync_models.sh (fuellt models/, --check), utils/modelle_status.gd
  (Autoload ModelleStatus), tools/probe_gen_map.gd
- neu: README_INSTALL.md (85 Zeilen, Schritt fuer Schritt + §5 Lizenzhinweis:
  ITHappy-Rohdaten NICHT weitergeben, App fuer Slys eigene Rechner)
- export_presets.cfg (eigenstaendiger Linux-/Windows-Export), .gitignore:
  models/ + export/ bleiben draussen (Lizenz + Groesse)
- Tests: test_model_sources (26/27; die rote ist umgebungsabhaengig:
  'lager_ist_leer' erwartet fehlende Sibling-Repos)

Belegt: Import 0 Fehler, gui_smoke 92, ui_layout 71, playtest_spawn 56.
2026-10-20 09:43:05 +00:00
scopedvr-operator
0f86472cfa T1b-Wiederanbindung (Operator): Test-Startpunkt zurueck nach dem U1-Umbau
Sly-Befund: der Knopf 'Test-Start' fehlte; tests/test_playtest_spawn.gd brach
mit "Nonexistent function '_test_start_reload'" ab und hing.

- Werkzeug-Modus 'teststart' wieder in _set_tool_mode (+ enter/leave/sync)
- ShortcutPolicy.esc_action: exit_teststart inkl. Test
- Taste T: Editor = Werkzeug umschalten, Lauf-Modus = Punkt setzen + Teleport
  aufs Fadenkreuz (playtest.teleport_crosshair)
- Entf im Werkzeug loescht den Punkt; Klartext-Hinweis des Werkzeugs wieder in
  der Statuszeile ('auf dem Boden unter dem Objekt')
- Leisten-Knopf '🎯 Test-Start' als Umschalter (registry.gd ACTIONS)
- neues Panel-Modul src/ui/panels/test_start_panel.gd + Registry-Eintrag
- Haken _test_start_apply/_delete/_reload + test_start_point/test_start_panel/
  test_start_btn stehen fest auf main (Vertrag der Pruefsuite)
- _test_start_reload() wieder nach Neu/Laden/Speichern; playtest.enter() bekommt
  den aufgeloesten Startpunkt (TestStart.resolve_start)

Belegt: test_playtest_spawn 56/56, test_shortcuts 204, gui_smoke 92, ui_layout 71,
Import 0 Fehler.
2026-10-20 09:37:05 +00:00
Hermes (scopedvr-dev)
40449932b9 K1d t_6c1027c1: Startansicht 80 m über der Kartenmitte (Pos1 bleibt ganze Karte)
fit_to_document setzt die Ansicht jetzt auf START_DISTANCE_M = 80 m über der
Kartenmitte (XZ-Mitte der Map-Bounds, Höhe = Gelände dort), yaw 45°, pitch 35°.
Die Regel ist unabhängig von Kartengröße (256/1024/4096) und Inhaltslage;
leeres Dokument ebenfalls 80 m. Statuszeile: „Ansicht: Kartenmitte, Abstand
80 m (Pos1 = ganze Karte).“ Pos1/Home bleibt fit_to_bounds = ganze Karte
(MAP-Bounds werden weiterhin gemerkt, nicht die Content-Bounds).

Ziel-Y bewusst auf der Geländehöhe: die y-Mitte der Bounds liegt bei neuen
Maps 35 m über dem Boden — damit hätte die Ansicht über den Boden gezielt und
die Objekte stünden am unteren Bildrand.

Suite test_orbit_camera auf die neue Regel umgestellt (50 Checks):
Startabstand/Richtung, 80-m-Regel über Größen und Inhaltslagen, leeres
Dokument, „Pos1 ≠ Startansicht“ (80 m → 1215,6 m, alle 8 Map-Ecken).
Dazu Renderprobe tests/probe_k1d_render.gd (2 PNGs).
2026-10-20 09:33:16 +00:00
scopedvr-operator
85bee00f3d U1-Nachbesserung (Operator, Sly-Befund 'Damit kann man nicht mehr arbeiten'): Werkzeugleiste erbte EditorPanel (=VBoxContainer) und wurde selbst senkrecht -> jeder Knopf eine fensterbreite Zeile (~440px), 3D-Fenster auf einen Streifen gedrueckt. Fix: toolbar.gd extends HBoxContainer + size_flags SHRINK_BEGIN; neue Groessenprobe in test_ui_layout (Leiste <=80px, Mittelbereich >=120px). 2026-10-20 09:22:39 +00:00
Hermes (scopedvr-dev)
8f0e011a07 U4 t_69687afc: Assets-Bereich Unity-artig ausgebaut — Kategorien-Leiste (Alle + Gruppen aus LibraryBrowser, Summe = Gesamtzahl), Suche Name+ID, Zaehler "N von M sichtbar", Zuletzt benutzt (cfg [library] zuletzt_benutzt, Chip + Ansicht), Kacheln mit 96-px-Vorschau + ID + Name, Hover vergroessert die ID, fehlende GLB = abgedunkeltes Bild + orange Badge "Modell fehlt" (GlbMeshStore.fehlt), Klick = auswaehlen (Signal object_selected genau 1x je Wechsel), Doppelklick = Werkzeug starten wie bisher (nochmal = abbrechen), Spaltenzahl breitenabhaengig (180 px je Kachel, ueber ui_scale), Dock-Groesse bleibt in [fenster] gemerkt (U1). Klapp-Gruppen + Alle auf/zu + gepinnte Masse (Suchfeld 36, Kachel 126, Thumb 96) unveraendert. Suite tests/test_assets_panel.gd 75 checks ALL OK; test_library_browser_ui 30, test_library 101, test_ui_layout 63, test_gui_smoke 92, test_inspector 49, test_playtest 11, test_object_mirror 74, test_ui_scale OK — alle unveraendert gruen. Renderproben unter /opt/data/scopedvr/work/u4_assets_beweise/. test_playtest_spawn ist VOR dieser Karte rot (U1-Regression _test_start_reload, siehe Kommentar auf t_eaccbfed) — nicht von U4 beruehrt. 2026-10-20 09:19:37 +00:00
scopedvr-operator
69ffe23a71 t_eaccbfed: U1 UI-Fundament (Operator-Push) — main.gd 3677->2479 Zeilen, src/ui/panels/ (11 Module + registry), Tabs rechts+links, Assets unten, theme/editor_theme.tres, tests/test_ui_layout.gd (63 checks). Worker meldete fertig ohne Push; Arbeit aus dem Scratch-Ordner gerettet. 2026-10-20 09:11:00 +00:00
Hermes (scopedvr-dev)
a5d8f7f79d T1b t_96e3c4ee: Test-Startpunkt per Klick — Toolbar/Taste T setzt den Punkt, wo F5 den Testlauf startet (Höhe automatisch vom Terrain, Klick auf Objekt/Bauteil = Boden darunter). Sidecar user://scopedvr_teststart.cfg je Kartenpfad, KEIN .svmap-Eintrag, kein Undo, kein Spawn-Check-Kontakt. F5-Fallback mit Klartext: Test-Start → erster Team-Spawnpunkt → Kartenmitte. T im Testlauf versetzt sofort zum Blickpunkt (Augenhöhe 1,70 m, Kollision geprüft) und setzt den Punkt neu. Marker (Säule+Ring, Akzentfarbe) sichtbar solange gesetzt. Suite tests/test_playtest_spawn.gd 56/56, Voll-Batterie 25/25 grün, Renderprobe (4 PNGs) unter /opt/data/scopedvr/work/t96e3_beweise/ 2026-10-20 08:22:47 +00:00
Hermes (scopedvr-dev)
b53e05a145 T1 t_1cdc1a72: F5-Smoke-Test an neuen Lauf-Modus angepasst (PlaytestMode statt Client-Fehler) + Render-Probe-Script 2026-10-20 08:07:15 +00:00
Hermes (scopedvr-dev)
1b943ceb35 T1 t_1cdc1a72: Testlauf im Map Builder selbst (erste Person, WASD+Maus, ohne Client/VR/Server) — PlaytestMode + PlaytestBody in src/editor/playtest/, minimale main.gd-Einbindung (F5/Toolbar), test_run.gd als ALT markiert, Suite tests/test_playtest.gd (11 Checks, vor Push noch Rebase auf 969e928 + Voll-Suiten-Batterie + Beweis-Bild) 2026-10-20 07:45:33 +00:00
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