Season System #32

Closed
opened 2026-05-19 11:03:48 +02:00 by daniel · 3 comments
Owner

Die Ligen sollen ein einfaches Season System kriegen. Dass man händisch, oder nach X Tagen, eine neue Season startet. MMR und Rangliste werden zurückgesetzt. Die Stats der letzten Seasons kann man nachschauen. Und auch die Gesamt Stats. Sollte einfach filterbar sein mit einer Tabelle die per Datum die aktuellen Stats von jedem Spieler per abgelaufene Season speichert. Die aktuellen Stats laufen immer weiter.

Die Ligen sollen ein einfaches Season System kriegen. Dass man händisch, oder nach X Tagen, eine neue Season startet. MMR und Rangliste werden zurückgesetzt. Die Stats der letzten Seasons kann man nachschauen. Und auch die Gesamt Stats. Sollte einfach filterbar sein mit einer Tabelle die per Datum die aktuellen Stats von jedem Spieler per abgelaufene Season speichert. Die aktuellen Stats laufen immer weiter.
daniel added this to the Erweiterungen und Neues project 2026-05-19 11:03:48 +02:00
Author
Owner

Warhammer Liga – Season-System Zusammenfassung
Projekt-Kontext
Stack: Python, NiceGUI, MariaDB
4 Spielsysteme (z.B. 40k, Spearhead, HdR, ...) mit unterschiedlichen Season-Rhythmen
Spieler-Stats sollen nicht zurückgesetzt werden – Gesamtstatistik bleibt immer sichtbar
Datenbank-Design: Seasons
Kernprinzip: Die player_game_statistic-Tabelle wird um eine season_id-Spalte erweitert. Jede Zeile repräsentiert die Stats eines Spielers für ein Spielsystem in einer bestimmten Season. Es gibt kein Zurücksetzen – neue Season = neue Zeile pro Spieler. Gesamtstatistik wird per SQL berechnet (SUM über alle Seasons).

3 Ansichten:

Aktuelle Season → Filter auf aktuelle season_id
Vergangene Seasons → Filter auf alte season_id
Gesamt → GROUP BY player_id, gamesystem_id mit SUM(wins), SUM(loss), etc.
Tabellen
seasons – Speichert die konkreten Seasons

Spalte Typ Beschreibung
id INT (PK, AUTO_INCREMENT) Season-ID
gamesystem_id INT (FK) Verknüpft mit Spielsystem
name VARCHAR Anzeigename, z.B. "40k Season 3"
start_date DATE Startdatum der Season
end_date DATE (nullable) Enddatum, NULL = laufend
Aktuelle Season abfragen:

Sql
SELECT id FROM seasons
WHERE gamesystem_id = X
AND start_date <= CURDATE()
AND (end_date IS NULL OR end_date >= CURDATE())
ORDER BY start_date DESC LIMIT 1
season_schedule – Definiert wiederkehrende Season-Starttermine (jährlich wiederholend)

Spalte Typ Beschreibung
id INT (PK, AUTO_INCREMENT) ID
gamesystem_id INT (FK) Verknüpft mit Spielsystem
start_month INT Monat (1-12)
start_day INT Tag (1-31)
Beispieldaten:

40k: 1.6. und 1.12. (halbjährlich)
Spearhead: 1.3., 15.6., 1.10. (vierteljährlich, mit Versatz)
HdR: 1.4. und 1.10. (halbjährlich, Sommer länger)
player_game_statistic – Bestehende Tabelle, erweitert um:

Spalte Typ Beschreibung
season_id INT (FK) Verknüpft mit seasons-Tabelle
Eindeutigkeit pro Zeile: (player_id, gamesystem_id, season_id)

Cron Job (täglich, z.B. 00:01)
Prüfe season_schedule auf Treffer wo start_month = HEUTE.Monat und start_day = HEUTE.Tag
Für jeden Treffer:
Prüfe ob heute schon eine Season für dieses Spielsystem erstellt wurde:

Sql
SELECT COUNT(*) FROM seasons
WHERE gamesystem_id = X AND start_date = CURDATE()
Wenn nein: Alte Season abschließen (end_date = GESTERN) + neue Season anlegen (start_date = HEUTE, end_date = NULL)
Match eintragen – Ablauf
App fragt DB nach aktueller season_id für das Spielsystem (Datumsabfrage)
Prüft ob Zeile für (player_id, gamesystem_id, season_id) existiert
Ja → UPDATE (wins +1, etc.)
Nein → INSERT (erstes Spiel in neuer Season)
Statistik wird mit der richtigen season_id geschrieben
Gesamtstatistik – Beispielabfrage

Sql
SELECT player_id, gamesystem_id,
SUM(wins) AS total_wins,
SUM(loss) AS total_loss,
SUM(draws) AS total_draws,
SUM(games_in_system) AS total_games
FROM player_game_statistic
GROUP BY player_id, gamesystem_id

Warhammer Liga – Season-System Zusammenfassung Projekt-Kontext Stack: Python, NiceGUI, MariaDB 4 Spielsysteme (z.B. 40k, Spearhead, HdR, ...) mit unterschiedlichen Season-Rhythmen Spieler-Stats sollen nicht zurückgesetzt werden – Gesamtstatistik bleibt immer sichtbar Datenbank-Design: Seasons Kernprinzip: Die player_game_statistic-Tabelle wird um eine season_id-Spalte erweitert. Jede Zeile repräsentiert die Stats eines Spielers für ein Spielsystem in einer bestimmten Season. Es gibt kein Zurücksetzen – neue Season = neue Zeile pro Spieler. Gesamtstatistik wird per SQL berechnet (SUM über alle Seasons). 3 Ansichten: Aktuelle Season → Filter auf aktuelle season_id Vergangene Seasons → Filter auf alte season_id Gesamt → GROUP BY player_id, gamesystem_id mit SUM(wins), SUM(loss), etc. Tabellen seasons – Speichert die konkreten Seasons Spalte Typ Beschreibung id INT (PK, AUTO_INCREMENT) Season-ID gamesystem_id INT (FK) Verknüpft mit Spielsystem name VARCHAR Anzeigename, z.B. "40k Season 3" start_date DATE Startdatum der Season end_date DATE (nullable) Enddatum, NULL = laufend Aktuelle Season abfragen: Sql SELECT id FROM seasons WHERE gamesystem_id = X AND start_date <= CURDATE() AND (end_date IS NULL OR end_date >= CURDATE()) ORDER BY start_date DESC LIMIT 1 season_schedule – Definiert wiederkehrende Season-Starttermine (jährlich wiederholend) Spalte Typ Beschreibung id INT (PK, AUTO_INCREMENT) ID gamesystem_id INT (FK) Verknüpft mit Spielsystem start_month INT Monat (1-12) start_day INT Tag (1-31) Beispieldaten: 40k: 1.6. und 1.12. (halbjährlich) Spearhead: 1.3., 15.6., 1.10. (vierteljährlich, mit Versatz) HdR: 1.4. und 1.10. (halbjährlich, Sommer länger) player_game_statistic – Bestehende Tabelle, erweitert um: Spalte Typ Beschreibung season_id INT (FK) Verknüpft mit seasons-Tabelle Eindeutigkeit pro Zeile: (player_id, gamesystem_id, season_id) Cron Job (täglich, z.B. 00:01) Prüfe season_schedule auf Treffer wo start_month = HEUTE.Monat und start_day = HEUTE.Tag Für jeden Treffer: Prüfe ob heute schon eine Season für dieses Spielsystem erstellt wurde: Sql SELECT COUNT(*) FROM seasons WHERE gamesystem_id = X AND start_date = CURDATE() Wenn nein: Alte Season abschließen (end_date = GESTERN) + neue Season anlegen (start_date = HEUTE, end_date = NULL) Match eintragen – Ablauf App fragt DB nach aktueller season_id für das Spielsystem (Datumsabfrage) Prüft ob Zeile für (player_id, gamesystem_id, season_id) existiert Ja → UPDATE (wins +1, etc.) Nein → INSERT (erstes Spiel in neuer Season) Statistik wird mit der richtigen season_id geschrieben Gesamtstatistik – Beispielabfrage Sql SELECT player_id, gamesystem_id, SUM(wins) AS total_wins, SUM(loss) AS total_loss, SUM(draws) AS total_draws, SUM(games_in_system) AS total_games FROM player_game_statistic GROUP BY player_id, gamesystem_id
Author
Owner
  1. Übersicht
    Das Season-System ermöglicht eine rhythmusbasierte Verwaltung von Spielstatistiken innerhalb der Warhammer-Liga. Es erlaubt die Unterteilung in Saisons (z.B. halbjährlich, vierteljährlich) bei gleichzeitiger Beibehaltung einer fortlaufenden Gesamtstatistik über alle Saisons hinweg.

  2. Datenbank-Struktur
    Das System basiert auf drei Kern-Tabellen:

seasons: Archiviert die Saisons.
Enthält id, gamesystem_id, name, start_date, end_date (nullable) und season_number.
end_date = NULL kennzeichnet die aktuell aktive Season.
season_schedule: Die "Planungs-Vorlage".
Speichert das Start-Datum (Monat/Tag) für wiederkehrende Saisons pro Spielsystem.
player_game_statistic: Die Statistik-Daten.
Erweitert um season_id. Eindeutigkeit wird über (player_id, gamesystem_id, season_id) gewährleistet.
3. Kernlogik: Automatisierung (Cron-Job)
Das System wird durch einen täglichen Scheduler (schedule-Library, 00:01 Uhr) automatisiert:

Prüfung: Abgleich des aktuellen Datums mit der season_schedule-Tabelle.
Abschluss: Die laufende Season der betroffenen Spielsysteme erhält als end_date das Datum des Vortages.
Initialisierung: Eine neue Season wird in der seasons-Tabelle angelegt. Die season_number wird dynamisch mittels MAX(season_number) + 1 ermittelt.
Auto-Join: Alle Spieler, die in der vorangegangenen Season aktiv waren, werden automatisch per INSERT INTO ... SELECT-Statement in die neue Season kopiert (Null-Werte für Stats), um sofort für Matches in der neuen Season auswählbar zu sein.
4. Statistik-Abfrage
Das System unterstützt zwei Modi zur Statistik-Auswertung:

Saison-Modus: Filterung der player_game_statistic über die spezifische season_id. Ranglisten-Berechnungen (MMR) erfolgen hier innerhalb dieses exklusiven Saison-Kontextes.
Gesamt-Modus: Aggregation der Daten über alle Saisons (SUM(points), SUM(games), etc.) mittels GROUP BY player_id und gamesystem_id ohne Filterung auf die season_id.
5. UI-Integration
Die Benutzeroberfläche nutzt für die Umschaltung ein ui.select-Dropdown:

Standardwert: "Gesamtstatistik" (season_id = NULL).
Chronologische Auswahl: Alle vergangenen Saisons sind auswählbar (sortiert nach season_number DESC).
Reaktion: Das UI reagiert auf Änderungen durch dynamisches Löschen (.clear()) und Neu-Rendern der Statistik-Karten, basierend auf den vom Backend gelieferten aggregierten oder saisonalen Daten.

1. Übersicht Das Season-System ermöglicht eine rhythmusbasierte Verwaltung von Spielstatistiken innerhalb der Warhammer-Liga. Es erlaubt die Unterteilung in Saisons (z.B. halbjährlich, vierteljährlich) bei gleichzeitiger Beibehaltung einer fortlaufenden Gesamtstatistik über alle Saisons hinweg. 2. Datenbank-Struktur Das System basiert auf drei Kern-Tabellen: seasons: Archiviert die Saisons. Enthält id, gamesystem_id, name, start_date, end_date (nullable) und season_number. end_date = NULL kennzeichnet die aktuell aktive Season. season_schedule: Die "Planungs-Vorlage". Speichert das Start-Datum (Monat/Tag) für wiederkehrende Saisons pro Spielsystem. player_game_statistic: Die Statistik-Daten. Erweitert um season_id. Eindeutigkeit wird über (player_id, gamesystem_id, season_id) gewährleistet. 3. Kernlogik: Automatisierung (Cron-Job) Das System wird durch einen täglichen Scheduler (schedule-Library, 00:01 Uhr) automatisiert: Prüfung: Abgleich des aktuellen Datums mit der season_schedule-Tabelle. Abschluss: Die laufende Season der betroffenen Spielsysteme erhält als end_date das Datum des Vortages. Initialisierung: Eine neue Season wird in der seasons-Tabelle angelegt. Die season_number wird dynamisch mittels MAX(season_number) + 1 ermittelt. Auto-Join: Alle Spieler, die in der vorangegangenen Season aktiv waren, werden automatisch per INSERT INTO ... SELECT-Statement in die neue Season kopiert (Null-Werte für Stats), um sofort für Matches in der neuen Season auswählbar zu sein. 4. Statistik-Abfrage Das System unterstützt zwei Modi zur Statistik-Auswertung: Saison-Modus: Filterung der player_game_statistic über die spezifische season_id. Ranglisten-Berechnungen (MMR) erfolgen hier innerhalb dieses exklusiven Saison-Kontextes. Gesamt-Modus: Aggregation der Daten über alle Saisons (SUM(points), SUM(games), etc.) mittels GROUP BY player_id und gamesystem_id ohne Filterung auf die season_id. 5. UI-Integration Die Benutzeroberfläche nutzt für die Umschaltung ein ui.select-Dropdown: Standardwert: "Gesamtstatistik" (season_id = NULL). Chronologische Auswahl: Alle vergangenen Saisons sind auswählbar (sortiert nach season_number DESC). Reaktion: Das UI reagiert auf Änderungen durch dynamisches Löschen (.clear()) und Neu-Rendern der Statistik-Karten, basierend auf den vom Backend gelieferten aggregierten oder saisonalen Daten.
Author
Owner

Die Liga Statistikseite (Rangliste, MMR, Punkte, ...) ist kaputt durch das neue Seasons System. Bzw. Das UI und die Bedienung muss angepasst werden damit das sauber integriert ist. Issue wird geschlossen. Umbau vom GUI auf Desktop-Mobile unterscheidung steht eh an. Dann verbinde ich das.

Die Liga Statistikseite (Rangliste, MMR, Punkte, ...) ist kaputt durch das neue Seasons System. Bzw. Das UI und die Bedienung muss angepasst werden damit das sauber integriert ist. Issue wird geschlossen. Umbau vom GUI auf Desktop-Mobile unterscheidung steht eh an. Dann verbinde ich das.
Sign in to join this conversation.
No Label
No Milestone
No Assignees
1 Participants
Notifications
Due Date
The due date is invalid or out of range. Please use the format 'yyyy-mm-dd'.

No due date set.

Dependencies

No dependencies set.

Reference: WestsideDiceghost/Liga-System#32
No description provided.