448 lines
9.5 KiB
Markdown
448 lines
9.5 KiB
Markdown
# Falukant: Schuldturm und Pfändung - Daemon-Spezifikation
|
|
|
|
Dieses Dokument beschreibt die Umsetzung des **Schuldturm-Systems** im externen Daemon.
|
|
|
|
Wichtig:
|
|
|
|
- Die projektseitigen DB-Felder, API-Erweiterungen, UI-Warnungen und Aktionssperren sind bereits umgesetzt.
|
|
- Der Daemon ist die führende Quelle für:
|
|
- Verzugstage
|
|
- Eintritt in den Schuldturm
|
|
- Pfändung und Verwertung
|
|
- soziale Folgen
|
|
- Freilassung
|
|
|
|
## 1. Bereits vorhandene Datenbasis
|
|
|
|
Bereits im Projekt vorhanden:
|
|
|
|
- `falukant_data.credit`
|
|
- `falukant_data.debtors_prism`
|
|
- `falukant_data.user_house`
|
|
- inkl. `household_tension_score`
|
|
- inkl. `household_tension_reasons_json`
|
|
- Familien-/Liebschaftsdaten in:
|
|
- `falukant_data.relationship`
|
|
- `falukant_data.relationship_state`
|
|
- `falukant_data.child_relation`
|
|
|
|
Bereits erweitert:
|
|
|
|
- `debtors_prism.status`
|
|
- `debtors_prism.entered_at`
|
|
- `debtors_prism.released_at`
|
|
- `debtors_prism.debt_at_entry`
|
|
- `debtors_prism.remaining_debt`
|
|
- `debtors_prism.days_overdue`
|
|
- `debtors_prism.reason`
|
|
- `debtors_prism.creditworthiness_penalty`
|
|
- `debtors_prism.next_forced_action`
|
|
- `debtors_prism.assets_seized_json`
|
|
- `debtors_prism.public_known`
|
|
|
|
Es sind für den Daemon derzeit keine weiteren DB-Änderungen nötig.
|
|
|
|
## 2. Grundregel
|
|
|
|
Ein Charakter kommt in den Schuldturm, wenn:
|
|
|
|
- mindestens ein aktiver Kredit offen ist
|
|
- fällige Kreditbedienung ausbleibt
|
|
- und `days_overdue >= 3`
|
|
|
|
Der Daemon prüft dies im Daily-Tick.
|
|
|
|
## 3. Zustände
|
|
|
|
`debtors_prism.status` verwendet mindestens:
|
|
|
|
- `delinquent`
|
|
- `imprisoned`
|
|
- `released`
|
|
|
|
Bedeutung:
|
|
|
|
- `delinquent`: Kreditverzug, aber noch nicht im Schuldturm
|
|
- `imprisoned`: im Schuldturm, Verwertung läuft
|
|
- `released`: historischer abgeschlossener Fall
|
|
|
|
## 4. Daily-Tick
|
|
|
|
Der Daily-Tick prüft pro Falukant-Nutzer:
|
|
|
|
1. aktive Kredite
|
|
2. verbleibende Schuld
|
|
3. geleistete Bedienung seit letztem Tick
|
|
4. neue Verzugstage
|
|
5. Schuldturm-Eintritt
|
|
6. laufende soziale Folgen
|
|
7. Verwertungsschritt
|
|
|
|
### 4.1 Verzugstage
|
|
|
|
Regel:
|
|
|
|
- wenn offene Schuld vorhanden und fällige Bedienung ausbleibt:
|
|
- `days_overdue += 1`
|
|
- wenn Kreditpflicht erfüllt wurde:
|
|
- `days_overdue = 0`
|
|
- falls nicht im Schuldturm
|
|
|
|
Wenn noch kein aktiver `debtors_prism`-Eintrag existiert:
|
|
|
|
- bei erstem Verzug `debtors_prism` anlegen mit
|
|
- `status = 'delinquent'`
|
|
- `days_overdue = 1`
|
|
- `remaining_debt = aktuelle offene Schuld`
|
|
- `next_forced_action = 'reminder'`
|
|
|
|
### 4.2 Warnstufen
|
|
|
|
Bei Verzug:
|
|
|
|
- Tag 1:
|
|
- `next_forced_action = 'reminder'`
|
|
- Event `falukantUpdateDebt` mit `reason: 'delinquency'`
|
|
- Tag 2:
|
|
- `next_forced_action = 'final_warning'`
|
|
- Event `falukantUpdateDebt` mit `reason: 'delinquency'`
|
|
- Tag 3:
|
|
- Schuldturm-Eintritt
|
|
|
|
Für Warnstufen senden:
|
|
|
|
- `falukantUpdateDebt`
|
|
- zusätzlich `falukantUpdateStatus`
|
|
|
|
## 5. Eintritt in den Schuldturm
|
|
|
|
Bei `days_overdue >= 3`:
|
|
|
|
- `status = 'imprisoned'`
|
|
- `entered_at = now()`
|
|
- `released_at = null`
|
|
- `debt_at_entry = aktuelle offene Schuld`
|
|
- `remaining_debt = aktuelle offene Schuld`
|
|
- `reason = 'credit_default'`
|
|
- `creditworthiness_penalty += 45`
|
|
- `next_forced_action = 'asset_seizure'`
|
|
- `public_known = true`
|
|
|
|
### 5.1 Sofortfolgen bei Eintritt
|
|
|
|
Einmalig anwenden:
|
|
|
|
- Reputation deutlich senken
|
|
- Empfehlung: `-12`
|
|
- `marriage_satisfaction` senken
|
|
- Empfehlung: `-10`
|
|
- `household_tension_score` erhöhen
|
|
- Empfehlung: `+15`
|
|
- `household_tension_reasons_json` um `debtorsPrison` ergänzen
|
|
|
|
Zusätzlich:
|
|
|
|
- aktive Liebhaber/Mätressen sichtbar destabilisieren
|
|
- mindestens `affection -= 4`
|
|
- Kreditaufnahme und aktive Falukant-Aktionen bleiben projektseitig bereits gesperrt
|
|
|
|
Bei Eintritt senden:
|
|
|
|
- `falukantUpdateDebt`
|
|
- `reason: 'debtors_prison_entered'`
|
|
- `falukantUpdateStatus`
|
|
- `falukantUpdateFamily`
|
|
- `reason: 'daily'`
|
|
- `falukantHouseUpdate`
|
|
- `falukantBranchUpdate`
|
|
|
|
## 6. Verwertung / Pfändung
|
|
|
|
Die Verwertung läuft nicht alles auf einmal, sondern schrittweise pro Tick.
|
|
|
|
Reihenfolge:
|
|
|
|
1. freies Geld
|
|
2. Fahrzeuge
|
|
3. Waren / Lagerbestände
|
|
4. Haus
|
|
5. Niederlassungen
|
|
|
|
Ziel:
|
|
|
|
- `remaining_debt` schrittweise senken
|
|
- Fortschritt im UI sichtbar machen
|
|
|
|
### 6.1 Geld
|
|
|
|
Wenn `falukant_user.money > 0`:
|
|
|
|
- direkt zur Schuld tilgen
|
|
- `remaining_debt -= eingezogener_betrag`
|
|
|
|
Events:
|
|
|
|
- `falukantUpdateDebt`
|
|
- `reason: 'asset_seizure'`
|
|
- `falukantUpdateStatus`
|
|
|
|
### 6.2 Fahrzeuge
|
|
|
|
Verkaufe zuerst:
|
|
|
|
- freie Fahrzeuge
|
|
- dann weniger wertvolle Typen
|
|
- keine Fahrzeuge in aktiven Transporten im selben Tick anfassen, falls technisch problematisch
|
|
|
|
Erlös:
|
|
|
|
- Empfehlung: `vehicle_type.cost * condition_factor * 0.55`
|
|
|
|
Zusätzlich in `assets_seized_json` protokollieren:
|
|
|
|
- Typ
|
|
- Anzahl
|
|
- Erlös
|
|
|
|
Events:
|
|
|
|
- `falukantUpdateDebt`
|
|
- `reason: 'vehicle_liquidation'`
|
|
- `falukantUpdateStatus`
|
|
|
|
### 6.3 Waren / Lager
|
|
|
|
Verwertbare Güter:
|
|
|
|
- Lagerbestände
|
|
- Inventar
|
|
- handelbare Waren
|
|
|
|
Erlös:
|
|
|
|
- Empfehlung: Marktwert mit Abschlag von `35% bis 50%`
|
|
|
|
Events:
|
|
|
|
- `falukantUpdateDebt`
|
|
- `reason: 'asset_seizure'`
|
|
- `falukantUpdateStatus`
|
|
- `falukantBranchUpdate`
|
|
|
|
### 6.4 Haus
|
|
|
|
Wenn Restschuld nach Geld/Fahrzeugen/Waren weiter hoch ist:
|
|
|
|
- Haus pfänden
|
|
- Spieler auf niedrigeres Haus oder Minimalhaus zurücksetzen
|
|
- Dienerschaft reduzieren
|
|
- `household_order` senken
|
|
|
|
Events:
|
|
|
|
- `falukantUpdateDebt`
|
|
- `reason: 'house_seizure'`
|
|
- `falukantHouseUpdate`
|
|
- `falukantUpdateStatus`
|
|
- `falukantUpdateFamily`
|
|
- `reason: 'daily'`
|
|
|
|
### 6.5 Niederlassungen
|
|
|
|
Wenn weiter nicht gedeckt:
|
|
|
|
- Niederlassungen schließen
|
|
- zuerst niedrige Stufe / niedriger Wert
|
|
- Hauptniederlassung nur als letzter Schritt
|
|
|
|
Events:
|
|
|
|
- `falukantUpdateDebt`
|
|
- `reason: 'branch_closure'`
|
|
- `falukantBranchUpdate`
|
|
- `falukantUpdateStatus`
|
|
|
|
## 7. Laufende soziale Folgen im Schuldturm
|
|
|
|
Solange `status = 'imprisoned'`:
|
|
|
|
- täglicher Reputationsmalus
|
|
- Empfehlung: `-2`
|
|
- zusätzliche `creditworthiness_penalty += 1` pro Tag
|
|
- `marriage_satisfaction -= 1`
|
|
- `household_tension_score += 2`
|
|
|
|
Wenn aktive Liebschaften bestehen:
|
|
|
|
- `affection -= 2`
|
|
- bei niedriger Zuneigung oder hoher Sichtbarkeit kann Beziehung enden
|
|
|
|
Empfohlene Absprungregel:
|
|
|
|
- wenn `affection <= 30` oder `months_underfunded >= 2`
|
|
- Chance auf Beziehungsende prüfen
|
|
- bei repräsentativen Beziehungen zusätzlich höhere Absprungchance, wenn `public_known = true`
|
|
|
|
Events bei sozialen Folgewirkungen:
|
|
|
|
- `falukantUpdateFamily`
|
|
- `reason: 'daily'`
|
|
- zusätzlich `falukantUpdateStatus`
|
|
|
|
## 8. Kreditwürdigkeit
|
|
|
|
Die UI rechnet bereits aus `creditworthiness_penalty` und Status einen sichtbaren Wert.
|
|
|
|
Der Daemon muss pflegen:
|
|
|
|
- `creditworthiness_penalty`
|
|
- `status`
|
|
- `days_overdue`
|
|
|
|
Empfehlung:
|
|
|
|
- Eintritt Schuldturm: `+45`
|
|
- pro weiterem Hafttag: `+1`
|
|
- Hauspfändung: zusätzlich `+10`
|
|
- Niederlassungsschließung: zusätzlich `+8`
|
|
|
|
## 9. Freilassung
|
|
|
|
Freilassung, wenn:
|
|
|
|
- keine relevante Restschuld mehr offen ist
|
|
oder
|
|
- ein definierter Restwert unterschritten wird, falls ihr einen Bagatellgrenzwert wollt
|
|
|
|
Dann:
|
|
|
|
- `status = 'released'`
|
|
- `released_at = now()`
|
|
- `next_forced_action = null`
|
|
- `days_overdue = 0`
|
|
- `remaining_debt = 0`
|
|
|
|
Events:
|
|
|
|
- `falukantUpdateDebt`
|
|
- `reason: 'debtors_prison_released'`
|
|
- `falukantUpdateStatus`
|
|
- `falukantUpdateFamily`
|
|
- `reason: 'daily'`
|
|
- `falukantHouseUpdate`
|
|
- `falukantBranchUpdate`
|
|
|
|
Keine automatische vollständige soziale Heilung:
|
|
|
|
- Reputation bleibt reduziert
|
|
- Kreditwürdigkeit bleibt reduziert
|
|
- Familie/Haus bleiben in Folgezuständen
|
|
|
|
## 10. Event-Kommunikation zur UI
|
|
|
|
Der Daemon sendet als Primärevent:
|
|
|
|
```json
|
|
{
|
|
"event": "falukantUpdateDebt",
|
|
"user_id": 123,
|
|
"reason": "delinquency"
|
|
}
|
|
```
|
|
|
|
Mögliche `reason`:
|
|
|
|
- `delinquency`
|
|
- `debtors_prison_entered`
|
|
- `asset_seizure`
|
|
- `vehicle_liquidation`
|
|
- `house_seizure`
|
|
- `branch_closure`
|
|
- `debtors_prison_released`
|
|
|
|
### 10.1 Begleitevents
|
|
|
|
Je nach Folge zusätzlich:
|
|
|
|
- `falukantUpdateStatus`
|
|
- `falukantHouseUpdate`
|
|
- `falukantBranchUpdate`
|
|
- `falukantUpdateFamily`
|
|
|
|
### 10.2 Empfohlene Minimalregeln
|
|
|
|
- `delinquency`:
|
|
- `falukantUpdateDebt`
|
|
- `falukantUpdateStatus`
|
|
- `debtors_prison_entered`:
|
|
- `falukantUpdateDebt`
|
|
- `falukantUpdateStatus`
|
|
- `falukantUpdateFamily`
|
|
- `falukantHouseUpdate`
|
|
- `falukantBranchUpdate`
|
|
- `asset_seizure`:
|
|
- `falukantUpdateDebt`
|
|
- `falukantUpdateStatus`
|
|
- optional `falukantBranchUpdate`
|
|
- `vehicle_liquidation`:
|
|
- `falukantUpdateDebt`
|
|
- `falukantUpdateStatus`
|
|
- `house_seizure`:
|
|
- `falukantUpdateDebt`
|
|
- `falukantUpdateStatus`
|
|
- `falukantHouseUpdate`
|
|
- `falukantUpdateFamily`
|
|
- `branch_closure`:
|
|
- `falukantUpdateDebt`
|
|
- `falukantUpdateStatus`
|
|
- `falukantBranchUpdate`
|
|
- `debtors_prison_released`:
|
|
- `falukantUpdateDebt`
|
|
- `falukantUpdateStatus`
|
|
- `falukantUpdateFamily`
|
|
- `falukantHouseUpdate`
|
|
- `falukantBranchUpdate`
|
|
|
|
## 11. Idempotenz
|
|
|
|
Der Worker muss idempotent arbeiten.
|
|
|
|
Wichtig:
|
|
|
|
- Eintritt in den Schuldturm nicht mehrfach für denselben aktiven Fall auslösen
|
|
- Verwertungsschritte nur einmal je Asset anwenden
|
|
- `released` nicht erneut freisetzen
|
|
|
|
Empfehlung:
|
|
|
|
- pro Tick Transaktion
|
|
- pro Nutzer eine klare Reihenfolge
|
|
- Änderungen in `assets_seized_json` protokollieren
|
|
|
|
## 12. Mindestumsetzung für Version 1
|
|
|
|
Pflicht:
|
|
|
|
1. Verzugstage pflegen
|
|
2. Eintritt nach 3 Tagen
|
|
3. Status und Penalty schreiben
|
|
4. Geld zuerst einziehen
|
|
5. danach Fahrzeuge
|
|
6. Events senden
|
|
|
|
Danach:
|
|
|
|
7. Hauspfändung
|
|
8. Niederlassungsschließung
|
|
9. volle Familienfolgen
|
|
|
|
## 13. Hinweis an den Daemon
|
|
|
|
Die projektseitigen Grundlagen sind bereits umgesetzt:
|
|
|
|
- `debtors_prism` ist erweitert
|
|
- Bank-/Haus-/Familien-/Übersichts-UI reagiert auf den Status
|
|
- aktive Falukant-Aktionen werden im Backend bereits gesperrt, sobald `inDebtorsPrison = true`
|
|
|
|
Der Daemon muss daher vor allem die Zustände und Folgen zuverlässig schreiben und die dokumentierten Events senden.
|