Files
yourpart3/backend/docs/falukant-character-development.md
Torsten Schulz (local) 6e31a114cf
All checks were successful
Deploy to production / deploy (push) Successful in 2m41s
Entkopple Partnersuche vom Altersabstand und entferne garantierte Schwangerschaften
2026-11-04 15:09:49 +01:00

6.1 KiB

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 und der Endocrine Society zur zeitlichen Entwicklung.

Spielregeln und API

Die Werbung bzw. Partnersuche beginnt ab 10, die Heiratsgrenze bleibt unabhängig davon bei 14 Spieljahren für beide Verlobten. Partnervorschläge haben keine Altersabstandsgrenze und keine Altersobergrenze. Bis zu fünf Kandidaten werden zufällig aus der passenden Region und Titelgruppe ausgewählt; ein ähnliches Alter und das Erstellungsdatum des Charakters sind keine Auswahlkriterien.

Automatische Schwangerschaften in bestehenden Ehen, Verlobungen und Liebschaften 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 für Ehen, Verlobungen und sämtliche Liebschaftsrollen einheitlich 50 Prozent pro regulärer Fertilitätsprüfung. Es gibt keine rollen-, zuneigungs- oder sichtbarkeitsabhängigen Chancenboni. Die Voraussetzungen für eine Prüfung gelten weiterhin. Schwangerschaftsdauer und Sperren gegen parallele Schwangerschaften entsprechen dem bestehenden Weg.

Liebschaften und Verlobungen werden nur im Jahres-/Abrechnungslauf geprüft, nicht zusätzlich im Tageslauf. Der garantierte Backend-Sonderweg nach einer Hochzeit entfällt; das Aufrufen der Familienseite plant keine Schwangerschaft. Bereits geplante Schwangerschaften und frühere Hochzeitsflags bleiben erhalten.

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. 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

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.