Enhance Falukant family dynamics: Updated the FalukantFamilyWorker to incorporate marriage buffs and detailed age rules for relationships. Added new WebSocket events for real-time updates and expanded SQL queries to support marriage state and buff management, improving overall family interaction and satisfaction tracking.

This commit is contained in:
Torsten Schulz (local)
2026-03-20 11:02:28 +01:00
parent 6a5ff4557e
commit ac5ec3a245
5 changed files with 547 additions and 62 deletions

View File

@@ -17,7 +17,52 @@ Technische Abstimmung mit dem Übergabedokument im Backend-Projekt (`FALUKANT_LO
**Hinweis:** Der Worker nutzt weiterhin **Wandzeit** (24 h / 30 Tage) als Intervall; die Idempotenz über die Zeitstempel verhindert Doppelverarbeitung bei Neustarts am selben Tag/Monat.
## WebSocket-Events (UI)
Pro betroffener `falukant_user.id` werden über den **MessageBroker** (Broadcast an alle WS-Clients) gesendet:
| Event | Payload (Beispiel) | Wann |
|-------|-------------------|------|
| `falukantUpdateFamily` | `{"event":"falukantUpdateFamily","user_id":N,"reason":"…"}` | Familie/Liebe relevant |
| `falukantUpdateStatus` | `{"event":"falukantUpdateStatus","user_id":N}` | Immer gleich mit `falukantUpdateFamily` (Refresh) |
| `children_update` | `{"event":"children_update","user_id":N}` | Kind aus Liebschaft |
| `falukant_family_scandal_hint` | `{"event":"falukant_family_scandal_hint","relationship_id":…}` | Skandal (ohne `user_id`) |
**`reason`** bei `falukantUpdateFamily`: `daily`, `monthly`, `scandal`, `lover_birth`.
Die UI kann auf `falukantUpdateFamily` filtern und nach `reason` unterscheiden; `falukantUpdateStatus` wie bisher für allgemeinen Daten-Refresh nutzen.
**Detaillierte UI-Anleitung (Payloads, Handler, Checkliste):** [`FALUKANT_UI_WEBSOCKET.md`](./FALUKANT_UI_WEBSOCKET.md)
## Altersregeln (Spec-Erweiterung, im Daemon umgesetzt)
`min_age_years` = jüngeres Alter beider Partner in **ganzen Jahren** (`LEAST(…/365, …/365)` aus `birthdate`).
| Bereich | Ansehen (zusätzl. zur Basisformel, Spec 5a) | Ehezufriedenheit (Spec §3 neg.) | Skandalrisiko (+ %, exkl. Stufen) |
|---------|---------------------------------------------|----------------------------------|-----------------------------------|
| ≤ 13 | 1,5 / Tag | 1 / Tag bei aktiver Berührung | +6 % |
| ≤ 15 | 0,8 / Tag | 1 / Tag (zusätzlich zu anderen Malus) | +3 % |
| ≤ 17 | 0,3 / Tag | — | +1 % |
| ≥ 18 | 0 | — | 0 |
Zusätzlich: wenn `min_age_years ≤ 15` **und** `visibility ≥ 50`: weiterer Ansehens-Malus **0,5** / Tag.
Ehe-Malus „≤ 15“ gilt pro Ehe, wenn **irgendeine** berührende Liebschaft dieses Altersprofils hat.
## Migrationen
1. `migrations/001_falukant_family_lovers.sql`
2. Optional: `migrations/002_falukant_family_rename_legacy_columns.sql` bei Altbestand
3. `migrations/003_falukant_family_marriage_buffs.sql` — Ehe-Buffs (`marriage_gift_buff_days_remaining`, `marriage_pending_feast_bonus`, `marriage_house_supply`, `marriage_no_lover_bonus_counter`); Daily-Tick schreibt Zufriedenheit + Zähler via `QUERY_UPDATE_MARRIAGE_STATE_AND_BUFFS`.
### Ehe-Buffs (Daemon)
- **Geschenk:** Backend setzt `marriage_gift_buff_days_remaining` (z. B. 5); Daemon **+1** Zufriedenheit/Tag, Zähler 1.
- **Fest:** `marriage_pending_feast_bonus` einmalig (typ. +2…+5, max. 5 pro Tick) beim Daily verbrauchen.
- **Haus:** `marriage_house_supply ≥ 65` und **keine** berührende Liebschaft: alle **4** Tage **+1** Zufriedenheit (`marriage_no_lover_bonus_counter`).
### Ansehen (Daily)
- **Ranggruppe 3:** Reputations-Multiplikator **0,7** nur bei „geordneter“ Liebschaft (`order_ok`: u. a. Unterhalt ≥ 65, Diskretion ≥ 60, Sichtbarkeit ≤ 35, höchstens eine Mätresse im Umfeld des Paares); sonst **1,0**; bei Skandal **1,5**.
- **Zwei sichtbare Liebschaften** (`visibility ≥ 60`, mindestens zwei Beziehungen pro Charakter): zusätzlich **4** Ansehen (einmal pro Person/Tag).
- **Zufall:** selten **Gerücht 3** oder **Tadel 5** (niedrige Wahrscheinlichkeit) für Charaktere mit Liebschaftsbezug.

View File

@@ -0,0 +1,160 @@
# Falukant: UI-Anpassung WebSocket & Familie / Liebschaften
Dieses Dokument beschreibt die **Nachrichten**, die der **YpDaemon** (`FalukantFamilyWorker`) über den WebSocket-Broadcast sendet, damit die **UI gezielt** reagieren kann (Refresh, Toasts, Family-Ansicht).
> **Transport:** Alle Clients erhalten denselben Broadcast. Die UI sollte Nachrichten **nach `user_id` filtern** (nur Events anzeigen/verarbeiten, die zur eingeloggten Session passen).
---
## 1. Übersicht der Events
| `event` | Pflichtfelder | Typische UI-Reaktion |
|---------|----------------|----------------------|
| `falukantUpdateFamily` | `user_id`, `reason` | Gezielter Refresh Familie/Liebe/Geld je nach `reason` |
| `falukantUpdateStatus` | `user_id` | Allgemeiner Status-/Spielstand-Refresh (wie bisher) |
| `children_update` | `user_id` | Kinderliste / FamilyView aktualisieren |
| `falukant_family_scandal_hint` | `relationship_id` | Optional: Toast, Log **kein** `user_id` (siehe unten) |
---
## 2. JSON-Payloads (exakt)
### 2.1 `falukantUpdateFamily`
```json
{
"event": "falukantUpdateFamily",
"user_id": 123,
"reason": "daily"
}
```
**`reason`** ist immer einer der folgenden **festen** Strings:
| `reason` | Bedeutung (Daemon) | Empfehlung UI |
|----------|---------------------|---------------|
| `daily` | Daily-Tick: Liebschafts-/Ehe-/Ansehens-Logik für den Tag | Family-API + ggf. Charakter/Ansehen neu laden |
| `monthly` | Monthly-Tick: Kosten, Unterversorgung, Monatsstand | **Geld** (`falukant_user.money`) + Family-State neu laden |
| `scandal` | Skandal-Ereignis (zusätzlich zu `daily` möglich) | Kurzer Hinweis / Eintrag „Skandal“; Family + Ruf |
| `lover_birth` | Uneheliches Kind angelegt | Wie `children_update`, plus Eltern-Story |
### 2.2 `falukantUpdateStatus`
```json
{
"event": "falukantUpdateStatus",
"user_id": 123
}
```
Kommt **typischerweise direkt nach** `falukantUpdateFamily` mit derselben `user_id` (gemeinsamer Refresh).
### 2.3 `children_update`
```json
{
"event": "children_update",
"user_id": 123
}
```
Tritt bei **Geburt aus Liebschaft** auf; oft zusammen mit `falukantUpdateFamily` (`reason: lover_birth`) und `falukantUpdateStatus`.
### 2.4 `falukant_family_scandal_hint`
```json
{
"event": "falukant_family_scandal_hint",
"relationship_id": 456
}
```
- **Kein** `user_id` Betroffene erkennst du nur über die **Beziehung** (Backend: `relationship.id` → Charaktere laden) oder du ignorierst das Event und verlässt dich auf `falukantUpdateFamily` mit `reason: scandal` für deine Nutzer.
---
## 3. Empfohlene Handler-Logik (Pseudo)
```text
onMessage(json):
if json.user_id != currentUserId: return // Broadcast filtern
switch json.event:
case "falukantUpdateStatus":
refreshPlayerStatus() // bestehend
return
case "children_update":
refreshChildrenAndFamilyView()
return
case "falukantUpdateFamily":
switch json.reason:
case "daily":
refreshFamilyAndRelationships()
refreshCharactersReputationIfNeeded()
break
case "monthly":
refreshMoney()
refreshFamilyAndRelationships()
break
case "scandal":
showScandalToastOptional()
refreshFamilyAndRelationships()
break
case "lover_birth":
refreshChildrenAndFamilyView()
break
return
case "falukant_family_scandal_hint":
// optional: relationship_id → Detail-Modal / Log
return
```
**Hinweis:** Am selben Tag kann ein Nutzer **`scandal`** und danach **`daily`** erhalten UI kann **deduplizieren** (z. B. nur ein voller Refresh) oder beide verarbeiten (idempotente API-Calls).
---
## 4. Welche Backend-Daten neu laden?
| Situation | Sinnvolle Endpunkte / Daten (konzeptionell) |
|-----------|---------------------------------------------|
| Jede `falukantUpdateFamily` | Family-/Relationship-API mit `relationship_state`, Ehe (`married`/`engaged`/`wooing`) |
| `reason: monthly` | **Geld** des Users, ggf. Kredit/Log |
| `reason: daily` / `scandal` | Ansehen (`character.reputation`), Sichtbarkeit/Diskretion der Liebschaften |
| `children_update` / `lover_birth` | `child_relation` inkl. `legitimacy`, `birth_context`, `public_known` |
Konkrete Routen stehen im **YourPart3**-Backend; das Frontend sollte eine zentrale Funktion `refreshFamilyContext(userId)` kapseln.
---
## 5. Sonderfälle
| Fall | Verhalten |
|------|-----------|
| Charakter ohne `user_id` (NPC) | **Keine** Socket-Events für diesen Charakter nur Spieler mit `falukant_user` erhalten `user_id`-Events. |
| Mehrere Events hintereinander | Normal; Requests sollten **idempotent** sein (mehrfaches Laden ok). |
| Nur `falukantUpdateStatus` ohne Family | Kann von **anderen** Workern kommen nicht nur Familie. |
---
## 6. Bezug zum Code (YpDaemon)
- Worker: `src/worker/falukant_family.rs`
- SQL-Konstanten: `src/worker/sql.rs` (Abschnitt Falukant Familie)
- Schema: `migrations/001_falukant_family_lovers.sql`
- Daemon-Handoff (technisch): `docs/FALUKANT_DAEMON_HANDOFF.md`
---
## 7. Checkliste UI-Integration
- [ ] WebSocket-Handler: `user_id` mit Session abgleichen
- [ ] Auf `falukantUpdateFamily` reagieren und **`reason`** auswerten
- [ ] `falukantUpdateStatus` weiter nutzen (globaler Refresh)
- [ ] `children_update` + `lover_birth`: Kinder-Ansicht
- [ ] Optional: `falukant_family_scandal_hint` mit `relationship_id`
- [ ] Optional: Deduplizierung bei `scandal` + `daily` am selben Tag
Damit kannst du die Oberfläche **gezielt** an die Daemon-Events anbinden, ohne jedes Mal den vollen Spielstand blind zu aktualisieren.