Skip to content

Releases: phase-rs/phase

v0.20.0

Choose a tag to compare

@github-actions github-actions released this 09 Jul 19:22
Immutable release. Only release title and notes can be modified.

Downloads

Platform File
Windows Phase_*_x64-setup.exe
macOS (Apple Silicon) Phase_*_aarch64.dmg
Linux Phase_*_amd64.AppImage or .deb

macOS note: If you see "this app is damaged", open Terminal and run: xattr -cr /Applications/Phase.app

Changes

  • feat(parser): static grant of an alt-cost keyword equal to its mana cost (#5435) (#5436)
  • chore: refresh metagame feeds (#5434)
  • test(parser): regression guard for compound-subject controller-suffix splitting (issue #5412) (#5414)
  • fix(parser): scope "becomes tapped during your turn" trigger to the controller's turn (Captain America) (#5325) (#5430)
  • perf(engine): convert known-tokens.toml to JSON at build time for ~10x faster catalog load (#5432)
  • Add Render Silent (#5110)
  • fix(client): surface player curses in split-view seat header + restore badge interactivity (#5431)
  • fix(client): player-attached Auras are selectable for every object choice (#5289) (#5429)
  • fix(parser): support filtered card counts in the chosen player's zone (#5425) (#5426)
  • perf(test): fold 206 top-level engine test binaries into the integration harness (#5427)
  • docs(changelog): add entry #168 (combat requirement badges) + Discord post (#5428)
  • Fix "blocks or becomes blocked by [filter]" trigger class (Cockatrice, Venom, Mammoth Harness, Karn Silver Golem, and more) (#5423)
  • test(parser): guard Sram Oxford-comma fix on mixed core+subtype lists (#5424)
  • MULTIPLAYER: resume server-hosted rooms after reload (#5359)
  • fix(engine): grant dynamic Mobilize X for "where X is its power" (Infantry Shield) (#5266) (#5413)
  • Fix spell-cast trigger pronoun binding (#5410)
  • Fix Oxford-comma spell-type lists in cast triggers (#5324) (#5421)
  • fix(parser): allow mixed top-of-library play/cast filters (#4820)
  • feat(parser): leading except-for exempt-list restriction static — Akron Legionnaire (CR 508.1c) (#5409)
  • fix(client): accept lowercase set codes in MTGA deck lines (#5191)
  • fix(client): include sideboard in the bracket-estimate cache key (#5188)
  • fix(client): include deckFolders in the backup digest and diff (#5185)
  • fix(client): guard zero-duration effects in ParticleSystem against a NaN leak (#5180)
  • fix(client): make toRoman render blank for a missing/invalid class level (#5179)
  • fix(client): avoid a NaN comparator in sortCreaturesForBlockers (#5177)
  • fix(client): require a positive integer count for feed deck entries (#5176)
  • fix(client): expand shorthand hex in hexToRgb instead of yielding a NaN channel (#5174)
  • fix(client): guard getArcPath against coincident endpoints (#5173)
  • fix(client): ignore NaN in setDownloadProgress instead of storing it (#5070)
  • fix(client): count mana shards serialized as engine variant names (#5065)
  • feat(engine,client): view and clear 'don't ask again' may-trigger auto-choices (#5419)
  • feat(engine,client): combat attack/block requirement indicators + goad-target confirm gating (#5418)
  • fix(client): scry/surveil dialog scrolls to reach all cards at large counts (#5416)
  • feat(client): render companion as far-right card in the hand fan (#5417)
  • fix(parser): Etali, Primal Sickness 'get that many poison counters' binds event amount (#5415)
  • Auto-order Stonehoof per-attacker triggers with 10+ attackers (#5335) (#5399)

  • fix(engine): defending-player resolution consults the triggering event, not just the ability source (Leeching Sliver) (#5407)
  • feat(parser): compound-subject chosen-type static (Rukarumel, Biologist) (#5246) (#5406)
  • fix(client): per-prompt key on combat damage modals so sequential trample prompts render (#5405)
  • feat(parser): Sothera, the Supervoid dies-edict exile + end-step linked reanimation (#5404)
  • feat(engine): Kaya, Geist Hunter -2 token doubling (floating until-EOT replacement) (#5402)
  • feat(parser): Vraska, Betrayal's Sting -2 become-Treasure and -9 poison-to-difference (#5403)
  • fix(parser): Jaheira grants mana ability to all tokens you control, not just creature tokens (#5400)
  • fix(parser): Quest for Renewal counter-gated Seedborn untap static (CR 502.3) (#5401)
  • fix(engine): declined "up to N target" sub-effect no longer inherits parent's target (Cruel Revival) (#5281) (#5397)
  • fix(pr-review): handle parser refactor proof and merge churn (#5398)
  • fix(engine): defer Kodama ETB triggers until search tutor spell finishes (#5336) (#5396)
  • Fix Veyran, Voice of Duality doubling non-spell triggers (#5291) (#5395)
  • Fix Winter Orb / Static Orb (#5394)
  • fix(parser): support "attacking the last chosen player" statics (Triarch Stalker) (#5393)
  • fix(parser): scope attached-creature damage-prevention shields to the equipped/enchanted creature (#5246) (#5390)
  • feat(parser): compound-quantified dual-subject become effect (Nightcreep class) (#5377) (#5385)
  • fix(engine): honor multi_target on Attach so Armory Automaton attach can be skipped (#5339) (#5387)
  • fix(engine): scope hexproof-bypass statics to their beneficiary (Glaring Spotlight) (#5389)
  • feat(parser): N-way Oxford-comma compound-subject keyword static — Shalai, Voice of Plenty (CR 611.3a) (#5384)
  • Fix remaining zone-of-function statics gathers (#1033 follow-up to #5350) (#5381)
  • test(engine): pin Witch's Oven Food token counts for ConditionInstead (#5340) (#5379)
  • feat: add action-based game replay system (#4633)
  • feat(parser): compound-quantified dual-subject become effect (CR 611.3) (#5380)
  • fix(parser): preserve Abzan Beastmaster toughness gate (#5376)
  • fix(parser): recognize "skip their next " for each-player step skips (#5382)
  • refactor(parser): nom P/T remainder combinator in parse_enchanted_is_type (#5300 follow-up) (#5302)
  • fix(parser): bind "the power of the creature that died" dies-trigger ref (#5364)
  • fix(parser): parameterize attacker-scope statics + add enchanted-player scope (#5375)
  • fix(pr-review): include full review metadata in scan (#5373)
  • fix(client): restore opponent hand + avatar hover previews in split-board layout (#5374)
  • fix(parser): keep amass after 'lose life and …' compound (#5341) (#5371)
  • feat(parser): compound player+object hexproof/shroud static (CR 702.11 / CR 702.18 / CR 611.3a) (#5367)
  • chore(changelog): publish #167 — Eidolon taxes opponents, dredge works mid-draw (#5372)

v0.19.0

Choose a tag to compare

@github-actions github-actions released this 09 Jul 07:09
Immutable release. Only release title and notes can be modified.

Downloads

Platform File
Windows Phase_*_x64-setup.exe
macOS (Apple Silicon) Phase_*_aarch64.dmg
Linux Phase_*_amd64.AppImage or .deb

macOS note: If you see "this app is damaged", open Terminal and run: xattr -cr /Applications/Phase.app

Changes

  • fix(engine): offer draw-replacement independently per unit of a multi-card draw (CR 121.6b) (#5360)
  • feat(engine): loyalty-ability activation cost modifiers (Eidolon of Obstruction) (#5319)
  • fix: require owner verification for P2P backup reads (#5365)
  • fix(parser): parse relative card-type target clauses (#5363)
  • fix(parser): capture the count in "Devour [quality] N" keywords (#5362)
  • fix(parser): bind perpetual cost grants to prior referents (#5098)
  • fix(parser): UNSUPPORTED full-set one-off: The Doctor's Tomb (#5205)
  • fix(parser): parse repeated named control clauses (#5114)
  • chore: refresh metagame feeds (#5361)
  • fix(parser): parse compound activation conditions (#5115)
  • [codex] fix(parser): parse repeated named control conditions (#5121)
  • fix(parser): parse source-exile play durations (#5116)
  • fix(parser): parse supertype-qualified enchant targets (#5109)
  • [codex] fix(parser): split repeated named spell conditions (#5123)
  • test(engine): pin Underworld Breach's grant to its own battlefield presence (#1033) (#5350)
  • Update review shipping workflow (#5357)
  • Update engine gameplay handling (#5358)
  • fix(parser): "destroy/exile all X except for " exclusion clause (#5356)
  • fix(engine): resolve triaged card interaction bugs (#5353)
  • Parse counted "you had N or more [type] enter this turn" conditions (Park Heights Pegasus) (#5087)
  • fix(engine): improve autopass grouped mana priority (#5229)
  • fix(parser): lower "if you put a [type] onto the battlefield this way" rider (Spelunking) (#4704)
  • feat(client): mana-font iconography + dialog z-layer (#5355)
  • test(engine): verify Land Grant's reveal-hand alternative cost (#1098) (#5354)
  • test(parser): verify Molten Echoes' chosen-type filter + LastCreated anaphors (#5352)
  • docs(ai-contributor): prioritized task ladder + correct coverage-data selectors (#5320)
  • test(engine): pin Pact of Negation's pay-or-lose upkeep trigger (#1058) (#5351)
  • fix(engine): cast/played permanents you don't own enter under your control (#696) (#5349)
  • test(parser): pin Violent Urge Delirium clause to ParentTarget (#1272) (#5348)
  • Update PR review loop fixup routing
  • fix(parser): target-player possessive zone references in ChangeZone (#1077) (#5347)
  • perf: reduce slow AI and token copy tests (#5343)
  • Fix board choice overlays and attack splitting (#5344)
  • feat(engine): auto-pass priority-window overhaul (G1/G2/G3/G5/G6) (#5346)
  • docs: verify card premise before planning + prefer installed toolchain (#5342)
  • docs(skill): fold MulliganBottomCards row into MulliganDecision (add-interactive-effect) (#5304)
  • chore(changelog): publish #166 - Ad Nauseam repeats resolve correctly (#5345)
  • fix: gate attacks-alone triggers on zero co-attackers (closes #5159) (#5162)
  • fix(parser): scope enchanted-creature's-controller phase triggers (#5275) (#5317)
  • fix(parser): "protection from X or from the color of your choice" is a modal choose-one (#5318)
  • style(ui): remove border tells from game surfaces (#5316)
  • fix(engine): apply Ad Nauseam's repeat-loop reveal/hand/life-loss immediately per iteration (#1032) (#5315)
  • ship/fix turn order hud card image fallback (#5311)
  • fix(parser): scope enchanted-player cast triggers to the enchanted player (#5288) (#5309)
  • engine: support Mycotyrant Tidus Doom and Chaos Warp (#5234)
  • feat(engine): K'rrik Phyrexian pause for activated ability mana costs… (#5307)
  • fix(parser): Lignify-class subtype-only enchanted type-change with base P/T (#5300) (#5305)
  • fix(engine): resolve mulligan bottoming at each player's declare point (CR 103.5b) (#5236)
  • test(engine): add Dina sacrifice-draw regression tests (#718) (#5303)
  • feat(parser): compound-subject land type-change static (CR 305.7 / CR 611.3) (#5301)

v0.18.0

Choose a tag to compare

@github-actions github-actions released this 07 Jul 14:20
Immutable release. Only release title and notes can be modified.

Downloads

Platform File
Windows Phase_*_x64-setup.exe
macOS (Apple Silicon) Phase_*_aarch64.dmg
Linux Phase_*_amd64.AppImage or .deb

macOS note: If you see "this app is damaged", open Terminal and run: xattr -cr /Applications/Phase.app

Changes

  • feat(engine): become-Equipment anthem + granted-equip runtime (Bram, Bludgeon Brawl) (CR 205.1a + 702.6) (#5224)
  • feat(parser): factor animation+additive predicate merge into parse_land_animation (#5297) (#5298)
  • feat(parser): compound-subject land type-change static (CR 611.3 / CR 305.7) (#5296)
  • chore: refresh metagame feeds (#5295)
  • fix(parser): self-ref "it's a " replaces card types (CR 205.1a) (#5218)
  • feat(parser): compound-subject replacement animation static (CR 205.1a / CR 611.3) (#5293)
  • fix(parser): accept U+2019 apostrophe in mana-ability activation exemption (#5217)
  • fix(tokens): role tokens grant their abilities and resolve face art (#5232)
  • fix(parser): bare 'it's a ' replaces card types per CR 205.1a (Arixmethes) (#5231)
  • Support source-defined token P/T presets (#5228)
  • fix: require host_peer_id to delete P2P draft backups (#5226)
  • feat(engine): coerced-attack + end-step punisher (Siren's Call, Maddening Imp) (#5220)
  • ship/token coverage clusters (#5221)
  • chore(changelog): publish #165 - Morph face-down casting arrives (#5225)
  • Fix Light-Paws searched Aura attach target (#4824) (#4867)
  • feat(parser): support "enter tapped this turn" (Due Respect, Nahiri's Lithoforming) (#5222)
  • feat(parser): compound-subject animation static — Life and Limb (CR 611.3) (#5219)
  • fix(engine): apply replacement conditions to pending damage shields (#5193)
  • fix(parser): strip leading universal quantifier (all/each/every) in parse_type_phrase (#5216)
  • feat(parser+engine): enforce "cast only during combat after blockers are declared" (#5215)
  • fix(engine): split cards report wrong mana value and colors off the stack (CR 202.3d / 709.4b) (#5093)
  • fix(parser): decompose supertype in 'you control a ' restrictions (#5212)
  • feat(parser): parse "for each you control with " counts (#5210)
  • fix(data): populate Alchemy spellbook lists from AtomicCards so DraftFromSpellbook works (#5206)
  • Improve setup deck selection UX (#5211)
  • fix(parser): classify each-object damage continuation as mass damage (#5208)
  • Improve PR review automation (#5209)
  • Fix fixed-alternative chosen-color auto-tap (#5207)
  • feat(engine): dynamic CDA power/toughness counted quantities (distinct subtypes, turns taken) (CR 604.3/613.4a) (#5130)
  • fix(parser): cycle the whole hand to the library bottom for Teferi's Puzzle Box (#5202)
  • fix(parser): Hollow One cost reduction miscounts battlefield permanents instead of cycled/discarded cards this turn (#5201)
  • fix(parser): strip ability-word prefix on subject-anchored statics (CR 207.2c) (#5198)
  • fix(parser): order generic subtype-count after qualifier-phrase conditions (#5203)
  • feat: morph / megamorph / disguise face-down spell casting (CR 708.4) (#5171)
  • chore(changelog): publish #164 - Spider-Man cards arrive (#5204)
  • fix(parser): scope "and gets a counter" to each opponent (Vraska's Fall, #4733) (#5200)
  • fix(parser): strip "additional" qualifier from "N additional counters" (#5199)
  • feat(engine): count opponents dealt any damage this turn (Furious Spinesplitter, You've Been Caught Stealing) (#5144)
  • fix(parser): terminate card-name filter at a locative zone ("named X in your graveyard") (#5197)
  • feat(parser): turn-window CDA — leading timing condition + constant P/T form (Angry Mob) (#5196)

v0.17.0

Choose a tag to compare

@github-actions github-actions released this 06 Jul 15:05
Immutable release. Only release title and notes can be modified.

Downloads

Platform File
Windows Phase_*_x64-setup.exe
macOS (Apple Silicon) Phase_*_aarch64.dmg
Linux Phase_*_amd64.AppImage or .deb

macOS note: If you see "this app is damaged", open Terminal and run: xattr -cr /Applications/Phase.app

Changes

  • Fix cast cancellation during distribution prompts (#5168)
  • fix(parser): UNSUPPORTED full-set one-off: Bad Wolf Bay (#5079)
  • fix(parser): UNSUPPORTED cluster: Hidden-commit / opponent-guess interactive primitive (genuinely NE (#4419)
  • fix(parser): UNSUPPORTED full-set one-off: Ood Sphere (#5170)
  • chore: refresh metagame feeds (#5195)
  • fix(engine): make the "before attackers declared" window phase-based (CR 508.1/508.2) (#5192)
  • fix(parser): UNSUPPORTED full-set one-off: Temple of Atropos (#5190)
  • Add Wretched Banquet (#5194)
  • parser: compose leading action with as-enters persisted choice (Anoin… (#5042)
  • fix(parser): UNSUPPORTED cluster: Land/permanent STATIC-STRUCTURE parsing — static_structure gap o (#4694)
  • feat(parser+engine): dynamic-cost keyword grants for Scavenge/Encore/… (#5054)
  • fix(engine): surface orphaned pending triggers on an empty collection batch (#770) (#5172)
  • fix(crew): pilot tokens crew for adjusted power, not raw or doubled (#5154)
  • fix(parser): UNSUPPORTED full-set one-off: Human—Time Lord Meta-Crisis (#4810)
  • Fix Orochi, Witherbloom, and Cloud behavior (#5164)
  • fix(parser): exile-on-enter-if-not-cast replacement for Containment Priest (#4761) (#5151)
  • fix(parser): UNSUPPORTED one-off: Clockspinning (#4595)
  • fix(parser): parse attacking-alone target clauses (#5091)
  • fix(client): guard resizeBand against a degenerate viewport height (#5068)
  • ENGINE: Support Gollum, Scheming Guide (#5055)
  • ENGINE: Fix amassed Army referents (#5102)
  • feat: discoverable priority-yield auto-pass UX (CR 117.3d) (#5167)
  • feat(client): report-picker art thumbnails, zone filter, and debug i18n (#5166)
  • fix(engine): keep Tin Street coverage honest (#5165)
  • feat(client): add report-card nudge and debug-menu entry point (#5160)
  • Add Deathknell Berserker (accept past-tense "was" in possessive stat conditions) (#5163)
  • Add Talruum Piper (#5131)
  • fix(grafana): repair game-completion query and make card triage sortable (#5161)
  • feat(engine): S25 standard-set tranche a (s25a) — 33 cards, Waves 1–4 (#5155)
  • fix(engine): route SearchLibrary's ParentTargetController prompt through the LKI-aware resolver (#822) (#5158)
  • fix: re-prompt behold creature type on spell re-cast (closes #5051) (#5157)
  • feat(parser): bare tribal compound anthem subject "s and other s" (Verdeloth the Ancient) (#5147)
  • feat(parser+engine): Imprisoned in the Moon type-swap-with-granted-ability aura (#4770) (#5142)
  • feat(client): polish card-report picker dialog (#5156)
  • fix: gate cast DistributeAmong on ChooseTarget completion (closes #5145) (#5148)
  • fix: gate discard triggers on madness intervening-if (closes #5143) (#5146)
  • fix(cards): resolve glued combined multi-face names in image lookup (#5125)
  • fix(deck): stop corrupting card names that literally contain "//" (#4790) (#5124)
  • chore(changelog): publish #163 - Priority yields and card reports (#5153)
  • feat(client): expose pinned debug click mode control (#5152)
  • fix(engine): fall back to manual mana payment (#5150)
  • feat(client): add player-facing card-report picker dialog (#5149)
  • chore: remove local Gittensor report scripts
  • chore: use reusable Gittensor impact action
  • feat: auto-pass control suite — priority yields, scoped phase stops, turn boundaries (#5132)
  • fix(engine): snapshot mana ability choices after source ceases (#5141)
  • feat(parser): attached-permanent type SWAP "isn't a X and is a Y in addition to its other types" (Luxior) (#5137)
  • feat(parser): compound bare-color cost-mod subject " spells and spells cost less" (Prophecy Familiar cycle) (#5138)
  • fix: redact nested draftSessionJson secrets in P2P backup snapshots (#5134)

v0.16.0

Choose a tag to compare

@github-actions github-actions released this 05 Jul 13:08
Immutable release. Only release title and notes can be modified.

Downloads

Platform File
Windows Phase_*_x64-setup.exe
macOS (Apple Silicon) Phase_*_aarch64.dmg
Linux Phase_*_amd64.AppImage or .deb

macOS note: If you see "this app is damaged", open Terminal and run: xattr -cr /Applications/Phase.app

Changes

  • feat(parser): "Lands you control are the chosen type in addition to their other types" (Realmwright) (#5136)
  • chore: refresh metagame feeds (#5133)
  • fix: require bearer auth for unauthenticated /admin/drafts endpoints (#5128)
  • fix(engine): stop Jinnie Fay replacement from re-prompting (#4886) (#4938)
  • fix(parser): gate a conditional draw on "if that creature has a +1/+1 counter" (Oblivion's Hunger) (#5129)
  • fix(parser): scope "each opponent attacking that player does the same" curse rider (CR 508.6 + CR 608.2c) (#5025)
  • ship/quantity grammar nom migration (#5127)
  • Add Dazzling Beauty (#5074)
  • feat(grafana): organize telemetry dashboard into rows; card-triage and abandons panels (#5126)
  • fix(engine): recover from dangling pending-trigger cursor; classify stale actions; card-report follow-ups (#5122)
  • fix(parser): preserve named Kookus condition (#5120)
  • fix(parser): preserve single-graveyard target constraint (#5119)
  • Add Sylvan Echoes (#5040)
  • fix(parser): parse anaphoric perpetual effects (#5117)
  • fix(parser): accept deconjugated-singular "assigns combat damage equal to its toughness" (#5111)
  • chore(changelog): publish #162 - World rule arrives (#5112)
  • fix(parser): count only creature cards for Dread Summons' token repeat (#5009)
  • Recover the count and filter when a verb cost continues past an and-clause (#4931)
  • feat(telemetry): card reports and usage events (Tier 2) (#5113)
  • [codex] improve discord issue automation (#4523)
  • fix(parser): parse any-one-plus-other-color mana (#5106)
  • fix(parser): count "the number of you control with " (Axebane Guardian, Doorkeeper) (#5059)
  • fix(parser): count "for each you control with a counter on it" (High Sentinels of Arashin, Armorcraft Judge) (#5024)
  • fix(pr-review): track proof hygiene without blocking reviews (#5108)
  • fix(engine): bind Helm copy-token haste to token (#5094)
  • ship/split board ui polish (#5107)
  • fix(engine): manifest dread drops a non-permanent card instead of manifesting it face down (#4641)
  • fix: enforce draft lobby password on join (password bypass) (#5038)
  • fix(parser): preserve legacy activation timing (#5103)
  • docs(skills): dual-walk boolean axes + sweep-delta evidence step (post-#5072 R4/R5) (#5100)
  • fix(parser): stop named filters before origin zones (#5101)
  • feat(manabrew-compat): adopt updated Manabrew prompt protocol (#5105)
  • feat(telemetry): first-party Tier 1 telemetry — client beacon, worker ingest, engine unimplemented accumulator (#5104)
  • fix(parser): parse targeted perpetual p/t grants (#5099)
  • docs(skills): add read/write-profiler (dual-walk) discipline to walker checklist step (#5086)
  • feat(engine): PR-6.75 — C0-full+C1 read/write conflict profiler; sound CR 603.3b same-event trigger ordering (#5072)
  • fix(parser): preserve optional target counts (#5095)
  • feat(lobby): capture usage analytics in the Cloudflare broker DO (#5097)
  • fix(parser+engine): Skullscorch unless that player has source deal damage (closes #4921) (#4922)
  • fix: redact P2P draft backup seat tokens from HTTP storage (#5053)
  • fix(import): support choose-a-color-or-colorless branches (#4827) (#4932)
  • fix(pr-review): resurface blocked PRs after author follow-up (#5096)
  • feat: support Ghyrson Starn damage trigger (#5090)
  • Configure multiplayer default server for self-hosted builds (#4992)
  • perf(engine): batch identical self-counter triggers (#5084)
  • fix(ci): always publish parse-diff sticky evidence (#5092)
  • fix(parser): protect card-named literals during normalization (#5080)
  • fix(engine): implement the World rule state-based action (CR 704.5k) (#5088)
  • [codex] Reclassify basic land mana backlog bucket (#5089)
  • fix(parser): parse opponent-turn activation restrictions (#5082)
  • fix: support Altaïr copies and freerunning casts (#5083)
  • chore(changelog): publish #161 — Foretell and excess damage arrive (#5085)
  • fix(client): treat a whitespace-only deck-search query as no criteria (#5067)
  • fix(engine): control effects don't end when a player leaves the game (CR 800.4a / 702.26k) (#5077)
  • fix(engine): cast-copy-of-a-card copies never cease to exist (CR 704.5e / 707.10a) + fix CR 707.10f token-transition timing (#5071)

v0.15.0

Choose a tag to compare

@github-actions github-actions released this 04 Jul 13:14
Immutable release. Only release title and notes can be modified.

Downloads

Platform File
Windows Phase_*_x64-setup.exe
macOS (Apple Silicon) Phase_*_aarch64.dmg
Linux Phase_*_amd64.AppImage or .deb

macOS note: If you see "this app is damaged", open Terminal and run: xattr -cr /Applications/Phase.app

Changes

  • Remove resolved root31 backlog entries (#5076)
  • chore: refresh metagame feeds (#5078)
  • fix(parser): UNSUPPORTED full-set one-off: Fixed Point in Time (#4864)
  • fix(parser): UNSUPPORTED cluster: EachDealsDamage variant — 'each you control (#4625)
  • Fix Rebound cast-origin lookup (#4555)
  • fix(frontend): compact commander damage in split view (#5069)
  • fix(parser): UNSUPPORTED cluster: CHOOSE-DISPATCHER seam — choose residual Unimplemented (choose N (#4700)
  • fix(engine): avoid retarget choice for targetless spells (#5066)
  • tools: harden PR review proof signals (#5064)
  • test(frontend): consolidate game state factories (#5063)
  • test(engine): extend scenario resolution driver (#5062)
  • Fix Etali exile cast target parsing (#5061)
  • Add Flame Spill (#5052)
  • fix(parser): Coalition Victory drops its win condition and auto-wins the game (#5060)
  • feat(parser,casting): grant foretell/miracle to hand cards at an MV-derived cost (#5032)
  • Reconstruct Psychic Paper prep branch on main (#4398)
  • fix(parser): UNSUPPORTED one-off: Last Night Together (#4562)
  • Add split multiplayer board layout (#5057)
  • fix(parser): UNSUPPORTED cluster: The Fourth Doctor (Blast COMMANDER) — play historic from TOP OF LI (#4341)
  • fix(parser): UNSUPPORTED cluster: SECRET-BALLOT vote seam — secret votes need a hidden-commit tally (#4685)
  • fix(parser): UNSUPPORTED one-off: The Face of Boe (#4619)
  • fix(parser): UNSUPPORTED one-off: Ace's Baseball Bat (#4591)
  • Parse rounded half quantities after noun phrases (#4901)
  • Fail closed on ignore-effect static riders (#4985)
  • Parse kicked spell trigger qualifiers (#4979)
  • fix(engine): batch delayed phase triggers with normal triggers (#5048)
  • chore(ai): refresh perf-baseline after #5036 Wave-1 AI vetoes (#5046)
  • fix: filter library-draw game events before client broadcast (hidden card leak) (#5037)
  • feat(engine): S07 condition-if standard cluster — 28 cards + token-chain and as-long-as class fixes (#4990)
  • feat(parser): parse Monomania "choose a card in hand, discard the rest" (#5043)
  • feat(parser): supertype-defining statics "[subject] is/are [no longer] [supertype]" (Leyline of Singularity, Melting) (#5020)
  • ENGINE: Scope counter replacements through type phrases (#5027)
  • docs: link Gittensor impact card
  • chore: add Gittensor impact report (#5039)
  • fix(parser): parse Volo creature-type spell qualifier (#4962) (#5013)
  • feat(ai): Wave-1 legality vetoes + x_cast_gate search-depth perf fix (#5036)
  • fix: redact RNG seed from client-visible game state (#5035)
  • fix(engine): Tomb of Annihilation "Sandfall Cell" is a life-loss punisher, not a fabricated Zombie token (#5034)
  • fix(parser): split "then any number of target players each ..." after a compound (#5031)
  • fix(effects): no-op tap/untap choice with zero eligible targets (#4961) (#5016)
  • Grant supertype via "Enchanted [type] is [supertype]" aura (Glittering Frost) (#4930)
  • chore(changelog): publish #160 — Directional attacks and modal forms (#5030)
  • fix(engine): Tomb of Annihilation "Veils of Fear" is a life-loss punisher, not a creature sacrifice (#5029)
  • fix(engine): Tomb of Annihilation "Oubliette" also sacrifices a creature, an artifact, and a land (#5026)
  • perf(engine): eliminate O(N²) full-battlefield static scans via StaticModePresence index (#5022)
  • fix(engine): grant The Atropal deathtouch (Tomb of Annihilation "Cradle of the Death God") (#5021)
  • fix(engine): implement Dungeon of the Mad Mage "Lost Level" as Scry 2 (was a wrong stub) (#5012)
  • feat(combat): directional attack restriction — "attack only the nearest opponent in the chosen direction" (CR 508.1c) (#5003)
  • feat(parser): activated-ability cost mods with mana-ability exemption (Suppression Field, Zirda) (#4981)
  • fix(parser): bind orphaned "choose new targets for the copy" across intervening clauses (CR 707.10c) (#5010)
  • fix(engine): Lost Mine of Phandelver room fidelity (Storeroom target, Fungi Cavern duration) (#5011)
  • feat(parser): gate Ravenous Trap's alt-cost on "an opponent had N cards put into their graveyard this turn" (#5017)
  • Fix Disruptor Flute tax and Oubliette host-bound phasing (#4833) (#4874)
  • fix(parser): parse dynamic pump "for each ... on the battlefield with " (Radiant Archangel, Pride of the Clouds) (#5008)
  • fix(parser): gate extra-blocker grants on trailing "as long as/if" conditions (Entourage of Trest) (#5005)
  • fix(engine): consume filtered one-shot spell cost reductions (CR 601.2f) (#5004)
  • fix(engine): route chosen-player mana prompt and deposit to the recipient (CR 106.4) (#5001)
  • feat(parser): parse variable-first "X plus/minus N" count offset (#5002)

v0.14.0

Choose a tag to compare

@github-actions github-actions released this 03 Jul 13:37
Immutable release. Only release title and notes can be modified.

Downloads

Platform File
Windows Phase_*_x64-setup.exe
macOS (Apple Silicon) Phase_*_aarch64.dmg
Linux Phase_*_amd64.AppImage or .deb

macOS note: If you see "this app is damaged", open Terminal and run: xattr -cr /Applications/Phase.app

Changes

  • chore: refresh metagame feeds (#4998)
  • fix(parser): bind anaphoric "equal to the difference" counter count to the trigger's power comparison (Drizzt Do'Urden) (#4994)
  • fix(engine): clamp negative mill and exile-top counts to zero (CR 107.1b) (#4995)
  • fix(engine): clamp negative discard counts to zero (CR 107.1b) (#4993)
  • feat(parser): modal "As ~ enters, it becomes your choice of" as-enters replacement (#4973)
  • fix(engine): scope Iona's chosen-color cast prohibition to the chosen color (#4937) (#4940)
  • fix(parser): gate self keyword-grants on trailing "unless " (Tadeas, Juniper Ascendant) (#4977)
  • Add Plague Drone (#4882)
  • fix(parser): route printed "all creatures able to block ~ do so" to a permanent forced-block static (Ochran Assassin) (#4989)
  • fix(parser): require a word boundary after English number words (#4986)
  • fix(parser): harden trailing if-gate combinator on static restrictions (#4876) (#4877)
  • fix(parser): resolve "an opponent's graveyard" target to a graveyard card (#4984)
  • Parse unless-pay mana costs strictly (#4982)
  • fix(parser): gate keyword statics on graveyard-card presence, distribute "the same is true for" (Cairn Wanderer) (#4925)
  • ship/local hotseat resolve all (#4983)
  • ship/mp resolve all auto yield (#4980)
  • fix(parser): source-scoped "if ~ has counters on it" intervening-if (#4929)
  • fix(parser): recognize filtered attacker presence conditions (Nemesis Trap, Slingbow Trap) (#4918)
  • fix(client): attach Manual mana toggle and Undo button to player HUD (#4976)
  • fix(client): scope mobile dock redesign to portrait, restoring landscape layout (#4975)
  • fix(parser): gate combat restrictions on trailing "as long as" conditions (Seer of the Bright Side) (#4927)
  • feat(client): attachment fan for in-place targeting of a permanent + its attachments (#4974)
  • Add Corrupted Resolve (#4854)
  • feat(scripts): pr-review deferral labels + author-followup holds; gittensor report wrapper (#4935)
  • feat(scripts): gittensor contributor impact analysis (#4934)
  • feat(ai): choose_action decision-cost baseline gate (median-of-5 perf counters) (#4928)
  • perf(engine): short-circuit priority cast simulation + event-indexed replacement candidates (#4912)
  • docs(skills): add walker-classification step to add-engine-variant checklist (combo-detector skill implementation update) (#4905)
  • Fix Ixhel corrupted poison-scoped exile trigger (fixes #3882) (#4899)
  • fix(parser): gate "can't attack" on "if there's another creature on the battlefield" (Shauku, Endbringer) (#4926)
  • feat(engine): PR-6.5 — growing-cascade multiplayer win detector (ω-coverability modulo growth) (#4904)
  • fix(parser+engine): Jabari's Influence — scope target to "attacked you this turn" + chain the dropped -1/-0 counter (#4908)
  • fix(parser): recognize "there are no [type] on the battlefield" absence condition (#4917)
  • Fix Bloodthorn Flail equip pay-or-discard cost (#4831) (#4872)
  • chore(changelog): publish #159 — Split attackers across multiple defenders (#4923)
  • Fix Trouble in Pairs disjunctive trigger (fixes #4356) (#4887)
  • Parse the it-entered-this-turn static condition (Crew Captain, Drownyard Behemoth, ...) (#4914)
  • fix(ai): dedup hidden-pool accounting overlap; discard rungs whose final candidate outlived the deadline (#4915)
  • feat(pr-review): codify praise signals; normalize legacy strays read-side (#4919)
  • fix(pwa): remove scryfall-images SW cache route that broke mana pips + card backs (#4920)
  • Fix Hama Pashar dungeon room trigger doubling (fixes #4358) (#4892)
  • fix(parser): parse Eidolon's distributive dual-subject dynamic pump (#4909)
  • perf(ai): AI search performance batch — session caching, TT + iterative deepening, determinized sampling (#4911)
  • feat(pr-review): contributor intelligence + transient-failure hardening for pr_review.py (#4910)
  • Add a modal-spell filter so Riku only triggers on modal spells (#4907)
  • Add Valakut Fireboar: switch its power and toughness (pronoun form) (#4906)
  • fix(parser): trigger on your own countered spell (Multani's Presence) (#4903)
  • fix(parser): parse parenthetical gate on cant-cast prohibitions (#4885)

v0.13.0

Choose a tag to compare

@github-actions github-actions released this 02 Jul 13:36
Immutable release. Only release title and notes can be modified.

Downloads

Platform File
Windows Phase_*_x64-setup.exe
macOS (Apple Silicon) Phase_*_aarch64.dmg
Linux Phase_*_amd64.AppImage or .deb

macOS note: If you see "this app is damaged", open Terminal and run: xattr -cr /Applications/Phase.app

Changes

  • fix(parser): opponent-scoped "control N or more" cost-reduction gate (Lashwhip Predator) (#4898)
  • Add Coastal Wizard (#4900)
  • Parse Bound in Gold restriction list with activation lock (#4895)
  • Fix Molecule Man miracle on draw (fixes #4357) (#4889)
  • fix(parser): Tinfoil Helm — copula "has +N/+M" pump + bare-list protection expansion (#4897)
  • chore: refresh metagame feeds (#4894)
  • Fix Wrenn and Realmbreaker emblem graveyard play (fixes #4786) (#4871)
  • Absorb reveal-until rest pile after damage (#4890)
  • fix(parser): support "Skip the [step] step of that turn" (#4888)
  • fix(parser): attach board-state count gate to self-spell cost reduction (Hour of Revelation) (#4880)
  • Fix Bloodthorn Flail disjunctive equip cost (#4831) (#4865)
  • Fix For the Ancestors chosen creature-type dig filter (#4834) (#4875)
  • fix(parser): source-scoped "if ~ attacked or blocked this turn" intervening-if (#4879)
  • Reclassify stale unless-payment backlog entry (#4881)
  • fix(parser): dynamic-power "can't be blocked by" restriction (Kraken of the Straits) (#4866)
  • Add Role Reversal (share a permanent type) (#4839)
  • Fix Isochron Scepter cast of copied imprint (fixes #4792) (#4870)
  • Fix single-type sacrifice another filters (#4869)
  • fix(engine): no-op empty-candidate attach instead of deadlocking (#4868)
  • fix(game): consolidate mobile action dock and prevent bottom UI overlap (#4177)
  • fix(parser): source-scoped "if ~ attacked this turn" intervening-if (#4863)
  • fix(parser): gate static restriction on "a[n] is on the battlefield" (Wirecat) (#4844)
  • Remove fixed cost-reduction misparse backlog entry (#4857)
  • Fix #4835: Intimidation Tactics exiles chosen hand card (#4847)
  • Fix Zenith Chronicler draw on first multicolored spell (fixes #4829) (#4851)
  • Remove fixed counter-type misparse backlog entry (#4856)
  • Fix Orvar copying itself instead of targeted permanent (fixes #4830) (#4852)
  • feat(client): board HUD polish — priority indicator badge + lands/support collapse controls (#4849)
  • Fix counter quantity type normalization (#4853)
  • fix(pwa): omit credentials on SW-side Scryfall fetches so wildcard ACAO passes CORS (#4855)
  • Hand organizing (sort + filter) + multi-defender attack distribution (#4680)
  • ci: bound R2 upload verification (#4850)
  • Fix Mindskinner combat mill when damage is prevented. (#4846)
  • fix(engine): preserve delayed spell tails after PreventDamage (#4826) (#4845)
  • Fix duplicate Strive static parsing (#4843)
  • fix(parser): UNSUPPORTED full-set one-off: Mondassian Colony Ship (#4713)
  • fix(parser): gate "can't play lands" on trailing "if" condition (Rock Jockey) (#4841)
  • docs(skills): make contributor pre-PR gates universal and harden test-rigor guidance (#4840)
  • Fix optional retarget parser misparse (#4838)
  • feat(pwa): runtime-cache Scryfall images and remaining data JSONs for offline play (#4822)
  • chore(changelog): publish #158 — Make mana on an opponent's turn (#4821)
  • Fix leave-graveyard token triggers firing from the graveyard (Teval, the Balanced Scale) (#4819)
  • Add Regenerate (#4818)
  • fix(engine): park discard-for-cost triggers when cost payment pauses (#4801)
  • fix(parser): support definite-article back-reference reveal ("Reveal the card") (#4804)
  • Bind delayed dies triggers to the chosen creature so Scarblade's Malice makes its token (#4816)
  • Add Identity Crisis (#4812)
  • fix(engine): hold priority for mana on opponent's turn (CR 117.1d, #4388) (#4814)
  • feat(parser): referenced-object perpetual base P/T (duplicate / its . become) (#4530)
  • infra: serve data files from data.phase-rs.dev instead of pub-*.r2.dev (#4815)
  • fix(engine): parse activation-scoped spend-as-any-color for Agatha (#4220) (#4714)
  • Scope power-threshold conditions to the trigger source so Amalia wipes only at power 20 (#4811)
  • perf(ai): skip frontend display sweep in AI simulation applies (#4798) (#4806)
  • fix(parser): split dual-target combat compound so both halves parse (Boros Battleshaper) (#4802)
  • Fix Twilight Prophet caster gaining 0 life from the revealed card's mana value (#4698)
  • fix: allow cancelling a modal activated ability's mode choice (#4695) (#4808)
  • feat(engine,client): show source object for replacement-effect choices (#4807)
  • fix(engine): pawprint modal budget authority for Season of the Burrow (#3670) (#4803)
  • fix(engine): don't cap attack pay-{X} at attacker count (#4226) (#4707)
  • feat(engine): S01 standard-set completion — 11 cards / 7 mechanic groups (#4688)
  • fix(engine): Slaughter the Strong — keep a total-power-capped subset, sacrifice the rest (#4380) (#4600)
  • fix(parser): "for each card this way" counts only that card type (#4703)
  • fix(parser): "target 's controller/owner s it" declares its object target (#4701)
  • fix(parser): set-base-P/T toughness-only axis ("change ~'s base toughness to ") (#4692)
  • Fix combat roles persisting through battlefield exits (CR 506.4) (#4679)

v0.12.0

Choose a tag to compare

@github-actions github-actions released this 01 Jul 14:08
Immutable release. Only release title and notes can be modified.

Downloads

Platform File
Windows Phase_*_x64-setup.exe
macOS (Apple Silicon) Phase_*_aarch64.dmg
Linux Phase_*_amd64.AppImage or .deb

macOS note: If you see "this app is damaged", open Terminal and run: xattr -cr /Applications/Phase.app

Changes

  • chore: refresh metagame feeds (#4699)
  • fix: DistributeAmong stuck decision (#4689), Final Parting prompt, Bribery control (#4691)
  • feat(client): tint turn-status narration with the waiting seat's color (#4690)
  • fix(parser): cast prohibition "during that player's next turn" sets a next-turn expiry (#4686)
  • fix(parser): set-base-P/T via the "change ~'s base power [and toughness] to " verb form (#4682)
  • chore(changelog): publish #157 — Mother of Runes protects again (#4687)
  • feat(client): surface who holds priority and why we're waiting (#4681)
  • fix: bind where-x target filters (#4684)
  • Fire taps-for-mana delayed triggers and route the bonus mana to the tapping player (#4683)
  • fix(parser): UNSUPPORTED cluster: Turn a creature face-down as a FIXED 2/2 of a printed type (Cyber (#4410)
  • Fix large-board AI priority timeouts (#4677)
  • Bind that-player anaphora in bullet-line modal triggers to the triggering player (#4676)
  • Add Aven Mindcensor (#4675)
  • fix(parser+engine): protection/hexproof from "the color of your choice" (#4371) (#4665)
  • Add Athreos, God of Passage (#4667)
  • refactor(engine): outline engine.rs + oracle_trigger.rs test modules into siblings (#4672)
  • docs: request high thinking for AI contributors (#4674)
  • fix(engine): route catalog token rules text through static parser (#4669)
  • feat(engine): die-roll result-filter triggers ("whenever you roll a [N]") (#4671)
  • fix(engine): handle optional attach choices (#4670)
  • refactor(engine): outline large inline test modules into sibling files (#4668)
  • feat(engine): support "whenever you activate a loyalty ability of [planeswalker]" triggers (#4664)
  • fix(engine): targeted multi-object ChangeZone records moved count for "that many" (#1093) (#4657)
  • chore(changelog): publish #156 — infinite combo detector (#4666)
  • fix(data): auto-unlock released sets and infer MSH legalities (#4365) (#4660)
  • fix(engine): install catalog triggers on debug preset token spawns (#4661)
  • Collapse large animation event runs (#4659)
  • fix ci rust test runner disk pressure (#4658)
  • fix(engine): Winter Soldier attack trigger and Hero counter rider (#4560) (#4580)
  • fix(parser): support 'your opponents control no [type]' static condition (#4656)
  • feat(engine): Alchemy perpetual self-cost modification (perpetually gains "this spell costs {N} less/more to cast") (#4642)
  • fix(engine): Dread Return into empty library breaks Thassa's Oracle win condition (#4637)
  • fix(parser): controller-scoped "you lost life this turn" intervening-if condition (#4643)

v0.11.0

Choose a tag to compare

@github-actions github-actions released this 30 Jun 13:44
Immutable release. Only release title and notes can be modified.

Downloads

Platform File
Windows Phase_*_x64-setup.exe
macOS (Apple Silicon) Phase_*_aarch64.dmg
Linux Phase_*_amd64.AppImage or .deb

macOS note: If you see "this app is damaged", open Terminal and run: xattr -cr /Applications/Phase.app

Changes

  • fix(parser): support "more cards in hand than each opponent" condition (#4640)
  • chore: refresh metagame feeds (#4639)
  • feat(engine): support Greymond, Avacyn's Stalwart (choose-two-keywords grant and conditional Human anthem) (#4638)
  • fix(server): release state + connections guards before broadcast_play… (#4563)
  • fix(parser): Replacement_Instead detector for flip-coin branches (#2236) (#4581)
  • test(parser): Condition_AsLongAs regression for equipment (#2234) (#4585)
  • fix(parser): UNSUPPORTED one-off: Fractured Identity (#4549)
  • fix(engine): Three Blind Mice Chapter II/III never occur (#2004) (#4636)
  • fix(parser): quote-aware choice-list splitter so nested-token abilities aren't a modal choice (#4230) (#4635)
  • fix(engine): delayed zone-change effects no-op on objects that ceased to exist (#3883) (#4634)
  • fix(engine): emit ZoneChanged for Incubate so ETB triggers fire (#4631)
  • fix(engine): Heartwood Storyteller — each of the casting player's opponents may draw (#4361) (#4626)
  • fix(engine): one-sided-fight source reuses its slot for "its power" magnitude (Bite Down #4234) (#4632)
  • fix: honor hexproof in per-opponent fanout targeting (#4614)
  • Add Endangered Armodon (#4630)
  • test(parser): Duration_NextTurn regression for Amplifire (#2239) (#4584)
  • fix(parser): support 'no opponent controls X' static conditions (#4629)
  • fix(parser): "choose a creature you don't control" routes to an opponent target (#4621)
  • feat(engine): ∞ unbounded-resource display for confirmed infinite loops (combo PR-6) (#4603)
  • fix(engine): assign inheriting life-gain rider's parent target under "up to one" (Solitude) (#4627)
  • chore(pr-review): treat CI status as evidence, not a review/merge gate (#4624)
  • fix(parser): support 'any player controls X' static conditions (#4623)
  • feat(engine): CR 613 layers conformance — face-down override, timestamp assignment, granted-ability timestamps (#4620)
  • Refresh card data inputs and cache clearing (#4622)
  • ship/client hand fan out delve (#4617)
  • fix(parser): parse 'choose a number' when it ends a sentence (closes #722) (#4618)
  • feat(engine): Koh, the Face Stealer + Sandswirl Wanderglyph (S21 static cluster) (#4611)
  • feat(engine): Alchemy perpetual type-change (Second Little Pig) (#4124) (#4616)
  • fix(parser): keep another leg-local in singular X or Y disjunctions (closes #4513) (#4597)
  • fix(parser): nested single-quoted token ability keeps its clause (Urza's Saga ch. II) (#4605) (#4610)
  • [codex] add PR review contributor analytics (#4609)
  • fix(parser): UNSUPPORTED one-off: The Foretold Soldier (#4579)
  • chore(changelog): record #155 Discord post
  • feat(changelog): publish #155
  • fix(parser): UNSUPPORTED one-off: As Foretold (#4592)
  • fix(engine): Deflecting Swat retargets mass "target player" spells (#4608)
  • fix(engine): BecomesBlocked "that creature" binds the blocked attacker, not the blocker (#4599) (#4607)
  • fix(parser): UNSUPPORTED one-off: The Pandorica (#4475)
  • fix(parser): Phase-triggered token-copier's delayed "sacrifice it" binds the created token, not the source (#4601) (#4604)
  • fix(parser): UNSUPPORTED one-off: The Wedding of River Song (#4593)
  • fix(parser): optional targeting for "attach any number of target" trigger (Super-Soldier Serum) (#4606)
  • chore: refresh metagame feeds (#4594)
  • fix(client): resolve oldest printing by release date and collector number (#4408)
  • fix(parser): UNSUPPORTED one-off: Amy Pond (#4602)
  • Fix stale PR hold routing (#4578)
  • fix(parser): delayed "sacrifice it unless you pay" rides the delayed trigger (#4369) (#4598)
  • fix(parser): Tamiyo flip return-transformed binds to source, not TriggeringSource (#4543) (#4596)
  • feat(engine): plot from the top of your library (Fblthp, Lost on the Range) (#4573)