chore: initial project state (godot-mcp addon, docs)
This commit is contained in:
39
docs/STATUS.md
Normal file
39
docs/STATUS.md
Normal file
@@ -0,0 +1,39 @@
|
||||
# Ruf der Pilze — Projektstatus
|
||||
|
||||
Zuletzt aktualisiert: 2026-04-13
|
||||
|
||||
---
|
||||
|
||||
## Aktueller Stand
|
||||
|
||||
### ✅ Abgeschlossen
|
||||
- MCP-Addon eingerichtet (`godot-mcp`, Claude Code verbunden)
|
||||
- Projektstruktur angelegt (`ruf-der-pilze/`)
|
||||
- CLAUDE.md mit vollständiger Spielkonzept-Dokumentation
|
||||
|
||||
### 🔄 In Arbeit
|
||||
— (nichts aktiv)
|
||||
|
||||
### ⏳ Als nächstes
|
||||
- **Multiplayer Grundgerüst** → Plan: `docs/plans/multiplayer-grundgeruest.md`
|
||||
- Server-Szene (headless-fähig)
|
||||
- Clients verbinden
|
||||
- Basis-RPC testen
|
||||
|
||||
---
|
||||
|
||||
## Entwicklungs-Reihenfolge (gesamt)
|
||||
|
||||
1. ✅ MCP eingerichtet
|
||||
2. ⏳ Multiplayer Grundgerüst (Server, Clients verbinden, rpc testen)
|
||||
3. ⏳ Refektorium — asymmetrische Wahrnehmung (erster Raum)
|
||||
4. ⏳ DM Regiepult Basics — Overlay-Toggle
|
||||
5. ⏳ Alle Räume aufbauen
|
||||
6. ⏳ Polish — Audio, Nebel, Licht, Würfel-UI
|
||||
|
||||
---
|
||||
|
||||
## Offene Entscheidungen
|
||||
|
||||
- Transport: ENet oder WebSocket? (WebSocket = Browser-kompatibel, ENet = performanter)
|
||||
- VPS bereits vorhanden oder noch einzurichten?
|
||||
0
docs/plans/.gitkeep
Normal file
0
docs/plans/.gitkeep
Normal file
184
docs/plans/2026-04-13-multiplayer-grundgeruest-design.md
Normal file
184
docs/plans/2026-04-13-multiplayer-grundgeruest-design.md
Normal file
@@ -0,0 +1,184 @@
|
||||
# Multiplayer Grundgerüst — Design Spec
|
||||
|
||||
**Datum:** 2026-04-13
|
||||
**Status:** Abgenommen
|
||||
**Projekt:** Ruf der Pilze (`ruf-der-pilze/`)
|
||||
|
||||
---
|
||||
|
||||
## Kontext
|
||||
|
||||
Das Spiel benötigt eine Multiplayer-Basis bevor irgendeine Spiellogik gebaut werden kann. Dieses Grundgerüst schafft die Verbindungsschicht: Server startet, Clients verbinden, RPCs funktionieren. Alles Weitere (Räume, Overlays, DM-Regiepult) baut darauf auf.
|
||||
|
||||
---
|
||||
|
||||
## Entscheidungen
|
||||
|
||||
| Entscheidung | Wahl | Begründung |
|
||||
|---|---|---|
|
||||
| Transport | ENet | Native Godot UDP, geringste Latenz, kein Browser-Support benötigt |
|
||||
| Dev-Server | Lokal headless | Kein VPS-Overhead während Entwicklung |
|
||||
| Max. Verbindungen | 8 | 5 Spieler + 1 DM + 2 Reserve |
|
||||
| Architektur | Eine Hauptszene + Autoload | Godot-idiomatisch |
|
||||
| Port | 4242 | Projektstandard |
|
||||
| Server-Erkennung | `--server` CLI-Argument | `OS.has_feature("dedicated_server")` gilt nur für Server-Exports, nicht für headless Dev-Runs |
|
||||
|
||||
---
|
||||
|
||||
## Dateistruktur
|
||||
|
||||
```
|
||||
ruf-der-pilze/
|
||||
├── scenes/
|
||||
│ └── main.tscn ← Root-Szene (Node)
|
||||
├── scripts/
|
||||
│ ├── main.gd ← Modus-Erkennung + Bootstrap
|
||||
│ └── network_manager.gd ← Autoload: Peer-Verwaltung, Signale
|
||||
└── project.godot ← NetworkManager als Autoload registriert
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Architektur
|
||||
|
||||
### NetworkManager (Autoload)
|
||||
|
||||
Singleton, der den gesamten Multiplayer-Peer hält. Szenen greifen über `NetworkManager` auf Verbindungsstatus und peer_ids zu.
|
||||
|
||||
**Verantwortlichkeiten:**
|
||||
- ENetMultiplayerPeer erstellen (Server oder Client)
|
||||
- Signale weiterleiten: `peer_connected(id)`, `peer_disconnected(id)`, `connected_to_server()`, `connection_failed()`
|
||||
- Eigene peer_id bereitstellen: `NetworkManager.my_id` (wird bei Verbindung gesetzt)
|
||||
- Liste aller verbundenen peers: `NetworkManager.peers` (Dictionary `id → {}`)
|
||||
|
||||
**Signale:**
|
||||
```gdscript
|
||||
signal peer_connected(id: int)
|
||||
signal peer_disconnected(id: int)
|
||||
signal connection_failed()
|
||||
signal connected_to_server()
|
||||
```
|
||||
|
||||
### main.gd — Modus-Erkennung
|
||||
|
||||
```gdscript
|
||||
func _ready() -> void:
|
||||
# OS.has_feature("dedicated_server") gilt nur bei Server-Export-Template.
|
||||
# Für lokale Dev-Runs: --server als CLI-Argument übergeben.
|
||||
var is_server := OS.has_feature("dedicated_server") \
|
||||
or "--server" in OS.get_cmdline_user_args()
|
||||
|
||||
if is_server:
|
||||
NetworkManager.start_server(4242, 8)
|
||||
else:
|
||||
NetworkManager.join_server("127.0.0.1", 4242)
|
||||
```
|
||||
|
||||
### Server-Initialisierung
|
||||
|
||||
```gdscript
|
||||
func start_server(port: int, max_clients: int) -> void:
|
||||
var peer := ENetMultiplayerPeer.new()
|
||||
var err := peer.create_server(port, max_clients)
|
||||
if err != OK:
|
||||
push_error("[Server] Port %d konnte nicht gebunden werden: %s" % [port, error_string(err)])
|
||||
return
|
||||
multiplayer.multiplayer_peer = peer
|
||||
multiplayer.peer_connected.connect(_on_peer_connected)
|
||||
multiplayer.peer_disconnected.connect(_on_peer_disconnected)
|
||||
print("[Server] Gestartet auf Port %d" % port)
|
||||
|
||||
func _on_peer_connected(id: int) -> void:
|
||||
peers[id] = {}
|
||||
peer_connected.emit(id)
|
||||
print("[Server] Peer verbunden: %d" % id)
|
||||
welcome.rpc_id(id, id) # nur an diesen Client
|
||||
|
||||
func _on_peer_disconnected(id: int) -> void:
|
||||
peers.erase(id)
|
||||
peer_disconnected.emit(id)
|
||||
print("[Server] Peer getrennt: %d" % id)
|
||||
```
|
||||
|
||||
### Client-Verbindung
|
||||
|
||||
```gdscript
|
||||
func join_server(ip: String, port: int) -> void:
|
||||
var peer := ENetMultiplayerPeer.new()
|
||||
var err := peer.create_client(ip, port)
|
||||
if err != OK:
|
||||
push_error("[Client] Verbindung zu %s:%d fehlgeschlagen: %s" % [ip, port, error_string(err)])
|
||||
return
|
||||
multiplayer.multiplayer_peer = peer
|
||||
multiplayer.connected_to_server.connect(_on_connected_to_server)
|
||||
multiplayer.connection_failed.connect(_on_connection_failed)
|
||||
|
||||
func _on_connected_to_server() -> void:
|
||||
my_id = multiplayer.get_unique_id()
|
||||
connected_to_server.emit()
|
||||
print("[Client] Verbunden. Meine peer_id: %d" % my_id)
|
||||
|
||||
func _on_connection_failed() -> void:
|
||||
connection_failed.emit()
|
||||
push_error("[Client] Verbindung fehlgeschlagen")
|
||||
```
|
||||
|
||||
### RPC-Smoke-Test
|
||||
|
||||
Server schickt nach jeder neuen Verbindung ein `welcome`-RPC **nur an diesen Client**:
|
||||
|
||||
```gdscript
|
||||
# Hinweis: call_remote bedeutet der Server führt diese Funktion NICHT lokal aus.
|
||||
# Sie wird ausschließlich auf dem Ziel-Client ausgeführt.
|
||||
@rpc("authority", "call_remote", "reliable")
|
||||
func welcome(peer_id: int) -> void:
|
||||
print("[Client] Willkommen, meine peer_id ist: %d" % peer_id)
|
||||
```
|
||||
|
||||
Erwartetes Verhalten:
|
||||
- **Server-Terminal:** zeigt nur `[Server] Peer verbunden: 123456`
|
||||
- **Client-Output:** zeigt `[Client] Verbunden. Meine peer_id: 123456` und `[Client] Willkommen, meine peer_id ist: 123456`
|
||||
|
||||
---
|
||||
|
||||
## Verifikation
|
||||
|
||||
### Schritt 1 — Server starten (headless)
|
||||
```bash
|
||||
cd ruf-der-pilze/
|
||||
godot --headless -- --server
|
||||
# Erwartete Ausgabe: [Server] Gestartet auf Port 4242
|
||||
```
|
||||
|
||||
> **Hinweis:** `--` trennt Godot-Argumente von User-Argumenten. `OS.get_cmdline_user_args()` gibt `["--server"]` zurück.
|
||||
|
||||
### Schritt 2 — Client verbinden (Godot Editor, F5)
|
||||
```
|
||||
# Server-Terminal zeigt:
|
||||
[Server] Peer verbunden: 123456
|
||||
|
||||
# Client-Ausgabe (Godot Output-Panel):
|
||||
[Client] Verbunden. Meine peer_id: 123456
|
||||
[Client] Willkommen, meine peer_id ist: 123456
|
||||
```
|
||||
|
||||
### Schritt 3 — Zweiten Client testen
|
||||
Zweiten Godot-Prozess starten → Server zeigt beide peer_ids, beide Clients erhalten ihre individuelle Welcome-Nachricht mit korrekter peer_id.
|
||||
|
||||
### Schritt 4 — Disconnect testen
|
||||
Client schließen → Server-Terminal zeigt `[Server] Peer getrennt: 123456`, `peers` Dictionary hat den Eintrag entfernt.
|
||||
|
||||
---
|
||||
|
||||
## Was dieses Grundgerüst NICHT enthält
|
||||
|
||||
- Spieler-Rollen (Spieler vs. DM) — kommt im nächsten Schritt
|
||||
- Authentifizierung / Lobby-Logik
|
||||
- Reconnect-Handling
|
||||
- Irgendwelche Spiellogik
|
||||
|
||||
---
|
||||
|
||||
## Nächster Schritt
|
||||
|
||||
Aufbauend auf diesem Grundgerüst: **Lobby + Rollen** (Spieler registrieren sich mit Name und Rolle, DM bekommt Sonderrechte).
|
||||
338
docs/plans/2026-04-13-multiplayer-grundgeruest-plan.md
Normal file
338
docs/plans/2026-04-13-multiplayer-grundgeruest-plan.md
Normal file
@@ -0,0 +1,338 @@
|
||||
# Multiplayer Grundgerüst — Implementation Plan
|
||||
|
||||
> **For agentic workers:** REQUIRED SUB-SKILL: Use superpowers:subagent-driven-development (recommended) or superpowers:executing-plans to implement this plan task-by-task. Steps use checkbox (`- [ ]`) syntax for tracking.
|
||||
|
||||
**Goal:** Server und Client verbinden sich via ENet, der Server schickt bei Verbindung ein welcome-RPC an den Client — verifiziert durch Terminal-Output.
|
||||
|
||||
**Architecture:** Eine einzige `main.tscn` erkennt per `OS.has_feature("dedicated_server") or "--server" in OS.get_cmdline_user_args()` ob sie Server oder Client ist und delegiert an den `NetworkManager`-Autoload. Der `NetworkManager` hält den ENet-Peer und leitet alle Verbindungs-Signale weiter.
|
||||
|
||||
**Tech Stack:** Godot 4.6.2, GDScript, ENetMultiplayerPeer, Godot MultiplayerAPI
|
||||
|
||||
**Spec:** `docs/plans/2026-04-13-multiplayer-grundgeruest-design.md`
|
||||
|
||||
**Arbeitsverzeichnis:** Alle Befehle werden aus `ruf-der-pilze/` ausgeführt, sofern nicht anders angegeben.
|
||||
|
||||
---
|
||||
|
||||
## Dateiübersicht
|
||||
|
||||
| Datei | Aktion | Verantwortlichkeit |
|
||||
|---|---|---|
|
||||
| `scripts/network_manager.gd` | Erstellen | Autoload: ENet-Peer, Signale, peer_id-Verwaltung |
|
||||
| `scripts/main.gd` | Erstellen | Modus-Erkennung (Server/Client), Bootstrap |
|
||||
| `scenes/main.tscn` | Erstellen | Root-Szene (Node + main.gd) |
|
||||
| `project.godot` | Modifizieren | NetworkManager als Autoload, main.tscn als Hauptszene |
|
||||
|
||||
---
|
||||
|
||||
### Task 0: Voraussetzungen
|
||||
|
||||
**Files:** keine
|
||||
|
||||
- [ ] **Step 1: Godot-Binary prüfen**
|
||||
|
||||
```bash
|
||||
which godot || which godot4
|
||||
```
|
||||
|
||||
Merke dir den Namen (wahrscheinlich `godot4` auf Arch Linux). Ersetze `godot` in allen folgenden Schritten durch den tatsächlichen Binary-Namen.
|
||||
|
||||
- [ ] **Step 2: Verzeichnisse anlegen**
|
||||
|
||||
```bash
|
||||
# aus ruf-der-pilze/
|
||||
mkdir -p scripts scenes
|
||||
```
|
||||
|
||||
- [ ] **Step 3: Git initialisieren (falls noch nicht vorhanden)**
|
||||
|
||||
Das Git-Repository soll den gesamten `DnD_Anna_OneShot/`-Ordner abdecken, damit `docs/` und `ruf-der-pilze/` gemeinsam versioniert werden.
|
||||
|
||||
```bash
|
||||
# aus DnD_Anna_OneShot/ (eine Ebene höher als ruf-der-pilze/)
|
||||
cd /home/mpuchstein/Dev/Godot/DnD_Anna_OneShot
|
||||
git status 2>/dev/null || git init
|
||||
```
|
||||
|
||||
Falls `git init` ausgeführt wurde: einmalig committen was schon da ist:
|
||||
|
||||
```bash
|
||||
git add .
|
||||
git commit -m "chore: initial project state (godot-mcp addon, docs)"
|
||||
```
|
||||
|
||||
Danach für alle weiteren Schritte wieder in `ruf-der-pilze/` wechseln:
|
||||
|
||||
```bash
|
||||
cd ruf-der-pilze/
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
### Task 1: NetworkManager-Autoload schreiben
|
||||
|
||||
**Files:**
|
||||
- Create: `scripts/network_manager.gd`
|
||||
|
||||
- [ ] **Step 1: Datei erstellen**
|
||||
|
||||
Erstelle `ruf-der-pilze/scripts/network_manager.gd`:
|
||||
|
||||
```gdscript
|
||||
extends Node
|
||||
|
||||
signal peer_connected(id: int)
|
||||
signal peer_disconnected(id: int)
|
||||
signal connected_to_server()
|
||||
signal connection_failed()
|
||||
|
||||
var peers: Dictionary = {}
|
||||
var my_id: int = 0
|
||||
|
||||
|
||||
func start_server(port: int, max_clients: int) -> void:
|
||||
var peer := ENetMultiplayerPeer.new()
|
||||
var err := peer.create_server(port, max_clients)
|
||||
if err != OK:
|
||||
push_error("[Server] Port %d konnte nicht gebunden werden: %s" % [port, error_string(err)])
|
||||
return
|
||||
multiplayer.multiplayer_peer = peer
|
||||
multiplayer.peer_connected.connect(_on_peer_connected)
|
||||
multiplayer.peer_disconnected.connect(_on_peer_disconnected)
|
||||
print("[Server] Gestartet auf Port %d" % port)
|
||||
|
||||
|
||||
func join_server(ip: String, port: int) -> void:
|
||||
var peer := ENetMultiplayerPeer.new()
|
||||
var err := peer.create_client(ip, port)
|
||||
if err != OK:
|
||||
push_error("[Client] Verbindung zu %s:%d fehlgeschlagen: %s" % [ip, port, error_string(err)])
|
||||
return
|
||||
multiplayer.multiplayer_peer = peer
|
||||
multiplayer.connected_to_server.connect(_on_connected_to_server)
|
||||
multiplayer.connection_failed.connect(_on_connection_failed)
|
||||
|
||||
|
||||
func _on_peer_connected(id: int) -> void:
|
||||
peers[id] = {}
|
||||
peer_connected.emit(id)
|
||||
print("[Server] Peer verbunden: %d" % id)
|
||||
welcome.rpc_id(id, id)
|
||||
|
||||
|
||||
func _on_peer_disconnected(id: int) -> void:
|
||||
peers.erase(id)
|
||||
peer_disconnected.emit(id)
|
||||
print("[Server] Peer getrennt: %d" % id)
|
||||
|
||||
|
||||
func _on_connected_to_server() -> void:
|
||||
my_id = multiplayer.get_unique_id()
|
||||
connected_to_server.emit()
|
||||
print("[Client] Verbunden. Meine peer_id: %d" % my_id)
|
||||
|
||||
|
||||
func _on_connection_failed() -> void:
|
||||
connection_failed.emit()
|
||||
push_error("[Client] Verbindung fehlgeschlagen")
|
||||
|
||||
|
||||
@rpc("authority", "call_remote", "reliable")
|
||||
func welcome(peer_id: int) -> void:
|
||||
# call_remote: wird NUR auf dem Ziel-Client ausgeführt, nicht auf dem Server.
|
||||
print("[Client] Willkommen, meine peer_id ist: %d" % peer_id)
|
||||
```
|
||||
|
||||
- [ ] **Step 2: Syntax im Editor prüfen**
|
||||
|
||||
`scripts/network_manager.gd` in Godot öffnen → Script-Editor zeigt keine roten Fehler-Markierungen. Kein Parse-Error im Output-Panel.
|
||||
|
||||
- [ ] **Step 3: Commit**
|
||||
|
||||
```bash
|
||||
# aus ruf-der-pilze/
|
||||
git add scripts/network_manager.gd
|
||||
git commit -m "net: add NetworkManager autoload with ENet server/client and welcome RPC"
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
### Task 2: Autoload in project.godot registrieren
|
||||
|
||||
**Files:**
|
||||
- Modify: `project.godot`
|
||||
|
||||
- [ ] **Step 1: Autoload über Editor registrieren**
|
||||
|
||||
In Godot: **Project → Project Settings → Autoload**
|
||||
- Pfad: `res://scripts/network_manager.gd`
|
||||
- Name: `NetworkManager`
|
||||
- Global Variable: ✅ aktiviert
|
||||
- Auf "Add" klicken → "NetworkManager" erscheint in der Liste
|
||||
|
||||
`project.godot` enthält danach:
|
||||
```ini
|
||||
[autoload]
|
||||
NetworkManager="*res://scripts/network_manager.gd"
|
||||
```
|
||||
|
||||
- [ ] **Step 2: Verifizieren**
|
||||
|
||||
Godot-Editor schließen und neu starten (Projekt erneut öffnen). Prüfen ob im Output-Panel beim Start Fehler erscheinen. Kein "Could not load script" oder "NetworkManager not found" → Autoload korrekt registriert.
|
||||
|
||||
- [ ] **Step 3: Commit**
|
||||
|
||||
```bash
|
||||
# aus ruf-der-pilze/
|
||||
git add project.godot
|
||||
git commit -m "net: register NetworkManager as autoload"
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
### Task 3: main.gd schreiben
|
||||
|
||||
**Files:**
|
||||
- Create: `scripts/main.gd`
|
||||
|
||||
- [ ] **Step 1: Datei erstellen**
|
||||
|
||||
Erstelle `ruf-der-pilze/scripts/main.gd`:
|
||||
|
||||
```gdscript
|
||||
extends Node
|
||||
|
||||
|
||||
func _ready() -> void:
|
||||
# OS.has_feature("dedicated_server") gilt nur bei Server-Export-Template.
|
||||
# Für lokale Dev-Runs: --server als User-Argument übergeben (nach -- in CLI).
|
||||
var is_server := OS.has_feature("dedicated_server") \
|
||||
or "--server" in OS.get_cmdline_user_args()
|
||||
|
||||
if is_server:
|
||||
NetworkManager.start_server(4242, 8)
|
||||
else:
|
||||
NetworkManager.join_server("127.0.0.1", 4242)
|
||||
```
|
||||
|
||||
- [ ] **Step 2: Syntax prüfen**
|
||||
|
||||
Script im Godot-Editor öffnen → keine Fehler.
|
||||
|
||||
- [ ] **Step 3: Commit**
|
||||
|
||||
```bash
|
||||
# aus ruf-der-pilze/
|
||||
git add scripts/main.gd
|
||||
git commit -m "net: add main.gd with server/client mode detection"
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
### Task 4: main.tscn erstellen und als Hauptszene setzen
|
||||
|
||||
**Files:**
|
||||
- Create: `scenes/main.tscn`
|
||||
- Modify: `project.godot`
|
||||
|
||||
- [ ] **Step 1: Szene erstellen**
|
||||
|
||||
In Godot: **Scene → New Scene**
|
||||
- Root-Node: `Node` (nicht Node2D oder Node3D)
|
||||
- Node umbenennen zu: `Main`
|
||||
- Script anhängen: über den Inspector → Script-Slot → `res://scripts/main.gd` wählen
|
||||
- Speichern als: `res://scenes/main.tscn` (Ctrl+S)
|
||||
|
||||
- [ ] **Step 2: Als Hauptszene setzen**
|
||||
|
||||
**Project → Project Settings → Application → Run → Main Scene** → `res://scenes/main.tscn` auswählen
|
||||
|
||||
- [ ] **Step 3: Commit**
|
||||
|
||||
```bash
|
||||
# aus ruf-der-pilze/
|
||||
git add scenes/main.tscn project.godot
|
||||
git commit -m "net: add main.tscn as root scene"
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
### Task 5: Integration testen — Server + Client
|
||||
|
||||
**Files:** keine Änderungen
|
||||
|
||||
- [ ] **Step 1: Server headless starten**
|
||||
|
||||
```bash
|
||||
# aus ruf-der-pilze/ — Binary-Name ggf. anpassen (siehe Task 0)
|
||||
godot --headless -- --server
|
||||
```
|
||||
|
||||
Erwartete Ausgabe:
|
||||
```
|
||||
[Server] Gestartet auf Port 4242
|
||||
```
|
||||
|
||||
Falls kein Output: `OS.get_cmdline_user_args()` prüfen — das `--` ist zwingend (trennt Godot-Args von User-Args). Ohne `--` landet `--server` in `get_cmdline_args()`, nicht in `get_cmdline_user_args()`.
|
||||
|
||||
- [ ] **Step 2: Client verbinden (Godot Editor)**
|
||||
|
||||
Godot-Editor → F5 (Projekt ausführen, kein `--server` Argument)
|
||||
|
||||
*Server-Terminal:*
|
||||
```
|
||||
[Server] Peer verbunden: 123456
|
||||
```
|
||||
|
||||
*Godot Output-Panel (Client):*
|
||||
```
|
||||
[Client] Verbunden. Meine peer_id: 123456
|
||||
[Client] Willkommen, meine peer_id ist: 123456
|
||||
```
|
||||
|
||||
Hinweis: Der Server printet `welcome` **nicht** — `call_remote` bedeutet die Funktion läuft nur auf dem Ziel-Client.
|
||||
|
||||
- [ ] **Step 3: Disconnect testen**
|
||||
|
||||
Client (Editor) schließen / F8 → Server-Terminal zeigt:
|
||||
```
|
||||
[Server] Peer getrennt: 123456
|
||||
```
|
||||
|
||||
- [ ] **Step 4: STATUS.md updaten**
|
||||
|
||||
`/home/mpuchstein/Dev/Godot/DnD_Anna_OneShot/docs/STATUS.md` öffnen und aktualisieren:
|
||||
|
||||
```markdown
|
||||
### ✅ Abgeschlossen
|
||||
- MCP-Addon eingerichtet
|
||||
- Projektstruktur angelegt
|
||||
- CLAUDE.md mit vollständiger Spielkonzept-Dokumentation
|
||||
- **Multiplayer Grundgerüst** — ENet Server/Client, NetworkManager Autoload, welcome RPC verifiziert
|
||||
|
||||
### ⏳ Als nächstes
|
||||
- Lobby + Rollen (Spieler registrieren sich mit Name + Rolle, DM kriegt Sonderrechte)
|
||||
Plan: noch zu erstellen
|
||||
```
|
||||
|
||||
- [ ] **Step 5: Finaler Commit**
|
||||
|
||||
```bash
|
||||
# aus DnD_Anna_OneShot/ (Repo-Root, weil docs/ dort liegt)
|
||||
cd /home/mpuchstein/Dev/Godot/DnD_Anna_OneShot
|
||||
git add docs/STATUS.md
|
||||
git commit -m "docs: mark Multiplayer Grundgerüst as complete in STATUS.md"
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Verifikations-Checkliste
|
||||
|
||||
Vor "fertig" erklären:
|
||||
|
||||
- [ ] `[Server] Gestartet auf Port 4242` erscheint beim headless Start
|
||||
- [ ] `[Server] Peer verbunden: <id>` erscheint wenn Client verbindet
|
||||
- [ ] `[Client] Verbunden. Meine peer_id: <id>` erscheint im Client
|
||||
- [ ] `[Client] Willkommen, meine peer_id ist: <id>` erscheint im Client (RPC angekommen)
|
||||
- [ ] `[Server] Peer getrennt: <id>` erscheint wenn Client schließt
|
||||
- [ ] Kein `push_error` oder Parser-Fehler in keiner Ansicht
|
||||
Reference in New Issue
Block a user