Refactor Falukant certificate management: Consolidated certificate logic into the FalukantFamilyWorker's daily processing, removing the separate FalukantCertificateWorker. Updated SQL queries to include app_user_id and enhanced documentation for clarity on certificate scoring and daily recalculation logic.
This commit is contained in:
40
docs/FALUKANT_DIRECTOR_PRODUCTION_COST.md
Normal file
40
docs/FALUKANT_DIRECTOR_PRODUCTION_COST.md
Normal file
@@ -0,0 +1,40 @@
|
||||
# Director: Stückkosten Produktion (Balancing)
|
||||
|
||||
## Problem
|
||||
|
||||
Die DB wählt das „beste“ Produkt über `QUERY_GET_BEST_PRODUCTION` (Worth-Formel mit `- 6 * ftp.category`), während der Daemon früher **nur** `certificate * 6` pro Stück abgebucht hat – **ohne** die Produktklasse. Dadurch konnten Stückkosten und Worth-Ranking auseinanderlaufen.
|
||||
|
||||
## Aktuelle Formel (Rust, `DirectorWorker::calc_one_piece_cost`)
|
||||
|
||||
```
|
||||
raw = certificate × PRODUCTION_COST_PER_CERT_LEVEL
|
||||
+ product_category × PRODUCTION_COST_PER_PRODUCT_CATEGORY
|
||||
effektiv = raw × (1 − headroom_discount)
|
||||
```
|
||||
|
||||
- `product_category` kommt aus `QUERY_GET_BEST_PRODUCTION` (`ftp.category`).
|
||||
- **Headroom** = `max(0, certificate − product_category)`
|
||||
Wenn du **nicht** am Klassenlimit produzierst (Zertifikat höher als nötig für das Produkt), gibt es einen kleinen Rabatt (Effizienz / Reserve).
|
||||
|
||||
Konstanten in `src/worker/director.rs` (anpassen zum Feintuning):
|
||||
|
||||
| Konstante | Standard | Bedeutung |
|
||||
|-----------|----------|-----------|
|
||||
| `PRODUCTION_COST_PER_CERT_LEVEL` | `6.0` | wie früher `×6` pro Zertifikatsstufe |
|
||||
| `PRODUCTION_COST_PER_PRODUCT_CATEGORY` | `1.0` | Material pro Produktklasse |
|
||||
| `PRODUCTION_HEADROOM_DISCOUNT_PER_STEP` | `0.035` | Rabatt pro Headroom-Stufe |
|
||||
| `PRODUCTION_HEADROOM_DISCOUNT_CAP` | `0.14` | maximaler Gesamtrabatt |
|
||||
|
||||
## Spielerfortschritt
|
||||
|
||||
- **Höheres Zertifikat** allein erhöht die Basis-Stückkosten linear – entspricht **besserer** Produktpalette (`ftp.category <= certificate` in SQL).
|
||||
- **Höhere Produktklasse** erhöht `raw` über `product_category` (bessere Ware = mehr Material).
|
||||
- **Zertifikat über der Produktklasse** (Headroom) senkt die effektiven Kosten – Belohnung, wenn du nicht immer nur am Limit produzierst.
|
||||
|
||||
## Worth in SQL
|
||||
|
||||
Die Worth-Zeile in `QUERY_GET_BEST_PRODUCTION` sollte bei größeren Formeländerungen **mit** angepasst werden, damit der Director weiterhin sinnvoll sortiert.
|
||||
|
||||
## Parallelproduktionen
|
||||
|
||||
`MAX_PARALLEL_PRODUCTIONS` (aktuell 2) bestimmt, wie viele Linien pro Tick Geld binden – unabhängig von der Stückkostenformel; bei Liquiditätsproblemen ggf. auf `1` setzen.
|
||||
@@ -1,18 +1,20 @@
|
||||
# Falukant: Produktionszertifikate (Daemon)
|
||||
|
||||
Der **`FalukantCertificateWorker`** berechnet einmal täglich die Zielstufe und schreibt `falukant_user.certificate` fort (max. **+1** pro Tag, keine normale Herabstufung).
|
||||
Die Zertifikatslogik läuft **ausschließlich im Daily-Tick** von `FalukantFamilyWorker` (`process_daily`, 24h), nicht in einem eigenen Worker-Thread. Sie schreibt `falukant_user.certificate` fort (max. **+1** pro Tag, keine normale Herabstufung).
|
||||
|
||||
Implementierung: `src/worker/falukant_certificate.rs` (`run_daily`).
|
||||
|
||||
## SQL
|
||||
|
||||
- `QUERY_GET_PRODUCTION_CERTIFICATE_INPUT_ROWS` – Eingangsdaten je Falukant-User (Spielercharakter, Wissen, Produktionen, Ämter, Haus …)
|
||||
- `QUERY_UPDATE_FALUKANT_USER_CERTIFICATE` – Update der Stufe
|
||||
|
||||
## Logik (Kurz)
|
||||
## Logik (Kurz, Spec §4)
|
||||
|
||||
- `certificateScore` aus gewichteten Punktwerten (Wissen, Produktion, Amt, Adel, Ruf, Haus)
|
||||
- `raw_target` aus Score-Schwellen (1.2 / 2.1 / 3.0 / 4.0)
|
||||
- `effective_target` mit Mindestanforderungen je Stufe (Spec §4.5)
|
||||
- Aufstieg nur wenn `effective_target > current` → **`current + 1`** (gegen `effective_target` begrenzt)
|
||||
- **certificateScore** (Gewichte): Wissen 0,45 · Produktion 0,30 · Amt 0,08 · Adel 0,05 · Ruf 0,07 · Haus 0,05
|
||||
- **raw_target** aus Score-Schwellen: **<0,9** → 1, **≥0,9** → 2, **≥1,8** → 3, **≥2,8** → 4, **≥3,8** → 5
|
||||
- **effective_target** mit Mindestanforderungen je Stufe (Spec §4.5)
|
||||
- Aufstieg nur wenn `effective_target > current` → **`current + 1`** (gegen `effective_target` und 5 begrenzt)
|
||||
- **Bankrott** (`money <= -5000`): Zertifikat auf **1**, mit Event
|
||||
|
||||
## Politische Ämter
|
||||
@@ -25,7 +27,7 @@ Rang aus **`political_office_type.name`** (Substring-Heuristik im Daemon, ohne D
|
||||
|
||||
## Abgeschlossene Produktionen
|
||||
|
||||
**`COUNT(*)`** aus `falukant_log.production` mit `producer_id = falukant_user.id` (Zeilen = aggregierte Log-Einträge).
|
||||
**`COUNT(*)`** aus `falukant_log.production` mit `producer_id = falukant_user.id`.
|
||||
|
||||
## Events (WebSocket)
|
||||
|
||||
@@ -34,6 +36,8 @@ Bei Änderung der Stufe:
|
||||
1. `falukantUpdateProductionCertificate` mit `reason: "daily_recalculation"`, `old_certificate`, `new_certificate`
|
||||
2. `falukantUpdateStatus`
|
||||
|
||||
`user_id` in den Events: **`app_user_id`** aus der Query (`COALESCE(fu.user_id, fu.id)`), sonst Fallback `falukant_user_id`.
|
||||
|
||||
## Nicht umgesetzt (optional / später)
|
||||
|
||||
- **Tod ohne Erben** / Zertifikats-Reset
|
||||
|
||||
Reference in New Issue
Block a user