Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
19 commits
Select commit Hold shift + click to select a range
b8b9a69
docs(openspec): propose setup-portal-command
TheMeinerLP Sep 29, 2026
e579946
docs(openspec): align setup-portal-command with lobby-portals
TheMeinerLP Sep 29, 2026
627940a
feat(setup): place portal discs from eye position and look direction
TheMeinerLP Sep 29, 2026
5b913c7
feat(setup): add the portal editor with per-player drafts
TheMeinerLP Sep 29, 2026
2cb866d
test(setup): keep the portal editor in step with the lobby validator
TheMeinerLP Sep 29, 2026
0e9cfe7
feat(setup): add pure outline points for saved and draft portals
TheMeinerLP Sep 29, 2026
2ab2501
feat(setup): add portal chat messages and editor logging
TheMeinerLP Sep 29, 2026
eb3a744
docs(openspec): tick editor tasks of setup-portal-command
TheMeinerLP Sep 29, 2026
fbb387c
Merge branch 'feat/setup-portals-editor' into feat/setup-portals
TheMeinerLP Sep 29, 2026
adebd00
feat(setup): persist portals through the map provider
TheMeinerLP Sep 29, 2026
5642a54
feat(setup): preview portals and open drafts with particles
TheMeinerLP Sep 29, 2026
d656d61
feat(setup): add the portal command with list, show and draft cleanup
TheMeinerLP Sep 29, 2026
3421150
docs(openspec): tick command tasks of setup-portal-command
TheMeinerLP Sep 29, 2026
46502ec
docs(setup): document portal commands
TheMeinerLP Sep 29, 2026
b548cd4
docs(openspec): tick readme task of setup-portal-command
TheMeinerLP Sep 29, 2026
67f8b78
feat(setup): guide portal creation with clickable steps and tab compl…
TheMeinerLP Sep 29, 2026
f0181a0
docs(openspec): tick flow tasks of setup-portal-command
TheMeinerLP Sep 29, 2026
54fed83
Merge branch 'feat/setup-portals-flow' into feat/setup-portals
TheMeinerLP Sep 29, 2026
19f7bb9
docs(openspec): tick verification task of setup-portal-command
TheMeinerLP Sep 29, 2026
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
28 changes: 28 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -312,6 +312,34 @@ deleted.
The setup server no longer edits configuration - the `/setup app ...` commands have been removed.
It only reads `spawn.simulationDistance` (default `2`) from the same configuration.

#### Portals

Lobby portals (see [docs/lobby-modules.md](docs/lobby-modules.md)) are edited with `/setup portal`
(players only, like all `/setup` commands) and stored in the `map.json` of the loaded world. Ids
consist of lower-case letters, digits, `-` and `_`; `list`, `show` and `create` are reserved.

- `/setup portal list`: saved portals (id, shape, task, permission) and, separately, your open drafts
- `/setup portal show`: outlines of all saved portals as particles, only for you, for a few seconds
- `/setup portal create <id>`: guided flow in chat with clickable buttons for each step (shape, corners
or centre and radius, task, permission, then save or cancel). A button runs exactly one of the
commands below; buttons that need free input put the command into your chat box.
- `/setup portal <id> pos1|pos2`: box corners at your block
- `/setup portal <id> shape box|ring`
- `/setup portal <id> centre`: ring centre and normal from your eyes and view direction
- `/setup portal <id> radius <r>`: ring radius only
- `/setup portal <id> disc <r>`: ring from your eyes, view direction and radius in one step
- `/setup portal <id> task <task>`
- `/setup portal <id> permission <permission|none>`
- `/setup portal <id> save|cancel|remove`

Every edit only changes your draft and answers with what is still missing, or "complete" with a
`[save]` button. Nothing is written until `/setup portal <id> save`, which validates the portal;
`cancel` (or disconnecting) discards the draft. While a draft is open, a live particle preview is
shown to you only. Tab completion suggests portal and draft ids, verbs, known tasks, `none`, `box`
and `ring`.

The lobby reads portals only at startup: restart it to pick up changed portals.

### Deployment

A CloudNet template, a Docker image or a Kubernetes deployment delivers `application.yaml` (or an
Expand Down
4 changes: 2 additions & 2 deletions docs/lobby-modules.md
Original file line number Diff line number Diff line change
Expand Up @@ -412,8 +412,8 @@ betreten, an einen CloudNet-Task.
den Start mit Welt, Id und Grund ab.

Portale ändern: Task in CloudNet anlegen, `map.json` bearbeiten, die Lobby neu starten. Die Liste
wird nur beim Start gelesen. Befehle zum Bearbeiten im Setup-Server folgen mit einer späteren
Änderung.
wird nur beim Start gelesen. Im Setup-Server bearbeitet `/setup portal` die Portale, siehe
[README](../README.md#portals).

## Erwartete Columns einer Variante

Expand Down
2 changes: 2 additions & 0 deletions openspec/changes/setup-portal-command/.openspec.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
schema: olf-spec-driven
created: 2026-09-29
141 changes: 141 additions & 0 deletions openspec/changes/setup-portal-command/design.md

Large diffs are not rendered by default.

47 changes: 47 additions & 0 deletions openspec/changes/setup-portal-command/proposal.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
# Proposal

## Why

Der Change `lobby-portals` lässt die Lobby Portale aus der `map.json` der Welt lesen (Quader und Ringe, je mit Aufgabe und optionalem Recht). Das Build-Team müsste diese Einträge von Hand in JSON schreiben: Blockkoordinaten abtippen, für Ringe Mittelpunkt und Normale ausrechnen. Fehler fallen erst beim Lobby-Start auf, weil ein ungültiges Portal ihn abbricht. Der Setup-Server, in dem die Welt ohnehin gebaut und gespeichert wird, soll Portale deshalb aus dem Spiel heraus anlegen, prüfen und speichern.

## What Changes

- **Voraussetzung:** Dieser Change baut auf `lobby-portals` auf und darf erst umgesetzt werden, wenn dessen Code in `main` ist. Er verwendet dessen Typen unter diesen Namen (in Aufgabe 1.1 gegen den gelieferten Code geprüft) `net.onelitefeather.titan.core.portal.PortalShape` (sealed, `Box(min, max)` und `Disc(center, radius, normal)`) und `Portal(String id, PortalShape shape, String task, @Nullable String permission)` sowie die Liste `portals` an `LobbyMap` samt Builder-Methode. Die Validierung liefert `lobby-portals` als `net.onelitefeather.titan.core.portal.PortalValidator` (`static List<PortalProblem> problems(List<Portal>)`, `PortalProblem(@Nullable String portalId, int index, String reason)` mit `portalLabel()`, `requireValid(String world, List<Portal>)`); die Records `Box`/`Disc`/`Portal` sind reine Daten ohne Konstruktorprüfung. Die Namen MÜSSEN mit dem übereinstimmen, was `lobby-portals` am Ende ausliefert; Aufgabe 1.1 prüft das und passt design.md und tasks.md sonst an.
- Neuer Unterbefehl `/setup portal ...` im Setup-Server (neben `/setup map ...`):
- `/setup portal <id> pos1` und `pos2`: Blockposition des Spielers als Quader-Ecke; der Quader ist die blockinklusive Spanne.
- `/setup portal <id> disc <radius>`: Ring um die Augenposition des Spielers, Normale ist die Blickrichtung, nahe an einer Achse wird sie auf die Achse eingerastet.
- `/setup portal <id> task <task>`, `/setup portal <id> permission <recht|none>`, `/setup portal <id> remove`.
- `/setup portal list`: alle gespeicherten Portale der Welt, darunter getrennt die offenen Entwürfe des Spielers. `/setup portal show`: Umrisse gespeicherter Portale als Partikel für wenige Sekunden, nur für den ausführenden Spieler.
- **Geführter Ablauf:** `/setup portal create <id>` startet eine Schritt-für-Schritt-Führung im Chat mit anklickbaren Knöpfen (Form Box oder Ring, Ecken bzw. Mittelpunkt und Radius, Aufgabe, optionales Recht, Zusammenfassung mit Speichern und Abbrechen). Jeder Knopf führt einen der Unterbefehle aus (`pos1`, `pos2`, `disc`, `task`, `permission` sowie die neuen kleinen Verben `shape`, `centre`, `radius`, `save`, `cancel`); der Ablauf ist eine dünne Schicht über den Befehlen, kein zweiter Codepfad. Der geführte Ablauf und die einzelnen Befehle bearbeiten denselben Entwurf.
- **Live-Vorschau:** Solange ein Spieler einen offenen Entwurf hat, zeigen Partikel nur ihm den Entwurf (gesetzte Ecken, Quader bis zum aktuellen Block des Spielers, Ring mit gewähltem Radius, vorher mit Blickrichtung und Standardradius, mit Hinweis), alle 5 Ticks aktualisiert, mit Obergrenze der Punktzahl; sie endet bei Speichern, Abbrechen, Entfernen und Trennen.
- **Tab-Vervollständigung:** Vorschläge für Portal-Ids (gespeichert und eigene Entwürfe), Verben, bereits verwendete Aufgaben und Radius-Hinweise.
- **Speichern nur per `save`:** Jeder Bearbeitungsbefehl (`pos1`, `pos2`, `shape`, `centre`, `radius`, `disc`, `task`, `permission`) ändert nur den Entwurf und antwortet mit dessen Stand (was noch fehlt, oder „vollständig" mit anklickbarem [save]). Ein Portal wird ausschließlich durch `/setup portal <id> save` gespeichert, im geführten Ablauf wie bei Befehlen; `cancel` verwirft den Entwurf. `save` prüft Vollständigkeit und `PortalValidator.problems(...)` aus `lobby-portals`; die Prüfung ist `PortalValidator.problems(...)` aus `lobby-portals`, die Probleme werden auf Chat-Meldungen abgebildet; dazu Regeln nur des Befehls (Id-Muster, gesperrte Ids `list`/`show`/`create`, Radius als Zahl, leere Aufgabe). Bei Problemen bleibt der Entwurf offen und der Chat nennt sie; ein ungültiges Portal wird nie gespeichert.
- Gespeichert wird über den bestehenden Weg (`MapProvider.saveMap` mit `LobbyMap`-Builder) in die `map.json` der aktuellen Welt; Spawn, Name und Autoren bleiben erhalten.
- Kein Rückgängig-Stapel, kein Wand-Item (der Setup-Server nutzt keins; ein Wand-Item ist ein mögliches Folge-Change).

## Capabilities

### New Capabilities

- `setup-portals`: Das Build-Team legt im Setup-Server Portale per Befehl an, ändert, listet, entfernt und zeigt sie an; nur gültige Portale werden in die Map-Datei der Welt geschrieben.

### Modified Capabilities

Keine. Es gibt keine Setup-Spec; die Lobby-Seite (Laden, Auslösen) liegt in `lobby-portals`.

## Impact

- **Code**: `setup` (neuer Befehl `PortalCommand` unter `SetupCommand`, reine Bearbeitungslogik, Partikel-Umriss, Anbindung an `MapProvider`). Neu sind außerdem reine Klassen für Führung (`PortalFlow`), Vorschau-Geometrie (`DraftOutline`) und Vervollständigung (`PortalCompletions`) sowie ein Vorschau-Dienst mit Scheduler-Task je Spieler. Kein Code in `common` oder `core`, sofern `lobby-portals` `PortalValidator` und Builder-Methode wie beschrieben liefert; `setup` hängt nicht von `features/*` ab (Aufgabennamen kommen aus den vorhandenen Portalen, nicht aus der Navigator-Spalte).
- **Abhängigkeiten**: keine neuen Bibliotheken; `setup/build.gradle.kts` bekommt für den Persistenztest `testImplementation(libs.cyano)` (wie `common`).
- **Tests**: Unit-Tests für Bearbeitung, Abbildung der `PortalValidator`-Probleme, Ringbildung, Umriss, Führungsschritte (Komponenten und Befehlstexte als reine Funktion), Vorschau-Geometrie samt Obergrenze und Vervollständigung ohne Server; ein Persistenztest mit `@TempDir`; Cyano-`Env` mit `env.tick()` für den Vorschau-Lebenszyklus.
- **Nutzertexte**: neue Chat-Rückmeldungen des Setup-Servers, englisch im Stil von `MapCommand` (das Repository hat keine Übersetzungsinfrastruktur, siehe design.md D8).
- **Doku**: Abschnitt „Setup server“ in `README.md` nennt die Befehle.
- **Betrieb**: keine Konfiguration.

## Delivery

PR-Titel: `feat(setup): create lobby portals from in-game commands`

Umfang: größer als zuvor (Führung, Vorschau, Vervollständigung kommen zu den Befehlen hinzu), aber ein Typ (`feat`) und ein Modul (`setup`), daher ein PR. Übersteigt die Umsetzung grob 900 geänderte Zeilen Produktivcode, wird an der Wellengrenze geteilt: erst Befehle, Speichern, `show`; dann Führung, Vorschau, Vervollständigung (beide `feat(setup): …`).

Nicht-Ziele, jeweils eigener Change: Rückgängig-Stapel, Wand-Item (mögliches Folge-Change), Ändern von Portalen anderer Welten als der aktiven, Vorschau in der Lobby, Bearbeiten der Form per Griffe.
Loading
Loading