Files
yourpart3/backend/docs/falukant-character-development.md
Torsten Schulz (local) 0178d33a21
All checks were successful
Deploy to production / deploy (push) Successful in 2m55s
Prüfe Liebschaftskinder neben bestehenden Ehen
2026-11-04 15:05:17 +01:00

102 lines
5.5 KiB
Markdown

# Individuelle Charakterentwicklung
`character.puberty_start_age` und `character.fertile_from_age` sind dauerhaft
gespeicherte ganze Spieljahre. Ein realer Kalendertag entspricht einem Spieljahr.
Die Sequelize-Attribute heißen `pubertyStartAge` und `fertileFromAge`.
## Vergabe
Die Migration `20261104000000-add-character-development-ages.cjs` ergänzt beide
Werte für bestehende Charaktere. Ein Datenbanktrigger initialisiert sie auch für
neue Charaktere, einschließlich der direkten SQL-Inserts des Daemons für NPCs
und Neugeborene. Normale Updates, auch das Übergeben von NULL, würfeln bereits
gespeicherte Werte nicht neu aus. Explizite gültige Änderungen bleiben möglich.
Die Migration kann auch nach manueller Vorbereitung der Spalten erneut laufen:
Vorhandene Werte bleiben erhalten, fehlende Spalten und Werte werden ergänzt.
Das vereinfachte Spielmodell verwendet folgende Verteilung:
- Weibliche Charaktere: Pubertätsbeginn zwischen 8 und 13 Spieljahren.
- Männliche und sonstige Charaktere: Pubertätsbeginn zwischen 9 und 14 Spieljahren.
- Zwei gemittelte Zufallsziehungen gewichten die Mitte stärker als die Ränder.
- Fruchtbarkeitsalter: Pubertätsbeginn plus zufällig zwei oder drei Spieljahre.
Die Abstände und Wahrscheinlichkeiten sind Modellentscheidungen. Sie stellen
keine medizinische Vorhersage und keine Schätzung mittelalterlicher
Bevölkerungsdaten dar. Der Beginn der Pubertät und das Erreichen der
Fortpflanzungsfähigkeit werden als getrennte Ereignisse modelliert. Als
Orientierung für die Bandbreite dienen die Informationen des
[NHS zum Pubertätsbeginn](https://www.nhs.uk/conditions/early-or-delayed-puberty/)
und der [Endocrine Society zur zeitlichen Entwicklung](https://www.endocrine.org/patient-engagement/endocrine-library/precocious-puberty).
## Spielregeln und API
Die Heiratsgrenze bleibt unabhängig davon bei 14 Spieljahren für beide
Verlobten. Automatische Schwangerschaften in bestehenden Ehen, Verlobungen und Liebschaften
sowie der Backend-Sonderweg nach einer Hochzeit prüfen das individuelle
Fruchtbarkeitsalter beider Eltern. Verlobungen bleiben als Beziehungsstatus erhalten.
Verlobte benötigen keinen Liebschaftsunterhalt oder vorherigen Abrechnungslauf.
Die Zuneigung muss mindestens 45 betragen; bei fehlendem Beziehungszustand gilt
wie im Backend der Standardwert 50. Inaktive Beziehungen und verstorbene Partner
sind ausgeschlossen. Die Chance beträgt pro Prüfung 4 Prozent, ab Zuneigung 75
zwei Prozentpunkte mehr; hohe Sichtbarkeit bei Zuneigung unter 50 reduziert sie
um zwei Prozentpunkte. Schwangerschaftsdauer und Sperren gegen parallele
Schwangerschaften entsprechen dem bestehenden Liebschaftsweg.
Eine Geburt während der Verlobung nutzt die vorhandene Kennzeichnung für
außereheliche Kinder (`birth_context = 'lover'`, zunächst `hidden_bastard` und
nicht öffentlich bekannt). Heiratet das Paar vor der Geburt, wird das Kind über
den bestehenden Geburtsweg als ehelich erfasst. Die Schwangerschaft bleibt dabei
erhalten. Für diese Freischaltung ist keine weitere Datenbankmigration nötig.
Auch verheiratete Charaktere können mit einer Liebschaft ein Kind bekommen.
Bei einer Mutter blockiert eine bereits geplante Schwangerschaft weitere
Konzeptionen unabhängig vom Partner. Der Eheweg hat eine Chance von 72 Prozent
pro regulärer Prüfung; der Liebschaftsweg verwendet je nach Rolle und Zustand
deutlich kleinere Chancen. Liebschaften benötigen Zuneigung ab 45, Unterhalt ab
30 und einen aktuellen Abrechnungsstempel. Ein Ehepartner wird bei einer bereits
geplanten Liebschaftsschwangerschaft nicht nachträglich als Vater eingesetzt.
Auch bei Altersmalussen, Sichtbarkeit und Unterhaltsprüfungen gilt ein
Kalendertag als Spieljahr. Die drei Liebschaftsabfragen für Tageslauf,
Abrechnungsstempel und Teilzahlungen verwenden deshalb die direkte Differenz
der Kalendertage ohne Division durch 365.
Eine bereits geplante Geburt wird nicht nachträglich durch die neuen Werte
blockiert. Die Migration verändert weder Schwangerschaftstermine noch
Beziehungen. Admin-Funktionen zum expliziten Setzen von Schwangerschaften
bleiben manuelle Eingriffe.
Die Charakterdaten unter `/api/falukant/info` enthalten beide Alterswerte.
Die Familienantwort enthält für den eigenen Charakter, Partner und Kinder
zusätzlich `development` mit beiden Werten sowie `hasReachedPuberty` und
`hasReachedFertility`. Diese booleschen Werte werden beim Abruf aus dem Alter
abgeleitet. Es gibt keine Änderungen an Porträts oder 3D-Modellen.
## Bereitstellung
Zuerst die Backend-Migration ausführen, dann Backend und Daemon gemeinsam
aktualisieren bzw. neu starten. Beide Anwendungen benötigen die neuen Spalten.
Die Daemon-Anpassungen liegen im benachbarten Repository `ypdaemon`, in
`src/worker/sql.rs`. Ein Rollback muss auch die vorherigen Anwendungsversionen
wiederherstellen, bevor die neuen Spalten entfernt werden.
## Prüfung
```sh
cd backend
node --test tools/characterDevelopment.test.mjs
```
Die Datenbanktests sind ohne `TEST_DATABASE_URL` übersprungen. Mit einer
explizit angegebenen, isolierten PostgreSQL-Datenbank namens
`yourpart_development_test` prüfen sie Migration, Backfill, direkte Inserts,
stabile Werte und Rollback. Diese Tests ersetzen die Schemas `falukant_data`
und `falukant_type` ausschließlich in dieser Testdatenbank.
Wird zusätzlich `DAEMON_SQL_PATH` auf `ypdaemon/src/worker/sql.rs` gesetzt,
führen sie die tatsächlichen Daemon-Abfragen aus: beide Eltern genau an und
unter ihrer Altersgrenze, Ehe- und Liebschaftswege sowie bestehende Geburten.
Für die Prüfung der Voraussetzungen wird der Zufallswurf im Test auf null
gesetzt.