Per-Sim leistung_pct: alle 14 Sims senden das eine Leistungs-% (0-100)

Jede Sim liefert jetzt selbst leistung_pct in GGS_LIVE_STATE UND im Submit
(Fundament fuer das einheitliche %-System) — kein Rueckrechnen aus Sternen
mehr, keine 0-3-Sonderfaelle. Formeln je Sim wie vereinbart:
- klima/fluss/kofferdetektiv/heli: = vorhandener 0-100-score
- weltkueche: richtige/(richtige+falsche)*100 (Fehler in %)
- busfahrt/fluggesellschaft: topoPunkte/(Auftraege*3)*100
- farmer: gewichteter totalScore; energiemanager: ausgegl./gesamt -15/Blackout
- eu-werkstatt: firstTry/Schritte -5/Muelleimer; sonnensystem: Erstversuch-Quote
- tourismustal: Ziele+Zufriedenheit+Natur gewichtet; tourismusregion: gewichteter score
- logistik: Kontostand->% (sendet erstmals eine Kennzahl, auch an /api/assessment)
Teacher _leistungPct + live.php extractScore bevorzugen bereits diesen Wert.
Additive Aenderungen, bestehende Logik/Sterne unveraendert; alle 15 Dateien
syntaktisch geprueft.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
2026-08-25 12:35:56 +02:00
parent 539f6b012e
commit 88e3c09e5c
15 changed files with 116 additions and 0 deletions
+22
View File
@@ -270,6 +270,26 @@ function pumpCards() {
// Wird vom live-client.js alle ~4 s an /api/live gesendet.
window.GGS_LIVE_STATE = function () {
if (!state) return null;
// Einheitliche Leistungskennzahl: gewichteter Score live (gleiche Formel wie finish()),
// Fallback avgStars/5*100, falls Teil-Stats fehlen.
const _avg = currentAvg(state);
let _leistung_pct;
try {
const _st = state.stats;
const _nonCar = _st.transports.foot + _st.transports.bike + _st.transports.bus;
const _totalSp = Math.max(1, _st.spawned);
let _lenkung = (_nonCar / _totalSp) * 100;
if (state.buildings.some(b => b.type === 'bushaltestelle')) _lenkung = Math.min(100, _lenkung + 10);
const _scoreLive = (_avg / 5) * 100 * 0.35
+ Math.min(100, (state.revenueTotal / 2500) * 100) * 0.25
+ state.env * 0.20
+ _lenkung * 0.10
+ (state.budget >= 0 ? 100 : Math.max(0, 100 * (1 + state.budget / 1000))) * 0.10;
_leistung_pct = Math.round(_scoreLive);
} catch (_) {
_leistung_pct = Math.round((_avg / 5) * 100);
}
_leistung_pct = Math.max(0, Math.min(100, _leistung_pct));
return {
scenarioId: state.map?.id, // Karten-Key = Lektions-Gruppierung
mapId: state.map?.id,
@@ -286,6 +306,7 @@ window.GGS_LIVE_STATE = function () {
goalsDone: GOALS.filter(g => g.check(state)).length,
goalsTotal: GOALS.length,
ended: !!state.ended,
leistung_pct: _leistung_pct,
};
};
@@ -311,6 +332,7 @@ function submitAssessment() {
level: state.map?.id,
stars: Math.max(0, Math.min(5, Math.round(r.avgStars))),
score: r.score,
leistung_pct: Math.max(0, Math.min(100, Math.round(r.score))),
duration_ms: Date.now() - (state._startedAt || Date.now()),
completed: goalsDone === r.goals.length,
results: {