CommunityCodierung & Entwicklunggithub.com

cEDH-Playgroup

Verwaltet eine cEDH-Spielgruppe basierend auf TopDeck.gg-Turnierdaten. Füge Spieler und Decks hinzu, rufe Ergebnisse ab, analysiere das Meta, protokolliere Trainingsspiele und erstelle ausgewogene Pods mit Posting an den Discord-Kanal der Gruppe.

Was ist cEDH-Playgroup?

Diese Skill verwaltet eine kleine, manuell editierbare Aufzeichnung einer cEDH-Spielgruppe und kombiniert diese mit Turnierdaten von TopDeck.gg. Sie hat vier Hauptaufgaben: Spieler verwalten (Hinzufügen über TopDeck-Profil-ID mit ihren Decks), Meta-Analyse (was gespielt wird und gewinnt, standardmäßig letzte 30 Tage), Eingabe (Trainingsergebnisse, aktuelle Decks, Meta-Notizen, Verfügbarkeit) und Pods erstellen (Sitzplatz für Trainingsabende, so dass die Gruppe nützliche Runden bekommt). Die gesamte Berechnung erfolgt in Python-Skripten im `scripts/`-Verzeichnis (nur Stdlib). Deine Aufgabe ist es, sie auszuführen, ihre Ausgabe zu lesen und in Ratschläge umzuwandeln, die die Gruppe nutzen kann. Die Skill unterstützt Plattformen wie Claude Code, Cursor und Codex und ist ideal für Spielgruppen, die ihr Training optimieren und datengesteuerte Einblicke in das Meta erhalten möchten.

Funktioniert mit✓Claude Code~Codex CLI~Cursor
npx skills add https://github.com/ejw179/cedh-playgroup/tree/main/cedh-playgroup

Installed? Explore more Codierung & Entwicklung skills: steipete/bluebubbles, steipete/eightctl, steipete/blucli · View all 6 →

In Ihrer bevorzugten KI fragen

Öffnet einen neuen Chat, in dem dieser Agent-Skill bereits geladen ist.

Dokumentation

Was macht cEDH-Playgroup?

Diese Skill führt eine kleine, manuell editierbare Aufzeichnung einer cEDH-Spielgruppe und kombiniert diese mit Turnierdaten von TopDeck.gg. Sie hat vier Hauptaufgaben, sowie das Posten der Ergebnisse auf dem Discord der Gruppe:

  1. Spieler: Hinzufügen von Personen über ihre TopDeck-Profil-ID zusammen mit den Decks, die sie besitzen.
  2. Meta: Was wird gespielt und was gewinnt, standardmäßig die letzten 30 Tage.
  3. Eingabe: Trainingsergebnisse, aktuelle Decks, Meta-Notizen, Verfügbarkeit.
  4. Pods: Sitzplatzzuweisung für einen Trainingsabend, so dass die Gruppe nützliche Runden bekommt.

Die gesamte Berechnung erfolgt in Python-Skripten im scripts/-Verzeichnis (nur Stdlib). Deine Aufgabe ist es, sie auszuführen, ihre Ausgabe zu lesen und in Ratschläge umzuwandeln, die die Gruppe nutzen kann. Berechne Statistiken nicht von Hand. Die Skripte behandeln die Randfälle (Partnernamen, Unentschieden, kleine Stichproben), und eine zweimalige Berechnung riskiert zwei unterschiedliche Antworten.

Einrichtung und Speicherorte

  • Skripte: scripts/ neben dieser Datei. Führe sie aus als python <skill-dir>/scripts/<name>.py ....
  • Daten: ~/cedh-playgroup/ (überschreibbar mit der Umgebungsvariablen CEDH_PLAYGROUP_DIR). roster.json, games.json, notes.json, availability.json und cache/tournaments.json (der TopDeck-Abruf). Sie sind einfaches JSON, daher ist es in Ordnung, sie dem Benutzer zu zeigen oder ihn sie von Hand bearbeiten zu lassen.
  • TopDeck-API-Schlüssel: Umgebungsvariable TOPDECK_API_KEY. Er ist kostenlos erhältlich unter https://topdeck.gg/account. Wenn er fehlt, sage dies und erkläre, wie man ihn setzt. Bitte den Benutzer nicht, den Schlüssel in den Chat einzufügen.

Namensnennung ist eine Bedingung der TopDeck-API. Jede Antwort, die Turnierdaten verwendet, endet mit: Turnierdaten von TopDeck.gg (https://topdeck.gg). Die Skripte geben dies aus. Behalte es bei, wenn du zusammenfasst.

Aktualität: zuerst synchronisieren

TopDeck hat keinen Endpunkt "Ergebnisse für Spieler X". sync.py ruft jedes abgeschlossene EDH-Turnier in einem Datumsfenster ab, und alle Spieler- und Meta-Statistiken stammen aus diesem Cache. Überprüfe vor einem Meta-Bericht, Spielerstatistiken oder Pods das Alter des Caches (die synced-Liste in cache/tournaments.json). Wenn er älter als etwa einen Tag ist oder das benötigte Fenster nicht abdeckt, synchronisiere:

python scripts/sync.py              # letzte 30 Tage, abgerufen Woche für Woche
python scripts/sync.py --days 60    # auch benötigt für die Meta-Trendspalte "Δ Anteil"
python scripts/sync.py --import saved_response.json   # offline / testen

Der Bulk-Endpunkt ist ratenbegrenzt. Das Skript bremst bei HTTP 429 selbstständig, also lass es laufen. Eine 30-Tage-Synchronisation kann ein oder zwei Minuten dauern.

1. Spieler

python scripts/playgroup.py add-player "Eric" --topdeck https://topdeck.gg/profile/<id> --deck kinnan
python scripts/playgroup.py set-decks "Sam" --deck najeela --deck "tymna kraum" --primary najeela
python scripts/playgroup.py set-decks "Lee" --deck "magda" --add      # hinzufügen ohne zu ersetzen
python scripts/playgroup.py set-decks "Jo" --deck glarb --gauntlet-pilot yes
python scripts/playgroup.py remove-player "Max"
python scripts/analyze.py players            # alle; oder: players Eric Sam
  • --topdeck akzeptiert einen Profillink, entweder als (topdeck.gg/profile/<id> oder topdeck.gg/profile/%40handle), einen @handle oder eine bloße ID. Turnierplatzierungen kennen nur die rohe Spieler-ID, daher öffnet das Skript die Profilseite und liest die ID aus ihrem player-id-Meta-Tag. Es gibt den gefundenen TopDeck-Anzeigenamen aus. Wenn dieser Name nicht wie die Person aussieht, die der Benutzer meinte, sage dies. Wenn die Suche fehlschlägt (offline), speichert es das Gegebene und warnt. Füge den Spieler später erneut hinzu, damit seine Statistiken übereinstimmen. Wenn der Benutzer nur einen Namen angibt, frage nach seinem TopDeck-Profil-Link. Die Übereinstimmung nach Anzeigenamen könnte Fremde mit demselben Namen erfassen.
  • Kommandanten-Namen werden unscharf auf die TopDeck-Schreibweise abgestimmt ("tymna kraum" → "Tymna the Weaver / Kraum, Ludevic's Opus"). Das Skript gibt die ausgewählte Übereinstimmung aus. Wenn es Alternativen auflistet, bestätige mit dem Benutzer. playgroup.py resolve <name> überprüft einen Namen, ohne etwas zu speichern.
  • Ein Gauntlet-Pilot ist bereit, eines der gemeinsamen Decks der Gruppe anstelle seines eigenen zu spielen. So landen Top-Meta-Decks, die niemand besitzt, in den Pods.
  • Ein Spieler mit null TopDeck-Events im Fenster ist kein Fehler. Er hat nur seit kurzem an keinem aufgezeichneten Event teilgenommen. Biete sync.py --days 90 für mehr Historie an.

Wenn du über Spieler berichtest, beginne mit dem, was für das Training nützlich ist: aktuelles Deck, aktuelle Form (Bilanz und Platzierungen) und was ihr Trainingsprotokoll sagt. Gib nicht einfach die Tabelle wieder.

2. Meta-Bericht

python scripts/analyze.py meta                       # 30 Tage, Events mit 16+ Spielern, Top 25
python scripts/analyze.py meta --days 14 --min-players 32 --top 15
python scripts/analyze.py matchups "kinnan"          # gegen wen dieses Deck gewinnt und verliert
python scripts/analyze.py matchups --player Eric     # dasselbe, aus den eigenen Tabellen eines Spielers

Spalten: Einträge, Meta-Anteil, Δ-Anteil gegenüber dem vorherigen gleichen Fenster, Gewinnrate, Unentschiedenrate, Top-Cut-Konvertierung und beste Platzierung.

Drei Blickwinkel auf das Meta. Wähle den, zu dem die Frage passt, oder zeige lokale und große Events nebeneinander, wenn der Benutzer einfach fragt "wie ist das Meta":

BlickwinkelBefehlAntwortet auf
Lokalmeta --localWas unsere Gruppe tatsächlich treffen wird: Events innerhalb der gespeicherten Entfernung von zu Hause, jede Größe, letzte 30 Tage
Große Eventsmeta --bigWas bei großen Turnieren gewinnt: über 100 Spieler, überall, letzte 90 Tage (sie sind selten)
GlobalmetaAlles auf TopDeck mit 16+ Spielern

Setze das Heimatgebiet und die Schwelle für "groß" einmalig mit playgroup.py home --zip 18201 --miles 100 --big-min 101, oder verwende eine einmalige Angabe --zip Z --miles M. Die lokale Ansicht verwendet die Event-Koordinaten von TopDeck. Online-Events und Events ohne Ort können nicht platziert werden, und der Bericht sagt, wie viele fehlen. Lokale Stichproben sind klein, daher bezeichne Anteile als "wer auftaucht" und Gewinnraten als Hinweise. Wo lokale und große Events abweichen, ist das der nützliche Teil: Ein Deck, das lokal beliebt, aber bei großen Events schwach ist, oder eines, das große Events gewinnt, aber niemand in deiner Nähe es noch spielt. pods.py --local oder --big lässt diese Blickwinkel für "dem Top-Meta stellen" verwenden.

Es ist wichtiger, es gut zu lesen, als es einfach auszudrucken:

  • Gewinnraten sind Vier-Spieler-Zahlen. Etwa 25 % ist der Durchschnitt, und niedriger, wenn Unentschieden gezählt werden. Der Bericht gibt den beobachteten Durchschnitt des Fensters aus. Ein Deck mit 30 % ist sehr stark. Lies Gewinnraten niemals im Vergleich zu 50 %.
  • Kleine Stichproben lügen. Bei unter etwa 20 Einträgen oder etwa 10 gemeinsamen Tabellen in matchups bezeichne eine Zahl als Hinweis, nicht als Ergebnis.
  • Beliebtheit (Anteil) und Stärke (Gewinnrate, Konvertierung) sind verschiedene Fragen. Weise auf Decks hin, die ihren Anteil übererfüllen, und beliebte Decks, die schlecht konvertieren.
  • --min-players 16 hält kleine lokale Events aus der Meta-Ansicht heraus. Wenn der Benutzer nach seiner lokalen Szene fragt, senke den Wert.
  • Beziehe die gruppeneigenen notes.json ein, wo es relevant ist ("du hast viel Magda im LGS notiert, und sie ist auch global um 2 % gestiegen").

Formuliere die Antwort als: 3–5 Aufzählungspunkte, dann die Tabelle (auf das Wesentliche reduziert), dann was es für das Training dieser Gruppe bedeutet (z. B. "niemand hier besitzt eine Najeela, und sie ist #3; eine Gauntlet-Kopie wert").

3. Eingabe: Ergebnisse, Decks, Notizen, Verfügbarkeit

python scripts/playgroup.py log-game --date 2026-11-08 \
    --seat "Eric=Kinnan" --seat "Sam=Najeela" --seat "Lee=Tymna Kraum" --seat "Kim=Yuriko" \
    --winner Sam                     # oder --winner draw; füge --no-order hinzu, wenn die Zugreihenfolge unbekannt ist
python scripts/playgroup.py note "In letzter Zeit viel Magda im LGS" --author Eric --tag meta
python scripts/playgroup.py avail 2026-11-08 Eric Sam Lee Kim Jo      # --replace zum Überschreiben
python scripts/playgroup.py gauntlet-deck add "Najeela" --list <url>
python scripts/playgroup.py show games      # roster | games | notes | avail

Leute melden Ergebnisse beiläufig ("sam hat mit najeela gewonnen, ich lee und kim mit kinnan tymna yuriko, dann ein unentschieden"). Verwandle jedes Spiel in einen log-game-Aufruf.

Sitzreihenfolge ist die Zugreihenfolge, und sie ist wichtig: über TopDecks 4-Spieler-Tabellen gewinnt Sitz 1 etwa 23 % und Sitz 4 etwa 14 %. Liste --seats in Zugreihenfolge auf (Sitz 1 zuerst). Wenn der Bericht die Zugreihenfolge nicht klar macht, frage einmal ("wer war zuerst dran?"). Wenn sie es nicht wissen, protokolliere mit --no-order. Das Spiel zählt trotzdem für die Bilanzen und Matchups, nur nicht für die Sitzstatistiken. Sage der Gruppe das beste Berichtsformat, weil es das Sitzprofil jedes Einzelnen füttert: G1 (Zugreihenfolge): Eric Kinnan, Sam Najeela, Lee Tymna/Kraum, Kim Yuriko. Gewinner Sam. Wenn etwas, das die Statistiken ändert, mehrdeutig ist, wie z. B. wer gewonnen hat oder welches Deck jemand gespielt hat, frage vor dem Protokollieren nach. Lies danach zurück, was aufgezeichnet wurde, eine Zeile pro Spiel, damit Fehler erkannt werden.

Wenn der Benutzer mehrere Spiele einfügt, protokolliere sie alle und fasse dann den Abend zusammen: wer was gewonnen hat und etwaige Serien.

4. Trainings-Pods

Wer spielt in dieser Session

Die Anwesenheit ändert sich jede Woche, also kläre, wer dabei ist, bevor du Pods erstellst. In der Reihenfolge der Präferenz:

  1. Der Benutzer nennt Personen ("alle außer Jeff", "Eric, Ryan, Saige, Alex").
  2. Eine Liste, die bereits für dieses Datum gespeichert ist (playgroup.py show avail).
  3. Frage nach. Wenn dein Client ein Multiple-Choice-Frage-Tool hat, liste den Kader als Kontrollkästchen auf, teile es auf mehrere Fragen auf, wenn es mehr Namen gibt, als eine Frage erlaubt, und frage auch nach dem Datum. Frage ansonsten in einer Zeile.

Speichere die Antwort, damit Pods, der Discord-Post und spätere Berichte übereinstimmen:

python scripts/playgroup.py avail 2026-11-08 --all --remove Jeff Saige   # alle außer
python scripts/playgroup.py avail 2026-11-08 Ishmael                      # ein spätes Ja hinzufügen
python scripts/playgroup.py avail 2026-11-08 --remove Ryan                # ein spätes Nein entfernen
python scripts/pods.py --date 2026-11-08                                  # aus der gespeicherten Liste erstellen
python scripts/pods.py --all --except Jeff                                # einmalig, ohne zu speichern

Wenn sich die Liste nach dem Posten der Pods ändert, erstelle neu und sage, wer gewechselt ist. Platziere Leute, die ihren Pod bereits gesehen haben, nicht stillschweigend neu.

python scripts/pods.py --date 2026-11-08               # verwendet die Verfügbarkeit dieses Abends
python scripts/pods.py --players Eric Sam Lee Kim Jo Ana Max
python scripts/pods.py --date 2026-11-08 --focus Eric  # Erics schwache Matchups zählen 4x
python scripts/pods.py --date 2026-11-08 --deck "Sam=Tymna Kraum" --w-repeat 0

Der Pod-Ersteller durchsucht Sitzplatz- und Deck-Kombinationen und bewertet sie nach vier Zielen, die standardmäßig alle aktiviert sind. Schalte ein Ziel aus, indem du sein Gewicht auf 0 setzt, oder erhöhe es, um es zu betonen:

ZielFlagWas es belohnt
Dem Top-Meta stellen--w-metaTop-N-Meta-Decks an jedem Tisch (--top-meta 15)
Ausgewogene Pods--w-balanceähnliche durchschnittliche Stärke (Spielerbilanz + Deck-Gewinnrate) pro Pod
Wiederholungen vermeiden--w-repeatPaare, die in letzter Zeit in protokollierten Spielen zusammensaßen, nicht neu setzen
Schwache Matchups anvisieren--w-matchupEinen Spieler Decks gegenüberstellen, gegen die er verliert (siehe unten)

Wessen schlechte Matchups? "An meinen schlechten Matchups arbeiten" bezieht sich auf die Person, nicht auf das Deck. Der Pod-Ersteller schätzt die Gewinnrate jedes Spielers gegen jeden gegnerischen Kommandanten aus seinen eigenen TopDeck-Tabellen und Trainingsspielen. Das sind kleine Stichproben, daher schrumpft er sie in Richtung der feldweiten Gewinnrate dieses Decks in derselben Paarung. Ein Pilot, der 1/11 gegen Rograkh/Thrasios steht, gilt dort trotzdem als schwach, selbst wenn Kinnan-Spieler insgesamt gut dagegen abschneiden. Bevor du Pods für jemanden erstellst, der nach seinen Matchups gefragt hat, schau dir die Beweise selbst an:

python scripts/analyze.py matchups --player Eric --days 90   # Erics eigene Tabellen, jede Eventgröße
python scripts/analyze.py matchups kinnan                    # das Deck feldweit, zum Vergleich

Wenn die beiden abweichen, sage dies deutlich ("Kinnan ist generell gut gegen Najeela, aber du stehst 0/3 gegen Sams"). Es ist nützliches Coaching: Die Lücke liegt in den Entscheidungen des Spielers, nicht im Deck.

Sitze. Der Pod-Ersteller legt auch die Zugreihenfolge jedes Pods fest. Mit --seat-mode practice (Standard) geht jeder Spieler auf den Sitz, auf dem seine Bilanz relativ zu dem, was dieser Sitz normalerweise gewinnt, am schwächsten ist. 0/6 auf Sitz 2 ist schlecht. 2/10 auf Sitz 4 ist etwa Durchschnitt. --seat-mode best trainiert ihre besten Sitze, z. B. vor einem Turnier, und random mischt einfach. Spielerbezogene Sitz- und Matchup-Beweise:

python scripts/analyze.py profile            # alle; oder: profile Eric Ryan

Die Pods erklären: das ist der Punkt. Für jeden Sitz gibt das Skript die Anzahl der Beweise des Spielers, die Sitzbewertung (schlechtester, bester oder noch keine Bewertung, mit Bilanz und Punkten relativ zum Sitzdurchschnitt), die Matchups an diesem Tisch ("braucht Übung gegen …" und "bevorzugt gegen …", mit eigener Bilanz und feldweiter Rate) und schwache Matchups, die nicht an diesem Tisch sind. Verwandle das in eine kurze, datengesteuerte "Warum"-Erklärung pro Spieler, z. B.:

Sitz 1: Alex mit Tayam. Sitz 1 ist Alex' schlechtester Sitz (1/10, etwa 7 Punkte unter dem, was Sitz 1 normalerweise gewinnt), also übt er ihn hier. Er steht auch 0/7 gegen Sisay bei Turnieren, und Darisons Sisay ist an diesem Tisch. Er ist bevorzugt gegen Ob Nixilis, also sollte er den gewinnen.

Regeln für diese Erklärungen:

  • Zitiere die tatsächlichen Bilanzen (1/10, 0/7). Sie machen es glaubwürdig.
  • Sage "dünne Stichprobe", wenn es auf weniger als ~6 Spiele gestützt ist. Verkaufe eine 0/2 nicht übermäßig.
  • Wenn ein Spieler keine Daten hat (kein TopDeck-Link, keine protokollierten Spiele), sage, dass sein Sitz ein Platzhalter ist und dass Trainingsberichte ihn füllen werden. Erfinde keinen Grund.
  • Beende damit, was mehr Trainingsdaten schärfen würden. Jedes protokollierte Spiel in Zugreihenfolge verbessert die Sitz- und Matchup-Ablesungen.

Pod-Größen sind Vierergruppen, wobei Dreiergruppen den Rest aufnehmen. Bei 5 Spielern setzt einer aus und rotiert. Wenn der Benutzer lieber einen 5er-Pod spielen möchte, sage, dass das seine Entscheidung ist, und platziere alle. Die Ausgabezeile "Sitting out" nennt, wer rotieren soll.

Präsentiere jeden Pod mit warum er so gebaut ist, in einfacher Sprache: welche Meta-Decks sie sehen werden, welches schwache Matchup jeder Spieler dort üben soll und jede Wiederholungspaarung, die nicht vermieden werden konnte. Die Notizen des Skripts sind Rohmaterial. Wähle die ein oder zwei aus, die pro Pod wichtig sind, und füge nicht alle ein. Wenn ein Gauntlet-Deck zugewiesen wurde, stelle sicher, dass der Pilot es weiß.

Verwandte Skills