18 KiB
Cozypaw Hospital — Game Design Document (GDD)
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:
- Keine Werbung — keine Ad-SDKs, kein AdMob, keine Rewarded Ads
- Keine Datensammlung — keine Analytics, kein Tracking, keine Telemetrie
- Offline-first — vollständig ohne Internetverbindung spielbar
- Keine In-App-Käufe — kein Premium-Content, keine Währungen
- Keine Achievements / Scoring — kein Sterne-System, kein Freischalten durch Sammeln
- Garten von Anfang an offen — kein Unlock-Gate
- Keine Gift-Mechaniken — alle Medikamente sind positiv/neutral
- COPPA/DSGVO-konform — Play Store Data Safety: "Keine Daten erhoben"
- Kein Text in der Spielwelt — Icons, Symbole, Farben statt Beschriftungen
- Minimum Touch-Target 64dp — für Kinder-Finger
Was wir besser machen als das Original (Yasa Pets Hospital)
| Original | Cozypaw |
|---|---|
| Werbung zwischen Räumen | ❌ Keine Werbung |
| Firebase Analytics | ❌ Kein Tracking |
| Grüne Giftflaschen machen krank | ❌ Alle Medikamente positiv |
| Garten erst nach Sternen freischaltbar | ✅ Von Anfang an offen |
| Kleine Touch-Targets | ✅ Mind. 64dp |
| Generische Figuren | ✅ Figuren basieren auf Haustieren der Kinder |
Kapitel 2 — Welt & Räume
Struktur
3 Etagen + Gartenbereich. Navigation:
- Innerhalb einer Etage: Camera-Pan per
NavigationArrow - Zwischen Etagen: Aufzug-Button +
RoomNavigator(Camera-Tween) - Garten:
HomeButton— wechselt Hospital ↔ Garten
Raum-Übersicht
| Etage | Raum | Scene | Room-Chest Inhalt | Besondere Interaktion |
|---|---|---|---|---|
| EG | Empfang | Reception.tscn |
Blumensträuße, Nummerntickets | Wartenummer-Automat: Tap → Ticket spawnt |
| EG | Geschenke-Shop | GiftShop.tscn |
Geschenkkörbe, Kuscheltiere, Grußkarten | — |
| EG | Restaurant | Restaurant.tscn |
Mahlzeit-Tabletts × 3, Getränke | Tablett auf Tisch stellen |
| EG | Notaufnahme | EmergencyRoom.tscn |
Trage, Verbandsmaterial | Ambulanz-Türen öffnen → Trage herausziehen |
| 1.OG | Röntgen | XRay.tscn |
Gips-Set, Röntgenfotos | Figur auf Tisch → Röntgenbild → Gips per Drag anlegen |
| 1.OG | Apotheke | Pharmacy.tscn |
Medikamentenflaschen × 3, Tüten | Flasche auf Figur → Figur wird gesünder |
| 1.OG | Labor | Lab.tscn |
Reagenzgläser × 2, Mikroskop-Slides | Slide in Mikroskop → Bild wechselt |
| 1.OG | Patientenzimmer | PatientRoom.tscn |
Kissen, Infusionsbeutel, TV-Fernbedienung | IV-Bag an Haken + Figur im Bett → SLEEPING |
| 2.OG | Ultraschall | Ultrasound.tscn |
Gel-Tube, Ultraschall-Sonde | Sonde an PREGNANT → Bildschirm zeigt Fötus |
| 2.OG | Kreißsaal | DeliveryRoom.tscn |
Baby-Decke, Windeln | DeliveryBed: PREGNANT rein → BABY spawnt |
| 2.OG | Säuglingsstation | Nursery.tscn |
Fläschchen, Rassel, Schnuller | Wiege schaukeln; Fläschchen an BABY → trinkt |
| Garten | Gartenparty | GardenParty.tscn |
Tassen, Kuchen, Luftballons | GiftBox: Tap → öffnet; TeaPot: Tap → gießt |
Kapitel 3 — Figurensystem
Roster MVP (8 Figuren)
| ID | Spezies | Rolle | Start-State |
|---|---|---|---|
bunny_f |
Häschen | Patientin / Mutter | HEALTHY |
bunny_m |
Häschen | Patient / Besucher | HEALTHY |
kitten_f |
Kätzchen | Patientin | HEALTHY |
kitten_m |
Kätzchen | Patient | HEALTHY |
bunny_baby |
Häschen | Baby | BABY |
kitten_baby |
Kätzchen | Baby | BABY |
fox_doctor |
Fuchs | Arzt | HEALTHY |
owl_nurse |
Eule | Krankenschwester | HEALTHY |
Zustände
Bereits in CharacterData.State implementiert:
HEALTHY → SICK → HEALTHY (durch Medikament)
HEALTHY → PREGNANT → (DeliveryBed) → HEALTHY + BABY spawnt
HEALTHY / SICK → SLEEPING (durch IV-Bag oder Bett)
SLEEPING → HEALTHY (nach Interaktion)
HEALTHY → TIRED (kann in Bett gelegt werden)
Animations-States (AnimatedSprite2D)
| State | Trigger | Frames |
|---|---|---|
idle |
Default, kein Snap, nicht gehalten | 4 — atmet, blinzelt (loop) |
held |
DragDropComponent aktiv | 2 — Arme leicht seitlich |
sitting |
Snap auf Stuhl / Hocker / Theke | 2 — aufrecht sitzend |
lying |
Snap auf Bett / Tisch / Trage | 2 — flach liegend |
happy |
Interaktion erfolgreich abgeschlossen | 4 — hüpft/jubelt (einmalig, dann idle) |
sleeping |
State = SLEEPING | 4 — Augen zu, langsamer Atem (loop) |
Node-Struktur
Character (Node2D) class_name Character
├── DragDropComponent ← Drag & Drop (bestehend)
├── SnapReceiver (Node2D) ← NEU: scannt SnapPoints beim Loslassen
├── AnimatedSprite2D ← NEU: ersetzt ColorRect-Placeholder
├── OutfitLayer1 (Sprite2D) ← NEU: Kleidung (Kittel, Patientenhemd)
├── OutfitLayer2 (Sprite2D) ← NEU: Medizinisch (Gips, Verband)
├── OutfitLayer3 (Sprite2D) ← NEU: Accessoire (Stethoskop, Mütze)
├── HandLeft (Node2D) ← NEU: Attachment-Point links
│ └── HeldItem (Node2D) ← aktuell gehaltenes Item (oder leer)
├── HandRight (Node2D) ← NEU: Attachment-Point rechts
│ └── HeldItem (Node2D)
└── CollisionArea (Area2D) ← bestehend
Outfit-Regeln
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_ticketspawntnumber_ticket— Holdablereception_desk— Snap-Host (Pose:sitting)waiting_chair× 3 — Snap-Host (Pose:sitting)
EG — Geschenke-Shop (4)
gift_basket— Holdableplush_toy— Holdablegreeting_card— Holdableshop_counter— Snap-Host (Pose:sitting)
EG — Restaurant (5)
meal_tray_1/2/3— Holdable (3 Mahlzeit-Varianten)drink_cup— Holdabledining_table— Snap-Host (Pose:sitting)
EG — Notaufnahme (4)
ambulance— Maschine: Türen öffnen → Trage sichtbar (bereits impl.)stretcher— Holdable + Snap-Host (Pose:lying)bandage_roll— Outfit Item (Layer 2: Verband)er_table— Snap-Host (Pose:lying)
1.OG — Röntgen (5)
xray_machine— Maschine: Figur auf Tisch → Röntgenbild (bereits impl.)xray_photo— Holdable (result item, spawnt nach Röntgen)cast_machine— Maschine: Figur rein → legt Gips-Outfit ancast_arm— Outfit Item (Layer 2: Gips)xray_table— Snap-Host (Pose:lying)
1.OG — Apotheke (4)
medicine_bottle_red/blue/yellow— Applier: auf Figur → State = HEALTHY +happymedicine_bag— Holdablepharmacy_counter— Snap-Host (Pose:sitting)
1.OG — Labor (4)
microscope— Maschine: Slide in Slot → Bild wechselttest_tube× 2 — Holdablemicroscope_slide— Holdable → passt inmicroscope-Slotlab_stool— Snap-Host (Pose:sitting)
1.OG — Patientenzimmer (6)
patient_bed× 2 — Snap-Host (Pose:lying) (bereits impl.)iv_bag— Holdable + Applier: in IV-Hook gehängt + Figur im Bett → State = SLEEPINGiv_hook— Slot an patient_bed, nimmtiv_bagauftv_remote— Holdablepillow— Holdablebedside_table— Snap-Host (Pose:sitting)
2.OG — Ultraschall (5)
ultrasound_machine— Maschine (bereits impl.)ultrasound_probe— Holdable + Applier: auf PREGNANT-Figur auf Tisch → Bildschirm zeigt Fötusgel_tube— Holdableexam_table— Snap-Host (Pose:lying)ultrasound_screen— reagiert auf Probe-Nähe (Kind des ultrasound_machine)
2.OG — Kreißsaal (4)
delivery_bed— Maschine: PREGNANT eingerastet → BABY spawnt (bereits impl.)baby_blanket— Holdablediaper— Outfit Item für BABY (Layer 1)baby_scale— Snap-Host (Pose:lying, nur BABY-Figuren)
2.OG — Säuglingsstation (5)
cradle× 2 — Snap-Host (Pose:lying) (bereits impl.)baby_bottle— Holdable + Applier: auf BABY →happy-Animation + Trink-SFXrattle— Holdablepacifier— Outfit Item für BABY (Layer 3)incubator— Snap-Host (Pose:lying, nur BABY-Figuren)
Garten (7)
gift_box× 3 — Tap → öffnet sich (bereits impl.)tea_pot— Tap → gießt (bereits impl.)tea_cup× 2 — Holdablecake— Holdableballoon× 2 — Holdablegarden_table— Snap-Host (Pose:sitting)garden_chair× 2 — Snap-Host (Pose:sitting)
Kapitel 5 — Core Systems
5.1 Snap-Point System
SnapPoint ist ein Node2D an Möbeln:
class_name SnapPoint extends Node2D
@export var pose: String = "sitting" # "sitting" | "lying"
@export var species_filter: Array[String] = [] # leer = alle; ["BABY"] = nur Babys
var occupant: 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:
@export var outfit_layer: int = 1 # 1 | 2 | 3
@export var outfit_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:
class_name RoomChest extends Node2D
@export var item_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:
| Item | Effekt |
|---|---|
medicine_bottle_* |
set_state(HEALTHY) + happy-Animation + sfx_medicine |
iv_bag (in IV-Hook, Figur im Bett) |
set_state(SLEEPING) |
baby_bottle auf BABY |
happy-Animation + sfx_baby_coo |
bandage_roll |
Outfit Layer 2: Verband-Sprite |
cast_arm |
Outfit Layer 2: Gips-Sprite |
diaper |
Outfit Layer 1 für BABY |
pacifier |
Outfit Layer 3 für BABY |
5.6 Maschinen-Interaktion
Maschinen haben einen receive_slot: SnapPoint. Zusätzliche Bedingungen lösen Ausgaben aus:
| Maschine | Bedingung | Ausgabe |
|---|---|---|
xray_machine |
Figur auf xray_table |
Röntgenbild-Animation → xray_photo spawnt |
ultrasound_machine |
PREGNANT auf exam_table + ultrasound_probe in HandSlot |
Fötus-Bild auf ultrasound_screen |
microscope |
microscope_slide in Slot |
Bild-Wechsel auf Screen |
queue_machine |
Tap | number_ticket spawnt |
iv_hook |
iv_bag eingehängt + Figur in patient_bed |
set_state(SLEEPING) |
delivery_bed |
PREGNANT eingerastet + 2s | BABY spawnt, Mutter → HEALTHY (bereits impl.) |
cast_machine |
Figur eingerastet | cast_arm-Outfit (Layer 2) auf Figur, Figur → HEALTHY |
baby_scale |
BABY-Figur eingerastet | happy-Animation + sfx_happy |
ultrasound_machine |
PREGNANT auf exam_table + ultrasound_probe in HandSlot |
Fötus-Bild auf ultrasound_screen |
Kapitel 6 — UI & Navigation
HUD (immer sichtbar)
- Aufzug-Button — Etagen-Wechsel, 64dp, links oder rechts je nach Raum
- HomeButton — Hospital ↔ Garten, 64dp (bereits impl.)
- Settings-Button — oben rechts, 48dp
- Kein Score, kein Timer, keine Sterne, kein Text
Navigation
| System | Status |
|---|---|
| Camera-Pan innerhalb Etage | NavigationArrow (bereits impl.) |
| Etagen-Wechsel | ElevatorButton + RoomNavigator (bereits impl.) |
| Hospital ↔ Garten | HomeButton (bereits impl.) |
Room Chest UI
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 |
sfx_pour |
TeaPot gießt |
sfx_gift_open |
GiftBox öffnet |
sfx_cradle_rock |
Wiege schaukelt |
sfx_xray_scan |
Röntgengerät aktiv |
sfx_ambulance |
Ambulanz-Türen öffnen |
sfx_baby_coo |
Baby-Interaktion (Fläschchen, Schaukeln) |
sfx_bunny_sniff |
Häschen-Figur aufgehoben |
sfx_kitten_meow |
Kätzchen-Figur aufgehoben |
sfx_fox_yip |
Fuchs-Figur aufgehoben |
sfx_owl_hoot |
Eulen-Figur aufgehoben |
Quellen: freesound.org, opengameart.org (Creative Commons)
Kapitel 8 — Save/Load
Format v2
Erweiterung des bestehenden SaveManager + GameState. Migration: v1-Saves werden beim Laden auf v2 hochkonvertiert (fehlende Felder → Defaults).
{
"version": 2,
"current_floor": 0,
"characters": {
"bunny_f": {
"position": [640, 360],
"state": "HEALTHY",
"outfit": ["white_coat", "", "stethoscope"],
"held_left": "medicine_bottle_blue",
"held_right": "",
"snap_point": "floor1/xray/xray_table/snap_0"
}
},
"room_chests": {
"floor0/reception/chest": {
"spawned_items": [
{"id": "number_ticket", "pos": [200, 300]}
]
}
}
}
Auto-Save: nach jeder Interaktion (Pick-up, Place, Snap, Outfit-Wechsel, State-Änderung).
Kapitel 9 — Sprint-Plan (Gesamt)
| Sprint | Titel | Kern-Deliverable |
|---|---|---|
| 0 | Setup | Git, Godot, Android-Export |
| 1–2 | Proof of Concept | Ein Raum, eine Figur, Drag & Drop |
| 3–4 | Core Systems | RoomNavigator, SaveManager, Settings |
| 5–7 | Erdgeschoss | Reception, GiftShop, Restaurant, EmergencyRoom |
| 8–10 | 1. Obergeschoss | XRay, Pharmacy, Lab, PatientRoom |
| 11–13 | 2. Obergeschoss | Ultrasound, DeliveryRoom, Nursery |
| 14 | Zuhause & Garten | GardenParty, HomeButton, GiftBox, TeaPot ✅ |
| 15 | Character System v2 | AnimatedSprite2D (6 States), SnapReceiver, HandSlots, OutfitLayers |
| 16 | Snap-Point System | SnapPoint an allen Möbeln in allen 12 Räumen |
| 17 | Hand-Slots + Outfits | Item-Holding, OutfitItem-Typ, Apply-Logik, Save-Extension |
| 18 | Room Chests + Items | RoomChest-Node, alle ~55 Objekte verteilt |
| 19 | Maschinen & Applier | XRay-Foto, Ultraschall-Fötus, Mikroskop, Wartenummer, IV-Bag, Medizin |
| 20 | Sound & Musik | Kompletter SFX-Katalog, Musik-Loops |
| 21 | Polish | Tutorial-Hint, Animations-Feinschliff, Settings-Erweiterung |
| 22 | Release | Icon, Splash, Play Store, Familien-Testing |
Sprints 0–14 ✅ abgeschlossen. Sprints 15–22 stehen aus.
Appendix — Asset-Strategie
Empfehlung: Hybrid
- Kinder malen Helden-Figuren (Häschen, Kätzchen) auf Papier → einscannen → digitalisieren
- Freelancer für Hintergründe und generische Objekte
- Tier-Geräusche: freesound.org (Creative Commons)
Asset-Formate:
- 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.