# Schritt 13 — Charakter-Platzhalter (Capsule-Avatare)

> **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:** Jeder Spieler wird in der Lobby als farbige Kapsel mit Namens-Label dargestellt. Farbe kommt aus `players[id]["char"]["class"]` (Fallback: Grau wenn char-Daten noch nicht vorhanden). Capsules sind eine eigene Szene — einfach austauschbar gegen echte Modelle später.

**Architecture:** Neue Szene `character_placeholder.tscn` (Node3D + CapsuleMesh + Label3D). `tavern_lobby.gd` instanziiert und entfernt Capsules wenn `player_joined`/`player_left` feuert. Capsules stehen an vordefinierten `Marker3D`-Lobby-Standpunkten (5 Spots in tavern_lobby.tscn). Farbe wird per `CharacterPlaceholder.set_color(class_name)` gesetzt; bei `character_updated`-Signal wird Farbe aktualisiert.

**Tech Stack:** Godot 4.x GDScript, MeshInstance3D, CapsuleMesh, StandardMaterial3D, Label3D, Marker3D

**Parallel-Hinweis:** Dieser Plan liest `players[id].get("char", {}).get("class", "")`. Falls Schritt 12 noch nicht gemergt ist, ist "class" leer → Grau-Fallback. Kein harter Blocker.

---

## Files

| File | Aktion |
|------|--------|
| `ruf-der-pilze/scenes/character_placeholder.tscn` | Create — Capsule + Label3D + Script |
| `ruf-der-pilze/scripts/character_placeholder.gd` | Create — `set_color(class_name)`, `set_label(name)` |
| `ruf-der-pilze/scenes/tavern_lobby.tscn` | Modify — 5 LobbySpot Marker3D-Nodes hinzufügen |
| `ruf-der-pilze/scripts/tavern_lobby.gd` | Modify — Capsule spawn/remove on join/leave |
| `docs/STATUS.md` | Modify — Schritt 13 ✅ |

---

## Task 1: character_placeholder.gd + .tscn erstellen

**Files:**
- Create: `ruf-der-pilze/scripts/character_placeholder.gd`
- Create: `ruf-der-pilze/scenes/character_placeholder.tscn`

- [ ] **Schritt 1: character_placeholder.gd erstellen**

  Datei anlegen unter `ruf-der-pilze/scripts/character_placeholder.gd`:

  ```gdscript
  extends Node3D

  const CLASS_COLORS: Dictionary = {
      "Krieger":  Color(0.80, 0.20, 0.20),  # Rot
      "Magier":   Color(0.20, 0.20, 0.90),  # Blau
      "Kleriker": Color(0.90, 0.85, 0.20),  # Gelb
      "Schurke":  Color(0.20, 0.65, 0.20),  # Grün
      "Druide":   Color(0.40, 0.75, 0.30),  # Hellgrün
      "Barbar":   Color(0.75, 0.40, 0.10),  # Orange
  }
  const DEFAULT_COLOR := Color(0.65, 0.65, 0.65)  # Grau

  func set_color(class_name: String) -> void:
      var mat := StandardMaterial3D.new()
      mat.albedo_color = CLASS_COLORS.get(class_name, DEFAULT_COLOR)
      ($Capsule as MeshInstance3D).material_override = mat

  func set_label(player_name: String) -> void:
      ($NameLabel as Label3D).text = player_name
  ```

- [ ] **Schritt 2: character_placeholder.tscn via Godot-Editor erstellen**

  Neue Szene: `Datei → Neue Szene → Node3D als Root`.
  Root umbenennen in `CharacterPlaceholder`, Script `character_placeholder.gd` zuweisen.
  
  Kinder-Nodes hinzufügen:
  
  **MeshInstance3D** mit Name `Capsule`:
  - `mesh` = neues `CapsuleMesh`
  - CapsuleMesh-Properties: `height = 1.8`, `radius = 0.3`
  - `material_override` = neues `StandardMaterial3D`, `albedo_color = Color(0.65, 0.65, 0.65)`

  **Label3D** mit Name `NameLabel`:
  - `text = ""`
  - `position = Vector3(0.0, 1.2, 0.0)`
  - `font_size = 48`
  - `billboard = BILLBOARD_ENABLED`
  - `no_depth_test = true`

  Szene als `ruf-der-pilze/scenes/character_placeholder.tscn` speichern.

- [ ] **Schritt 3: Parse-Fehler prüfen**

  Godot-Editor: Ausgabe-Panel prüfen, keine Fehler in `character_placeholder.gd`.

- [ ] **Schritt 4: Commit**

  ```bash
  git add ruf-der-pilze/scenes/character_placeholder.tscn ruf-der-pilze/scripts/character_placeholder.gd
  git commit -m "feat: add CharacterPlaceholder scene — colored capsule + name label"
  ```

---

## Task 2: LobbySpot-Marker in tavern_lobby.tscn

**Files:** Modify `ruf-der-pilze/scenes/tavern_lobby.tscn`

`tavern_lobby.tscn` instanziiert `taproom.tscn` als Sub-Scene und hat einen CanvasLayer für UI. Die Marker3D-Nodes kommen in die 3D-Welt (unter der Root-Node, nicht unter CanvasLayer).

- [ ] **Schritt 1: 5 Marker3D-Nodes in tavern_lobby.tscn hinzufügen**

  Im Godot-Editor `tavern_lobby.tscn` öffnen. Im Scene-Panel: Root-Node (oder die Node3D direkt unterhalb der Root) → `Marker3D` hinzufügen. Fünfmal wiederholen.

  Namen und Positionen:
  ```
  Marker3D "LobbySpot0" — position = Vector3(-2.0, 0.0,  1.0)
  Marker3D "LobbySpot1" — position = Vector3(-1.0, 0.0,  1.5)
  Marker3D "LobbySpot2" — position = Vector3( 0.0, 0.0,  1.8)
  Marker3D "LobbySpot3" — position = Vector3( 1.0, 0.0,  1.5)
  Marker3D "LobbySpot4" — position = Vector3( 2.0, 0.0,  1.0)
  ```

  Koordinaten ggf. anpassen damit Kapseln im Gastraum stehen (nicht in Wänden). Orientierung der Marker: `rotation_degrees.y = 180` so dass Kapseln zur Kamera schauen.

- [ ] **Schritt 2: Screenshot via godot-mcp prüfen**

  Godot-Editor: Szene kurz ausführen oder Viewport nutzen um zu prüfen ob Positionen im Gastraum liegen. Anpassen falls nötig.

- [ ] **Schritt 3: Commit**

  ```bash
  git add ruf-der-pilze/scenes/tavern_lobby.tscn
  git commit -m "lobby: add 5 LobbySpot Marker3D for capsule placement"
  ```

---

## Task 3: Capsule-Spawn-Logik in tavern_lobby.gd

**Files:** Modify `ruf-der-pilze/scripts/tavern_lobby.gd`

Zuerst das Script lesen um bestehende Struktur zu verstehen. Neue Felder und Methoden hinzufügen — bestehenden Code nicht anfassen.

- [ ] **Schritt 1: Capsule-Tracking-Variablen + Preload hinzufügen**

  Am Anfang der Klasse (nach bestehenden `var`-Deklarationen):

  ```gdscript
  const CharacterPlaceholder := preload("res://scenes/character_placeholder.tscn")
  var _capsules: Dictionary = {}        # peer_id: int → Node3D
  var _lobby_spots: Array[Marker3D] = []
  ```

- [ ] **Schritt 2: Spot-Array + Signal-Verbindungen in `_ready()` ergänzen**

  Am Ende von `_ready()` anhängen:

  ```gdscript
  _lobby_spots = [
      $LobbySpot0 as Marker3D,
      $LobbySpot1 as Marker3D,
      $LobbySpot2 as Marker3D,
      $LobbySpot3 as Marker3D,
      $LobbySpot4 as Marker3D,
  ]
  NetworkManager.player_joined.connect(_on_player_joined_capsule)
  NetworkManager.player_left.connect(_on_player_left_capsule)
  NetworkManager.character_updated.connect(_on_character_updated_capsule)
  ```

  Pfade `$LobbySpot0` etc. anpassen wenn Marker3D-Nodes unter einer anderen Parent-Node liegen.

- [ ] **Schritt 3: Spawn/Remove/Update-Methoden hinzufügen**

  ```gdscript
  func _on_player_joined_capsule(peer_id: int, _data: Dictionary) -> void:
      if _capsules.has(peer_id):
          return
      var spot_index := _capsules.size() % _lobby_spots.size()
      var capsule: Node3D = CharacterPlaceholder.instantiate()
      add_child(capsule)
      capsule.global_position = _lobby_spots[spot_index].global_position
      var player_data: Dictionary = NetworkManager.players.get(peer_id, {})
      capsule.set_label(player_data.get("name", "???"))
      capsule.set_color(player_data.get("char", {}).get("class", ""))
      _capsules[peer_id] = capsule

  func _on_player_left_capsule(peer_id: int) -> void:
      if not _capsules.has(peer_id):
          return
      (_capsules[peer_id] as Node3D).queue_free()
      _capsules.erase(peer_id)

  func _on_character_updated_capsule(peer_id: int, data: Dictionary) -> void:
      if not _capsules.has(peer_id):
          return
      (_capsules[peer_id] as Node3D).set_color(data.get("class", ""))
  ```

- [ ] **Schritt 4: Godot öffnen, Parse-Fehler prüfen**

- [ ] **Schritt 5: End-to-End-Test**

  Server + 2 Spieler-Clients starten.
  - Spieler A joined → Kapsel A erscheint an LobbySpot0 (grau, kein char-Daten)
  - Spieler B joined → Kapsel B erscheint an LobbySpot1
  - Wenn Schritt 12 gemergt: Spieler A klickt "Magier" → Kapsel A wird blau
  - Spieler A verlässt → Kapsel A verschwindet

- [ ] **Schritt 6: Commit**

  ```bash
  git add ruf-der-pilze/scripts/tavern_lobby.gd
  git commit -m "lobby: spawn colored capsule avatars for each player at LobbySpots"
  ```

---

## Task 4: STATUS.md updaten

- [ ] **Schritt 1: Schritt 13 als ✅ markieren in `docs/STATUS.md` und `ruf-der-pilze/CLAUDE.md`**

- [ ] **Schritt 2: Commit**

  ```bash
  git add docs/STATUS.md ruf-der-pilze/CLAUDE.md
  git commit -m "docs: mark Schritt 13 complete — Charakter-Capsules"
  ```
