feat(bisaya-course): expand exercises for shopping, neighborhood visits, conflict resolution, and free speaking
All checks were successful
Deploy to production / deploy (push) Successful in 2m57s
All checks were successful
Deploy to production / deploy (push) Successful in 2m57s
- Added new exercises in multiple-choice, gap-fill, and situational response formats for categories including 'Einkaufen vertiefen', 'Nachbarschaft & Besuche', 'Rollenspiel - Konflikt und Hilfe', and 'Freies Sprechen - Alltag ohne Stütze'. - Each exercise includes detailed instructions, question data, answer data, and explanations to enhance the learning experience for Bisaya language learners. - Focused on practical scenarios to improve conversational skills and vocabulary retention.
This commit is contained in:
178
docs/FALUKANT_PREGNANCY_SCHEDULED_BIRTH_DAEMON_SPEC.md
Normal file
178
docs/FALUKANT_PREGNANCY_SCHEDULED_BIRTH_DAEMON_SPEC.md
Normal file
@@ -0,0 +1,178 @@
|
||||
# Falukant: Geplante Schwangerschaft & Geburt – Daemon- und Datenbankkonzept
|
||||
|
||||
Dieses Dokument beschreibt das **vereinheitlichte Konzept** für Schwangerschaft, die der **externe Daemon** (`UserCharacterWorker`, C++) verarbeiten soll, sowie die **Datenbank** und die **Abgrenzung zur bestehenden Zufallslogik**. Ziel ist, dass gesetzte Termine (`pregnancy_due_at`) und der gewählte Vater (`pregnancy_father_character_id`) – u. a. aus dem Admin-Tool – **tatsächlich zu Geburten führen**, ohne dass nur die Node-API „Geburt erzwingen“ funktioniert.
|
||||
|
||||
---
|
||||
|
||||
## 1. Ist-Zustand (Problem)
|
||||
|
||||
### 1.1 Datenbank (bereits vorhanden)
|
||||
|
||||
Auf `falukant_data."character"` existieren (siehe `backend/sql/add_character_pregnancy.sql`):
|
||||
|
||||
| Spalte | Typ | Bedeutung |
|
||||
|--------|-----|-----------|
|
||||
| `pregnancy_due_at` | `TIMESTAMPTZ` NULL | Erwarteter Geburtstermin |
|
||||
| `pregnancy_father_character_id` | `INTEGER` NULL, FK auf `character(id)` | Vater-Charakter |
|
||||
|
||||
Die **Node-Backend**-Logik (Admin, `falukantService`) **liest und schreibt** diese Felder.
|
||||
|
||||
### 1.2 Daemon – aktuelles Verhalten
|
||||
|
||||
In `src/usercharacterworker.cpp` / `src/usercharacterworker.h`:
|
||||
|
||||
- `processPregnancies()` führt **`QUERY_GET_PREGNANCY_CANDIDATES`** aus.
|
||||
- Diese Query:
|
||||
- bezieht sich **nur** auf Ehen (`falukant_type.relationship.tr = 'married'`),
|
||||
- nutzt **keine** `pregnancy_*`-Spalten,
|
||||
- modelliert Geburten **per Zufallsprozess** (altersabhängige Wahrscheinlichkeit),
|
||||
- setzt implizit **`character1_id` = Vater** und **`character2_id` = Mutter** (fest verdrahtet, ohne Geschlechts- oder Rollenprüfung).
|
||||
|
||||
**Folge:** Wer im Spiel oder per Admin als „schwanger“ mit Termin und Vater gespeichert wird, **wird vom Daemon nicht erkannt**. Geburten aus diesem Konzept passieren nur, wenn sie **manuell** per Node (z. B. Admin „Geburt erzwingen“) ausgelöst werden.
|
||||
|
||||
**Zusätzlich:** `QUERY_AUTOBATISM` setzt nur `child_relation.name_set` nach einigen Tagen – hat **nichts** mit Schwangerschafts-Spalten zu tun.
|
||||
|
||||
---
|
||||
|
||||
## 2. Soll-Konzept (Zwei parallele Wege, eine klare Priorität)
|
||||
|
||||
### 2.1 Weg A – **Geplante Schwangerschaft** (DB-gesteuert, neu für den Daemon)
|
||||
|
||||
**Auslöser:** `pregnancy_due_at` ist gesetzt und der Zeitpunkt ist **fällig**.
|
||||
|
||||
**Regeln (Vorschlag):**
|
||||
|
||||
1. **Eine** Mutter ist immer der Datensatz in `character`, auf dem `pregnancy_due_at` und die Schwangerschaft „liegen“.
|
||||
2. **Vater:** `pregnancy_father_character_id`
|
||||
- Wenn gesetzt: muss ein existierender Charakter sein, **nicht** `mother.id`.
|
||||
- Wenn `NULL`: Policy festlegen (siehe Abschnitt 8).
|
||||
3. **Fälligkeit:** z. B. `date_trunc('day', pregnancy_due_at AT TIME ZONE 'Europe/Berlin') <= current_date` (oder einheitlich **UTC** – wichtig ist **eine** Definition im Team).
|
||||
4. Nach erfolgreicher Geburt: **`pregnancy_due_at` und `pregnancy_father_character_id` auf NULL** setzen (Schwangerschaft beendet).
|
||||
|
||||
Dieser Weg entspricht dem, was Admin und Spieler erwarten, wenn ein **Termin** existiert.
|
||||
|
||||
### 2.2 Weg B – **Legacy: Zufallsgeburten bei Ehe** (bestehende Query)
|
||||
|
||||
Die Query `QUERY_GET_PREGNANCY_CANDIDATES` modelliert **„natürliche“** Zufallsgeburten ohne `pregnancy_*`-Felder.
|
||||
|
||||
**Entscheidung für die Umsetzung:**
|
||||
|
||||
- **Option B1:** Weg B **abschalten** oder stark reduzieren, wenn Weg A das offizielle Modell ist.
|
||||
- **Option B2:** Weg B **beibehalten** für Atmosphäre, aber **nur**, wenn **keine** aktive geplante Schwangerschaft auf den betroffenen Charakteren existiert (doppelte Geburten vermeiden).
|
||||
- **Option B3:** Weg B nur noch **Simulation**, bis Spiel-Logik „Konzeption“ explizit setzt (größerer Umbau).
|
||||
|
||||
**Empfehlung:** Mindestens **B2** oder **B1**, damit keine zwei Geburten pro Tag für dieselbe Ehe aus unterschiedlichen Regeln entstehen.
|
||||
|
||||
---
|
||||
|
||||
## 3. Datenbank – Erweiterungen (Vorschlag)
|
||||
|
||||
Die Minimalvariante kommt **ohne** neue Spalten aus (nur Daemon-Logik). Für Robustheit und spätere Features sind **optionale** Erweiterungen sinnvoll:
|
||||
|
||||
### 3.1 Pflicht (kein Schema-Zwang, aber empfohlen)
|
||||
|
||||
- **Index** für den Daemon-Tick, z. B.:
|
||||
|
||||
```sql
|
||||
CREATE INDEX IF NOT EXISTS idx_character_pregnancy_due
|
||||
ON falukant_data."character" (pregnancy_due_at)
|
||||
WHERE pregnancy_due_at IS NOT NULL;
|
||||
```
|
||||
|
||||
### 3.2 Optional – Metadaten
|
||||
|
||||
| Spalte | Typ | Zweck |
|
||||
|--------|-----|--------|
|
||||
| `pregnancy_source` | `TEXT` oder `ENUM` | z. B. `admin`, `gameplay`, `npc` – für Logging und Regeln |
|
||||
| `pregnancy_conception_at` | `TIMESTAMPTZ` | optional, für Anzeige/Quests |
|
||||
| `pregnancy_birth_context` | `TEXT` | `marriage` | `lover` – für korrekten `child_relation.birth_context` ohne Heuristik |
|
||||
|
||||
Wenn `pregnancy_birth_context` **nicht** eingeführt wird, leitet der Daemon den Kontext aus der **Beziehung** zwischen Mutter und Vater ab (verheiratet → `marriage`, Liebhaber → `lover`, sonst Default `marriage` oder Policy).
|
||||
|
||||
### 3.3 `child_relation` – Parität mit Node
|
||||
|
||||
Das Sequelize-Modell erwartet u. a. `father_name`, `mother_name`, `legitimacy`, `birth_context`, `public_known`. Die **Daemon-INSERT**-Query (`QUERY_INSERT_CHILD_RELATION`) muss mit der **realen DB** übereinstimmen (Pflichtfelder, Defaults). Falls nötig:
|
||||
|
||||
- INSERT um **Namen** (aus Vordefiniert-Tabellen) und **legitimacy / birth_context / public_known** erweitern,
|
||||
- oder DB-Defaults / Trigger ergänzen,
|
||||
- **gleiche Semantik** wie `adminForceFalukantBirth` in `adminService.js` anstreben.
|
||||
|
||||
---
|
||||
|
||||
## 4. Daemon – Umsetzung (technisch)
|
||||
|
||||
### 4.1 Neue SQL-Query: „fällige geplante Geburten“
|
||||
|
||||
**Skizze (logisch):**
|
||||
|
||||
- SELECT Mutter-`character` `c` mit:
|
||||
- `c.pregnancy_due_at IS NOT NULL`
|
||||
- `c.pregnancy_due_at` fällig (siehe Zeitzone)
|
||||
- JOIN Vater `c_father` auf `c.pregnancy_father_character_id = c_father.id` **wenn** Vater Pflicht ist
|
||||
- Pro Zeile: `father_cid`, `mother_cid`, `region_id`, `title_of_nobility` (vom passenden Elternteil), `last_name`, `father_uid`, `mother_uid` analog zur bestehenden Schleife.
|
||||
|
||||
**Wichtig:** Vater/Mutter **nicht** aus `relationship.character1/2` ableiten, sondern aus **expliziten IDs** (`pregnancy_father_character_id` + Zeilen-ID der Mutter).
|
||||
|
||||
### 4.2 Ablauf in `processPregnancies()`
|
||||
|
||||
1. `QUERY_AUTOBATISM` wie bisher (optional, Reihenfolge beachten).
|
||||
2. **Neu:** Transaktion oder feste Reihenfolge:
|
||||
- Kandidaten für **geplante Geburt** laden
|
||||
- **pro Kandidat:** Kind einfügen (`QUERY_INSERT_CHILD` oder gemeinsame Funktion), `child_relation` einfügen, **Schwangerschaft** auf der Mutter **leeren**
|
||||
- Benachrichtigungen (`children_update`, `falukantUpdateStatus`) wie bei bestehender Schleife
|
||||
3. **Legacy-Query** nur ausführen, wenn nach Absprache (Option B1–B3).
|
||||
|
||||
**Idempotenz:** Pro Tick darf dieselbe schwangere Zeile **nicht** zweimal gebären. Am sichersten: **UPDATE … RETURNING** oder **DELETE** der Schwangerschaftsdaten in derselben Transaktion wie das Kind.
|
||||
|
||||
### 4.3 Geschlecht der Eltern
|
||||
|
||||
Optional: Plausibilitätsprüfung (`gender` Mutter/Vater) – kann im ersten Schritt weggelassen werden, sollte aber langfristig mit dem Spielregelwerk übereinstimmen.
|
||||
|
||||
---
|
||||
|
||||
## 5. Backend (Node) – Abstimmung
|
||||
|
||||
- **Zeitzonen:** `pregnancy_due_at` wird in JS als `Date` gesetzt; Daemon muss **dieselbe** Fälligkeitsdefinition nutzen wie die UI („heute“ = 0 Tage).
|
||||
- **WebSocket:** Nach Daemon-Geburt dieselben Events wie bei Admin-Geburt, damit Clients die Familie aktualisieren.
|
||||
|
||||
---
|
||||
|
||||
## 6. Frontend
|
||||
|
||||
- Hinweis in der Familien-Ansicht: „Geburt erfolgt automatisch am Termin“ (wenn Daemon aktiv), sonst „nur nach Admin-Aktion“ – je nach Rollout.
|
||||
|
||||
---
|
||||
|
||||
## 7. Test-Checkliste
|
||||
|
||||
- [ ] Admin: Schwangerschaft mit Termin **heute** und Vater – nach Daemon-Lauf: Kind existiert, Schwangerschaft weg.
|
||||
- [ ] Kein Vater (`NULL`) – definiertes Verhalten (Fehler loggen / überspringen / NPC-Vater – **Policy**).
|
||||
- [ ] Doppel-Tick: keine doppelte Geburt.
|
||||
- [ ] Legacy-Zufallsgeburt: keine Kollision mit aktivem `pregnancy_due_at` auf derselben Mutter.
|
||||
- [ ] `child_relation` und `character`-Kind konsistent mit Node-Admin-Geburt.
|
||||
|
||||
---
|
||||
|
||||
## 8. Offene Policy-Fragen (bitte vor Implementierung festlegen)
|
||||
|
||||
1. **Vater `NULL`:** Geburt abbrechen, stillen Vater aus Beziehung erraten, oder festen Platzhalter?
|
||||
2. **Legacy-Query:** komplett entfernen oder nur noch unter Bedingungen?
|
||||
3. **Zeitzone** für „Termin ist heute“: Server-UTC, Europe/Berlin, oder Nutzer-TZ?
|
||||
4. **Liebschaftsgeburten:** nur über `pregnancy_*` + `birth_context`/`pregnancy_birth_context`, nie über reine Ehe-Query?
|
||||
|
||||
---
|
||||
|
||||
## 9. Referenzdateien im Repo
|
||||
|
||||
| Bereich | Datei |
|
||||
|---------|--------|
|
||||
| Daemon | `src/usercharacterworker.cpp` (`processPregnancies`) |
|
||||
| SQL-Strings | `src/usercharacterworker.h` (`QUERY_GET_PREGNANCY_CANDIDATES`, `QUERY_INSERT_CHILD`, `QUERY_INSERT_CHILD_RELATION`) |
|
||||
| DB-Spalten Schwangerschaft | `backend/sql/add_character_pregnancy.sql` |
|
||||
| Modell Character | `backend/models/falukant/data/character.js` |
|
||||
| Admin / Geburt Node | `backend/services/adminService.js` (`adminForceFalukantPregnancy`, `adminForceFalukantBirth`) |
|
||||
| Familie API | `backend/services/falukantService.js` (`_getCharacterPregnancyOptional`, `getFamily`) |
|
||||
|
||||
---
|
||||
|
||||
*Stand: technische Analyse des Repos; zur Abstimmung mit Game-Design und Deployment des Daemons.*
|
||||
Reference in New Issue
Block a user