Optfall

Search syntax

Typing words searches names and printed text. Everything below narrows that, and all of it composes — an operator can be negated, grouped, or joined with another.

Fields

A field operator scopes a word to one part of the card. Operands on name, text, type, trait and keyword are read as prose and split into one requirement per word, so type:"illusionist action" asks for both. Everything else — a set code, a rarity, a printed number — is matched whole.

ExampleMatches
name:dashThe card's name contains this word.
text:dominateo:The printed rules text contains this word.
type:guardianclass:The card's type line contains this word — see the note below.
trait:mechanologistThe card carries this trait.
keyword:go-againkw:The card has this keyword.
artist:fikria:An artist credited on any printing of the card.
ft:bloodflavour:flavor:The flavour text on any printing — never the rules text.
set:wtrThe card was printed in this set.
power>defencepow>toupower=defenceCompare two printed values on the same card. Scryfall's pow>tou works too. Cards printing X or nothing have no place in the order and do not match.
year:2024The card was printed at least once that year. Comparisons work: year>=2024.
date>=2024-06-21The same question by the day rather than the year. 17 sets carry no published date and no date filter can match them; the search says so when you use one.
rarity:majesticThe card was printed at this rarity.
pitch:3The card's pitch value.
cost:2The printed resource cost.
power:6The printed attack power.
defence:3defense:def:The printed defence.

class: and type: are the same operator, and that is a property of the data rather than an oversight. The upstream dataset publishes classes and card types in one list — Guardian, Action and Attack are all entries in it — so separating them would mean inventing a class vocabulary Optfall does not have. Documenting them as one operator is the honest description of what the engine can answer.

artist:, ft:, set: and rarity: are facts about a PRINTING, not about a card, and a card matches when any one of its printings does. A card reprinted with new art is found by either artist; one whose second printing carries different flavour is found by either. That is usually what you want, and it is worth knowing when it is not.

Flavour text is a separate index from rules text, and neither reaches the other. text:blood asks what a card does; ft:blood asks what it says about itself, and they return different cards. A bare word searches names, types, keywords, traits and rules text — never flavour, because a card that merely mentions a thing is not a card that does it.

What the answer looks like

display: picks the shape of the results, and it is part of the query rather than a setting beside it — so the link you copy shows what you were looking at.

display:grid — the default
The card face is the row. Recognising a card by its picture is faster than reading its name.
display:list (also display:rows)
A dense row: pitch, name, type line and the printed stats, plus why the card matched.

display:text, display:checklist and display:names used to name a third view — names one per line, and nothing else. They still work and now mean display:list, which is the same rows with more on them.

How much one row stands for

A search returns ROWS, and a row is not obviously a card. Head Jab is printed at three pitches and reprinted in six sets, so "how many Head Jabs are there" has three defensible answers. unique: picks which one you get.

unique:names — the default
One row per NAME. The red, yellow and blue Head Jabs are one result, linking to the card page where the versions are tabs. A player calls them one card, and being told "3 cards match" should mean three things to click.
unique:cards
One row per CARD. Those three versions separate, because they genuinely are three cards — different text, different legality, and a page each.
unique:art (also unique:prints)
One row per distinct PICTURE, alternate arts included, each linking to that art's own page.

unique:prints resolves to unique:art, and that is a fact about this data rather than a shortcut. The corpus carries 16,502 printing rows and 11,378 distinct pictures: a card printed Regular, Rainbow Foil and Cold Foil in one set is three rows sharing one image, one collector number and one page. A separate prints level could only have emitted three identical rows pointing at the same URL.

Collapsing happens after matching, never before it. A query only one pitch version satisfies still finds the card under the default, and the row links to the version that actually matched — not to whichever version happens to be first.

Comparisons

cost, power and defence accept >, >=, <, <= and != — so power>=6 is a query. No other field does, because no other field has an order to compare along.

A card printing X matches no comparison at all. Printed costs in this corpus include X, XX and blanks, and those have no place in a numeric order. So a comparison means "this value is a number, and it satisfies the comparison", and a card printing X is simply absent from the answer rather than sorted arbitrarily into it.

Legality

Four operators, each naming a format. Legality here is today's.

ExampleMatches
legal:ccLegal in Classic Constructed.
banned:blitzBanned in Blitz.
suspended:ccSuspended in Classic Constructed.
restricted:commonerRestricted in Commoner.
FormatAccepted names
Classic Constructedcc, classic-constructed, classic, constructed
Blitzblitz
Living Legendll, living-legend, livinglegend
Commonercommoner
Silver Agesilver-age, silverage, silver
Ultimate Pit Fightupf, ultimate-pit-fight

Ordering

Results come back by relevance — an exact name match ahead of a text match — until you ask for something else. order: replaces that ranking rather than refining it, and dir: reverses whatever it chose.

ExampleSorts by
order:costSort by printed cost instead of by relevance.
order:nameSort alphabetically.
order:pitchSort by pitch value.
order:powerSort by printed attack power.
order:defencedefensedefSort by printed defence.
order:raritySort by the scarcest rarity the card was ever printed at.
order:setSort by the first set the card appeared in.
order:releasedorder:releaseSort by when the card first came out — a reprint is not a release. Cards from undated sets sort last.
dir:descReverse the order. The default is ascending.
unique:artHow much one row stands for — names, cards or art. See below.
display:listdisplay:rowsThe shape of the results — grid or list. See below.

A card with no value for the key sorts last, whichever direction you asked for. Printed costs include X, XX and blanks, and a card with no defence has no defence rather than zero of it — putting those first under dir:desc would claim they are the largest, and first under asc that they are the smallest. They are neither, so the direction applies to the cards that have a value and the rest go to the end. It is the same refusal comparisons already make.

An ordering is an option on the whole query rather than a term in it, so it can be written anywhere and does not change which cards match. order:cost on its own finds nothing — it says how to arrange results, not which to find — and says so rather than returning an empty page.

Booleans and grouping

ExampleMeans
dash daggerTwo words next to each other both have to match. There is no need to type AND.
dash or daggerEither one matches.
-type:attackNegation. It composes with every operator, not only with bare words.
(dash or dagger) pitch:1Parentheses group, so an either-or can be narrowed by something else.
"head jab"Quotes match a phrase rather than two separate words.
!"Head Jab"!headjabThe exact-name operator: this card and no other.

What Optfall will not guess

Dated legality is not answered yet. legal:cc@2026-03-14 parses, and asks a real question — what was legal on a given date — and Optfall publishes present-day legality only. Rather than answer with today's flags and let the date read as though it were honoured, the query returns a notice saying the feature is unbuilt. A wrong answer is worse than a missing one, and it is worse precisely because it looks like an answer.

An unknown operator, an unknown format name, or an operator typed with nothing after it is reported the same way: the query says what it ignored rather than quietly returning everything.