feat(parser): implement Tekuthal, Inquiry Dominus — fix split_cost_parts for multi-type from-among costs#3699
Conversation
…s one cost
Tekuthal, Inquiry Dominus has activation cost:
{1}{U/P}{U/P}, Remove three counters from among other artifacts, creatures, and planeswalkers you control
split_cost_parts was splitting on the commas in the type list, producing
four fragments ([mana], [Remove...artifacts], [creatures], [planeswalkers])
instead of two ([mana], [Remove...planeswalkers you control]).
The "creatures" and "planeswalkers" fragments parsed as Unimplemented, so
the ability showed a coverage gap and was treated as always-payable.
Fix: when the accumulated cost segment already contains "from among", skip
comma and " and " splits — they are type-list separators, not cost separators.
The full target phrase then reaches parse_remove_counter_target intact, which
calls parse_target → parse_type_phrase on "other artifacts, creatures, and
planeswalkers you control" and correctly builds
Or[Typed{Artifact,Another,You}, Typed{Creature,Another,You}, Typed{Planeswalker,Another,You}].
All five Dominus cards (Phyrexia: All Will Be One) share this cost pattern
and benefit from the same fix.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
|
Warning You have reached your daily quota limit. Please wait up to 24 hours and I will start processing your requests again! |
matthewevans
left a comment
There was a problem hiding this comment.
VERDICT: request-changes
[MED] The from among guard suppresses every later separator until the end of the cost string. Evidence: crates/engine/src/parser/oracle_cost.rs:94 and crates/engine/src/parser/oracle_cost.rs:104 check whether the whole accumulated segment contains from among, but never re-anchor start after the target phrase ends. Why it matters: this fixes Tekuthal because its from-among cost is the final cost part, but the shared splitter will merge any later top-level cost (for example a future Remove ... from among ..., Sacrifice ... shape) into the remove-counter target text and silently drop/misparse that later cost. Suggested fix: make the exception bounded to the comma/and separators inside the parsed from among <type-list> target phrase, or split normally first and repair only the known RemoveCounter continuation fragments with a helper that stops once the target phrase is complete.
[LOW] The new CR citation points at the wrong rule. Evidence: crates/engine/src/parser/oracle_cost.rs:90 cites CR 118.12b, but docs/MagicCompRules.txt defines 118.12b as an “If [a player] does” search-choice rule, not remove-counter activation costs or counter objects. Why it matters: incorrect CR annotations are worse than absent ones in this repo because they make future reviewers trust the wrong rules basis. Suggested fix: cite the actual rule(s) being implemented here, such as the activation-cost payment rule plus the counter rule, or remove the CR number from this splitter comment if it is only documenting parser structure.
Summary
Tekuthal, Inquiry Dominus has two parseable abilities:
Proliferate replacement — "If you would proliferate, proliferate twice instead."
Already implemented and tested (
parse_proliferate_count_replacement, testtekuthal_proliferate_replacement_parses).Activated ability —
{1}{U/P}{U/P}, Remove three counters from among other artifacts, creatures, and planeswalkers you control: Proliferate.The cost had a coverage gap:
split_cost_partswas splitting on commas in the type list, producing[{1}{U/P}{U/P}],[Remove...artifacts],[creatures],[planeswalkers]— four parts instead of two. The last two parsed asUnimplemented, blocking cost evaluation.Fix: When the accumulated cost segment already contains
"from among", skip comma and" and "splits — they are type-list separators, not cost separators. The intact phrase reachesparse_remove_counter_target→parse_target→parse_type_phrase, which already handles comma-separated type lists and buildsOr[Typed{Artifact,Another,You}, Typed{Creature,Another,You}, Typed{Planeswalker,Another,You}].All five Dominus cards from Phyrexia: All Will Be One share this cost pattern and benefit from the same fix.
Model: claude-sonnet-4-6
Tier: Standard
Gate A
Anchored on
crates/engine/src/parser/oracle_cost.rs:76—split_cost_partsalready uses brace-depth tracking to avoid splitting inside{...}mana symbols. My change extends this with a look-back condition for"from among"phrases using the same per-character loop.crates/engine/src/parser/oracle_cost.rs:130—fixup_bare_noun_continuationswas the prior mechanism for handling false cost fragments produced by over-eager splitting (for Sacrifice/Exile/TapCreatures). My fix addresses the same problem at the split level rather than post-hoc, keepingRemoveCounter's multi-type target unified.crates/engine/src/parser/oracle_target.rs:1911–1968— comma-separated type list → OR filter is already implemented inparse_type_phrase_with_ctx, confirmed by test at line 9238 ("creatures, artifacts, and enchantments you control"→Or[Creature{You}, Artifact{You}, Enchantment{You}]). My fix enables this path to receive the full type-list string.crates/engine/src/parser/oracle_cost.rs:2185— existing testcost_remove_x_counters_from_among_creatures_you_controlestablishes theAmongObjectsselection path for single-type "from among" costs; my new testcost_tekuthal_remove_three_counters_from_among_or_typesextends the pattern to the multi-type OR case.Test plan
cost_tekuthal_remove_three_counters_from_among_or_types— new discriminating test; verifies the full composite cost parses asComposite[Mana, RemoveCounter{count=3, AmongObjects, Or[Artifact|Creature|Planeswalker, each Another+You]}]CompositewithUnimplementedfragments if thesplit_cost_partsguard is removedcost_remove_x_counters_from_among_creatures_you_control(single-type) and all othersplit_cost_partstests unchanged🤖 Generated with Claude Code