Releases: phase-rs/phase
Release list
v0.16.0
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
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 —
chooseresidual 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
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
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
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
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)
v0.10.0
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): Heroic Defiance — gate +3/+3 on most-common-color among permanents (#4590)
- test(parser): wishboard outside-game fetch regression (#2276) (#4582)
- fix(engine): Captain America Team Leader +1/+1 counters (Fixes #4564) (#4576)
- chore(data): remove retired creature subtypes from oracle-subtypes.json (#4588)
- fix(parser): parse Stridehangar appended Thopter token replacement (#4587)
- test(engine): regression coverage for counter spell non-mana unless costs (#3466) (#4565)
- fix(parser): Jocasta graveyard return enters tapped and attacking (#4575)
- test(parser): APNAP regression for Protection Racket (#2241) (#4583)
- feat(engine): one-shot draw replacement ("the next time you would draw a card this turn, [effect] instead") (#4116)
- fix(parser): UNSUPPORTED one-off: The Master, Formed Anew (#4586)
- Parse Fastbond land-play permission as static (#4545)
- feat(engine): Locus of Enlightenment — grant craft-pile activated abilities (S21 B4) (#4561)
- fix(engine): suppress reflexive-target rider on declined optional target (Faller's Faithful) (#4567)
- fix(engine): stamp discard count for chained draw that many (#4574)
- fix(server): avoid full-mode create deadlock (#4570)
- Fix PR review loop scan routing (#4569)
- fix(parser): UNSUPPORTED one-off: Run for Your Life (#4568)
- fix(parser): UNSUPPORTED one-off: Weeping Angel (#4439)
- fix(parser,engine): bind "if it was tapped" reflexive rider + LKI-tapped plumbing (Brackish Blunder) (#4559)
- fix(parser): Kishla Skimmer leaves-graveyard "during your turn" trigger (#4521) (#4558)
- Fix counter-cost token counts (#4550)
- fix(parser): UNSUPPORTED one-off: Everything Comes to Dust (#4539)
- fix(parser): UNSUPPORTED one-off: Duggan, Private Detective (#4537)
- feat(analysis): combo-verify CLI over the corpus (PR-5) (#4547)
- feat(engine): Nowhere to Run — scoped hexproof-bypass + ward-suppression statics (#4557)
- feat(changelog): publish #154 (#4556)
- feat(engine): static cost reduction for plot/unlock + dynamic activated-ability cost (S21) (#4551)
- fix(parser): bind reflexive conditional riders (S01 reflexive-if-rider cluster) (#4553)
- fix(frontend): cancel stale auto-pass timers (#4540)
- fix(parser): Namor the Sub-Mariner colored-pip cast trigger (#4370) (#4552)
- ship/fix engine prevent attachment cycles (#4546)
- feat(engine): Alchemy perpetual keyword grant (perpetually gains [kw]) (#4529)
- fix(parser): hoist "if it's an opponent's turn" intervening-if condition (#4536)
- feat(analysis): combo-graph effect/trigger breadth + life-symmetry cost (Engine B, PR-4b) (#4534)
- feat(engine): Baron Helmut Zemo (MSH) — Boast aggregate-exile cost + copy/cast up to three (CR 702.142a) (#4533)
- fix(parser): UNSUPPORTED one-off: Displaced Dinosaurs (#4535)
v0.9.0
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): Incremental Growth multi-target +1/+1 counter chain (closes #4503) (#4504)
- fix(engine): The Incredible Hulk — gate Enrage riders and untap him when attacking (CR 608.2c) (#4526)
- fix(parser): UNSUPPORTED one-off: River Song (#4481)
- chore: refresh metagame feeds (#4532)
- feat(analysis): static ability-graph combo-candidate extractor (Engine B, PR-4a) (#4493)
- fix(parser): UNSUPPORTED one-off: River of Tears (#4531)
- fix(parser): Desperate Gambit ChooseDamageSource you-control filter (#4508)
- feat(engine): Alchemy perpetual P/T modifier (perpetually gets +N/+M) (#4525)
- perf(ai): memoize legality verdicts by equivalence class on go-wide boards (#4520)
- fix(parser): Bound by Moonsilver sacrifice-another attach activated (#4502)
- feat(pr-review): extract review-loop into policy-driven pr_review.py (#4522)
- fix(parser): keep haunt creature payoff as one compound trigger (#4506)
- fix(parser): UNSUPPORTED cluster: Player voting — secret/open votes with per-label tallies (Effect:: (#4402)
- fix(changelog): wrap custom Discord emoji as <:name:id> for bot posts (#4519)
- feat(engine): Omnath, Locus of All — eligibility, dynamic mana, and decline-to-hand (#4518)
- fix(client): recover from unresponsive engine worker via request timeout (#4517)
- fix(parser+engine): Faith's Fetters combat lock on enchanted host (closes #3249) (#4496)
- fix(parser+engine): Haze Frog other-creature combat prevention (closes #4497) (#4498)
- fix(parser): Mana Severance search-exile-shuffle duplicate ChangeZone (#4499) (#4500)
- fix(engine): airbend stack spells for Aang, Swift Savior (#4384) (#4490)
- fix(parser): Guardian of Faith "any number of other target creatures" drops multi_target (#4236) (#4488)
- fix(parser+engine): Read the Runes draw-then-discard unless sacrifice (closes #4486) (#4487)
- fix(parser): recover dynamic "gets +N/+M for each" after a leading keyword (Glamdring) (#4495)
- fix(casting): restore pending cast when convoke payment fails (#4379) (#4494)
- fix(parser): Bounty of the Hunt cleanup counter removal (#4382) (#4492)
- fix(parser): represent dropped ActivateOnlyDuring clauses (closes #2238) (#4485)
- feat(engine): support 'you or a permanent becomes the target' triggers (Loki, God of Mischief) (#4491)
- fix(parser): assemble 3+ color prenominal disjunction filters (#4438)
- ship/lobby readme changelog 153 (#4489)
- fix(parser+engine): Drag to the Underworld devotion cost reduction (#4484)
- fix(parser): UNSUPPORTED cluster: Suspend casting + time-counter manipulation (Time Travel) — dispat (#4346)
- feat(engine): The Ruinous Wrecking Crew + Hawkeye, Master Marksman (MSH) (#4482)
- fix(parser): UNSUPPORTED cluster: Doctor's-companion legendary creatures' bespoke ABILITY bodies are (#4337)
- feat(analysis): detect mandatory-loop winner for drain-cascade combos (CR 704.5a) (#4480)
- fix(parser+engine): Wretched Banquet least-power destroy gate (#4477)
- perf(engine): eliminate O(N^2) mana sweep in legality probes on go-wide boards (#4479)
- ship/engine centralize priority pass clearing (#4474)
- chore(agents): grant SendMessage to sub-agents for graceful cull + report-back (#4478)
- fix(parser): Blademane Baku for-each bare counter removed (closes #4472) (#4473)
- feat: Cosmic Cube + Hawkeye, Young Avenger (MSH) (#4471)
- fix(client): collapse identical-token board sacrifice picker to a single quantity action (#4375) (#4432)
- fix(parser): UNSUPPORTED one-off: Adipose Offspring (#4470)
- fix(engine): apply mass force-block to all matching creatures (Predatory Rampage) (#4447)
- fix(parser+engine): Visions of Ruin flashback commander cost reduction (closes #4467) (#4468)
v0.8.0
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 (#4469)
- Card/lightning dart (#4466)
- fix(parser): UNSUPPORTED one-off: Confession Dial (#4465)
- fix(parser): Progenitor's Icon chosen-type next-spell flash filter (closes #4462) (#4463)
- client: group large combat damage animations (#4464)
- Feat/curse remaining tests (#4454)
- fix(parser): Decoy Gambit unless-have-you-draw alternative (#4460)
- Add False Peace (#4457)
- ship/engine add team topology foundation (#4458)
- feat(changelog): publish #152 (card fixes, big-board perf, hand-fan casts) (#4461)
- fix(parser): Lethargy Trap alt-cost gate on attacking creature count (#4456)
- fix(engine,client): auto-skip exhausted optional target slots (#4242) (#4326)
- fix(deck-builder): Slime Against Humanity unlimited copies in Commander (#1138) (#4257)
- perf(engine): hoist shadow-block existence gate and per-controller granted-ability provider cache (#4453)
- engine: fix land mana priority owner (#4452)
- fix(client): recover AI CastOffer fallback (#4451)
- Fix ETB Equipment attach resolution (#4450)
- parser: handle Accumulate Wisdom dig alternative (#4449)
- perf(engine): hoist loop-invariant battlefield scans in priority/mana/crew/combat paths (#4448)
- fix(parser): apply literal "named " override on token copies (CR 707.9b) (#4446)
- fix(parser): parse disjunctive unless-pay mana on Lim-Dul's Hex (closes #4442) (#4443)
- perf(engine): hoist O(N^2) static-ability scans out of combat/untap legality loops (#4445)
- fix(parser): parse Enchant creature without flying Aura targets (closes #4440) (#4441)
- fix(parser): RevealUntil chosen-type and shares-a-type filters (closes #4435) (#4436)
- fix(engine): read buffed LKI for dies-trigger P/T quantities (#4269) (#4428)
- perf(engine): skip mana-availability clone-storm for {T}/{Q}-only mana abilities (#4437)
- fix(parser): Limited Resources gates CantPlayLand on lands-on-battlefield count (#4434)
- fix(parser): Molten Influence unless-have-deal-damage (closes #4429) (#4430)
- fix(parser): UNSUPPORTED one-off: Missy (#4431)
- fix(parser): Dominaria's Judgment gates each color's protection on its own land (#4423)
- fix(engine,ai): open CR 601.2g pre-payment mana window for mana+removal activation costs (#4427)
- fix(engine): pay Lava Blister unless-have-deal-damage at runtime (closes #4420) (#4421)
- fix(parser): parse Dragonfire Blade equip color discount (closes #4425) (#4426)
- fix(parser): parse Lava Blister unless alternative (#4424)
- fix(parser): normalize additional dynamic counters (#4422)
- feat(ui): weave castable graveyard/exile cards into the hand fan (#4418)
- feat(changelog): auto-publish announcement-channel posts to followers (#4417)
- feat(changelog): publish #151 (iOS crash fixes, deck folders & Rooms) (#4416)
- fix(engine): preserve opponent scope in compound draw targets (#4415)
- perf(client): skip AI worker pool on mobile to fix iOS VeryHard OOM (#4413)
- feat(changelog): auto-publish new entry to Discord #announcements (#4412)
- fix(engine): resolve DefendingPlayer when ability source isn't the attacker (#4268) (#4355)
- fix(engine): lifelink gains life once per source per combat batch (#4366) (#4411)
v0.7.0
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(import): exclude Moxfield maybeboard from URL deck imports (#4406)
- chore: refresh metagame feeds (#4403)
- fix(engine): fire 'whenever [player] is attacked' triggers (CR 508.3b) (#4401)
- fix(parser): UNSUPPORTED cluster: The Second Doctor — 'each opponent who can't attack you or (#4391)
- feat(tests): Curse of Conformity — base P/T 3/3 + remove creature types (enchanted player) (#4397)
- Fix granted extra blocker statics (#4396)
- feat(parser): wire game-state unless gates through effect conditions (#4340)
- test(engine): add runtime integration test for Curse of the Restless Dead (#4351)
- fix(client): keep GameplayTooltip on-screen near viewport edges (#4354)
- perf(client): MP-host validates guest decks via worker card DB (fix iOS OOM) (#4353)
- fix(client): revert crossOrigin on Scryfall
tags (fixes card-art regression) (#4352)
- perf(client): load game-scoped card-DB subset in AI worker pool to fix iOS OOM (#4348)
- feat(frontend): in-app "What's New" changelog with search, pagination & unread badge (#4347)
- perf(engine): trim
compute_combat_taxtax-attribution scans (#4344) - chore(client): mark Scryfall
tags crossOrigin=anonymous (#4343)
- fix(engine): Sanar Vivid reveal stays in library for per-color exile (#4253) (#4339)
- fix(engine): generalize composite-cost affordability witness to Exile/ReturnToHand-from-battlefield (AI dead-end) (#4342)
- Fix Mad Wizard's Lair dungeon room not resolving (#4251) (#4336)
- fix(parser): parse bare "except it's legendary" on token copies (#4254) (#4338)
- feat(parser): route equal-to and enter-with-counters through full CDA… (#4333)
- fix(engine): allow casting either half of a Room split card (#4248) (#4331)
- Fix Octavia, Living Thesis cost reduction applying unconditionally (#4250) (#4332)
- Fix commit-a-crime on opponent damage (#2008) (#4291)
- fix(engine): reject uncompletable composite mana+sacrifice activations (AI dead-end) (#4335)
- chore: gitignore generated scryfall-token-images.json (#4327)
- Fix Court of Cunning milling only the first targeted player (#4252) (#4319)
- fix(engine): Well Rested granted trigger uses Aura controller (#4330)
- perf(combat-ai): HashSet for blocker/attacker membership in choose_blockers (#4329)
- fix(engine): skip Braids decline tail when controller declines sacrifice (#4328)
- fix(engine): From the Rubble targets graveyard cards (#4321)
- perf(combat): hoist O(battlefield²) static scan out of legality loops (#4312)
- Refactor/remove hardcoded parser debt (#4317)
- feat(MyDecks): implement folder management with prompts for creating, renaming, and assigning decks (#4205)
- fix(ai): demand-aware mana color selection prevents ManaPayment dead-ends (#4325)
- fix(engine): Temple Altisaur prevents all but 1 damage to Dinosaurs (#4320)
- fix(engine): Intruder Alarm untap after token from discard (#4323)
- Fix Memory's Journey dropping its up-to-three target count (fixes #4255) (#4318)
- fix(engine): autotap accounts for TapsForMana aura bonus (Wild Growth, Fertile Ground, Utopia Sprawl) (#4303)