Document game architecture and update README

This commit is contained in:
2026-08-19 09:46:22 +02:00
parent 64d473de6d
commit 110a8596a5
2 changed files with 72 additions and 5 deletions
+44
View File
@@ -5,3 +5,47 @@
- Git-Commits nur auf explizite Anforderung des Users. Niemals eigenständig committen.
- Vor einem Commit: `git status`, `git diff` und `git log --oneline -10` prüfen; nur beabsichtigte Dateien stagen, keine Secrets.
- Commit-Message kurz und im Stil des Repos (bisher englisch, imperative).
## Build & Verifikation
```bash
cd web
npx tsc --noEmit # Typcheck (Pflicht nach Änderungen)
npm run build # tsc + vite build → web/dist
npm run dev # Dev-Server mit HMR
```
- Stack: Three.js 0.170 + TypeScript + Vite. Keine weiteren Laufzeit-Dependencies (kein Postprocessing verfügbar — Screen-Effekte als CSS-Overlays).
- `Makefile`: `make web`/`make dev`/`make build` (Container-Build via Podman).
- UI-Sprache: Deutsch (Skill-Namen, Level-up-Karten); Code-Kommentare bisher gemischt, Git-Messages englisch.
## Architektur (web/src)
| Datei | Inhalt |
|---|---|
| `Game.ts` | Zentrale Klasse: State-Machine, Render-Loop (`animate()`), Input, UI-Verdrahtung, Spawning, Partikel-/Effekt-Arrays (bloodParticles, traps, gasClouds, slashEffects, projectiles), Hotbar |
| `Player.ts` | Blob-Spieler: Movement, Sprung, `damage()`/`heal()` (Schild-Absorption), Stats (`applySkillSystem`), Hurt-Feedback (Flash + Blut via `game.onPlayerHurt`) |
| `Enemy.ts` | Abstrakte Basis: `body` (THREE.Group), `takeDamage` (Sound + XP/Lifesteal via `game.onDamageDealt`), Fade-Death, Felder `knockback`, `rootTime` |
| `Skills.ts` | Alle Skill-Definitionen (`SKILLS`-Array: id, name, type, maxLevel, describe) + Level-Wertetabellen (z. B. `auraRadius(level)`). `SkillSystem` = XP/Level/Angebote. `HOTBAR_SKILLS` = aktive Skills in Erwerbs-Reihenfolge |
| `SkillIcons.ts` | SVG-Icons (64×64, Template-Strings) für die Level-up-Karten |
| `Weapon.ts` | Basis für aktive Skills: `cooldown1-3` + `reduceCooldowns()` |
| `Sword.ts` / `Staff.ts` | Linksklick-Schwert (Bogen-Trefferzone via `SwordTrail.ts`), Rechtsklick-Feuerball + Teleport |
| `ChainLightning.ts` | Kettenblitz (Q-Slot) |
| `Trapper.ts` | Falle (skill1) + Gaswolke (skill2) |
| `Aura.ts` / `Boomerang.ts` | Passive Skills, lesen Level live aus `game.skillSystem` |
| `Trap.ts` / `GasCloud.ts` | Platzierbare Effekte; `update(dt, game): boolean` (false = entfernen), `dispose()` |
| `*Enemy*.ts` (Spider, Ghost, Frog, Bat, BeeSwarm, Slime, Brute/Boss, Crab, Turret) | Prozedurale Gegner-Modelle; je `update(dt, game)` |
| `SoundManager.ts` | Vorab geladene .ogg-Buffer (`playSound(name, volume)`); Sounds: damage, spawn, fireball, explosion, teleport, gameover, sword_hit1, spiderwalking |
| `MeshLoader.ts` | `loadGLB(name)``web/public/models/*.glb`; Texturen in `web/public/textures/` |
## Wichtige Konventionen & Fallstricke
- **Blickrichtung = lokale +Z**: Three.js `Object3D.lookAt` richtet +Z zum Ziel aus. Augen/Gesichter von Gegnern und Spieler müssen auf **+Z** liegen (sonst laufen sie rückwärts — war schon mal ein Bug bei Frosch/Golem/Brute/Slime/Bat/Crab).
- **UI-Overlays**: Alle Panels liegen absolut in `#ui-overlay` (`pointer-events: none`). Versteckte Panels brauchen **drei** Dinge: `opacity: 0` + `pointerEvents: none` + `visibility: hidden`. Achtung: `.menu-button { pointer-events: auto }` übersteuert `pointer-events: none` des Parents — ohne `visibility: hidden` sind unsichtbare Buttons klickbar (verursachte „stille Neustarts" mitten im Spiel). Neues Panel → immer `visibility` mitsetzen.
- **State-Machine**: `menu | playing | levelup | gameover` + Flag `paused` (ESC). `animate()` rendert bei Pause nur UI. `showMenu()` hat einen Guard (nur aus menu/gameover/pause).
- **Hotbar**: Aktive Skills (Kettenblitz, Teleport, Falle, Gaswolke) werden beim Erwerb auf Q, E, 1, 2, 3, 4 verteilt (`HOTBAR_KEY_CODES`). Dispatch über `triggerHotbarSkill()`. Cooldown-Labels zeigen Taste + Name (`syncSkillVisibility`).
- **Skill-Arten**: Aktive = `Weapon`-Subklassen mit Cooldowns (UI-Balken in `index.html`, Update in `updateUI`). Passive = Stats in `Player.applySkillSystem` ODER Game-seitige Objekte (Aura/Boomerang), die in `syncSkillVisibility` erzeugt/zersstört und im Loop geupdated werden.
- **Effekt-Lifecycle**: Neue Effekte mit eigenem `update(dt, game)`-Rückgabewert (false = aufräumen) und `dispose()`; in `Game.resetWorld()` ALLES aufräumen (sonst Geister-Objekte nach „Nochmal spielen").
- **Gegner-Festhalten**: `enemy.rootTime > 0` friert `enemy.update()` ein (siehe `Game.updateEnemies`) — so funktioniert die Falle, ohne jede Gegner-Klasse anzufassen.
- **Kontaktschaden** (Gegner berührt Spieler) läuft in `Game.ts` (Close-Encounter-Loop) mit `contactDps * dt`; Dornen-Skill ebendort als Gegenschlag.
- **`playSound`** erzeugt pro Aufruf einen AudioBufferSourceNode — bei hochfrequenten Effekten (Aura-Ticks, Bumerang-Hits) ggf. throtteln.
+28 -5
View File
@@ -50,14 +50,37 @@ npm run dev
- Three.js + TypeScript + Vite
- Steuerung: WASD bewegen, Space springen, Maus zielen,
Linksklick Schwert, Rechtsklick Feuerball (per Skill),
Q Kettenblitz (per Skill), E Teleport (per Skill), H Hitboxen (Debug)
- Roguelike-Skillsystem: Kills geben XP, bei Level-Up pausiert das Spiel
und bietet 3 Skill-Karten (neue Skills oder Upgrades). Seed (Startmenü)
steuert die Angebote, "Nochmal spielen" behält den Seed bei.
Q/E/14 Skills (Hotbar, siehe unten), ESC Pause, H Hitboxen (Debug)
### Skillsystem
Kills geben XP, bei Level-Up pausiert das Spiel und bietet 3 Skill-Karten
(neue Skills oder Upgrades). Seed (Startmenü) steuert die Angebote,
„Nochmal spielen" behält den Seed bei.
| Skill | Art | Effekt |
|---|---|---|
| Feuerball | Aktiv (Rechtsklick) | Explodierender Feuerball |
| Teleport | Aktiv (Hotbar) | Teleport zum Zielpunkt |
| Kettenblitz | Aktiv (Hotbar) | Blitz springt auf mehrere Gegner |
| Falle | Aktiv (Hotbar) | Hält 1 Gegner fest und fügt Schaden zu |
| Gaswolke | Aktiv (Hotbar) | Bleibt am Boden, Schaden über Zeit |
| Aura | Passiv | Bodenkreis um den Spieler, Schaden + Wegstoß |
| Bumerang | Passiv | Kreist um den Spieler (ab Stufe 3 mehrere) |
| Reichweite / Schärfe | Passiv | Schwert-Range/-Schaden |
| Regeneration / HP-Absorption | Passiv | Heilung |
| Schild | Passiv | Absorbiert Schaden, lädt nach 8 s neu |
| Vitalität / Dornen / Flinke Füße | Passiv | Max-HP / Kontakt-DPS / Tempo |
- **Hotbar**: Aktive Skills werden in Erwerbs-Reihenfolge auf Q, E, 14
verteilt; Cooldown-Anzeigen zeigen Taste + Name, Level-up-Karten die
künftige Taste.
- **Schadens-Feedback**: Blutpartikel, roter Vignette-Flash, Blob blitzt rot
auf, ab <30 % HP pulsierende rote Vignette.
## Verzeichnisse
- `Original/` — Original-Build (Blobtest.exe, JME3-Libs)
- `extracted/` — Aus dem Original extrahierte Assets
- `decompiled/` — Decompilierter Java-Source
- `web/` — Browser-Version
- `web/` — Browser-Version (Code-Struktur: siehe `AGENTS.md`)