Sign inSign up

andyxtreme/game-watch

By andyxtreme

Updated 4 days ago

Image
0

606

andyxtreme/game-watch repository overview

Support

If this edition helps you, I'd appreciate a small donation – thank you! ☕

Ko-fi

Game Watch

Beobachtet öffentliche RSS-Quellen zu den Spielen, auf die du wartest, lässt jede Meldung von einem lokalen Sprachmodell (Ollama/Qwen) bewerten und auf Deutsch zusammenfassen und schickt aufs Handy, was wirklich zählt.

Im Mittelpunkt steht der Erscheinungstermin: Steht in einer Meldung ein Datum, wird es gemerkt. Ändert es sich, kommt eine eigene Nachricht. Vor dem Erscheinen erinnert der Dienst von selbst.

Alles auf Deutsch, keine Anmeldung, keine Cloud, keine Datenbank, kein Konto bei Steam, Epic oder sonstwem.


Schnellstart

Zwei Dienste aus einem Image: der Beobachter (Standardbefehl) und die Weboberfläche (webui.py). Dazu ein ntfy-Server für die Pushes – der läuft bewusst getrennt, damit ihn mehrere Projekte teilen können.

services:

  monitor:
    image: andyxtreme/game-watch:latest
    container_name: game-watch
    environment:
      - TZ=Europe/Berlin
      # Sprachmodell. Gesetzt schlägt es die config.yaml – praktisch, weil die
      # mitgelieferte Vorlage eine fremde LAN-Adresse enthält. Weglassen oder
      # leer lassen = es gilt, was in der Konfiguration steht.
      - OLLAMA_URL=http://192.168.x.y:11434
      - OLLAMA_MODEL=qwen3:14b
      # Nur nötig, wenn die Dateien woanders liegen sollen als voreingestellt:
      # - CONFIG_PATH=/config/config.yaml
      # - STATE_PATH=/data/seen.json
      # - TOPICS_PATH=/data/recent_topics.json
      # - HEALTH_PATH=/data/feed_health.json
      # - RELEASES_PATH=/data/releases.json
    volumes:
      # Verzeichnisse, keine Einzeldateien – sonst sieht der Monitor
      # Änderungen aus der Weboberfläche nicht.
      - ./config:/config
      - ./data:/data
    restart: unless-stopped

  webui:
    image: andyxtreme/game-watch:latest   # dasselbe Image, anderer Startbefehl
    container_name: game-watch-webui
    command: ["python", "-u", "webui.py"]
    environment:
      - TZ=Europe/Berlin
      # Dieselben Werte wie oben. Stehen sie nur bei einem der beiden Dienste,
      # prüft die Oberfläche eine andere Adresse, als der Beobachter benutzt.
      - OLLAMA_URL=http://192.168.x.y:11434
      - OLLAMA_MODEL=qwen3:14b
      # Nur nötig, wenn die Dateien woanders liegen sollen als voreingestellt:
      # - CONFIG_PATH=/config/config.yaml
      # - STATE_PATH=/data/seen.json
      # - TOPICS_PATH=/data/recent_topics.json
      # - HEALTH_PATH=/data/feed_health.json
      # - RELEASES_PATH=/data/releases.json
    volumes:
      # Beides ohne :ro – dieser Dienst schreibt die Konfiguration UND die von
      # Hand eingetragenen Erscheinungstermine.
      - ./config:/config
      - ./data:/data
    ports:
      - "8092:8081"
    restart: unless-stopped

  # Push-Server. Gehört strenggenommen in einen eigenen Stapel, damit er
  # weiterläuft, wenn der Monitor neu gebaut oder gestoppt wird.
  ntfy:
    image: binwiederhier/ntfy:v2.27.0
    container_name: ntfy
    command: ["serve"]
    environment:
      - TZ=Europe/Berlin
      # Die Adresse, unter der DEIN HANDY den Server erreicht – nicht der
      # containerinterne Name. Steht hier etwas Falsches, laufen die
      # "Artikel öffnen"-Knöpfe aus der App ins Leere.
      - NTFY_BASE_URL=http://192.168.x.y:8090
      # Ohne Cache verwirft ntfy jede Nachricht sofort.
      - NTFY_CACHE_FILE=/var/cache/ntfy/cache.db
      - NTFY_CACHE_DURATION=24h
    volumes:
      - ./ntfy/cache:/var/cache/ntfy
      - ./ntfy/etc:/etc/ntfy
    ports:
      - "8090:80"
    restart: unless-stopped

Danach: http://localhost:8092

Der erste Weg dort führt zur Karte „Push-Server (ntfy)" – Adresse und Kanal eintragen, die Oberfläche prüft sofort, ob der Server antwortet. Erst danach die Merkliste. Auf dem Handy in der ntfy-App denselben Server als Standard eintragen und den Kanal abonnieren.

Ein Spiel braucht nur einen Namen. Die Steam-AppID sucht die Oberfläche auf Wunsch dazu und schaltet damit den offiziellen Herstellerkanal frei – dort steht ein Termin oft zuerst. Ohne AppID läuft die Überwachung trotzdem, nur ohne diesen Kanal; bei Konsolen-Exklusivtiteln ist das der Normalfall.

Erstlauf ohne Lawine: Beim allerersten Start ist jeder gefundene Artikel „neu". Der erste Durchlauf baut deshalb nur die Historie auf und schickt nichts. Echte Meldungen kommen ab dem zweiten Durchlauf.


Schnittstellen

Port8081 im Container – nur die Weboberfläche. Der Beobachter lauscht auf nichts.
/configKonfiguration. Beim ersten Start wird eine durchgehend kommentierte Vorlage hineinkopiert, eine vorhandene Datei nie überschrieben. Ein Update wirft die Merkliste also nicht weg.
/dataGesehene Artikel, bekannte Termine, Themen-Gedächtnis, Zustand der Quellen. Darf verloren gehen – dann ist der nächste Lauf wieder ein Erstlauf und meldet einmalig nichts. Mit ihm gehen allerdings die gemerkten Erscheinungstermine, also auch die Countdowns.
Umgebungsvariablen
VariableStandardZweck
TZUTCZeitzone – sonst stimmen Tageszusammenfassung und Countdown nicht
CONFIG_PATH/config/config.yamlOrt der Konfiguration
STATE_PATH/data/seen.jsonschon gesehene Artikel
TOPICS_PATH/data/recent_topics.jsonGedächtnis für Doppelmeldungen
HEALTH_PATH/data/feed_health.jsonZustand je Nachrichtenquelle
RELEASES_PATH/data/releases.jsonbekannte Erscheinungstermine und verschickte Erinnerungen
OLLAMA_URLAdresse des Sprachmodells. Gesetzt schlägt sie die config.yaml
OLLAMA_MODELModellname, z. B. qwen3:14b. Gesetzt schlägt er die config.yaml

Alles Übrige – Merkliste, Nachrichtenquellen, Kategorien, Schwellen, Prioritäten, Zeiten, Push-Server – steht in /config/config.yaml und lässt sich vollständig über die Weboberfläche pflegen; die Kommentare in der Datei bleiben dabei erhalten. Der Beobachter liest die Konfiguration vor jedem Durchlauf neu, ein Neustart ist also nicht nötig.


Sprachmodell (optional)

Für Bewertung, deutsche Zusammenfassung, Termin-Erkennung und die Erkennung von Doppelmeldungen wird ein lokales Ollama angebunden – entwickelt und getestet mit qwen3:14b. Ohne läuft alles weiter – je nach Einstellung ungefiltert und mit der englischen Schlagzeile statt eines deutschen Satzes, oder gar nicht.

Adresse und Modell stehen normalerweise in der config.yaml. Wer lieber alles in einer Datei hat, setzt stattdessen OLLAMA_URL und OLLAMA_MODEL in der Compose-Datei – die gewinnen dann gegen die Konfiguration. Bei beiden Diensten eintragen, sonst zeigt die Oberfläche etwas anderes an, als der Beobachter benutzt. Welcher Wert gerade gilt, steht in der Oberfläche unter „Status".

Drei Stolpersteine:

  • localhost ist aus dem Container heraus der Container selbst. Es muss die LAN-Adresse des Ollama-Rechners sein.
  • Ollama lauscht in der Grundeinstellung nur lokal. Damit ein Container es erreicht, braucht es dort OLLAMA_HOST=0.0.0.0.
  • Bei Denk-Modellen (qwen3 und Verwandte) muss think: false gesetzt bleiben. Mit aktivem Denk-Modus und erzwungenem JSON antwortet das Modell nur mit {} – die Bewertung fällt dann still komplett aus.

Wie eine Meldung aussieht

🗓️ Hollow Knight: Silksong · Erscheinungstermin        [Prio 4]

Hollow Knight: Silksong erscheint am 4. September 2025 für PC und Switch.
🗓️ Termin: 4. September 2025
–––
Silksong release date announced for September 4
                                        [ Artikel öffnen ]

Das Symbol am Titelanfang ist die Art der Meldung: 🗓️ Termin, ⏳ Verschiebung, 🎬 Trailer, 🎮 Gameplay, 🧩 DLC, ⭐ Test, 🔧 Patch, 📰 Sonstiges, ❔ unbewertet, weil das Modell nicht erreichbar war. „Erscheinungstermin" steht nur dann drüber, wenn auch wirklich ein Datum drinsteht – sonst liest man diese Überschrift wochenlang zu Leaks und Gerüchten und glaubt ihr nicht mehr, wenn der Termin einmal feststeht. Ein vages „Winter 2026" wird als Angepeilt ausgewiesen, nicht als Termin. Die englische Originalschlagzeile steht unter der Übersetzung, damit ein Patzer des Modells auffällt.

Der Termin ist der Kern

Ein Sprachmodell füllt ein leeres Feld lieber, als es leer zu lassen – ohne Bremse schreibt es das heutige Datum aus dem Prompt als Termin zurück, und dann „erscheint" ein Spiel jeden Tag aufs Neue, samt Push und Countdown. Eine Bitte im Prompt genügt dagegen nicht, deshalb prüft der Code selbst:

  • Beleg im Artikel. Jahr, Monat und (bei taggenauen Terminen) Tag müssen im Originaltext vorkommen – als Name oder Zahl, deutsch oder englisch. Sonst wird das Datum verworfen.
  • Nur aus Termin-Meldungen, nur wenn genau ein Spiel der Merkliste erwähnt ist (Sammelartikel würden dasselbe Datum sonst allen zuschreiben) und nichts, was lange vorbei ist.
  • Ungenauer schlägt genauer nicht. „2026" neben gespeichertem 19.11.2026 ist eine Bestätigung, keine Verschiebung.

Bleibt trotzdem einmal ein falsches Datum stehen, löscht es ein Knopf in der Oberfläche. Termine lassen sich dort auch von Hand setzen – ab dann zählt der Dienst darauf herunter.

Was drin ist

  • Bewertung statt Weiterleitung. Jeder Treffer bekommt Relevanz 1–10, eine Kategorie und einen deutschen Satz. Nur ab der eingestellten Schwelle wird gepusht; der Rest steht in der Tageszusammenfassung.
  • Drei Quellen je Spiel: allgemeine Spielepresse (GameStar, Golem, Eurogamer, IGN, PC Gamer, Rock Paper Shotgun, VG247, GamesRadar, GameSpot, Gematsu, Nintendo Life, Push Square) gefiltert gegen die Merkliste, dazu der offizielle Steam-Nachrichtenkanal und eine Nachrichtensuche nach dem exakten Titel.
  • Termin-Gedächtnis: neues Datum, Verschiebung, Vorziehen und Absage werden als eigene Meldung verschickt, mit altem und neuem Termin im Text.
  • Erinnerungen vor dem Erscheinen (Standard 7 Tage, 1 Tag, am Tag selbst). Es feuert immer nur die nächstliegende Schwelle, nicht alle auf einmal.
  • Kategorien einzeln steuerbar: je Kategorie melden, immer (an der Relevanzschwelle vorbei) und laut. Nötig, weil die Skala an Terminen ausgerichtet ist – gemessen an 16 echten Patch-Meldungen blieb die Hälfte darunter hängen. Termine selbst lassen sich nicht abwählen.
  • Doppelmeldungen zum selben Ereignis lösen nur einen Push aus; in der Zusammenfassung stehen sie eingerückt darunter. Reiner Textvergleich reicht dafür nicht – dieselbe Nachricht sieht bei IGN anders aus als bei GameStar, zumal in zwei Sprachen.
  • Tageszusammenfassung mit den nächsten bekannten Terminen und dem Zustand der Quellen. Sie kommt auch an ruhigen Tagen und ist damit zugleich das Lebenszeichen.
  • Notbremse gegen Push-Fluten: Deckel pro Durchlauf, stiller Erstlauf, Prioritäten auf 1–4 begrenzt. Stufe 5 ist bewusst nicht wählbar – sie durchbricht auf dem Handy „Nicht stören", und dafür ist keine Spielenachricht wichtig genug.

Was es nicht ist

Kein Shop, kein Vorbesteller, keine Verbindung zu einem Spielekonto. Das Programm liest öffentliche Nachrichten. Termine stammen aus diesen Nachrichten und aus dem, was ein Sprachmodell daraus liest – sie können falsch sein oder sich am nächsten Tag ändern. Deshalb steht die Quelle immer dabei und das Original immer darunter.


Tags

Tag
latestjeweils aktueller Stand
1.6feste Version

Vollständige Dokumentation – jede Einstellung, jede Schwelle, jedes Feld der Weboberfläche – liegt als README.md im Quellverzeichnis des Projekts.

Tag summary

Content type

Image

Digest

sha256:f840f29d6

Size

50 MB

Last updated

4 days ago

docker pull andyxtreme/game-watch