> **Dieses Dokument ist die einzige Quelle der Wahrheit für das Spiel-Design.**
> Sprint-Specs und Implementierungspläne werden daraus abgeleitet. Änderungen hier zuerst besprechen, dann in Sprint-Specs übernehmen.
*Zuletzt aktualisiert: 2026-05-07*
---
## Kapitel 1 — Vision & Prinzipien
### Kern-Idee
**Genre:** Digitales Puppenhaus / Pretend Play. Sandbox — kein Ziel, kein Scheitern, kein Scoring.
**Zielgruppe:** Kinder ab 3 Jahren. Primär auf Tablet (Android zuerst, iOS später).
**Kern-Fantasie:** Ich bin Arzt oder Schwester in einem Tier-Krankenhaus. Ich entscheide, wer wo liegt, wer behandelt wird, wer ein Baby bekommt. Ich erzähle mir meine eigene Geschichte.
### Nicht-Verhandelbare Prinzipien
Diese Punkte werden in keinem Sprint, keiner Spec und keinem PR geändert:
1.**Keine Werbung** — keine Ad-SDKs, kein AdMob, keine Rewarded Ads
2.**Keine Datensammlung** — keine Analytics, kein Tracking, keine Telemetrie
3.**Offline-first** — vollständig ohne Internetverbindung spielbar
4.**Keine In-App-Käufe** — kein Premium-Content, keine Währungen
5.**Keine Achievements / Scoring** — kein Sterne-System, kein Freischalten durch Sammeln
6.**Garten von Anfang an offen** — kein Unlock-Gate
7.**Keine Gift-Mechaniken** — alle Medikamente sind positiv/neutral
8.**COPPA/DSGVO-konform** — Play Store Data Safety: "Keine Daten erhoben"
9.**Kein Text in der Spielwelt** — Icons, Symbole, Farben statt Beschriftungen
10.**Minimum Touch-Target 64dp** — für Kinder-Finger
### Was wir besser machen als das Original (Yasa Pets Hospital)
Ein `OutfitItem` hat `layer: int` (1–3). Per Drag auf eine Figur gezogen → Layer-Sprite wechselt auf das Item-Bild, Item verschwindet aus der Welt. Tap auf aktiven OutfitLayer → Item fällt neben Figur zurück in die Welt. Outfit wird in `CharacterData` als `outfit: Array[String]` (3 Einträge, leer = kein Outfit) gespeichert.
---
## Kapitel 4 — Objekt-Katalog
### Kategorien
| Typ | Beschreibung |
|---|---|
| **Möbel / Snap-Host** | Statisch, hat einen oder mehrere SnapPoints für Figuren |
| **Holdable Item** | Kann aufgehoben und in einen Hand-Slot gelegt werden |
| **Outfit Item** | Holdable + per Drag auf Figur anwendbar (belegt Outfit-Layer) |
| **Maschine** | Nimmt Figur oder Item auf → produziert Ausgabe |
| **Spawner** | Tap → neues Item-Exemplar erscheint in der Welt |
| **Applier** | Auf Figur gezogen → ändert State oder spielt Animation |
### Vollständige Liste (~55 Objekte)
**EG — Empfang (6)**
-`queue_machine` — Spawner: Tap → `number_ticket` spawnt
@exportvarspecies_filter:Array[String]=[]# leer = alle; ["BABY"] = nur Babys
varoccupant:Character=null
```
`SnapReceiver` sitzt auf jeder Figur. Bei `drag_released` scannt er alle `SnapPoint`-Nodes im Radius 80px. Nächster freier Snap (unter Berücksichtigung `species_filter`) gewinnt: Figur teleportiert auf SnapPoint-Position, Animation wechselt zu `pose`. Beim erneuten Aufnehmen (`drag_picked_up`) gibt SnapPoint `occupant` frei → Animation zurück zu `held`.
### 5.2 Hand-Slot System
`HandLeft` und `HandRight` sind `Node2D`-Nodes an der Figur. Bei `drag_released` eines Holdable Items prüft das Item ob es sich in Reichweite (~60px) eines leeren Hand-Slots befindet. Wenn ja: Item wird Kind des Hand-Slots, `global_position` relativ zum Slot, reist mit Figur mit. Zweiter Drag vom Hand-Slot löst das Item. Maximum 1 Item pro Hand.
### 5.3 Outfit Layer System
Drei `Sprite2D`-Nodes über dem Basis-Sprite der Figur. `OutfitItem` hat:
```gdscript
@exportvaroutfit_layer:int=1# 1 | 2 | 3
@exportvaroutfit_sprite:Texture2D
```
Per Drag auf Figur → Layer-Sprite zeigt `outfit_sprite`, Item verschwindet aus Welt. Tap auf aktiven Layer → Item fällt neben Figur, Layer-Sprite wird leer. Gespeichert in `CharacterData.outfit: Array[String]` (3 Item-IDs).
### 5.4 Room Chest System
Jeder Raum hat einen `RoomChest`-Node:
```gdscript
class_nameRoomChestextendsNode2D
@exportvaritem_ids:Array[String]=[]
```
Tap auf Chest → öffnet sich, zeigt Items als Icon-Reihe (tappbar). Tap auf Icon → Item-Instanz spawnt neben Chest. Items die in die Chest-Zone (~100px) zurückgezogen werden despawnen. Gehaltene oder eingerastete Items werden nie automatisch entfernt. Chest-State (welche Items spawnt, wo) wird per SaveManager persistiert.
### 5.5 Applier-Logik
Items mit `apply_on_drop: bool = true` triggern `apply_to(character: Character)` wenn auf eine Figur gedroppt. Mapping:
Tap auf Chest → Icon-Reihe erscheint direkt in der Spielwelt über/neben der Chest (kein separater Screen). Tap außerhalb → Chest schließt. Icons haben 64dp Mindestgröße.
### Settings-Menü
- Lautstärke Musik (Slider)
- Lautstärke SFX (Slider)
- Savegame zurücksetzen (mit Bestätigung)
- Später: Sprache
---
## Kapitel 7 — Audio Design
### Musik
| Bereich | Stil | Loop-Länge |
|---|---|---|
| EG | Fröhlich, Empfangs-Feeling | ~2 min |
| 1.OG | Ruhig, Glockenspiel-Elemente | ~2 min |
| 2.OG | Sanft, Schlaflied-Atmosphäre | ~2 min |
| Garten | Beschwingt, Party-Feeling | ~2 min |
Cross-Fade bei Etagen-Wechsel (AudioManager bereits impl.). Default-Lautstärke: 60%.
### SFX-Katalog
| ID | Trigger |
|---|---|
| `sfx_pickup` | Figur oder Item aufheben |
| `sfx_place` | Figur oder Item ablegen (kein Snap) |
| `sfx_snap` | Figur rastet in SnapPoint ein |
| `sfx_happy` | `happy`-Animation startet |
| `sfx_chest_open` | RoomChest öffnet |
| `sfx_item_spawn` | Item spawnt aus Chest |
| `sfx_medicine` | Medikament auf Figur angewendet |
- Sprites: PNG mit Transparenz, 2× (für Retina-Displays)
- Animationen: SpriteSheet oder einzelne Frames in `AnimatedSprite2D`
- Audio: OGG für Loops, WAV für kurze SFX
---
*Dieses Dokument wird nur bei Produkt-Entscheidungen aktualisiert, nie bei rein technischen Implementierungsdetails.*
Reference in New Issue
Block a user
Blocking a user prevents them from interacting with repositories, such as opening or commenting on pull requests or issues. Learn more about blocking a user.