- Bibliothek-Browser: 11 etablierte Objekte in deutschen Klapp-Gruppen (Kisten & Barrieren / Bauwerke / Natur, neue IDs wandern nach Sonstiges) - 128-px-Thumbnails einmalig gerendert (tools/gen_thumbs.gd, xvfb) und committed; fehlendes PNG = sauberer Text-Fallback (LibraryBrowser) - Snap to Ground: ein Klick setzt ALLE schwebenden Objekte auf Terrain-Höhe, EIN Undo-Eintrag (ObjectOps.snap_to_ground) - Raster-Snap (1 m): Toggle — rastet Platzieren und Ziehen auf ganze Meter - Deutsche Namen nach LibraryBrowser verschoben (headless testbar) - tests/test_library.gd: 47 Checks (Bibliothek, Gruppen, Thumbnails, Snap, CRUD+Undo über alle Objekte, svmap-Roundtrip byte-identisch, Poly-Budget) - Desktop-Smoke: --library-demo erzeugt Screenshots (lokal via xvfb verifiziert) - UI-Layout: linke Spalte min 909→797 px, Statusleiste wieder vollständig sichtbar
125 lines
7.4 KiB
Markdown
125 lines
7.4 KiB
Markdown
# ScopedVR Map Editor
|
||
|
||
Standalone-PC-App zum Bauen von ScopedVR-Maps. Technisches Fundament: Godot 4.x
|
||
(MIT-Lizenz, lizenzfrei, keine Fremd-Abhängigkeit). Creator sehen/brauchen
|
||
Godot NIE — die App ist das Produkt (PLAN.md, Entscheidung 14).
|
||
|
||
## ⭐ Chef-Grundsatz (Sly, 15.10.): MAXIMALE NUTZERFREUNDLICHKEIT
|
||
> „Der soll auf jeden Fall so nutzerfreundlich sein, wie es nur geht, damit
|
||
> echt richtig easy ist Maps zu bauen und es auch Spaß macht!"
|
||
|
||
Konkret heißt das für JEDE Editor-Karte:
|
||
- Deutsch, große Buttons, Klartext-Beschriftungen — kein Fachchinesisch.
|
||
- Klick statt Konsole: gewünschte Aktion per Maus erreichbar (ziehen, drehen,
|
||
klicken), ohne Tastenkürzel auswendig zu lernen (Kürzel dürfen optional sein).
|
||
- Sofortiges visuelles Feedback (Objekt leuchtet beim Anfassen, Vorschau
|
||
vor dem Platzieren, Undo mit STRG+Z).
|
||
- Die App hilft: ungültige Aktionen erklären WARUM („Spawn-Zone fehlt noch
|
||
für Team Rot — klicke auf den Boden, um sie zu setzen").
|
||
- Test-Benchmark: Sly baut ohne Anleitung in < 10 Minuten eine kleine Map.
|
||
|
||
## Philosophie (Entscheidung 20 — GESCHLOSSENER Baukasten)
|
||
- Objekte kommen ausschließlich aus der Spiel-Asset-Bibliothek (geprüfte Poly-Budgets).
|
||
- KEINE freien Mesh-Imports. Konsistenz + Performance statt unbegrenzter Freiheit.
|
||
- Performance-Prüfung ist eingebaut (Objekt-Count-/Poly-Limits), nicht optional.
|
||
|
||
## MVP-Werkzeuge (Reihenfolge = Karten-Kette)
|
||
1. **Terrain** — Höhenfeld bearbeiten (heben/senken/glätten), Sniper-Distanzen 100–800 m (Entscheidung 7).
|
||
2. **Objekt-Platzierung** — Bibliothek-Browser, platzieren/drehen/verschieben.
|
||
3. **Spawn-Zonen** — pro Team (TDM), Validierung gegen Regeln.
|
||
4. **Map-Metadaten** — Name, Autor, Version, Wetter-Preset (mittag/abend/regen/nacht, siehe Weather-System 9ebe8ef/a296986).
|
||
5. **Performance-Check** — Objekt-Count/Poly-Budget gegen die FPS-Baseline.
|
||
6. **Export** — `.svmap`-Paket (Format: docs/map_format.md im scopedvr-match-server Repo, Karte t_74976e9f).
|
||
|
||
## Architektur (MVP)
|
||
- Godot 4.x Desktop-App (die Editor-UI IST Godot-Control-UI — pragmatisches MVP).
|
||
- Map-Datenmodell = 1:1 das svmap-Format (kein internes Zwischenformat → kein Konverter).
|
||
- Speichern/Laden direkt auf .svmap; Export = Kopie + Validierung.
|
||
|
||
## Milestone-Zuordnung
|
||
M2 (siehe PLAN.md §6): Map-Paket-Format → Editor-MVP → erste offizielle Map
|
||
(offenes Gelände) → Map-Repo/Release-Workflow über Forgejo (M3).
|
||
|
||
## Status (M2, Karte t_40d855d0 — UX-Fundament FERTIG)
|
||
|
||
UX-Fundament auf dem App-Skelett (t_5badf371), nach dem Chef-Grundsatz gebaut:
|
||
|
||
*(Unverändert darunter: svmap laden/speichern V1–V14 mit Prüfsummen-Interop,
|
||
Neue-Map-Dialog mit 4 Pflicht-Spawns pro Team, Orbit-Viewport mit Gitter/
|
||
Boden/Wetter-Stimmung — siehe Commit 84bc081 und `svmap_io.gd`.)*
|
||
|
||
- **Undo/Redo (`src/editor/action_history.gd`):** zentrale ActionHistory über
|
||
die svmap-Ober-Blöcke (`objects`/`terrain`/`spawn_zones` — tiefe Kopien vor
|
||
und nach jeder Änderung, merge_tags gegen Mausrad-Tick-Fluten, Max-Stufe 100).
|
||
Strg+Z / Strg+Y UND große Buttons „↩ Rückgängig / ↪ Wiederholen" oben.
|
||
Spätere Werkzeuge melden sich mit `snapshot(keys)` vor und
|
||
`commit(desc, before, after)` nach der Änderung an — Terrain-Strokes und
|
||
Spawn-Zonen landen damit automatisch in derselben History.
|
||
- **Objekt-Platzierung mit Ghost-Preview (`src/editor/interaction.gd`):**
|
||
Bibliothek links (deutsche Namen + Poly-Zahl), Klick startet den
|
||
Platzier-Modus — eine transparente Vorschau schwebt am Cursor auf dem Boden
|
||
(Höhe kommt aus dem Terrain), Klick setzt, Rechtsklick/ESC bricht ab,
|
||
Mausrad dreht die Vorschau VOR dem Setzen (15°-Raster). Modus bleibt an
|
||
für schnelles Mehrfachsetzen. Poly-Budget wird VOR dem Platzieren geprüft.
|
||
- **Auswahl-Anfassen:** Klick wählt ein Objekt (orange + Emission), Ziehen
|
||
verschiebt es (auf Terrain-Höhe geclampt in der Map), R-Taste ODER Mausrad
|
||
dreht (15°-Raster, Shift+R zurück), Entf löscht. Auch über den Objekt-Baum
|
||
wählbar (beide Wege bleiben synchron). Panel „Auswahl“ rechts zeigt Position/
|
||
Richtung + Bedienhinweise.
|
||
- **Helfende Meldungen:** Statusleiste unten erklärt nach jeder Aktion den
|
||
NÄCHSTEN Schritt („Klicke in die Karte“, „Strg+Z holt es zurück“,
|
||
Budget-Warnung ab 80 %). Fehler-Dialoge bleiben Klartext, keine Godot-Texte
|
||
im sichtbaren UI.
|
||
- **Deutsche, große UI:** Schrift 16 px Basis (≥ 14 px überall), Buttons/
|
||
Klickflächen ≥ 40 px Höhe, Mausrad-Konflikt gelöst: Rad dreht Objekt/
|
||
Vorschau, wenn eines aktiv ist — sonst zoomt es die Kamera.
|
||
- **Tests:** `tests/test_ux.gd` (History-Roundtrips setzen/löschen/verschieben/
|
||
drehen, Merge-Tag-Verhalten, Alias-Sicherheit der Snapshots, Kapazität,
|
||
Terrain-Höhen-Abfrage, Platzhalter-Meshes).
|
||
Lauf: `godot --headless --path . --script res://tests/test_ux.gd`
|
||
|
||
**Bekannte Falle (15.10. live passiert):** Nach `git pull` mit NEUEN
|
||
`class_name`-Skripten (z. B. `action_history.gd`) muss einmal
|
||
`godot --headless --import` laufen, bevor die GUI gestartet wird — sonst ist
|
||
der globale Klassen-Cache (`.godot/`) alt, `main.gd` wirft „Identifier not
|
||
declared" und das Fenster startet ohne UI. Symptom: Parse-Errors im App-Log
|
||
trotz grünem Test-Lauf (der ja selbst mit importiertem Cache lief).
|
||
|
||
**Bibliothek:** `library/objects.json` ist die Editor-Kopie der offiziellen
|
||
Registry aus dem Match-Server-Repo — neue Objekte DORT registrieren und hier
|
||
synchron ziehen (IDs sind der Vertrag, Entscheidung 20).
|
||
|
||
## Status (M2, Karte t_3a998ae4 — Objekt-Bibliothek FERTIG)
|
||
|
||
Auf dem Terrain-Werkzeug (t_9aba04f1) aufgebaut, nach dem Chef-Grundsatz:
|
||
|
||
- **Bibliothek-Browser mit Gruppen (`src/editor/library_browser.gd`):** Die
|
||
11 etablierten Objekte aus `library/objects.json`, sortiert in deutsche
|
||
Klapp-Gruppen (Kisten & Barrieren / Bauwerke / Natur + automatisch
|
||
„Sonstiges" für neue, noch ungruppierte IDs). Jeder Button zeigt ein
|
||
128-px-Thumbnail (`library/thumbs/*.png` — einmalig mit
|
||
`xvfb-run -a godot4 --rendering-driver opengl3 --path . --script
|
||
res://tools/gen_thumbs.gd` gerendert und committed; fehlt ein PNG, fällt
|
||
der Button sauber aufs Text-Layout zurück). Deutsche Namen wohnen jetzt in
|
||
`LibraryBrowser` (ohne UI → headless testbar).
|
||
- **Snap to Ground (`src/editor/object_ops.gd`):** Ein Klick auf
|
||
„⚡ Alles auf den Boden setzen" holt ALLE schwebenden Objekte auf die
|
||
Terrain-Höhe (z. B. nach dem Terrain-Formen) — EIN Undo-Eintrag für die
|
||
ganze Aktion. Objekte, die schon auf dem Boden stehen, bleiben unangetastet.
|
||
- **Raster-Snap (1 m):** CheckButton in den Objekt-Werkzeugen — beim
|
||
Platzieren UND Ziehen rasten X/Z auf ganze Meter (Höhe folgt weiter dem
|
||
Terrain). AUS = freies Platzieren wie bisher.
|
||
- **svmap-Roundtrip:** Objekte (Bibliotheks-ID + Pos/Rot/Scale) überleben
|
||
Speichern/Laden identisch, save→load→save bleibt byte-identisch
|
||
(`tests/test_library.gd`).
|
||
- **Tests:** `tests/test_library.gd` (Bibliothek laden, Gruppen komplett/
|
||
überschneidungsfrei, Thumbnails 128×128, Raster-Snap, Snap-to-Ground + je
|
||
Undo für setzen/drehen/verschieben/löschen über ALLE 11 Objekte,
|
||
svmap-Roundtrip mit Objekten + Poly-Budget aus dem Katalog).
|
||
- **Desktop-Smoke:** `godot … -- --library-demo [ordner] [--library-demo-quit]`
|
||
fährt Bibliothek/Platzierung/Schweben/Snap programmatisch durch und
|
||
speichert Screenshots.
|
||
|
||
**Noch offen (folgende Karten der MVP-Kette):** Spawn-Zonen-Editor
|
||
(t_c4162c5d — Spawn-Zonen malen, Live-Validierung, Export-Signierung),
|
||
Performance-Check-UI, Export-Workflow.
|