Implement incremental updating

When `seed/all_in_one` is now called, it will update with only that data
that exists later than the most-recently-played* game, allowing the
upload to be used repeatedly without having to clear the database.

\* Actually, "highest-ID game", as we haven't implemented
`list_games_by_date`, yet
This commit is contained in:
Jack Jackson 2024-07-27 19:58:34 -07:00
parent 1c9aa30721
commit 2fb5a291e5
5 changed files with 225 additions and 19 deletions

View File

@ -16,3 +16,9 @@ alter sequence games_id_seq restart with 1;
alter sequence players_id_seq restart with 1; alter sequence players_id_seq restart with 1;
alter sequence elo_scores_id_seq restart with 1; alter sequence elo_scores_id_seq restart with 1;
``` ```
# To copy the database out to local
```
$ docker cp edh-elo-server-1:/app/database/<name>
```

View File

@ -61,11 +61,30 @@ def create_game(game: schemas.GameCreate, db: Session = Depends(get_db)):
return created_game return created_game
# TODO - when this is updated to support sorting, also update `app/routers/seed.py:all_in_one` to take advantage of it
# TODO - and `latest_game`
@api_router.get("/list", response_model=list[schemas.Game]) @api_router.get("/list", response_model=list[schemas.Game])
def list_games(skip: int = 0, limit: int = 100, db=Depends(get_db)): def list_games(skip: int = 0, limit: int = 100, db=Depends(get_db)):
return crud.get_games(db, skip=skip, limit=limit) return crud.get_games(db, skip=skip, limit=limit)
# This is helpful for at least the `all_in_one` data-seed path, but it could conceivably also be useful for a
# "Frontpage/dashboard" widget
@api_router.get("/latest_game", response_model=schemas.Game)
def latest_game(db=Depends(get_db)):
# Limit gives me a bit of time to allow natural growth before being forced into updating to basing on sorted-response
# Will error out if called on a database with no games
# TODO - logging does not seem to be coming up during testing
latest_game = db.query(models.Game).order_by(models.Game.date.desc()).first()
if latest_game is None:
# I.e. database is empty
raise HTTPException(
status_code=404, detail="Cannot read latest_game of an empty database"
)
return latest_game
# Note that this must be after all the "static" routes, lest it take precedence
@api_router.get("/{game_id}", response_model=schemas.Game) @api_router.get("/{game_id}", response_model=schemas.Game)
def read_game(game_id: int, db=Depends(get_db)): def read_game(game_id: int, db=Depends(get_db)):
db_game = crud.get_game_by_id(db, game_id) db_game = crud.get_game_by_id(db, game_id)
@ -79,6 +98,9 @@ def delete_game(game_id: str, db=Depends(get_db)):
crud.delete_game_by_id(db, int(game_id)) crud.delete_game_by_id(db, int(game_id))
# Do not add more api routes under here! See the comment above `read_game`
######## ########
# HTML Routes # HTML Routes
######## ########

View File

@ -5,11 +5,13 @@ import logging
from collections import defaultdict from collections import defaultdict
from fastapi import APIRouter, Depends, Request, UploadFile from fastapi import APIRouter, Depends, HTTPException, Request, UploadFile
from fastapi.responses import HTMLResponse from fastapi.responses import HTMLResponse
from sqlalchemy.orm import Session from sqlalchemy.orm import Session
from .games import create_game from .decks import list_decks
from .games import create_game, latest_game, list_games
from .players import list_players
from ..templates import jinja_templates from ..templates import jinja_templates
from ..sql import crud, schemas from ..sql import crud, schemas
from ..sql.database import get_db from ..sql.database import get_db
@ -89,6 +91,29 @@ def all_in_one(file: UploadFile, db: Session = Depends(get_db)):
file_contents = file.file.read().decode("utf-8").split("\n") file_contents = file.file.read().decode("utf-8").split("\n")
reader = csv.DictReader(file_contents, delimiter=",") reader = csv.DictReader(file_contents, delimiter=",")
# Fetch the currently-known-information so that we can avoid recreating existing data
current_player_ids_by_name = {
player.name: player.id for player in list_players(db=db)
}
current_deck_ids_by_name = {deck.name: deck.id for deck in list_decks(db=db)}
try:
latest_recorded_game = latest_game(db=db)
date_of_latest_game = latest_recorded_game.date
except HTTPException:
# No games have been returned from the db, thus no games should be skipped for downloading
date_of_latest_game = datetime.datetime(datetime.MINYEAR, 1, 1, 0, 0, 0, 0)
current_games = list_games(db=db)
print(f"{current_games}")
# Depends on being sorted by date - which is currently _coincidentally_ true of our source data as games have thus
# far only been added in date order, but is not necessarily the case.
# TODO - implement sorting (and pagination) of returned data, then update this to take advantage of it.
if current_games:
# I.e. if any games have been returned from the db
date_of_latest_game = current_games[-1].date
else:
# No games have been returned from the db, thus no games should be skipped for downloading
date_of_latest_game = datetime.datetime(datetime.MINYEAR, 1, 1, 0, 0, 0, 0)
# Mapping from name to set-of-owned-decks # Mapping from name to set-of-owned-decks
# (Set rather than list so that we can blindly `.add`) # (Set rather than list so that we can blindly `.add`)
player_decks = defaultdict(set) player_decks = defaultdict(set)
@ -116,13 +141,25 @@ def all_in_one(file: UploadFile, db: Session = Depends(get_db)):
deck_id_lookup = {} deck_id_lookup = {}
for player_name, decks in player_decks.items(): for player_name, decks in player_decks.items():
if player_name in current_player_ids_by_name:
LOGGER.info(f"Looked up {player_name=} from existing database")
player_id = current_player_ids_by_name[player_name]
else:
player = crud.create_player( player = crud.create_player(
db=db, player=schemas.PlayerCreate(name=player_name) db=db, player=schemas.PlayerCreate(name=player_name)
) )
LOGGER.info(f"Seeded {player=}") LOGGER.info(f"Seeded {player=}")
player_id = player.id player_id = player.id
player_id_lookup[player_name] = player_id player_id_lookup[player_name] = player_id
for deck_name in decks: for deck_name in decks:
if deck_name in current_deck_ids_by_name:
LOGGER.info(f"Looked up {deck_name=} from existing database")
deck_id_lookup[f"{player_name}:{deck_name}"] = current_deck_ids_by_name[
deck_name
]
else:
deck = crud.create_deck( deck = crud.create_deck(
db=db, db=db,
deck=schemas.DeckCreate( deck=schemas.DeckCreate(
@ -149,6 +186,21 @@ def all_in_one(file: UploadFile, db: Session = Depends(get_db)):
# ((Yes, I know that's an abuse of Big-O notation, shut up - you knew what I meant :P )) # ((Yes, I know that's an abuse of Big-O notation, shut up - you knew what I meant :P ))
reader = csv.DictReader(file_contents, delimiter=",") reader = csv.DictReader(file_contents, delimiter=",")
for row in reader: for row in reader:
# Skip any games created before the date of the latest current game
# (Note that this means that the `all_in_one` method cannot be used to backfill any previously-played games. If
# there arises a desire for that, instead will have to check each potentially-uploaded game against _every_
# currently-uploaded one to check for pre-existence (or, make the "create" option idempotent...though that
# probably shouldn't be the case, as attempting to upload the same game twice is _probably_ an indication of an
# automated script or summarization going rogue, which should be flagged up _as_ an error rather than blindly
# continued. For the User-facing UI, just present a "whoops! You submitted a duplicate" screen))
date_of_current_row = parse_date(row["Date"])
if date_of_current_row <= date_of_latest_game:
message = f"Skipped a game on {date_of_current_row} because it is not later than {date_of_latest_game}"
LOGGER.info(message)
# TBD - logging does not seem to be showing up as-expected
print(message)
continue
# Note that we intentionally create via the API, not via direct `crud.create_game`, to trigger ELO calculation. # Note that we intentionally create via the API, not via direct `crud.create_game`, to trigger ELO calculation.
index_of_winning_deck = [ index_of_winning_deck = [
@ -157,7 +209,7 @@ def all_in_one(file: UploadFile, db: Session = Depends(get_db)):
print(f"DEBUG - checking row {row}") print(f"DEBUG - checking row {row}")
created_game = create_game( created_game = create_game(
schemas.GameCreate( schemas.GameCreate(
date=parse_date(row["Date"]), date=date_of_current_row,
**{ **{
f"deck_id_{i+1}": deck_id_lookup[ f"deck_id_{i+1}": deck_id_lookup[
row[f"Player {i+1}"] + ":" + row[f"Deck {i+1}"] row[f"Player {i+1}"] + ":" + row[f"Deck {i+1}"]

View File

@ -0,0 +1,96 @@
Date,Player 1,Deck 1,Player 2,Deck 2,Player 3,Deck 3,Player 4,Deck 4,Player 5,Deck 5,Player 6,Deck 6,Winning Player,Winning Deck,# turns,turn 1st player out,Type of win,Format,Notes
1/13/24,Evan,Kelsien the Plague,Terence,Ravos/Rebbec,Patrick,Duke Ulder Ravengard,Jeff,Mondrak,,,,,Terence,Ravos/Rebbec,15,12,combat damage,FFA,3-4 board wipes; Biotransference
1/13/24,Terence,Wernog/Cecily,Patrick,Duke Ulder Ravengard,Ryan,Don Andres,Jeff,Mondrak,Evan,Jasmine Boreal of the Seven,,,Patrick,Duke Ulder Ravengard,12,10,combat damage,FFA,Possessed Portal scary!
1/13/24,Jeff,Go-Shintai of Life's Origin,Evan,Kethis the Hidden Hand,Terence,Rograkh/Silas ninjas,Patrick,Tekuthal,Ryan,Gitrog,,,Patrick,Tekuthal,8,8,poison,FFA,Flux Channeler + Tekuthal
1/13/24,Patrick,Tekuthal,Jeff,Illuna,Evan,"Atraxa, Praetor's Voice",Terence,Muldrotha,,,,,Patrick,Tekuthal,20,5,combat damage,FFA,3 Hullbreaker Horrors simultaneously (Evan forfeited ~t5; game took ~2hrs)
1/17/24,Patrick,Duke Ulder Ravengard,Ryan,Grist,Terence,Ravos/Rebbec,,,,,,,Patrick,Duke Ulder Ravengard,12,12,combat damage,FFA,"Eternal Wanderer wipe, Angel Serenity + Sun Titan followup"
1/17/24,Terence,Ravos/Rebbec,Patrick,Duke Ulder Ravengard,Ryan,Grist,,,,,,,Terence,Ravos/Rebbec,13,11,combat damage,FFA,Verge Rangers + Conjurer's Mantle
1/23/24,Ryan,Goose Mother,Patrick,Maarika,Terence,Wilson/Cultist,,,,,,,Patrick,Maarika,8,7,21+ commander,FFA,Maarika + Runes of the Deus
1/23/24,Ryan,Goose Mother,Patrick,Maarika,Terence,Wilson/Cultist,,,,,,,Terence,Wilson/Cultist,10,8,combat damage,FFA,Scepter of Celebration brings an army
1/23/24,Terence,Abdel Adrian/Far Traveler,Ryan,Obeka,Patrick,Laelia,,,,,,,Patrick,Laelia,9,8,21+ commander,FFA,Nalfeshnee copying Storm's Wrath cleared the way; Ryan mana screwed
1/23/24,Terence,Jan Jansen,Ryan,Don Andres,Patrick,Laelia,,,,,,,Terence,Jan Jansen,10,10,aristocrats/burn,FFA,Mirkwood Bats + Thornbite Staff ftw; Ryan mana screwed
1/30/24,Patrick,Urza,Terence,"Me, the Immortal",Ryan,Gitrog,,,,,,,Ryan,Gitrog,8,7,combat damage,FFA,Mending of Dominaria + Lotus Cobra (10 lands)
1/30/24,Patrick,Kiora,Terence,Raffine,Ryan,Kozilek,,,,,,,Patrick,Kiora,11,9,combat damage,FFA,"Raffine does all the work, then Kederekt Leviathan cleans up"
2/4/24,Ajit,Jhoira of the Ghitu,Brandon,Anikthea,Patrick,Oops all Kayas,,,,,,,Brandon,Anikthea,12,11,combat damage,FFA,Unopposed enchantress with card draw and Nature's Will
2/4/24,Brandon,Silvar/Trynn,Patrick,Oops all Kayas,Ryan,"Purphoros, God of the Forge",Ajit,Jhoira of the Ghitu,,,,,Brandon,Silvar/Trynn,12,10,aristocrats/burn,FFA,Bastion of Remembrance overcame Emrakul + It That Betrays
2/4/24,Ajit,Brago,Brandon,Marneus Calgar,Patrick,Laelia,Ryan,Gitrog,,,,,Ryan,Gitrog,15,12,combat damage,FFA,Gitrog draws a zillion cards and closes w/ Multani
2/4/24,Terence,Slimefoot and Squee,Patrick,Ayara,Ryan,Omnath,,,,,,,Ryan,Omnath,8,8,combat damage,FFA,"Vorinclex, Voice of Hunger enables Crackle with Power (x=4) to overcome Army of the Damned"
2/20/24,Terence,Wilson/Cultist,Ryan,Gitrog,Patrick,Tekuthal,,,,,,,Terence,Wilson/Cultist,15,12,combat damage,FFA,Weatherlight and Ormendahl collect many tithes
2/20/24,Ryan,Myrel,Patrick,Tekuthal,Terence,Ravos/Rebbec,,,,,,,Patrick,Tekuthal,10,9,combat damage,FFA,Arcbound Crusher got chonky (w/ Sword of Truth & Justice)
2/20/24,Terence,Ravos/Rebbec,Ryan,Myrel,Patrick,Tekuthal,,,,,,,Terence,Ravos/Rebbec,10,9,combat damage,FFA,Ryan's Coat of Arms + Terence's Door of Destinies and Haunted One = math!
2/25/24,Patrick,Elmar storm,Jack J,Gale/Scion of Halaster,Terence,Kefnet the Mindful,Jeff,Mondrak,Ryan,Don Andres,,,Jeff,Mondrak,12,9,combat damage,FFA,Elesh Norn is a good finisher; Ryan achievement unlocked: control all other commanders at once
2/25/24,Terence,Rograkh/Silas ninjas,Jeff,Illuna,Ryan,Emiel,Patrick,Myrkul planeswalkers,Jack J,Syr Ginger,,,Terence,Rograkh/Silas ninjas,16,15,combat damage,FFA,Yuriko + ninja informant = overwhelming card advantage
2/25/24,Ryan,Omnath,Patrick,Rafiq,Terence,Yoshimaru/Reyhan,Jeff,Go-Shintai of Life's Origin,,,,,Jeff,Go-Shintai of Life's Origin,8,5,combat damage,FFA,Shrine of tapping stuff down bought just enough time
2/28/24,Terence,Dargo/Nadier,Ryan,Pantlaza,Patrick,Niv-Mizzet,,,,,,,Ryan,Pantlaza,10,9,combat damage,FFA,Hasty dinosaurs post-wrath with a Savage Order for Gishath chonks life totals
2/28/24,Ryan,Gitrog,Patrick,Niv-Mizzet,Terence,Dargo/Nadier,,,,,,,Patrick,Niv-Mizzet,9,9,combat damage,FFA,Faeburrow Elder enables quick acceleration; Case of the Shattered Pact is quick damage
2/28/24,Ryan,Gitrog,Patrick,Niv-Mizzet,Terence,Dargo/Nadier,,,,,,,Terence,Dargo/Nadier,8,5,combat damage,FFA,Dargo with Jeska 1-shot Ryan (and earned 27 impulse draws via Fire Giant's Fury - into Burnt Offering); Skull Storm precisely lethal
2/28/24,Ryan,"Liesa, Shroud of Dusk",Patrick,Duke Ulder Ravengard,Terence,Malcolm/Ich-Tekik,,,,,,,Patrick,Duke Ulder Ravengard,13,11,combat damage,FFA,Stealing Angel of Destiny and giving myriad 1-shot Ryan (while earning 60 life)
3/10/24,stranger,"Krenko, Tin Street Kingpin",Patrick,Tekuthal,stranger,Gishath,stranger,Ur-Dragon,,,,,stranger,Ur-Dragon,7,7,combat damage,FFA,"Master Warcraft with Atarka, Miirym, and 2 Ur-Dragons; poor threat analysis (2 friends didn't target each other)"
3/10/24,stranger,Gishath,stranger,Ur-Dragon,stranger,Korvold,Patrick,Dihada,,,,,Patrick,Dihada,10,8,combat damage,FFA,Heroes' Podium + Day of Destiny stacks quickly; Malik gets around Lightning Greaves (same 2 friends)
3/10/24,stranger,"Lazav, the Multifarious",stranger,"Mirri, Weatherlight Duelist",Patrick,Duke Ulder Ravengard,stranger,Anzrag,,,,,Patrick,Duke Ulder Ravengard,11,9,combat damage,FFA,Lazav cast an honest Eater of Days to block Anzrag buffed by Xenagos; Knight-Captain of Eos perma-fogged Anzrag to victory
3/10/24,stranger,"Brimaz, Blight of Oreskos",stranger,"The Master, Multiplied",stranger,"Lonis, Cryptozoologist",stranger,"Mirri, Weatherlight Duelist",Patrick,Tekuthal,,,stranger,"The Master, Multiplied",7,7,combat damage,FFA,unchecked Master Multiplied with ramp = 13 Masters attacking everyone; Brimaz + Tekuthal both mana screwed
3/10/24,stranger,"Brimaz, Blight of Oreskos",stranger,"The Master, Multiplied",stranger,"Lonis, Cryptozoologist",stranger,"Mirri, Weatherlight Duelist",Patrick,Tekuthal,,,stranger,"Brimaz, Blight of Oreskos",12,12,quality of life concede,FFA,Several board wipes + removal with life totals largely intact; dealt with Koma; Myojin of Seeing Winds drew 13 and could keep going but conceded
3/15/24,Terence,Atraxa win-cons,Ryan,Emiel,Patrick,Duke Ulder Ravengard,,,,,,,Patrick,Duke Ulder Ravengard,16,13,combat damage,FFA,Ghostway + wrath to slow down Emiel+Seedborn
3/15/24,Patrick,Niv-Mizzet,Terence,Yidris dredge,Ryan,Pantlaza,,,,,,,Terence,Yidris dredge,10,9,combat damage,FFA,"Living End claims another victim, even when scripted a turn ahead"
3/15/24,Ryan,Pantlaza,Patrick,Niv-Mizzet,Terence,Yidris dredge,,,,,,,Ryan,Pantlaza,12,12,combat damage,FFA,Ghalta discover trigger into Portal to Phyrexia (with Skullspore Nexus)
3/15/24,Ryan,Reyav,Patrick,Laelia,Terence,Yidris dredge,,,,,,,Terence,Yidris dredge,9,7,combat damage,FFA,Echoing Equation on Hogaak takes out Patrick; Narcomoeba attacking was the final damage to Ryan
3/30/24,Jack F,"Brenard, Ginger Sculptor",Terence,Ravos/Rebbec,Patrick,Duke Ulder Ravengard,Jeff,Mondrak,Brandon,The Wise Mothman,,,Jeff,Mondrak,11,8,combat damage,FFA,Anointed Procession + (destroyed: Cathar's Crusade + Starlight Spectacular) with multiple wraths overcame a LARGE Mothman and Brenard's army
3/30/24,Ajit,Brago,Patrick,Laelia,Jeff,Go-Shintai of Life's Origin,Brandon,"Liberty Prime, Recharged",Jack F,"Astor, Bearer of Blades",,,Ajit,Brago,14,9,combat damage,FFA,"Brago + Medomai turns ft. 21/21 Astor (RIP Patrick), 22/22 Danitha; 31/31 Laelia; Goblin Welder loops of Synth-Reflector Mages; 7+ shrines threatening w/ Zur"
4/10/24,Terence,Ishai/Tana,Ryan,Don Andres,Patrick,Tekuthal,,,,,,,Terence,Ishai/Tana,9,9,combat damage,FFA,Assemble the Legion + Felidar Retreat
4/10/24,Patrick,Tekuthal,Terence,Ishai/Tana,Ryan,Don Andres,,,,,,,Patrick,Tekuthal,10,10,poison,FFA,Don Andres cast Eternal Dominion
4/16/24,Ryan,Goose Mother,Terence,"Vorinclex, Monstrous Raider",Patrick,Maarika,,,,,,,Terence,"Vorinclex, Monstrous Raider",10,9,21+ commander,FFA,Vorinclex + Bone Saws backed up by hexproof
4/16/24,Terence,Kefnet the Mindful,Patrick,Maarika,Ryan,Goose Mother,,,,,,,Terence,Kefnet the Mindful,10,9,21+ commander,FFA,Kefnet wears a Robe of the Archmagi and survives Phasing of Zhalfir; Ryan Mana Drained a t4 Harmonize into a large Goose
4/16/24,Terence,Kefnet the Mindful,Patrick,Dihada,Ryan,Emiel,,,,,,,Terence,Kefnet the Mindful,13,12,21+ commander,FFA,Kefnet w/ Empyrial Plate
4/20/24,Jack J,Syr Ginger,Patrick,Kamahl/Prava,Terence,Atraxa win-cons,,,,,,,Patrick,Kamahl/Prava,9,8,combat damage,FFA,Inspiring Leader + both commanders
4/20/24,Terence,Atraxa win-cons,Jack J,Syr Ginger,Ryan,Emiel,Patrick,Kamahl/Prava,,,,,Jack J,Syr Ginger,15,12,combat damage,FFA,Ghalta/Mavren made 20 vampires (w/ Doubling Season); Millenium Calendar hit 50; Spine of Ish Sah recurred each turn
4/20/24,Ryan,Gitrog,Patrick,Laelia,Terence,Amber/Veteran Soldier,Jack J,Ghyrson Starn,,,,,Patrick,Laelia,10,9,21+ commander,FFA,"Throne of Eldraine into Etali snowballed, then Laelia cascaded for +50/+50. Slicer *nearly* took Laelia out. Terence Generous Gifted Ryan's only land"
4/20/24,Terence,Vial Smasher/Sidar Kondo,Ryan,"Liesa, Shroud of Dusk",Patrick,Dihada,,,,,,,Ryan,"Liesa, Shroud of Dusk",11,10,combat damage,FFA,Austere Command
4/20/24,Patrick,Dihada,Terence,Vial Smasher/Sidar Kondo,Ryan,"Liesa, Shroud of Dusk",,,,,,,Terence,Vial Smasher/Sidar Kondo,10,8,combat damage,FFA,Authority of the Consul
4/23/24,Patrick,Ashad,Terence,Phabine,Ryan,Zaxara,,,,,,,Terence,Phabine,8,7,combat damage,FFA,"Adeline, Port Razer, Halana and Alena into Phabine"
4/23/24,Ryan,Zaxara,Patrick,Ashad,Terence,(Borrowed) Ryan's Jon Irenicus,,,,,,,Ryan,Zaxara,9,7,combat damage,FFA,Genesis Wave for 7; Exponential Growth for 3; Villainous Wealth for 19; Biomass Mutation for 32 (477 trample damage)
4/23/24,Ryan,Reyav,Patrick,Gwenna,Terence,Yidris dredge,,,,,,,Patrick,Gwenna,11,7,combat damage,FFA,Living Death wiped out Reyav early; Ram Through post Zopandrel for lethal
4/23/24,Ryan,Gitrog,Patrick,Rafiq,Terence,Jan Jansen,,,,,,,Terence,Jan Jansen,9,8,aristocrats/burn,FFA,Mirkwood Bats + Thornbite Staff + Mayhem Devil + Jan Jansen ftw; Rafiq flooded after a terrifying start
5/1/24,Brandon,"Gavi, Nest Warden",Ryan,Ziatora,Patrick,Ashad,Terence,"Izzet (Jori En, Ruin Diver)",,,,,Terence,"Izzet (Jori En, Ruin Diver)",9,8,combat damage,FFA,"Arcane Bombardment, Stormkiln Artist, Haughty Djinn should've been stopped sooner. Djinn Illuminatus replicated Lightning Bolt x8 to take out Ashad"
5/1/24,Patrick,Ashad,Terence,"Izzet (Bilbo, Retired Burglar)",Brandon,"Dogmeat, Ever Loyal",Ryan,Ziatora,,,,,Patrick,Ashad,11,6,combat damage,FFA,Ziatora+GE-Rhonas+Zopandrel KO'ed Brandon on t6; Ashad and 8 Mishra's Self-Replicators went wide enough
5/7/24,Terence,Tevesh Szat/Kraum,Ryan,Ur-Dragon,Patrick,Kamahl/Prava,,,,,,,Ryan,Ur-Dragon,11,10,combat damage,FFA,"Elminster's Simulacrum (copied) created 2 dragons and a Kamahl, but didn't live to untap"
5/7/24,Terence,Wernog/Cecily,Ryan,Ur-Dragon,Patrick,Kamahl/Prava,,,,,,,Terence,Wernog/Cecily,11,11,alt win-con,FFA,Hellkite Tyrant win-con enabled by Storm the Vault and Wernog flickers (equalled 32 life!)
5/7/24,Terence,Ravos/Rebbec,Ryan,Zaxara,Patrick,Kamahl/Prava,,,,,,,Terence,Ravos/Rebbec,11,10,combat damage,FFA,"Rammas Echor, Door of Destinies, Metallic Mimic, Hero of Bladehold took out Ryan 2 turns before Simic Ascendancy, then Anduril, Narsil Reforged + Biotransference closed it out after a mana-screwed Patrick dropped 8 lands (Harvest Season) w/ Felidar Retreat and Doubling Season"
5/15/24,Ryan,"Tinybones, the Pickpocket",Patrick,"Smeagol, Helpful Guide",Terence,Atraxa win-cons,,,,,,,Terence,Atraxa win-cons,10,10,alt win-con,FFA,Accidental Millennium Calendar win; Smeagol milled both opponents out but forgot Calendar would win on upkeep (and had artifact removal in hand)
5/15/24,Patrick,"Smeagol, Helpful Guide",Terence,Atraxa win-cons,Ryan,"Tinybones, the Pickpocket",,,,,,,Patrick,"Smeagol, Helpful Guide",11,10,combat damage,FFA,Awakening Zone triggered Smeagol every turn; Rampaging Baloths + Invasion of Lorwyn closed out
5/15/24,Terence,Emry,Ryan,Omnath,Patrick,Niv-Mizzet,,,,,,,Terence,Emry,9,9,combat damage,FFA,"T3 Kappa Cannoneer survived 2 board wipes, then Echo Storm created 4 more"
5/15/24,Patrick,Niv-Mizzet,Terence,Emry,Ryan,Omnath,,,,,,,Ryan,Omnath,8,8,aristocrats/burn,FFA,Nissa + Ancient Greenwarden into Crackle With Power
5/18/24,Jack J,Syr Ginger,Patrick,Maarika,Jack F,"Brenard, Ginger Sculptor",Brandon,"Dogmeat, Ever Loyal",,,,,Brandon,"Dogmeat, Ever Loyal",9,6,combat damage,FFA,31-power Dogmeat (Strong Back+Mantle of the Ancients) archenemy'ed the table
5/18/24,Patrick,Maarika,Jack F,Jeskai (The War Doctor/Clara Oswald (blue)),Brandon,"Caesar, Legion's Emperor",Jack J,Ghyrson Starn,,,,,Patrick,Maarika,12,7,combat damage,FFA,Maarika/Tergrid stole Fervent Charge and Iroas to lethal Brandon
5/18/24,Jack F,Jeskai (Kate Stewart),Brandon,"Morska, Undersea Sleuth",Jack J,Ghyrson Starn,Patrick,Kamahl/Prava,,,,,Jack J,Ghyrson Starn,7,7,aristocrats/burn,FFA,"Niv-Mizzet, Ghyrson Starn, Ophidian Eye"
5/18/24,Jack F,"Astor, Bearer of Blades",Brandon,Commodore Guff,Ryan,Don Andres,Jack J,Jon Irenicus,Patrick,Kamahl/Prava,,,Jack F,"Astor, Bearer of Blades",15,9,combat damage,FFA,Lae'Zel and 5 planeswalkers (unanswered for 5 turns) played archenemy until Holy Day and 2 Bruenor swings to the face
5/21/24,Terence,Wilson/Cultist,Patrick,Tekuthal,Ryan,Emiel,,,,,,,Terence,Wilson/Cultist,16,14,combat damage,FFA,Wilson's card-advantage engines never stopped; Jace TMS ult'ed (after a 5*2 proliferate turn) on Emiel; Emiel's White Dragon tapped down Tekuthal's blockers
5/21/24,Ryan,Toxrill,Terence,Rigo,Patrick,Jared [Jegantha],,,,,,,Terence,Rigo,10,8,poison,FFA,"Norn's Decree: incentivized Jared to only attack Toxrill (which halted the 1/1 swarm), then was lethal to a first strike + normal strike would-be attack"
5/21/24,Terence,Vial Smasher/Sidar Kondo,Patrick,Ayara,Ryan,Gitrog,,,,,,,Terence,Vial Smasher/Sidar Kondo,9,8,combat damage,FFA,"Vial Smasher literally only hit Ayara (~20 damage); Ayara jumped from 2 to 20 (taking out mana-screwed Gitrog) w/ Gary, but unblockable + Mercadia's Downfall was exactly lethal"
5/25/24,Jeff,Mondrak,Terence,Viconia/Cultist,Patrick,Kiora,,,,,,,Terence,Viconia/Cultist,9,9,aristocrats/burn,FFA,Living Death: Ayara + Abhorrent Overlord devotion 32 insta lethal
5/25/24,Patrick,Kiora,Jeff,Mondrak,Terence,Viconia/Cultist,,,,,,,Terence,Viconia/Cultist,16,15,combat damage,FFA,Slow one: multiple board bounces and one wipe; bestowed Nighthowler for 19 closed it out
5/26/24,stranger,Jeska/Vial Smasher,stranger,Riku of Many Paths,stranger,Sovereign Okinec Ahau,Patrick,Rafiq,,,,,Patrick,Rafiq,10,5,21+ commander,FFA,"T3 Rafiq w/ mom protection took out Riku, then rebuilt post board wipe (mom survived) and 3/3 commander lethal"
5/26/24,Patrick,Ayara,stranger,"Kellan, the Fae-Blooded",stranger,Sovereign Okinec Ahau,,,,,,,stranger,"Kellan, the Fae-Blooded",13,8,combat damage,FFA,(opted not to play Bolas' Citadel b/c had just won previous game); Kellan won due to fog effect stopping Sovereign from hitting for 100+
5/26/24,stranger,The Swarmlord,stranger,Tergrid,Patrick,Ashad,stranger,"Rocco, Street Chef",,,,,stranger,"Rocco, Street Chef",10,9,combat damage,FFA,Rocco and Tergrid emerged as heavyweights; Rocco Final Showdown'ed in response to Tergrid's Myojin of Night's Reach; Tergrid had to leave and Rocco cleaned up fast
6/2/24,Brandon,Sliver Gravemother,Ajit,Brago,Terence,Umori,Jeff,Go-Shintai of Life's Origin,Patrick,"Smeagol, Helpful Guide",,,Terence,Umori,12,8,combat damage,Star,"Smeagol was a punching bag; Aetherspouts stopped a lethal Rumbleweed, but Sanctum of Stone Fangs inadvertently took out Brandon before Ajit could be taken out"
6/2/24,Patrick,"Smeagol, Helpful Guide",Brandon,Abaddon,Ajit,Jhoira of the Ghitu,Terence,Borborygmos Enraged,Jeff,Mondrak,,,Patrick,"Smeagol, Helpful Guide",6,6,mill,Star,Naturally drew the mill combo
6/2/24,Terence,Borborygmos Enraged,Jeff,Mondrak,Patrick,Duke Ulder Ravengard,Brandon,"Morska, Undersea Sleuth",Ajit,Jhoira of the Ghitu,,,Terence,Borborygmos Enraged,10,8,combat damage,Star,"Windshaper Planetar rerouted 21 Mondrak damage from Brandon to Terence; Mondrak's Starlight Spectacular (would've won if we'd done math precombat to play 1 more creature) was short of killing Brandon so took out Patrick; Morska's Kappa Cannoneer ended Jeff, leaving Terence last one standing"
6/2/24,Brandon,"Atraxa, Grand Unifier",Patrick,Talion,Jeff,Illuna,Ajit,Kadena,Terence,Rograkh/Silas ninjas,,,Patrick,Talion,11,9,combat damage,Star,"Kadena early Tempt for Discovery and stole Talion; Atraxa early Breach the Multiverse (Mommy Norn, Oko, Apex Altisaur, Elspeth Knight Errant) became archenemy; loads of interaction; eventually Talion+Sakashima + Sheoldred closed the door"
6/11/24,Ryan,Reyav,Patrick,Talion,Terence,Umori,,,,,,,Patrick,Talion,13,11,21+ commander,FFA,T2 Hunted Horror centaurs nearly solo'ed Patrick; Sword of W&P stabilized from 5 life
6/11/24,Patrick,Duke Ulder Ravengard,Terence,Ardenn/Esior,Ryan,Emiel,,,,,,,Ryan,Emiel,11,9,combat damage,FFA,Esior w/ Sword of F&F and double strike was dominant until double Manglehorn
6/11/24,Terence,Slimefoot and Squee,Ryan,Chatterfang,Patrick,Ayara,,,,,,,Patrick,Ayara,9,8,aristocrats/burn,FFA,Bolas' Citadel activation lethaled Terence; Muranda Petroglyphs buffed more zombies than squirrels (thus keeping big Liliana alive)
7/5/24,Jeff,Illuna,Natalie,Anikthea,Jack J,Gale/Scion of Halaster,,,,,,,Jeff,Illuna,15,15,aristocrats/burn,FFA,A large Setessan Champion provided ample fuel for a triple Brash Taunter activation
7/5/24,Jeff,Ulalek,Natalie,(Borrowed) Jeff's Go-Shintai,Jack J,Slivers,,,,,,,Jack J,Slivers,8,8,combat damage,FFA,Jack snookered himself as Crystalline Sliver blocked Magma Sliver from going off. Magma Sliver + Sliver Queen + Heart Sliver + Ashnod's Altar is nuts (as is Mana Echoes)
7/5/24,Natalie,(Borrowed) Jack's Ghyrson Starn,Jack J,Evra,Jeff,Ulalek,,,,,,,Natalie,(Borrowed) Jack's Ghyrson Starn,9,9,aristocrats/burn,FFA,"Natalie won by playing a pointless Mana Geyser which triggered a bunch of ""on instant/sorcery"" effects"
7/5/24,Jeff,Mondrak,Natalie,(Borrowed) Jack's Melek,Jack J,Evra,,,,,,,Jack J,Evra,6,6,alt win-con,FFA,Jack wins with Felidar Sovereign after a slow start and with Aetherflux Reservoir
7/5/24,Jack J,Evra,Jeff,Mondrak,Natalie,(Borrowed) Jack's Melek,,,,,,,Jeff,Mondrak,11,11,combat damage,FFA,Guardian of Faith whiffed a huge Evra swing
7/5/24,Natalie,Anikthea,Jack J,Syr Ginger,Jeff,"Liesa, Forgotten Archangel",,,,,,,Natalie,Anikthea,15,15,combat damage,FFA,Enchantments are oppressive!
7/13/24,Ryan,Ulalek,Patrick,Oops all Kayas,Jeff,Ulalek,,,,,,,Jeff,Ulalek,9,7,combat damage,FFA,MH3 Ulamog as a 19/19 w/ Annihilator 12 > two It That Betrays; Patrick mana screwed
7/13/24,Patrick,Oops all Kayas,Jeff,Ulalek,Ryan,Ulalek,,,,,,,Patrick,Oops all Kayas,11,10,combat damage,FFA,13 spirit and bird tokens ftw! Buffed by Intangible Virtue
7/13/24,Patrick,Ashad,Jeff,"Liesa, Forgotten Archangel",Ryan,Rin and Seri,,,,,,,Ryan,Rin and Seri,11,10,combat damage,FFA,"Liesa + Luminous Broodmoth + Vito = redundancy and fast drains! But, double Combustible Gearhulk dropped Liesa from 39 to 4 before dying; Rin and Seri had exactly enough creatures for lethal (upon noting Dauthi Voidwalker has shadow and couldn't block!)"
7/13/24,Patrick,Tekuthal,Jeff,Mondrak,Ryan,Gitrog,,,,,,,Jeff,Mondrak,8,7,combat damage,FFA,"Sol Ring -> Throne of Eldraine -> Cathar's Crusade -> Elesh Norn, GC took out Tekuthal + Flux Channeler + Danny Pink w/ Sword of Truth and Justice one turn before lethal; Gitrog mana screwed"
7/13/24,Jeff,Go-Shintai of Life's Origin,Ryan,Breya,Patrick,Gwenna,,,,,,,Patrick,Gwenna,12,12,combat damage,FFA,Heavyweight battle! KO turn: topdecked Return of the Wildspeaker for 10 cards -> Old Gnawbone + Pest Infestation to clear out leftovers after exiling Darksteel Forge. Double Portal to Phyrexia ate enough Shrines; red Shrine took Daretti and 1 Garruk
7/13/24,Ryan,Reyav,Patrick,Dihada,Jeff,Mondrak,,,,,,,Ryan,Reyav,5,4,21+ commander,FFA,Sol Ring -> Reyav + Shadowspear + 3 more equipment
7/13/24,Patrick,Dihada,Jeff,Mondrak,Ryan,Reyav,,,,,,,Patrick,Dihada,8,7,combat damage,FFA,Reaver Cleaver on Mogis into Gallifrey Falls+No More to (mostly) 1-sided wipe
7/25/24,Ryan,Ulalek,Terence,Ardenn/Esior,Patrick,Ashad,,,,,,,Terence,Ardenn/Esior,12,7,21+ commander,FFA,Ardenn w/ Colossus Hammer for 22; Ugin's Binding bought Ryan a couple turns before the inevitable
7/25/24,Terence,Ardenn/Esior,Patrick,Ashad,Ryan,Goose Mother,,,,,,,Ryan,Goose Mother,12,12,combat damage,FFA,Esior stalled big time; 2x Blinkmoth Urn accelerated large Goose Mothers; critical Silence stopped Ashad; Momentous Fall for 12 into 2x counterspell + Questing Beast lethal
7/25/24,Terence,Vial Smasher/Sidar Kondo,Patrick,Niv-Mizzet,Ryan,Emiel,,,,,,,Terence,Vial Smasher/Sidar Kondo,11,7,combat damage,FFA,Mercadia's Downfall adds 20+ damage to oust Niv-Mizzet
1 Date Player 1 Deck 1 Player 2 Deck 2 Player 3 Deck 3 Player 4 Deck 4 Player 5 Deck 5 Player 6 Deck 6 Winning Player Winning Deck # turns turn 1st player out Type of win Format Notes
2 1/13/24 Evan Kelsien the Plague Terence Ravos/Rebbec Patrick Duke Ulder Ravengard Jeff Mondrak Terence Ravos/Rebbec 15 12 combat damage FFA 3-4 board wipes; Biotransference
3 1/13/24 Terence Wernog/Cecily Patrick Duke Ulder Ravengard Ryan Don Andres Jeff Mondrak Evan Jasmine Boreal of the Seven Patrick Duke Ulder Ravengard 12 10 combat damage FFA Possessed Portal scary!
4 1/13/24 Jeff Go-Shintai of Life's Origin Evan Kethis the Hidden Hand Terence Rograkh/Silas ninjas Patrick Tekuthal Ryan Gitrog Patrick Tekuthal 8 8 poison FFA Flux Channeler + Tekuthal
5 1/13/24 Patrick Tekuthal Jeff Illuna Evan Atraxa, Praetor's Voice Terence Muldrotha Patrick Tekuthal 20 5 combat damage FFA 3 Hullbreaker Horrors simultaneously (Evan forfeited ~t5; game took ~2hrs)
6 1/17/24 Patrick Duke Ulder Ravengard Ryan Grist Terence Ravos/Rebbec Patrick Duke Ulder Ravengard 12 12 combat damage FFA Eternal Wanderer wipe, Angel Serenity + Sun Titan followup
7 1/17/24 Terence Ravos/Rebbec Patrick Duke Ulder Ravengard Ryan Grist Terence Ravos/Rebbec 13 11 combat damage FFA Verge Rangers + Conjurer's Mantle
8 1/23/24 Ryan Goose Mother Patrick Maarika Terence Wilson/Cultist Patrick Maarika 8 7 21+ commander FFA Maarika + Runes of the Deus
9 1/23/24 Ryan Goose Mother Patrick Maarika Terence Wilson/Cultist Terence Wilson/Cultist 10 8 combat damage FFA Scepter of Celebration brings an army
10 1/23/24 Terence Abdel Adrian/Far Traveler Ryan Obeka Patrick Laelia Patrick Laelia 9 8 21+ commander FFA Nalfeshnee copying Storm's Wrath cleared the way; Ryan mana screwed
11 1/23/24 Terence Jan Jansen Ryan Don Andres Patrick Laelia Terence Jan Jansen 10 10 aristocrats/burn FFA Mirkwood Bats + Thornbite Staff ftw; Ryan mana screwed
12 1/30/24 Patrick Urza Terence Me, the Immortal Ryan Gitrog Ryan Gitrog 8 7 combat damage FFA Mending of Dominaria + Lotus Cobra (10 lands)
13 1/30/24 Patrick Kiora Terence Raffine Ryan Kozilek Patrick Kiora 11 9 combat damage FFA Raffine does all the work, then Kederekt Leviathan cleans up
14 2/4/24 Ajit Jhoira of the Ghitu Brandon Anikthea Patrick Oops all Kayas Brandon Anikthea 12 11 combat damage FFA Unopposed enchantress with card draw and Nature's Will
15 2/4/24 Brandon Silvar/Trynn Patrick Oops all Kayas Ryan Purphoros, God of the Forge Ajit Jhoira of the Ghitu Brandon Silvar/Trynn 12 10 aristocrats/burn FFA Bastion of Remembrance overcame Emrakul + It That Betrays
16 2/4/24 Ajit Brago Brandon Marneus Calgar Patrick Laelia Ryan Gitrog Ryan Gitrog 15 12 combat damage FFA Gitrog draws a zillion cards and closes w/ Multani
17 2/4/24 Terence Slimefoot and Squee Patrick Ayara Ryan Omnath Ryan Omnath 8 8 combat damage FFA Vorinclex, Voice of Hunger enables Crackle with Power (x=4) to overcome Army of the Damned
18 2/20/24 Terence Wilson/Cultist Ryan Gitrog Patrick Tekuthal Terence Wilson/Cultist 15 12 combat damage FFA Weatherlight and Ormendahl collect many tithes
19 2/20/24 Ryan Myrel Patrick Tekuthal Terence Ravos/Rebbec Patrick Tekuthal 10 9 combat damage FFA Arcbound Crusher got chonky (w/ Sword of Truth & Justice)
20 2/20/24 Terence Ravos/Rebbec Ryan Myrel Patrick Tekuthal Terence Ravos/Rebbec 10 9 combat damage FFA Ryan's Coat of Arms + Terence's Door of Destinies and Haunted One = math!
21 2/25/24 Patrick Elmar storm Jack J Gale/Scion of Halaster Terence Kefnet the Mindful Jeff Mondrak Ryan Don Andres Jeff Mondrak 12 9 combat damage FFA Elesh Norn is a good finisher; Ryan achievement unlocked: control all other commanders at once
22 2/25/24 Terence Rograkh/Silas ninjas Jeff Illuna Ryan Emiel Patrick Myrkul planeswalkers Jack J Syr Ginger Terence Rograkh/Silas ninjas 16 15 combat damage FFA Yuriko + ninja informant = overwhelming card advantage
23 2/25/24 Ryan Omnath Patrick Rafiq Terence Yoshimaru/Reyhan Jeff Go-Shintai of Life's Origin Jeff Go-Shintai of Life's Origin 8 5 combat damage FFA Shrine of tapping stuff down bought just enough time
24 2/28/24 Terence Dargo/Nadier Ryan Pantlaza Patrick Niv-Mizzet Ryan Pantlaza 10 9 combat damage FFA Hasty dinosaurs post-wrath with a Savage Order for Gishath chonks life totals
25 2/28/24 Ryan Gitrog Patrick Niv-Mizzet Terence Dargo/Nadier Patrick Niv-Mizzet 9 9 combat damage FFA Faeburrow Elder enables quick acceleration; Case of the Shattered Pact is quick damage
26 2/28/24 Ryan Gitrog Patrick Niv-Mizzet Terence Dargo/Nadier Terence Dargo/Nadier 8 5 combat damage FFA Dargo with Jeska 1-shot Ryan (and earned 27 impulse draws via Fire Giant's Fury - into Burnt Offering); Skull Storm precisely lethal
27 2/28/24 Ryan Liesa, Shroud of Dusk Patrick Duke Ulder Ravengard Terence Malcolm/Ich-Tekik Patrick Duke Ulder Ravengard 13 11 combat damage FFA Stealing Angel of Destiny and giving myriad 1-shot Ryan (while earning 60 life)
28 3/10/24 stranger Krenko, Tin Street Kingpin Patrick Tekuthal stranger Gishath stranger Ur-Dragon stranger Ur-Dragon 7 7 combat damage FFA Master Warcraft with Atarka, Miirym, and 2 Ur-Dragons; poor threat analysis (2 friends didn't target each other)
29 3/10/24 stranger Gishath stranger Ur-Dragon stranger Korvold Patrick Dihada Patrick Dihada 10 8 combat damage FFA Heroes' Podium + Day of Destiny stacks quickly; Malik gets around Lightning Greaves (same 2 friends)
30 3/10/24 stranger Lazav, the Multifarious stranger Mirri, Weatherlight Duelist Patrick Duke Ulder Ravengard stranger Anzrag Patrick Duke Ulder Ravengard 11 9 combat damage FFA Lazav cast an honest Eater of Days to block Anzrag buffed by Xenagos; Knight-Captain of Eos perma-fogged Anzrag to victory
31 3/10/24 stranger Brimaz, Blight of Oreskos stranger The Master, Multiplied stranger Lonis, Cryptozoologist stranger Mirri, Weatherlight Duelist Patrick Tekuthal stranger The Master, Multiplied 7 7 combat damage FFA unchecked Master Multiplied with ramp = 13 Masters attacking everyone; Brimaz + Tekuthal both mana screwed
32 3/10/24 stranger Brimaz, Blight of Oreskos stranger The Master, Multiplied stranger Lonis, Cryptozoologist stranger Mirri, Weatherlight Duelist Patrick Tekuthal stranger Brimaz, Blight of Oreskos 12 12 quality of life concede FFA Several board wipes + removal with life totals largely intact; dealt with Koma; Myojin of Seeing Winds drew 13 and could keep going but conceded
33 3/15/24 Terence Atraxa win-cons Ryan Emiel Patrick Duke Ulder Ravengard Patrick Duke Ulder Ravengard 16 13 combat damage FFA Ghostway + wrath to slow down Emiel+Seedborn
34 3/15/24 Patrick Niv-Mizzet Terence Yidris dredge Ryan Pantlaza Terence Yidris dredge 10 9 combat damage FFA Living End claims another victim, even when scripted a turn ahead
35 3/15/24 Ryan Pantlaza Patrick Niv-Mizzet Terence Yidris dredge Ryan Pantlaza 12 12 combat damage FFA Ghalta discover trigger into Portal to Phyrexia (with Skullspore Nexus)
36 3/15/24 Ryan Reyav Patrick Laelia Terence Yidris dredge Terence Yidris dredge 9 7 combat damage FFA Echoing Equation on Hogaak takes out Patrick; Narcomoeba attacking was the final damage to Ryan
37 3/30/24 Jack F Brenard, Ginger Sculptor Terence Ravos/Rebbec Patrick Duke Ulder Ravengard Jeff Mondrak Brandon The Wise Mothman Jeff Mondrak 11 8 combat damage FFA Anointed Procession + (destroyed: Cathar's Crusade + Starlight Spectacular) with multiple wraths overcame a LARGE Mothman and Brenard's army
38 3/30/24 Ajit Brago Patrick Laelia Jeff Go-Shintai of Life's Origin Brandon Liberty Prime, Recharged Jack F Astor, Bearer of Blades Ajit Brago 14 9 combat damage FFA Brago + Medomai turns ft. 21/21 Astor (RIP Patrick), 22/22 Danitha; 31/31 Laelia; Goblin Welder loops of Synth-Reflector Mages; 7+ shrines threatening w/ Zur
39 4/10/24 Terence Ishai/Tana Ryan Don Andres Patrick Tekuthal Terence Ishai/Tana 9 9 combat damage FFA Assemble the Legion + Felidar Retreat
40 4/10/24 Patrick Tekuthal Terence Ishai/Tana Ryan Don Andres Patrick Tekuthal 10 10 poison FFA Don Andres cast Eternal Dominion
41 4/16/24 Ryan Goose Mother Terence Vorinclex, Monstrous Raider Patrick Maarika Terence Vorinclex, Monstrous Raider 10 9 21+ commander FFA Vorinclex + Bone Saws backed up by hexproof
42 4/16/24 Terence Kefnet the Mindful Patrick Maarika Ryan Goose Mother Terence Kefnet the Mindful 10 9 21+ commander FFA Kefnet wears a Robe of the Archmagi and survives Phasing of Zhalfir; Ryan Mana Drained a t4 Harmonize into a large Goose
43 4/16/24 Terence Kefnet the Mindful Patrick Dihada Ryan Emiel Terence Kefnet the Mindful 13 12 21+ commander FFA Kefnet w/ Empyrial Plate
44 4/20/24 Jack J Syr Ginger Patrick Kamahl/Prava Terence Atraxa win-cons Patrick Kamahl/Prava 9 8 combat damage FFA Inspiring Leader + both commanders
45 4/20/24 Terence Atraxa win-cons Jack J Syr Ginger Ryan Emiel Patrick Kamahl/Prava Jack J Syr Ginger 15 12 combat damage FFA Ghalta/Mavren made 20 vampires (w/ Doubling Season); Millenium Calendar hit 50; Spine of Ish Sah recurred each turn
46 4/20/24 Ryan Gitrog Patrick Laelia Terence Amber/Veteran Soldier Jack J Ghyrson Starn Patrick Laelia 10 9 21+ commander FFA Throne of Eldraine into Etali snowballed, then Laelia cascaded for +50/+50. Slicer *nearly* took Laelia out. Terence Generous Gifted Ryan's only land
47 4/20/24 Terence Vial Smasher/Sidar Kondo Ryan Liesa, Shroud of Dusk Patrick Dihada Ryan Liesa, Shroud of Dusk 11 10 combat damage FFA Austere Command
48 4/20/24 Patrick Dihada Terence Vial Smasher/Sidar Kondo Ryan Liesa, Shroud of Dusk Terence Vial Smasher/Sidar Kondo 10 8 combat damage FFA Authority of the Consul
49 4/23/24 Patrick Ashad Terence Phabine Ryan Zaxara Terence Phabine 8 7 combat damage FFA Adeline, Port Razer, Halana and Alena into Phabine
50 4/23/24 Ryan Zaxara Patrick Ashad Terence (Borrowed) Ryan's Jon Irenicus Ryan Zaxara 9 7 combat damage FFA Genesis Wave for 7; Exponential Growth for 3; Villainous Wealth for 19; Biomass Mutation for 32 (477 trample damage)
51 4/23/24 Ryan Reyav Patrick Gwenna Terence Yidris dredge Patrick Gwenna 11 7 combat damage FFA Living Death wiped out Reyav early; Ram Through post Zopandrel for lethal
52 4/23/24 Ryan Gitrog Patrick Rafiq Terence Jan Jansen Terence Jan Jansen 9 8 aristocrats/burn FFA Mirkwood Bats + Thornbite Staff + Mayhem Devil + Jan Jansen ftw; Rafiq flooded after a terrifying start
53 5/1/24 Brandon Gavi, Nest Warden Ryan Ziatora Patrick Ashad Terence Izzet (Jori En, Ruin Diver) Terence Izzet (Jori En, Ruin Diver) 9 8 combat damage FFA Arcane Bombardment, Stormkiln Artist, Haughty Djinn should've been stopped sooner. Djinn Illuminatus replicated Lightning Bolt x8 to take out Ashad
54 5/1/24 Patrick Ashad Terence Izzet (Bilbo, Retired Burglar) Brandon Dogmeat, Ever Loyal Ryan Ziatora Patrick Ashad 11 6 combat damage FFA Ziatora+GE-Rhonas+Zopandrel KO'ed Brandon on t6; Ashad and 8 Mishra's Self-Replicators went wide enough
55 5/7/24 Terence Tevesh Szat/Kraum Ryan Ur-Dragon Patrick Kamahl/Prava Ryan Ur-Dragon 11 10 combat damage FFA Elminster's Simulacrum (copied) created 2 dragons and a Kamahl, but didn't live to untap
56 5/7/24 Terence Wernog/Cecily Ryan Ur-Dragon Patrick Kamahl/Prava Terence Wernog/Cecily 11 11 alt win-con FFA Hellkite Tyrant win-con enabled by Storm the Vault and Wernog flickers (equalled 32 life!)
57 5/7/24 Terence Ravos/Rebbec Ryan Zaxara Patrick Kamahl/Prava Terence Ravos/Rebbec 11 10 combat damage FFA Rammas Echor, Door of Destinies, Metallic Mimic, Hero of Bladehold took out Ryan 2 turns before Simic Ascendancy, then Anduril, Narsil Reforged + Biotransference closed it out after a mana-screwed Patrick dropped 8 lands (Harvest Season) w/ Felidar Retreat and Doubling Season
58 5/15/24 Ryan Tinybones, the Pickpocket Patrick Smeagol, Helpful Guide Terence Atraxa win-cons Terence Atraxa win-cons 10 10 alt win-con FFA Accidental Millennium Calendar win; Smeagol milled both opponents out but forgot Calendar would win on upkeep (and had artifact removal in hand)
59 5/15/24 Patrick Smeagol, Helpful Guide Terence Atraxa win-cons Ryan Tinybones, the Pickpocket Patrick Smeagol, Helpful Guide 11 10 combat damage FFA Awakening Zone triggered Smeagol every turn; Rampaging Baloths + Invasion of Lorwyn closed out
60 5/15/24 Terence Emry Ryan Omnath Patrick Niv-Mizzet Terence Emry 9 9 combat damage FFA T3 Kappa Cannoneer survived 2 board wipes, then Echo Storm created 4 more
61 5/15/24 Patrick Niv-Mizzet Terence Emry Ryan Omnath Ryan Omnath 8 8 aristocrats/burn FFA Nissa + Ancient Greenwarden into Crackle With Power
62 5/18/24 Jack J Syr Ginger Patrick Maarika Jack F Brenard, Ginger Sculptor Brandon Dogmeat, Ever Loyal Brandon Dogmeat, Ever Loyal 9 6 combat damage FFA 31-power Dogmeat (Strong Back+Mantle of the Ancients) archenemy'ed the table
63 5/18/24 Patrick Maarika Jack F Jeskai (The War Doctor/Clara Oswald (blue)) Brandon Caesar, Legion's Emperor Jack J Ghyrson Starn Patrick Maarika 12 7 combat damage FFA Maarika/Tergrid stole Fervent Charge and Iroas to lethal Brandon
64 5/18/24 Jack F Jeskai (Kate Stewart) Brandon Morska, Undersea Sleuth Jack J Ghyrson Starn Patrick Kamahl/Prava Jack J Ghyrson Starn 7 7 aristocrats/burn FFA Niv-Mizzet, Ghyrson Starn, Ophidian Eye
65 5/18/24 Jack F Astor, Bearer of Blades Brandon Commodore Guff Ryan Don Andres Jack J Jon Irenicus Patrick Kamahl/Prava Jack F Astor, Bearer of Blades 15 9 combat damage FFA Lae'Zel and 5 planeswalkers (unanswered for 5 turns) played archenemy until Holy Day and 2 Bruenor swings to the face
66 5/21/24 Terence Wilson/Cultist Patrick Tekuthal Ryan Emiel Terence Wilson/Cultist 16 14 combat damage FFA Wilson's card-advantage engines never stopped; Jace TMS ult'ed (after a 5*2 proliferate turn) on Emiel; Emiel's White Dragon tapped down Tekuthal's blockers
67 5/21/24 Ryan Toxrill Terence Rigo Patrick Jared [Jegantha] Terence Rigo 10 8 poison FFA Norn's Decree: incentivized Jared to only attack Toxrill (which halted the 1/1 swarm), then was lethal to a first strike + normal strike would-be attack
68 5/21/24 Terence Vial Smasher/Sidar Kondo Patrick Ayara Ryan Gitrog Terence Vial Smasher/Sidar Kondo 9 8 combat damage FFA Vial Smasher literally only hit Ayara (~20 damage); Ayara jumped from 2 to 20 (taking out mana-screwed Gitrog) w/ Gary, but unblockable + Mercadia's Downfall was exactly lethal
69 5/25/24 Jeff Mondrak Terence Viconia/Cultist Patrick Kiora Terence Viconia/Cultist 9 9 aristocrats/burn FFA Living Death: Ayara + Abhorrent Overlord devotion 32 insta lethal
70 5/25/24 Patrick Kiora Jeff Mondrak Terence Viconia/Cultist Terence Viconia/Cultist 16 15 combat damage FFA Slow one: multiple board bounces and one wipe; bestowed Nighthowler for 19 closed it out
71 5/26/24 stranger Jeska/Vial Smasher stranger Riku of Many Paths stranger Sovereign Okinec Ahau Patrick Rafiq Patrick Rafiq 10 5 21+ commander FFA T3 Rafiq w/ mom protection took out Riku, then rebuilt post board wipe (mom survived) and 3/3 commander lethal
72 5/26/24 Patrick Ayara stranger Kellan, the Fae-Blooded stranger Sovereign Okinec Ahau stranger Kellan, the Fae-Blooded 13 8 combat damage FFA (opted not to play Bolas' Citadel b/c had just won previous game); Kellan won due to fog effect stopping Sovereign from hitting for 100+
73 5/26/24 stranger The Swarmlord stranger Tergrid Patrick Ashad stranger Rocco, Street Chef stranger Rocco, Street Chef 10 9 combat damage FFA Rocco and Tergrid emerged as heavyweights; Rocco Final Showdown'ed in response to Tergrid's Myojin of Night's Reach; Tergrid had to leave and Rocco cleaned up fast
74 6/2/24 Brandon Sliver Gravemother Ajit Brago Terence Umori Jeff Go-Shintai of Life's Origin Patrick Smeagol, Helpful Guide Terence Umori 12 8 combat damage Star Smeagol was a punching bag; Aetherspouts stopped a lethal Rumbleweed, but Sanctum of Stone Fangs inadvertently took out Brandon before Ajit could be taken out
75 6/2/24 Patrick Smeagol, Helpful Guide Brandon Abaddon Ajit Jhoira of the Ghitu Terence Borborygmos Enraged Jeff Mondrak Patrick Smeagol, Helpful Guide 6 6 mill Star Naturally drew the mill combo
76 6/2/24 Terence Borborygmos Enraged Jeff Mondrak Patrick Duke Ulder Ravengard Brandon Morska, Undersea Sleuth Ajit Jhoira of the Ghitu Terence Borborygmos Enraged 10 8 combat damage Star Windshaper Planetar rerouted 21 Mondrak damage from Brandon to Terence; Mondrak's Starlight Spectacular (would've won if we'd done math precombat to play 1 more creature) was short of killing Brandon so took out Patrick; Morska's Kappa Cannoneer ended Jeff, leaving Terence last one standing
77 6/2/24 Brandon Atraxa, Grand Unifier Patrick Talion Jeff Illuna Ajit Kadena Terence Rograkh/Silas ninjas Patrick Talion 11 9 combat damage Star Kadena early Tempt for Discovery and stole Talion; Atraxa early Breach the Multiverse (Mommy Norn, Oko, Apex Altisaur, Elspeth Knight Errant) became archenemy; loads of interaction; eventually Talion+Sakashima + Sheoldred closed the door
78 6/11/24 Ryan Reyav Patrick Talion Terence Umori Patrick Talion 13 11 21+ commander FFA T2 Hunted Horror centaurs nearly solo'ed Patrick; Sword of W&P stabilized from 5 life
79 6/11/24 Patrick Duke Ulder Ravengard Terence Ardenn/Esior Ryan Emiel Ryan Emiel 11 9 combat damage FFA Esior w/ Sword of F&F and double strike was dominant until double Manglehorn
80 6/11/24 Terence Slimefoot and Squee Ryan Chatterfang Patrick Ayara Patrick Ayara 9 8 aristocrats/burn FFA Bolas' Citadel activation lethaled Terence; Muranda Petroglyphs buffed more zombies than squirrels (thus keeping big Liliana alive)
81 7/5/24 Jeff Illuna Natalie Anikthea Jack J Gale/Scion of Halaster Jeff Illuna 15 15 aristocrats/burn FFA A large Setessan Champion provided ample fuel for a triple Brash Taunter activation
82 7/5/24 Jeff Ulalek Natalie (Borrowed) Jeff's Go-Shintai Jack J Slivers Jack J Slivers 8 8 combat damage FFA Jack snookered himself as Crystalline Sliver blocked Magma Sliver from going off. Magma Sliver + Sliver Queen + Heart Sliver + Ashnod's Altar is nuts (as is Mana Echoes)
83 7/5/24 Natalie (Borrowed) Jack's Ghyrson Starn Jack J Evra Jeff Ulalek Natalie (Borrowed) Jack's Ghyrson Starn 9 9 aristocrats/burn FFA Natalie won by playing a pointless Mana Geyser which triggered a bunch of "on instant/sorcery" effects
84 7/5/24 Jeff Mondrak Natalie (Borrowed) Jack's Melek Jack J Evra Jack J Evra 6 6 alt win-con FFA Jack wins with Felidar Sovereign after a slow start and with Aetherflux Reservoir
85 7/5/24 Jack J Evra Jeff Mondrak Natalie (Borrowed) Jack's Melek Jeff Mondrak 11 11 combat damage FFA Guardian of Faith whiffed a huge Evra swing
86 7/5/24 Natalie Anikthea Jack J Syr Ginger Jeff Liesa, Forgotten Archangel Natalie Anikthea 15 15 combat damage FFA Enchantments are oppressive!
87 7/13/24 Ryan Ulalek Patrick Oops all Kayas Jeff Ulalek Jeff Ulalek 9 7 combat damage FFA MH3 Ulamog as a 19/19 w/ Annihilator 12 > two It That Betrays; Patrick mana screwed
88 7/13/24 Patrick Oops all Kayas Jeff Ulalek Ryan Ulalek Patrick Oops all Kayas 11 10 combat damage FFA 13 spirit and bird tokens ftw! Buffed by Intangible Virtue
89 7/13/24 Patrick Ashad Jeff Liesa, Forgotten Archangel Ryan Rin and Seri Ryan Rin and Seri 11 10 combat damage FFA Liesa + Luminous Broodmoth + Vito = redundancy and fast drains! But, double Combustible Gearhulk dropped Liesa from 39 to 4 before dying; Rin and Seri had exactly enough creatures for lethal (upon noting Dauthi Voidwalker has shadow and couldn't block!)
90 7/13/24 Patrick Tekuthal Jeff Mondrak Ryan Gitrog Jeff Mondrak 8 7 combat damage FFA Sol Ring -> Throne of Eldraine -> Cathar's Crusade -> Elesh Norn, GC took out Tekuthal + Flux Channeler + Danny Pink w/ Sword of Truth and Justice one turn before lethal; Gitrog mana screwed
91 7/13/24 Jeff Go-Shintai of Life's Origin Ryan Breya Patrick Gwenna Patrick Gwenna 12 12 combat damage FFA Heavyweight battle! KO turn: topdecked Return of the Wildspeaker for 10 cards -> Old Gnawbone + Pest Infestation to clear out leftovers after exiling Darksteel Forge. Double Portal to Phyrexia ate enough Shrines; red Shrine took Daretti and 1 Garruk
92 7/13/24 Ryan Reyav Patrick Dihada Jeff Mondrak Ryan Reyav 5 4 21+ commander FFA Sol Ring -> Reyav + Shadowspear + 3 more equipment
93 7/13/24 Patrick Dihada Jeff Mondrak Ryan Reyav Patrick Dihada 8 7 combat damage FFA Reaver Cleaver on Mogis into Gallifrey Falls+No More to (mostly) 1-sided wipe
94 7/25/24 Ryan Ulalek Terence Ardenn/Esior Patrick Ashad Terence Ardenn/Esior 12 7 21+ commander FFA Ardenn w/ Colossus Hammer for 22; Ugin's Binding bought Ryan a couple turns before the inevitable
95 7/25/24 Terence Ardenn/Esior Patrick Ashad Ryan Goose Mother Ryan Goose Mother 12 12 combat damage FFA Esior stalled big time; 2x Blinkmoth Urn accelerated large Goose Mothers; critical Silence stopped Ashad; Momentous Fall for 12 into 2x counterspell + Questing Beast lethal
96 7/25/24 Terence Vial Smasher/Sidar Kondo Patrick Niv-Mizzet Ryan Emiel Terence Vial Smasher/Sidar Kondo 11 7 combat damage FFA Mercadia's Downfall adds 20+ damage to oust Niv-Mizzet

View File

@ -62,6 +62,36 @@ def test_add_and_retrieve_deck(test_client: TestClient, cleanups):
cleanups.add_success(success_cleanup) cleanups.add_success(success_cleanup)
def test_incremental_add_of_games(test_client: TestClient, cleanups):
latest_deck_response = _json_get(test_client, "/game/latest_game")
assert latest_deck_response.status_code == 404
# https://github.com/tiangolo/fastapi/issues/1536#issuecomment-640781718
with open("seed-data/all-in-one.csv", "rb") as f:
test_client.post(
"/api/seed/all_in_one",
files={"file": ("fake_all_in_one_filename.csv", f, "text/csv")},
)
latest_deck_response = _json_get(test_client, "/game/latest_game")
assert latest_deck_response.status_code == 200
print(latest_deck_response.json())
assert latest_deck_response.json()["date"] == "2024-07-05T00:00:00"
# then seed again, and check that it successfully gets the expected latest
with open(
"seed-data/all-in-one-updated-for-incremental-add-testing.csv", "rb"
) as f:
test_client.post(
"/api/seed/all_in_one",
files={"file": ("fake_all_in_one_filename.csv", f, "text/csv")},
)
latest_deck_response = _json_get(test_client, "/game/latest_game")
assert latest_deck_response.status_code == 200
assert latest_deck_response.json()["date"] == "2024-07-25T00:00:00"
def _json_get(c: TestClient, path: str) -> httpx.Response: def _json_get(c: TestClient, path: str) -> httpx.Response:
return c.get(f"/api{path}", headers={"Content-Type": "application/json"}) return c.get(f"/api{path}", headers={"Content-Type": "application/json"})