Files
spacel/ARCHITECTURE.md
T
alpacaman edc40f9008 Initial commit — Godot space roguelite source
- Touch controls: direct InputEventScreenTouch in shop_ui (bypass relay)
- ItemDB: static preload list instead of DirAccess scan (export fix)
- All 18 items with EN localisation (name_en, desc_en, category_en)
- Ship playstyles: NOVA-1 shield, INFERNO ram, AURORA agile/tank
- Quasar: SMBH visual, jet boost, merge, push, BH-eating
- Atlas & UI text updated EN+DE

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-04-21 14:38:09 +02:00

432 lines
18 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# spacel — Architektur-Dokumentation
## Überblick
**spacel** ist ein 2D-Space-Shooter mit Roguelite-Elementen, gebaut in **Godot 4.6** (Forward Plus, D3D12). Das Spiel unterstützt 12 Spieler (Split-Keyboard). Es gibt keine externen Assets — alles wird prozedural gezeichnet und synthetisiert (keine Sprites, keine Audio-Dateien).
---
## Projektstruktur
```
spacel/
├── project.godot # Projekt-Konfiguration, Autoloads, Input-Map
├── scenes/
│ ├── main.tscn # Root-Scene (enthält alles)
│ ├── game_world.tscn # Spielwelt / Hintergrund-Canvas
│ ├── hud.tscn # HUD (CanvasLayer)
│ └── ship_select.tscn # Schiff-Auswahlbildschirm
├── scripts/
│ ├── main.gd # State Machine — Spielfluss-Controller
│ ├── game_world.gd # Spielwelt: Simulation, Rendering, Kollisionen
│ ├── spaceship.gd # Spieler-Schiff (Datenklasse)
│ ├── enemy_ship.gd # Gegner-Schiff mit KI
│ ├── boss_ship.gd # Bosse: WRAITH (Welle 5) & LEVIATHAN (Welle 8)
│ ├── bullet.gd # Projektil
│ ├── black_hole.gd # Schwarzes Loch mit Gravitation + Supernova
│ ├── big_wipe.gd # Big-Wipe-Event (Bildschirm-Reset)
│ ├── cosmic_objects.gd # Alle Weltraum-Objekte (Star, Planet, ...)
│ ├── ship_stats.gd # Roguelite-Stat-System
│ ├── item_db.gd # Item-Datenbank (20 Items, 4 Seltenheiten)
│ ├── hud.gd # HUD-Logik
│ ├── hud_draw.gd # HUD-Rendering
│ ├── settings.gd # Einstellungen (Autoload)
│ ├── sound_manager.gd # Procedurales Audio (Autoload)
│ ├── music_player.gd # Musik
│ ├── shop_ui.gd # Shop zwischen den Wellen
│ ├── ship_select.gd # Schiff-Auswahl UI
│ ├── main_menu.gd # Hauptmenü
│ ├── pause_menu.gd # Pause-Menü
│ └── tr.gd # Lokalisierung (Autoload, de/en)
└── addons/godot_mcp/ # MCP-Plugin für KI-gestützte Entwicklung
```
---
## Autoloads (Singletons)
| Name | Script | Funktion |
|------|--------|----------|
| `Settings` | `settings.gd` | Lautstärke, Grafik, Sprache — persisted in `user://settings.cfg` |
| `SoundManager` | `sound_manager.gd` | Alle SFX prozedural generiert (Sinus/Säge/Square-Wellen, kein Audio-File) |
| `Tr` | `tr.gd` | Übersetzungen DE/EN |
| MCP-Dienste | `addons/godot_mcp/` | Nur für Entwicklung (Editor-Plugin) |
---
## State Machine (`main.gd`)
`main.gd` ist der zentrale Controller. Er verwaltet alle UI-Panels und schaltet zwischen folgenden Zuständen um:
```
MAIN_MENU → SELECT → (SELECT_P2) → LAUNCHING → PLAYING ⟷ PAUSED
RETURNING → SHOP → LAUNCHING (nächste Welle)
GAMEOVER → MAIN_MENU
WAVE_CLEAR → SHOP
```
**Wichtige Variablen in `main.gd`:**
- `lives_p1 / credits_p1 / stats_p1 / owned_items_p1` — Run-Zustand Spieler 1
- `wave_number` — aktuelle Wellennummer (steigt nach jedem Shop)
- `SHIPS[]` — 4 Schiffe (NOVA-1, INFERNO, AURORA, TITAN) mit Farbpaletten und Basis-Stats
**Schiff-Spielstile** (`_apply_ship_base_stats()` in `main.gd`):
| ID | Name | Besonderheit |
|----|------|--------------|
| `classic` | NOVA-1 | 1 Schutzschild — ausgewogener Einstieg |
| `inferno` | INFERNO | Speed +28 %, Feuerrate +55 %, Kurve 28 % · Passiv: Ramm-Schaden ab ≥ 4.5 px/s |
| `aurora` | AURORA | Kurve +55 %, Speed 20 %, 2 Schilde, BH-Resist 55 %, 2× Unverwundbarkeitszeit |
| `titan` | TITAN | Speed 28 %, Kurve 15 % · Aktiv: Boost-Impuls (SHIFT, 5 s Cooldown) |
`ship_id: String` in `ShipStats` wird beim Spielstart gesetzt und ermöglicht runtime-Verzweigungen (z. B. INFERNO-Rammen in `game_world.gd`).
**Hauptlogik:**
- `_set_state(new_state)` — zeigt/versteckt UI, initialisiert `game_world`
- `_process()` — Countdown vor Spielstart, Return-/Wave-Timer
- `add_credits(player, amount)` — Credits dem Spieler gutschreiben
- `on_game_over() / on_wave_complete()` — von `game_world` aufgerufen
---
## Spielwelt (`game_world.gd`)
Das Herzstück des Spiels. `game_world.gd` ist ein `Node2D` und macht **alles selbst** per `_draw()` — keine Child-Nodes für Spielobjekte.
### Physik-Loop
Fixed-Timestep bei **60 Hz** (`PHYS_DT = 1/60`):
```gdscript
_process(delta):
_phys_accum += delta # akkumuliert reale Zeit
while _phys_accum >= PHYS_DT:
_phys_accum -= PHYS_DT
frame += 1
_tick(PHYS_DT)
queue_redraw()
```
### `_tick(dt)` — Reihenfolge pro Frame
1. `_handle_input(dt)` — Spieler-Input lesen, Schüsse erzeugen
2. `_update_objects(dt)` — Alle kosmischen Objekte updaten, Gegner KI
3. `_update_bullets()` — Projektile bewegen, tote entfernen
4. Boss-Update (falls vorhanden) → erzeugt Bullets
5. `_update_particles(dt)` — Partikeleffekte
6. `_check_collisions()` — Bullet/Enemy, Bullet/Player, Antimatter/Player, Bullets/Boss
7. `_check_big_wipe()` — Threshold prüfen (> 500 Objekte)
8. BigWipe-Update
9. Schwierigkeit + Wave-Timer + Credit-Trickle
10. All-Dead-Check → `main_node.on_game_over()`
11. Kometen- und Antimatter-Spawn-Timer
### Arrays der Spielobjekte
```gdscript
var stars, planets, nebulae, comets, galaxies: Array
var black_holes, quasars, white_holes, neutron_stars: Array
var antimatter, antimatter_stars: Array
var bullets, particles: Array
var players, enemies: Array
```
### Rendering (`_draw()`)
Alles wird mit Godot's Canvas-API gezeichnet — **keine Sprites**:
- `draw_rect()` für Pixel/Rumpfe
- `draw_circle()` für Schwarze Löcher, White Holes
- `draw_arc()` für Akkretionsscheiben, Ringe
- `draw_line()` für Trails
**Zeichenreihenfolge:** Nebulae → Sterne → Galaxien → Planeten → Kometen → Quasare → White Holes → Neutronensterne → Schwarze Löcher → Antimatter → Bullets → Enemies → Boss → Spieler → Partikel → BigWipe-Overlay
---
## Datenklassen (alle `extends RefCounted`)
Alle Spielobjekte sind **keine Nodes** — sie sind reine Datenklassen, die von `game_world` in Arrays verwaltet werden. Das verhindert den Node-Overhead und ermöglicht den eigenen Physik-Loop.
### `Spaceship` (`spaceship.gd`)
Spieler-Schiff.
| Eigenschaft | Wert | Beschreibung |
|-------------|------|--------------|
| `THRUST` | 0.28 | Beschleunigung pro Frame |
| `TURN_SPEED` | 0.08 | Drehgeschwindigkeit (rad/frame) |
| `MAX_SPEED` | 7.5 | Maximale Geschwindigkeit |
| `DRAG` | 0.985 | Trägheit (Reibung) |
| `INVULN_FRAMES` | 90 | ~1.5s Unverwundbarkeit nach Treffer |
| `stats.ship_id` | String | Schiff-ID für runtime-spezifische Mechaniken |
**Methoden:**
- `update(thrust, turn, W, H, delta)` — Bewegung, Screen-Wrap, Trail
- `shoot_burst() → Array[Bullet]` — erzeugt 1N Bullets je nach `stats.bullet_count`
- `draw(canvas, frame)` — malt Rumpf aus `HULL_PIXELS`-Tabelle mit Heading-Rotation
**Screen-Wrap:** Wenn Schiff den Bildschirmrand verlässt, erscheint es auf der anderen Seite (Toroidal).
### `EnemyShip` (`enemy_ship.gd`)
KI-Gegner. 2 Farbvarianten (idx 0 = Rot, idx 1 = Cyan). Jeder Gegner hat eine **Role** (AGGRO / CIRCLE / FLANK), die per `role_id % 3` beim Spawn bestimmt wird und über Respawns hinweg erhalten bleibt. `role_id` wird in `game_world.gd` als laufender Index vergeben.
**Rollen:**
- **AGGRO**: stürmt direkt auf den nächsten Spieler zu
- **CIRCLE**: hält Abstand (~180 px) und kreist kontinuierlich um den Spieler (orbit_offset dreht sich)
- **FLANK**: nähert sich aus ±90°-Flankenwinkel statt frontal
**Gemeinsamkeiten:**
- Schuss immer direkt auf Spieler gezielt (unabhängig von der Bewegungsrichtung) → CIRCLE/FLANK-Gegner bleiben gefährlich
- **Separation Force**: Gegner stoßen sich gegenseitig ab (Radius 110 px) → kein Clumping
- **Patrol**: außerhalb Reichweite navigieren Gegner zu zufälligen Zielpunkten auf dem Bildschirm (nicht mehr reines Heading-Drehen) → natürliche Verteilung
- **Schwarzloch-Ausweichen**: spürt BH-Radius und weicht ab
- Feuer-Timer ist pro `role_id` gestaffelt (FIRE_INTERVAL + rid×17) → Salven verteilt
- Nach Tod: respawnt nach 48s vom zufälligen Bildschirmrand, behält Role bei
**Wellenskalierung:**
- Alte Formel: `2 + (wave-1)/2` (cap 6→8 nach letztem Balancing-Pass)
- **Neue Formel:** `min(2 + (wave - 1), MAX_ENEMEYS)` → Welle 1: 2, Welle 5: 6, Welle 10: 11, Welle 20: 21
### `BossShip` (`boss_ship.gd`)
Zwei Bosse — gleiche Klasse, unterschiedliche Parameter:
| | WRAITH (Welle 5) | LEVIATHAN (Welle 8) |
|--|--|--|
| HP | 20 | 50 |
| Farbe | Magenta | Orange/Feuerrot |
| Orbit-Geschwindigkeit | 0.55 rad/s | 0.44 / 0.72 (Phase 2) |
| Feuer-Intervall | 72 Frames | 60 / 42 (Phase 2) |
| Schüsse | 3-Way | 5-Way / 8-Way |
| Pixel-Größe | 5 | 7 |
**Mechaniken:**
- Orbitiert elliptisch um Bildschirmmitte
- Heading zeigt immer zur Mitte (schießt nach innen)
- LEVIATHAN: Phase-2-Übergang bei ≤ 50% HP → Black Hole spawnt, Musik verdichtet
### `Bullet` (`bullet.gd`)
- Geschwindigkeit: 9.6 px/frame
- Lebensdauer: 240 Frames, Fade ab Frame 210
- Besitzer-Typen: `"p1"`, `"p2"`, `"enemy"`, `"boss"` (bestimmt Kollisions-Check und Farbe)
- `pierce`: true wenn `damage_mult >= 2.0` → trifft bis zu 2 Ziele
### `BlackHole` (`black_hole.gd`)
Komplexestes Objekt im Spiel.
**Parameter:**
- `PULL_RADIUS`: 160px Gravitationsfeld
- `SWALLOW_RADIUS`: 14px Verschluck-Radius
- `FORCE_MULT`: 45.0 (Gravitationsstärke)
- `SUPERNOVA_AT`: 30 verschluckte Objekte → Supernova
**Mechaniken:**
- Wandert langsam umher (Micro-Drift)
- 18% Chance: jagt den nächsten Spieler (Hunting-Mode)
- Wächst mit jedem verschluckten Objekt (radius, pull_radius, gravity)
- Bei 30 Verschluckungen: **Supernova** → stirbt, spawnt Quasar + neue BHs + White/Neutron Star + Sterne/Planeten
- **SMBH**: nach 12 verschluckten Galaxien → Super-Massive BH, nach 45s kollabiert er
- BH-BH-Verschmelzung: größerer frisst kleineren
### `BigWipe` (`big_wipe.gd`)
Notfall-Reset wenn > 500 kosmische Objekte vorhanden sind.
**Phasen:**
1. `COLLAPSE` (2.33s): Bildschirm verdunkelt sich, Spieler müssen Wipe-Taste halten
2. `FLASH` (0.4s): Weißer Flash
3. Alle Objekte außer Planeten/Sternen werden gelöscht
**Spieler-Reaktion:** Signal `p1_wipe` / `p2_wipe` drücken während COLLAPSE → überleben. Wer nicht drückt, stirbt. Belohnung: 25 Credits (+ Credit-Bonus).
### `CosmicObjects` (`cosmic_objects.gd`)
Statische äußere Klasse mit inneren Klassen:
| Klasse | Beschreibung |
|--------|-------------|
| `Star` | Wandert nach oben, kann gravitationell angezogen werden, spiralt ins BH |
| `Planet` | Kreist um Orbit-Punkt, kann von BH gefangen und zerrissen werden |
| `Nebula` | Rein dekorativ, bewegt sich langsam |
| `Comet` | Fliegt von Bildschirmrand zu Bildschirmrand |
| `Galaxy` | Spiral-Galaxie, kann von BH konsumiert werden → SMBH |
| `Quasar` | Entsteht aus Supernova, lebt 30s, rein dekorativ |
| `WhiteHole` | Gegenteil des BH: stößt Spieler ab, ejiziert Sterne/Planeten, lebt 60s |
| `NeutronStar` | Rotierender Pulsar-Strahl, stößt Objekte im Beam-Bereich ab |
| `Antimatter` | Partikel, tötet Spieler/Gegner bei Berührung, ziehen sich an |
| `AntimatterStar` | Entsteht wenn 5+ Antimatter-Partikel clustern, repulsiert Spieler, lebt 50s |
---
## Roguelite-System
### `ShipStats` (`ship_stats.gd`)
Alle Stats sind **multiplikativ** (ausgenommen additive: `bullet_count`, `shield_charges`, `bh_resist`):
| Stat | Standard | Effekt |
|------|----------|--------|
| `speed_mult` | 1.0 | Schub und Max-Speed |
| `turn_mult` | 1.0 | Drehgeschwindigkeit |
| `fire_rate_mult` | 1.0 | Teilt Cooldown (höher = schneller) |
| `damage_mult` | 1.0 | Trefferzone; ≥ 2.0 → Pierce |
| `bullet_speed_mult` | 1.0 | Projektil-Geschwindigkeit |
| `bullet_count` | 1 | Projektile pro Schuss |
| `shield_charges` | 0 | Absorbiert N Treffer |
| `invuln_mult` | 1.0 | Unverwundbarkeitszeit nach Treffer |
| `bh_resist` | 0.0 | 00.9: Anteil des BH-Zugs der negiert wird |
| `wipe_mult` | 1.0 | BigWipe-Haltezeit-Faktor |
| `credit_bonus` | 1.0 | Multiplikator auf alle Credits |
### `ItemDB` (`item_db.gd`)
Zwei Pools:
- **Legacy `ITEMS`** (6 Einträge) — nur noch für Enemy-Boosts ab Welle 10 (`game_world.gd` rollt 1× daraus und wendet es auf jeden Gegner an).
- **Werkstatt-Plugin-Pool** (auto-discover unter `res://items/`, derzeit 17 ItemDefs) — der eigentliche Shop-Pool.
Seltenheiten:
| Seltenheit | Gewicht | Farbe |
|------------|---------|-------|
| STANDARD (Common) | 60 | Grau |
| SELTEN (Uncommon) | 25 | Grün |
| EPISCH (Rare) | 12 | Blau |
| LEGENDÄR (Epic) | 3 | Lila |
Shop zeigt nach jeder Welle 4 zufällige Items (gekaufte werden aus Folge-Rolls ausgeschlossen). Credits kommen aus:
- Kill: 15 Credits × `credit_bonus`
- Passiv: 5 Credits alle 10 Sekunden
- BigWipe überlebt: 25 Credits × `credit_bonus`
- Boss getötet: 150 (Miniboss) / 300 (Boss) Credits
### Werkstatt-Flow (`shop_ui.gd`)
Zwei Phasen pro Shop-Öffnung:
1. **Attribut-Phase** — nur in **ungeraden Wellen** (1, 3, 5, …). 3 zufällige Gratis-Buffs, einer wird gewählt. Werte `+8 % bis +18 %`. Gerade Wellen (2, 4, …) starten direkt in der Shop-Phase → dämpft frühes Snowballing.
2. **Shop-Phase** — 4 Karten aus dem Plugin-Pool. Kauf per ENTER, Reroll per R, SPACE/ESC zum Verlassen.
**Reroll-Kosten:** `60 + 42 × reroll_count` CR → `60 / 102 / 144 / 186 / 228 …`. Der `reroll_count` wird in `main.gd` (`reroll_count_p1` / `_p2`) gehalten und **wellenübergreifend** persistiert — verteuerter Reroll schützt den Rest des Runs vor billigem Ketten-Reroll. Reset nur bei neuem Run / Game Over.
---
## Input-Mapping
| Aktion | Spieler 1 | Spieler 2 |
|--------|-----------|-----------|
| Schub | Pfeil Oben | W |
| Links | Pfeil Links | A |
| Rechts | Pfeil Rechts | D |
| Schießen | Leertaste | F |
| BigWipe | N | E |
---
## Wellen-Progression
| Welle | Dauer | Gegner | Boss |
|-------|-------|--------|------|
| 1 | 20s | 2 | — |
| 3 | 36s | 3 | — |
| 5 | 52s | 4 | WRAITH (Miniboss) |
| 7 | 68s | 5 | — |
| 8 | 76s | 5 | LEVIATHAN (Full Boss) |
| 10+ | ≤120s | 6 (mit Stats!) | — |
| 13+ | 120s | 8 (Cap) | — |
Formel: `enemy_count = min(2 + (wave-1)/2, 8)`. Enemy-Stats bleiben Welle 19 auf Basis; ab Welle 10 bekommt jeder Gegner zusätzlich 1 zufälliges Legacy-Item.
**Schwierigkeits-Ramp:** `difficulty = clamp(game_time / 300.0, 0.0, 1.0)` — steuert Kometen-Spawn-Rate, BH-Cap und mehr.
---
## Balancing-Notizen
Die Power-Kurve ist bewusst **langsam**. Quellen wurden 2026-04-20 global gesenkt, um zu verhindern, dass der Spieler Welle 3 bereits dominiert.
### Plugin-Items (Kern-Multiplikatoren)
| Kategorie | Item | Kern-Effekt | Kosten |
|-----------|------|-------------|--------|
| Waffe | `wk_burst` (EPIC) | fire_rate ×1.80, damage ×0.45 | 160 |
| Waffe | `wk_laser` | fire_rate ×1.35, damage ×0.70 | 115 |
| Waffe | `wk_plasma` | damage ×1.55, proj_speed ×0.60 | 130 |
| Waffe | `wk_ion` | damage ×1.25, +1 Projektil, speed ×0.70 | 140 |
| Waffe | `wk_rail` | proj_speed ×1.50, fire_rate ×0.50 | 125 |
| Waffe | `wk_sniper` | proj_speed ×1.30, damage ×1.18, fire_rate ×0.55 | 115 |
| Waffe | `wk_shotgun` | +2 Projektile, proj_speed ×0.40, damage ×0.80 | 105 |
| Waffe | `wk_scatter` | +1 Projektil, damage ×0.75 | 115 |
| Antrieb | `drive_overdrive` | speed ×1.35, 1 Schild | 95 |
| Antrieb | `drive_quantum` | speed ×1.22, turn ×1.18, proj_speed ×0.80 | 135 |
| Antrieb | `drive_steer` | turn ×1.35, speed ×0.90 | 85 |
| Hülle | `hull_giant` (EPIC) | +2 Schild, invuln ×1.20, speed ×0.70, turn ×0.80 | 220 |
| Hülle | `hull_plating` | +1 Schild, speed ×0.85 | 120 |
| Hülle | `hull_reaktor` | invuln ×1.45, fire_rate ×0.85 | 115 |
| Hülle | `hull_nullfeld` | bh_resist +0.45, speed ×0.80 | 125 |
| Spezial | `special_credit_mag` | credit_bonus ×1.18 | 170 |
| Spezial | `special_wipe_core` | wipe_mult ×0.65 | 150 |
### Legacy-ITEMS (nur Enemy-Boosts Welle 10+)
| id | Effekt | Kosten |
|----|--------|--------|
| thrust_1 | speed ×1.12 | 50 |
| firerate_1 | fire_rate ×1.15 | 50 |
| damage_1 | damage ×1.15 | 50 |
| shield_1 | +1 Schild | 55 |
| firerate_2 | fire_rate ×1.22 | 90 |
| damage_2 | damage ×1.22, proj_speed ×1.10 | 100 |
### Attribute (Gratis, ungerade Wellen)
`ATTR_POOL` in `shop_ui.gd` — Werte: speed/turn/fire/damage/proj je **1.081.12**, invuln 1.18, credit_bonus 1.08, Schild +1.
---
## Audio-System (`sound_manager.gd`)
Kein einziger Audio-File im Projekt. Alle Sounds werden mit `AudioStreamGenerator` pro Frame synthetisiert:
- `_play_tone(freq, duration, wave, vol_db, end_freq)` — Sinus/Säge/Square mit Frequenz-Sweep und Hüllkurve
- `_play_noise(duration, vol_db)` — Weißes Rauschen mit Decay
- `_play_chord_fanfare()` — Drei Töne mit kurzem Delay (BigWipe überlebt)
SFX-Typen: `player_shoot`, `enemy_shoot`, `enemy_die`, `player_die`, `antimatter_hit`, `bh_swallow`, `wipe_start`, `wipe_flash`, `wipe_survived`, `smbh_spawn`, `antimatter_swarm`
---
## Grafik-System
**Viewport:** 960×600px, Stretch-Modus `canvas_items / expand`
**Hintergrundfarbe:** `#0a0a14` (Tiefschwarz-Blau)
**FPS-Cap:** 60
**Pixel-Filter:** Nearest-Neighbor (`default_texture_filter=0`)
Alle Schiffe benutzen `HULL_PIXELS`-Arrays — lokale Koordinaten-Offsets, die per `cos(heading)/sin(heading)` in Weltkoordinaten gedreht werden. Jeder "Pixel" ist ein 3×3-`draw_rect`.
---
## Signalfluss
```
game_world → main_node.on_game_over() # alle Spieler tot
game_world → main_node.on_wave_complete() # Wave-Timer abgelaufen
game_world → main_node.add_credits(player, n) # Credits vergeben
game_world → main_node.start_boss_music(final) # Boss spawnt
game_world → main_node.boss_phase_changed(2) # Leviathan Phase 2
big_wipe.wipe_complete → game_world._on_wipe_complete()
shop_ui.shop_closed → main._on_shop_closed()
pause_menu.resume_requested → main._on_pause_resume()
main_menu.mode_selected → main._on_mode_selected(multi)
```
---
## MCP-Plugin (`addons/godot_mcp/`)
Das Godot-MCP-Pro-Plugin verbindet den Godot-Editor per WebSocket mit externen KI-Tools (Claude Code). Ermöglicht das Lesen/Schreiben von Szenen, Scripts und Eigenschaften direkt aus der KI-Konversation heraus. Nur für die Entwicklung relevant — kein Einfluss auf das Spiel. Referenz dazu in der CLaude.md