diff --git a/docs/plans/2026-04-14-tavern-scene-plan.md b/docs/plans/2026-04-14-tavern-scene-plan.md new file mode 100644 index 0000000..bb44a78 --- /dev/null +++ b/docs/plans/2026-04-14-tavern-scene-plan.md @@ -0,0 +1,606 @@ +# Taverne In-Game-Szene 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:** 2-stöckige In-Game-Taverne bauen (Blockout), Gastraum als Sub-Scene extrahieren, und nach `game_started` Spieler in ihre Zimmer und DM in eine Stub-Szene routen. + +**Architecture:** `taproom.tscn` (Geometrie-Only) wird von `tavern_lobby.tscn` und `tavern.tscn` instanziert. `SceneManager` routet bei `game_started` Spieler zu `tavern.tscn` und DM zu `dm_view.tscn`. Room-Zuweisung wird als Parameter in `start_game` RPC mitgeschickt (verhindert Timing-Probleme zwischen RPC-Empfang und Scene-`_ready()`). + +**Tech Stack:** Godot 4.x, GDScript, ENet Multiplayer, BoxMesh Placeholder-Geometrie, godot-mcp MCP Tools + +--- + +## File Map + +| Aktion | Pfad | Verantwortung | +|--------|------|---------------| +| Umbenennen | `scenes/tavern.tscn` → `scenes/tavern_lobby.tscn` | Lobby/Warteraum | +| Umbenennen | `scripts/tavern.gd` → `scripts/tavern_lobby.gd` | Lobby-Script | +| Erstellen | `scenes/taproom.tscn` | Gastraum-Geometrie (kein Script, kein UI) | +| Erstellen | `scenes/tavern.tscn` | In-Game-Taverne (Erd- + Obergeschoss) | +| Erstellen | `scenes/dm_view.tscn` | DM-Szene Stub | +| Erstellen | `scripts/tavern.gd` | Spawn-Logik: Spieler im richtigen Zimmer | +| Erstellen | `scripts/dm_view.gd` | DM-Stub-Script | +| Ändern | `scripts/scene_manager.gd` | SCENES dict, `_on_root_ready`, `_on_game_started`, `pending_room_index` | +| Ändern | `scripts/network_manager.gd` | `start_game(room_assignments)`, `_build_room_assignments()` | + +Alle Pfade relativ zu `ruf-der-pilze/`. + +--- + +## Task 1: Bestehende Tavern-Dateien umbenennen + +**Files:** +- Rename: `scenes/tavern.tscn` → `scenes/tavern_lobby.tscn` +- Rename: `scripts/tavern.gd` → `scripts/tavern_lobby.gd` + +- [ ] **Step 1: Dateien per git mv umbenennen** + +```bash +cd ruf-der-pilze +git mv scenes/tavern.tscn scenes/tavern_lobby.tscn +git mv scripts/tavern.gd scripts/tavern_lobby.gd +``` + +- [ ] **Step 2: Script-Referenz in `tavern_lobby.tscn` aktualisieren** + +`tavern_lobby.tscn` referenziert das Script noch als `res://scripts/tavern.gd`. Ändere die erste Zeile: + +``` +# ALT: +[ext_resource type="Script" path="res://scripts/tavern.gd" id="1"] +# NEU: +[ext_resource type="Script" path="res://scripts/tavern_lobby.gd" id="1"] +``` + +- [ ] **Step 3: Klassennamen in `tavern_lobby.gd` anpassen (optional, aber sauber)** + +Datei `scripts/tavern_lobby.gd` — keine Änderung am Code nötig, `extends Node3D` bleibt. + +- [ ] **Step 4: Verifizieren — Godot öffnen, Scene-Fehler prüfen** + +Öffne Godot. Prüfe im Editor dass `tavern_lobby.tscn` keine Fehler im Script-Attachment zeigt. +Erwartung: Scene öffnet, JoinPanel sichtbar, keine Fehlermeldungen im Output. + +- [ ] **Step 5: Committen** + +```bash +git add scenes/tavern_lobby.tscn scripts/tavern_lobby.gd +git commit -m "refactor: rename tavern → tavern_lobby (scene + script)" +``` + +--- + +## Task 2: SceneManager aktualisieren + +**Files:** +- Modify: `scripts/scene_manager.gd` + +- [ ] **Step 1: SCENES dict, pending_room_index und `_on_root_ready` aktualisieren** + +Ersetze den gesamten Inhalt von `scripts/scene_manager.gd`: + +```gdscript +extends Node + +const SCENES := { + "lobby": "res://scenes/tavern_lobby.tscn", + "tavern": "res://scenes/tavern.tscn", + "dm_view": "res://scenes/dm_view.tscn", + "entrance_hall": "res://scenes/entrance_hall.tscn", + "refectory": "res://scenes/refectory.tscn", + "library": "res://scenes/library.tscn", + "chapel": "res://scenes/chapel.tscn", + "cloister": "res://scenes/cloister.tscn", + "sanctum": "res://scenes/sanctum.tscn", +} + +var pending_room_index: int = 0 +var _current_scene_node: Node = null + + +func _ready() -> void: + NetworkManager.game_started.connect(_on_game_started) + get_tree().root.ready.connect(_on_root_ready, CONNECT_ONE_SHOT) + + +func _on_root_ready() -> void: + var args := OS.get_cmdline_args() + OS.get_cmdline_user_args() + var is_server := OS.has_feature("dedicated_server") or "--server" in args + if not is_server: + transition_to("lobby") + + +func transition_to(scene_name: String) -> void: + var path: String = SCENES.get(scene_name, "") + var packed := ResourceLoader.load(path, "PackedScene", ResourceLoader.CACHE_MODE_REUSE) as PackedScene + if packed == null: + push_error("[SceneManager] Scene not found: %s" % scene_name) + return + var container := get_node_or_null("/root/Main/CurrentScene") + if container == null: + push_error("[SceneManager] CurrentScene node not found in main.tscn") + return + if _current_scene_node != null: + _current_scene_node.get_parent().remove_child(_current_scene_node) + _current_scene_node.queue_free() + _current_scene_node = null + _current_scene_node = packed.instantiate() + container.add_child(_current_scene_node) + + +func _on_game_started() -> void: + var args := OS.get_cmdline_args() + OS.get_cmdline_user_args() + if OS.has_feature("dedicated_server") or "--server" in args: + return + var role: String = NetworkManager.players.get(NetworkManager.my_id, {}).get("role", "player") + if role == "dm": + transition_to("dm_view") + else: + transition_to("tavern") +``` + +- [ ] **Step 2: Verifizieren — Lobby lädt noch** + +Starte das Spiel (kein Server). Erwartung: Lobby erscheint mit JoinPanel. +Console: `[SceneManager]` kein Fehler-Output. + +- [ ] **Step 3: Committen** + +```bash +git add scripts/scene_manager.gd +git commit -m "feat: update SceneManager — lobby/tavern/dm_view keys, game_started routing" +``` + +--- + +## Task 3: taproom.tscn erstellen und Lobby darauf umstellen + +**Files:** +- Create: `scenes/taproom.tscn` +- Modify: `scenes/tavern_lobby.tscn` + +Die bestehende Geometrie aus `tavern_lobby.tscn` (Floor, Ceiling, Wände) wird in `taproom.tscn` extrahiert. Der Gastraum bleibt atmosphärisch identisch. + +- [ ] **Step 1: `taproom.tscn` erstellen** + +Erstelle `scenes/taproom.tscn` mit folgender Node-Struktur (MCP-Tool oder manuell): + +``` +Node3D "Taproom" ← Root, kein Script + StaticBody3D "Floor" + MeshInstance3D mesh: BoxMesh(12, 0.1, 8) + CollisionShape3D shape: BoxShape3D(12, 0.1, 8) + StaticBody3D "Ceiling" + MeshInstance3D mesh: BoxMesh(12, 0.1, 8), transform.origin.y = 4.0 + CollisionShape3D shape: BoxShape3D(12, 0.1, 8) + StaticBody3D "WallBack" + MeshInstance3D mesh: BoxMesh(12, 4, 0.1), transform.origin = (0, 2, -4) + CollisionShape3D + StaticBody3D "WallLeft" + MeshInstance3D mesh: BoxMesh(0.1, 4, 8), transform.origin = (-6, 2, 0) + CollisionShape3D + StaticBody3D "WallRight" + MeshInstance3D mesh: BoxMesh(0.1, 4, 8), transform.origin = (6, 2, 0) + CollisionShape3D + StaticBody3D "Bar" ← Tresen: Küchen-Grenze + MeshInstance3D mesh: BoxMesh(4, 1.1, 0.3), transform.origin = (4, 0.55, -3.5) + CollisionShape3D + OmniLight3D "Light" + transform.origin = (0, 2.5, 0) + light_color = Color(0.91, 0.643, 0.29) + light_energy = 1.2 + omni_range = 10.0 + WorldEnvironment "WorldEnvironment" + environment: (fog, warm ambient — gleich wie in bisheriger tavern.tscn) +``` + +Materialien: Braun-Töne wie in bisheriger `tavern.tscn` (StandardMaterial3D albedo_color ≈ Color(0.169, 0.102, 0.051)). + +- [ ] **Step 2: `tavern_lobby.tscn` aktualisieren** + +Ersetze die bestehende Geometrie in `tavern_lobby.tscn` durch eine Instanz von `taproom.tscn`. Die Szene behält Camera3D und CanvasLayer. + +Neue Node-Struktur von `tavern_lobby.tscn`: +``` +Node3D "TavernLobby" ← script = tavern_lobby.gd + [taproom.tscn instanziert als Child] ← Name: "Taproom" + Camera3D "Camera3D" ← bestehende Lobby-Kamera (transform bleibt) + CanvasLayer "CanvasLayer" ← JoinPanel + WaitPanel (unverändert) +``` + +- [ ] **Step 3: Verifizieren** + +Starte das Spiel. Erwartung: Lobby sieht identisch aus wie vorher (gleicher Gastraum, gleiche UI). +Falls Geometrie fehlt oder falsch positioniert: Transform-Werte in taproom.tscn korrigieren. + +- [ ] **Step 4: Committen** + +```bash +git add scenes/taproom.tscn scenes/tavern_lobby.tscn +git commit -m "refactor: extract taproom as reusable sub-scene, update lobby" +``` + +--- + +## Task 4: `tavern.tscn` Erdgeschoss bauen + +**Files:** +- Create: `scenes/tavern.tscn` +- Create: `scripts/tavern.gd` (Stub — Spawn-Logik kommt in Task 7) + +Erdgeschoss: Taproom + sichtbare Küche (nicht betretbar) + Private Gemächer (Tür) + Ausgang + Myzelspur. + +- [ ] **Step 1: `scripts/tavern.gd` Stub erstellen** + +```gdscript +extends Node3D + + +func _ready() -> void: + print("[Tavern] Scene loaded. Room index: %d" % SceneManager.pending_room_index) +``` + +- [ ] **Step 2: `scenes/tavern.tscn` Erdgeschoss bauen** + +Node-Struktur: +``` +Node3D "Tavern" ← script = tavern.gd + [taproom.tscn instanziert] ← Name: "Taproom", transform.origin = (0,0,0) + Node3D "GroundFloor" + StaticBody3D "KitchenBack" ← Hinterwand Küche (sichtbar hinter Tresen) + MeshInstance3D mesh: BoxMesh(4, 3, 0.1), transform.origin = (4, 1.5, -5.9) + StaticBody3D "KitchenLeft" + MeshInstance3D mesh: BoxMesh(0.1, 3, 2.3), transform.origin = (2.05, 1.5, -4.85) + StaticBody3D "KitchenRight" + MeshInstance3D mesh: BoxMesh(0.1, 3, 2.3), transform.origin = (5.95, 1.5, -4.85) + StaticBody3D "PrivateRoomDoor" ← Tür zu Privatgemächern (geschlossen) + MeshInstance3D mesh: BoxMesh(0.1, 4, 2), transform.origin = (-6, 2, 2) + StaticBody3D "ExitDoor" ← Ausgang zur Myzelspur (später: interaktiv) + MeshInstance3D mesh: BoxMesh(0.1, 4, 2), transform.origin = (6, 2, 4) + Node3D "MyzelTrailGround" ← Myzelspur: Treppe → Ausgang + MeshInstance3D "TrailSegment1" mesh: BoxMesh(0.5, 0.01, 3), grünlich, transform.origin = (0, 0.06, 1.5) + MeshInstance3D "TrailSegment2" mesh: BoxMesh(0.5, 0.01, 4), transform.origin = (2, 0.06, 0) + # Weitere Segmente dem Weg entlang anpassen +``` + +Material Myzelspur: StandardMaterial3D, albedo_color = Color(0.2, 0.8, 0.3), emission_enabled = true, emission = Color(0.1, 0.4, 0.1). + +- [ ] **Step 3: Verifizieren — Scene lädt ohne Fehler** + +Öffne `tavern.tscn` im Godot Editor. Erwartung: Kein Parser-Fehler, Erdgeschoss sichtbar in 3D-Vorschau. + +- [ ] **Step 4: Committen** + +```bash +git add scenes/tavern.tscn scripts/tavern.gd +git commit -m "feat: tavern scene — ground floor blockout (taproom, kitchen, exit, myzel trail)" +``` + +--- + +## Task 5: `tavern.tscn` Obergeschoss bauen + +**Files:** +- Modify: `scenes/tavern.tscn` + +8 Gästezimmer + Annas Zimmer + Korridor + Treppe. Jedes Gästezimmer hat einen `Marker3D` SpawnPoint. + +Maße: Gebäude ~16m breit, 8m tief. Korridor: 1.5m breit, Zimmer: 3m x 3.5m. + +- [ ] **Step 1: Treppe einbauen** + +In `tavern.tscn` unter `GroundFloor` hinzufügen: +``` +StaticBody3D "Stairs" + MeshInstance3D mesh: BoxMesh(1.5, 0.2, 4) als Rampe — transform mit Rotation X ca. -25° + transform.origin = (0, 1, 3) ← verbindet EG mit OG + CollisionShape3D +``` + +- [ ] **Step 2: Obergeschoss-Struktur und Korridor bauen** + +Füge zu `tavern.tscn` hinzu: +``` +Node3D "UpperFloor" + StaticBody3D "Floor" + MeshInstance3D mesh: BoxMesh(16, 0.1, 8), transform.origin = (2, 4, 0) + CollisionShape3D + StaticBody3D "Ceiling" + MeshInstance3D mesh: BoxMesh(16, 0.1, 8), transform.origin = (2, 7, 0) + CollisionShape3D + StaticBody3D "WallBack" + MeshInstance3D mesh: BoxMesh(16, 3, 0.1), transform.origin = (2, 5.5, -4) + CollisionShape3D + StaticBody3D "WallFront" + MeshInstance3D mesh: BoxMesh(16, 3, 0.1), transform.origin = (2, 5.5, 4) + CollisionShape3D + StaticBody3D "WallLeft" + MeshInstance3D mesh: BoxMesh(0.1, 3, 8), transform.origin = (-6, 5.5, 0) + CollisionShape3D + StaticBody3D "WallRight" + MeshInstance3D mesh: BoxMesh(0.1, 3, 8), transform.origin = (10, 5.5, 0) + CollisionShape3D + StaticBody3D "CorridorWall" ← Korridor-Innenwand (trennt Zimmer von Korridor) + MeshInstance3D mesh: BoxMesh(16, 3, 0.1), transform.origin = (2, 5.5, 2) + CollisionShape3D +``` + +- [ ] **Step 3: 8 Gästezimmer mit SpawnPoints** + +Pro Zimmer (i = 1..8, je 2m breit, nebeneinander): +``` +Node3D "Room{i}" ← parent: UpperFloor + StaticBody3D "Bed" + MeshInstance3D mesh: BoxMesh(1.8, 0.5, 0.9), transform.origin lokal (0, 0.25, -2.5) + CollisionShape3D + Marker3D "SpawnPoint" ← Name MUSS "SpawnPoint" sein + transform.origin lokal (0, 1.0, -1) ← steht neben dem Bett +``` + +Zimmer-Positionen (global, je 2m Abstand in X): +- Room1: x = -5, z = 2.8, y = 4.1 +- Room2: x = -3, z = 2.8, y = 4.1 +- Room3: x = -1, z = 2.8, y = 4.1 +- ... bis Room8: x = 9, z = 2.8, y = 4.1 + +- [ ] **Step 4: Annas Zimmer (Room9) mit Myzel-Dekoration** + +``` +Node3D "Room9" ← Annas Zimmer, ganz rechts (x = 9, oder eigener Bereich) + StaticBody3D "Bed" + MeshInstance3D mesh: BoxMesh(1.8, 0.5, 0.9) — Material: myzel-überzogen (grünlich) + StaticBody3D "OpenDoor" ← Tür steht offen (BoxMesh als Tür-Panel, seitlich gedreht) + MeshInstance3D mesh: BoxMesh(0.05, 2.5, 1.2), transform rotiert 90° in Y + Node3D "MyzelDecor" + MeshInstance3D "MyzelPatch1" ← Fleck auf dem Boden, grünlich + MeshInstance3D "MyzelPatch2" ← Fleck an der Wand + Node3D "MyzelTrailAnna" ← Spur aus Annas Zimmer in den Korridor + MeshInstance3D "TrailOut" mesh: BoxMesh(0.4, 0.01, 1.5), grünlich, transform.origin lokal (0, 0.06, 1.2) +``` + +Alle Myzel-Materialien: gleich wie in Task 4 (grünlich, leicht emissiv). + +- [ ] **Step 5: Verifizieren — Obergeschoss in Editor prüfen** + +Öffne `tavern.tscn`. Vergewissere dich im 3D-Viewport: +- Obergeschoss sichtbar über dem Taproom +- 9 Zimmer mit Betten erkennbar +- Room9 (Annas Zimmer) mit Myzel-Dekoration +- SpawnPoints als gelbe Marker sichtbar (Marker3D Icons im Editor) + +- [ ] **Step 6: Committen** + +```bash +git add scenes/tavern.tscn +git commit -m "feat: tavern scene — upper floor blockout (8 rooms + Anna's room, SpawnPoints)" +``` + +--- + +## Task 6: NetworkManager — Room-Zuweisung in start_game + +**Files:** +- Modify: `scripts/network_manager.gd` + +Room-Index wird als Dictionary-Parameter in `start_game` RPC mitgeschickt. Das vermeidet Timing-Probleme (SceneManager.pending_room_index ist gesetzt bevor `game_started` emittiert wird). + +- [ ] **Step 1: `_build_room_assignments()` hinzufügen** + +Füge diese Methode am Ende von `network_manager.gd` hinzu: + +```gdscript +func _build_room_assignments() -> Dictionary: + var result := {} + var player_peers: Array = players.keys().filter( + func(id: int) -> bool: return players[id].role == "player" + ) + for i in player_peers.size(): + result[player_peers[i]] = i % 8 # 8 Gästezimmer (Index 0–7) + return result +``` + +- [ ] **Step 2: `start_game` RPC um room_assignments erweitern** + +Ändere die bestehende `start_game` Funktion: + +```gdscript +@rpc("authority", "call_local", "reliable") +func start_game(room_assignments: Dictionary) -> void: + if my_id in room_assignments: + SceneManager.pending_room_index = room_assignments[my_id] + game_started.emit() +``` + +- [ ] **Step 3: `request_start_game` anpassen — Assignments bauen und mitschicken** + +Ändere die bestehende `request_start_game` Funktion: + +```gdscript +@rpc("any_peer", "call_remote", "reliable") +func request_start_game() -> void: + if not multiplayer.is_server(): + return + var requester_id := multiplayer.get_remote_sender_id() + if players.get(requester_id, {}).get("role", "") != "dm": + return + var assignments := _build_room_assignments() + start_game.rpc(assignments) +``` + +- [ ] **Step 4: Verifizieren — Script-Syntax prüfen** + +Öffne Godot. Erwartung: Kein GDScript-Fehler in `network_manager.gd`. +Alternativ: `godot --check-only` im `ruf-der-pilze/` Verzeichnis ausführen. + +- [ ] **Step 5: Committen** + +```bash +git add scripts/network_manager.gd +git commit -m "feat: include room assignments in start_game RPC" +``` + +--- + +## Task 7: `tavern.gd` — Spawn-Logik implementieren + +**Files:** +- Modify: `scripts/tavern.gd` + +Liest `SceneManager.pending_room_index` und platziert einen minimalen PlayerController (Node3D + Camera3D) am zugehörigen SpawnPoint. + +- [ ] **Step 1: `tavern.gd` implementieren** + +Ersetze den Stub-Inhalt von `scripts/tavern.gd`: + +```gdscript +extends Node3D + +const ROOM_COUNT := 8 + + +func _ready() -> void: + var args := OS.get_cmdline_args() + OS.get_cmdline_user_args() + if OS.has_feature("dedicated_server") or "--server" in args: + return + var room_index := SceneManager.pending_room_index + _spawn_player(room_index) + + +func _spawn_player(room_index: int) -> void: + var room_num := (room_index % ROOM_COUNT) + 1 # Zimmer heißen Room1..Room8 + var spawn_path := "UpperFloor/Room%d/SpawnPoint" % room_num + var spawn := get_node_or_null(spawn_path) as Marker3D + if spawn == null: + push_error("[Tavern] SpawnPoint nicht gefunden: %s" % spawn_path) + return + var controller := Node3D.new() + controller.name = "PlayerController" + var camera := Camera3D.new() + camera.name = "Camera3D" + camera.current = true + controller.add_child(camera) + add_child(controller) + controller.global_transform = spawn.global_transform + print("[Tavern] Spieler gespawnt in %s" % spawn_path) +``` + +- [ ] **Step 2: Verifizieren — Solo-Test** + +Starte das Spiel ohne Multiplayer. Verbinde mit Server und starte das Spiel als DM. +Als Spieler-Client: Erwartung: Szene wechselt zu `tavern.tscn`, Kamera steht im zugewiesenen Zimmer. +Console: `[Tavern] Spieler gespawnt in UpperFloor/Room1/SpawnPoint` + +- [ ] **Step 3: Committen** + +```bash +git add scripts/tavern.gd +git commit -m "feat: tavern.gd — spawn player at assigned room SpawnPoint" +``` + +--- + +## Task 8: `dm_view.tscn` Stub erstellen + +**Files:** +- Create: `scenes/dm_view.tscn` +- Create: `scripts/dm_view.gd` + +Minimale Platzhalter-Szene für den DM. Wird in Schritt 7 (DM Regiepult) vollständig ausgebaut. + +- [ ] **Step 1: `scripts/dm_view.gd` erstellen** + +```gdscript +extends Node + + +func _ready() -> void: + print("[DmView] DM-Szene geladen (Stub)") +``` + +- [ ] **Step 2: `scenes/dm_view.tscn` erstellen** + +Node-Struktur: +``` +Node "DmView" ← script = dm_view.gd + SubViewportContainer "ViewportContainer" + SubViewport + Camera3D "Camera3D" ← top-down, transform.origin = (0, 20, 0), rotation_degrees.x = -90 + current = true + CanvasLayer "UI" + Label "StubLabel" + text = "DM View — Stub\n(wird in Schritt 7 ausgebaut)" + horizontal_alignment = CENTER + anchors_preset = CENTER +``` + +- [ ] **Step 3: Verifizieren** + +Starte als DM-Client, starte das Spiel. Erwartung: DM sieht Label "DM View — Stub". + +- [ ] **Step 4: Committen** + +```bash +git add scenes/dm_view.tscn scripts/dm_view.gd +git commit -m "feat: dm_view stub scene" +``` + +--- + +## Task 9: End-to-End Test + +**Files:** keine Änderungen + +Vollständiger Durchlauf: Server + 2 Spieler-Clients + 1 DM-Client. + +- [ ] **Step 1: Server starten** + +```bash +cd ruf-der-pilze +godot --headless -- --server +``` + +- [ ] **Step 2: Spieler-Client 1 starten und verbinden** + +Starte Godot-Client 1. Lobby erscheint, verbinden als "Spieler1" (Rolle: Spieler). +Erwartung: JoinPanel verschwindet, WaitPanel zeigt Spielerliste. + +- [ ] **Step 3: Spieler-Client 2 starten und verbinden** + +Starte Godot-Client 2. Verbinden als "Spieler2" (Rolle: Spieler). +Erwartung: Beide Clients sehen beide Spieler in der WaitPanel-Liste. + +- [ ] **Step 4: DM-Client starten, verbinden und Spiel starten** + +Starte Godot-Client 3. Verbinden als "DM1" (Rolle: DM). StartButton wird sichtbar. +Klicke StartButton. + +- [ ] **Step 5: Ergebnis prüfen** + +Erwartungen: +- Spieler-Client 1: Szene wechselt zu `tavern.tscn`, Kamera steht in Room1 +- Spieler-Client 2: Szene wechselt zu `tavern.tscn`, Kamera steht in Room2 +- DM-Client: Szene wechselt zu `dm_view.tscn`, Label "DM View — Stub" sichtbar +- Console (Server): Keine Fehler, `[Server] game_started` verarbeitet +- Console (Clients): `[Tavern] Spieler gespawnt in UpperFloor/Room1/SpawnPoint` etc. + +- [ ] **Step 6: MCP Screenshot für visuelle Verifikation** + +Nutze `mcp__godot-mcp__scene` Screenshot-Tool um die Spieler-Perspektive und DM-Ansicht zu dokumentieren. + +- [ ] **Step 7: docs/STATUS.md und CLAUDE.md updaten** + +In `docs/STATUS.md`: +- Schritt 5 (Szenen-Wechsel nach Spielstart) auf ✅ setzen +- "In Arbeit" leeren +- Schritt 6 (Refectorium) als "Als nächstes" eintragen + +In `ruf-der-pilze/CLAUDE.md`: +- Entwicklungs-Reihenfolge: Schritt 5 auf ✅ + +- [ ] **Step 8: Finaler Commit** + +```bash +git add docs/STATUS.md ruf-der-pilze/CLAUDE.md +git commit -m "docs: mark scene switching complete, update STATUS" +```