Appearance
Legends of Runeterra card data
Ruleset and calculator scripts get Legends of Runeterra cards as plain objects straight from the card catalog. This page lists every field on those objects and in the catalog globals, with a real example and a few recipes.
Where the cards show up:
- Card rules receive one card as their first argument.
- Deck and deck set rules receive
cardsById, an object keyed by card ref that holds every card in the deck (it can hold more). - Calculators receive
cardsByIdas their second argument.
See the ruleset script API and the calculator script API for the full function signatures.
Card keys and deck refs
Every Legends of Runeterra card is keyed by its card code, the same code the game client and deck codes use:
01DE012is set01, regionDE(Demacia), card012.- Tokens and level-ups add a suffix:
01DE012T1is Garen's level-up.
A deck is a map of card code to copies ({ "01DE012": 3 }), and cardsById uses the same card codes as keys, so cardsById[ref] is always the card for a deck entry. Legends of Runeterra has no reprints, so cards have no printings list.
Guard against a missing card before reading from it: cardsById[ref] can be undefined when the catalog doesn't know a ref.
Card fields
Every card, in every game, has these top-level fields:
| Property | Type | Description |
|---|---|---|
id | string | Catalog id of the card identity ("01DE012" in LoR, "pikachu-ex--1f29b66b68bc" in Pokémon). |
name | string | Display name in the catalog locale. |
setCode | string | Set of the card, or of its default printing ("set1", "sv2", "OGN"). |
collectible? | boolean | False for cards that can't go in a deck (LoR tokens and level-ups). |
assets? | CardCatalogCardAssetContract[] | Images of the card's default printing. |
printings? | CardPrintingContract[] | Every printing of the identity, default printing first. Absent in LoR. |
hasImage? | boolean | False when none of the card's printings has an image in this language. Absent means it has one. |
game? | TGameData | Game-specific fields; see the per-game *CardGameData type. |
Game fields (card.game)
Everything specific to Legends of Runeterra lives on card.game. Text fields and type / supertype are in the viewer's language, so compare the *Ref fields in logic: typeRef is "Unit" in every language, while type is "Einheit" in German.
| Property | Type | Description |
|---|---|---|
associatedCardRefs? | string[] | Card codes of related cards: level-ups, spawned tokens, spells a champion creates (["01DE012T1"]). |
formatRefs? | string[] | Formats the card is legal in, as globals.formats keys ("client_Formats_Standard_name"). |
keywordRefs? | string[] | Keywords on the card, as globals.keywords keys ("QuickStrike", "Regeneration"). |
rarityRef? | string | Rarity key into globals.rarities: "Common", "Rare", "Epic", "Champion" or "None" (tokens, spells a card creates). |
regionRefs? | string[] | Regions, as globals.regions keys ("Demacia", "PiltoverZaun"). A Runeterra champion's own cards also carry its card code ("06RU001"), matching a globals.runeterraChampions key. |
spellSpeedRef? | string | Spell speed key into globals.spellSpeeds ("Burst", "Fast", "Slow"); spells only. |
vocabTerms? | string[] | Glossary terms linked from the card text, as globals.vocabTerms keys ("Strike", "Allegiance"). |
supertype? | string | Localized supertype; "Champion" on champions, absent otherwise. Use supertypeRef in logic. |
type? | string | Localized card type ("Unit", "Einheit" in German). Use typeRef in logic. |
typeRef? | string | English card type in every locale: "Unit", "Spell", "Landmark", "Equipment", "Ability" or "Trap". |
supertypeRef? | string | English supertype in every locale: "Champion" on champions, absent otherwise. |
cost? | number | Mana cost. |
attack? | number | Power (attack); usually 0 on non-units. |
health? | number | Health; usually 0 on non-units. |
description? | string | Rules text with the game client's inline markup (<link=…>, <style=…> tags). |
descriptionRaw? | string | Rules text as plain text, markup removed. |
levelupDescription? | string | Champion level-up condition, with inline markup. |
levelupDescriptionRaw? | string | Champion level-up condition as plain text. |
flavorText? | string | Flavor text. |
subtypes? | string[] | Unit subtypes in upper case (["ELITE"], ["YETI"]). |
artistName? | string | Card artist's name. |
Globals (ctx.globals)
The catalog's globals are lookup tables that turn the refs on a card into display names, icons and descriptions: regionRefs: ["Demacia"] resolves through ctx.globals.regions.Demacia.
When globals are available
Globals are passed to ruleset scripts as ctx.globals (the last argument). Calculators may not receive ctx at all, and a ruleset can run without it too. Always check ctx && ctx.globals before using them and fall back to the raw ref.
| Property | Type | Description |
|---|---|---|
formats? | Record<string, LorCatalogFormatLookupEntry> | Formats by formatRefs key ("client_Formats_Standard_name" → Standard). |
keywords? | Record<string, LorCatalogKeywordLookupEntry> | Keywords by keywordRefs key ("QuickStrike" → Quick Attack), with reminder text. |
rarities? | Record<string, LorCatalogRarityLookupEntry> | Rarities by rarityRef key ("Common", "Rare", "Epic", "Champion", "None"). |
regions? | Record<string, LorCatalogRegionLookupEntry> | Regions by regionRefs key ("Demacia", "PiltoverZaun", "Runeterra"). |
runeterraChampions? | Record<string, LorCatalogRuneterraChampionLookupEntry> | Runeterra champions by card code ("06RU001"): the champion refs that can appear in regionRefs. |
sets? | Record<string, LorCatalogSetLookupEntry> | Sets by the card's setCode ("set1", "set7b", "setevent"). |
spellSpeeds? | Record<string, LorCatalogSpellSpeedLookupEntry> | Spell speeds by spellSpeedRef key ("Burst", "Fast", "Slow"). |
types? | Record<string, LorCatalogTypeLookupEntry> | Card types by English type ("Unit", "Spell", "Champion", "Follower", …). |
vocabTerms? | Record<string, LorCatalogVocabTermLookupEntry> | Glossary terms by vocabTerms key ("Allegiance"), with descriptions. |
Lookup entries
Every globals table maps a key to an entry with these fields:
| Property | Type | Description |
|---|---|---|
color? | string | Display color: a hex value ("#10C26E") or a CSS variable name ("--color-Demacia"). |
icon? | string | null | Icon image URL; empty or null when there is none. |
label | string | Display name in the catalog locale ("Piltover & Zaun"). |
metadataRef? | LorCatalogMetadataReference | Anchor an operator override is matched on. |
order? | number | Sort position in filters and lists, lowest first. |
showInFilter? | boolean | Whether the entry is offered as a filter option in the card browser. |
Keyword and vocab term entries
keywords and vocabTerms entries also have:
| Property | Type | Description |
|---|---|---|
description? | string | Reminder text for the keyword, in the catalog locale. |
Runeterra champion entries
runeterraChampions entries also have:
| Property | Type | Description |
|---|---|---|
cardCode | string | The champion's card code ("06RU001" for Bard), also its key in runeterraChampions. |
Example card
Garen (01DE012), trimmed to one image:
json
{
"id": "01DE012",
"name": "Garen",
"setCode": "set1",
"collectible": true,
"assets": [
{
"kind": "card",
"url": "https://cdn.turny.gg/cards/lor/assets/01DE012-card-8a863d8a21d1029ab31bd8454e9456e89c2de96072d27705e2f11883752034f5.webp"
}
],
"game": {
"associatedCardRefs": ["01DE012T1", "01DE012T2"],
"formatRefs": [
"client_Formats_Eternal_name",
"client_Formats_Standard_name"
],
"keywordRefs": ["Regeneration"],
"rarityRef": "Champion",
"regionRefs": ["Demacia"],
"vocabTerms": ["Strike"],
"supertype": "Champion",
"supertypeRef": "Champion",
"type": "Unit",
"typeRef": "Unit",
"cost": 5,
"attack": 5,
"health": 5,
"description": "When I'm summoned, give other allies +1|+1 this round.",
"descriptionRaw": "When I'm summoned, give other allies +1|+1 this round.",
"levelupDescription": "I've <link=vocab.Strike><style=Vocab>struck</style></link> twice.<style=Variable></style>",
"levelupDescriptionRaw": "I've struck twice.",
"flavorText": "Training and resilience are the way of a soldier. Even in the face of great peril, we will not falter.",
"subtypes": ["ELITE"],
"artistName": "SIXMOREVODKA"
}
}Common recipes
js
// Calculator: cards per type, with champions split out.
export default function compute(pile, cardsById) {
const counts = {};
Object.keys(pile).forEach((ref) => {
const game = (cardsById[ref] && cardsById[ref].game) || {};
const type =
game.supertypeRef === "Champion" ? "Champion" : game.typeRef || "Other";
counts[type] = (counts[type] || 0) + pile[ref];
});
return {
widgets: [
{
kind: "donut",
label: "Card types",
segments: Object.keys(counts).map((type) => ({
label: type,
value: counts[type],
})),
},
],
};
}js
// Card rule: commons only, plus champions.
export default function validateCard(card) {
const rarity = card.game && card.game.rarityRef;
if (rarity === "Common" || rarity === "Champion") {
return true;
}
return {
valid: false,
issues: [{ message: card.name + " is not a common." }],
};
}js
// Card rule: Demacia only. Uses the region's display name when globals exist.
export default function validateCard(card, ctx) {
const regions = (card.game && card.game.regionRefs) || [];
if (regions.indexOf("Demacia") !== -1) {
return true;
}
const globals = ctx && ctx.globals;
const region =
globals && globals.regions && globals.regions.Demacia
? globals.regions.Demacia.label
: "Demacia";
return {
valid: false,
issues: [{ message: card.name + " is not from " + region + "." }],
};
}js
// Calculator: copies at each mana cost, 7+ grouped.
export default function compute(pile, cardsById) {
const buckets = [0, 0, 0, 0, 0, 0, 0, 0];
Object.keys(pile).forEach((ref) => {
const game = (cardsById[ref] && cardsById[ref].game) || {};
const cost = Math.min(Math.max(game.cost || 0, 0), 7);
buckets[cost] += pile[ref];
});
return {
widgets: [
{
kind: "histogram",
label: "Mana curve",
buckets: buckets,
labels: ["0", "1", "2", "3", "4", "5", "6", "7+"],
},
],
};
}