From 7493d948e6c6885d5941e1f44f7fd6be31ed6c12 Mon Sep 17 00:00:00 2001 From: Christopher Monsanto Date: Sun, 23 Aug 2026 01:45:36 -0400 Subject: [PATCH] Name the icons that share one, instead of deriving them The last commit answered "these 22 formes have no icon" with a generated 418-line table of every forme's parent and a loop that walked it, which is a lot of apparatus for a list that fits on a screen and changes when a generation does. Write the list. Same 1556 files out of xyicons/, byte for byte. The two throws are the part the derivation gave for free: an alias whose source icon has gone, and an alias for a name that has since been drawn, are both mistakes worth stopping the build for rather than quietly serving the wrong picture. data/lib/formes.ts and tools/spritedata/formes.ts go; nothing else read either. Co-Authored-By: Claude Opus 5 (1M context) --- data/lib/formes.ts | 418 ------------------------------------- smogon.build.ts | 53 +++-- tools/spritedata/formes.ts | 79 ------- 3 files changed, 37 insertions(+), 513 deletions(-) delete mode 100644 data/lib/formes.ts delete mode 100644 tools/spritedata/formes.ts diff --git a/data/lib/formes.ts b/data/lib/formes.ts deleted file mode 100644 index 365407ed..00000000 --- a/data/lib/formes.ts +++ /dev/null @@ -1,418 +0,0 @@ -// Generated by tools/spritedata/formes.ts; do not edit. -// Each forme's published name -> the name it falls back on for art. - -export const FORME_PARENTS: Record = { - 'venusaur-mega': 'venusaur', - 'charizard-mega-x': 'charizard', - 'charizard-mega-y': 'charizard', - 'blastoise-mega': 'blastoise', - 'beedrill-mega': 'beedrill', - 'pidgeot-mega': 'pidgeot', - 'rattata-alola': 'rattata', - 'raticate-alola': 'raticate', - 'raticate-alola-totem': 'raticate-alola', - 'pikachu-original': 'pikachu', - 'pikachu-hoenn': 'pikachu', - 'pikachu-sinnoh': 'pikachu', - 'pikachu-unova': 'pikachu', - 'pikachu-kalos': 'pikachu', - 'pikachu-alola': 'pikachu', - 'pikachu-partner': 'pikachu', - 'pikachu-starter': 'pikachu', - 'pikachu-world': 'pikachu', - 'pikachu-rock-star': 'pikachu', - 'pikachu-belle': 'pikachu', - 'pikachu-pop-star': 'pikachu', - 'pikachu-phd': 'pikachu', - 'pikachu-libre': 'pikachu', - 'pikachu-cosplay': 'pikachu', - 'raichu-alola': 'raichu', - 'raichu-mega-x': 'raichu', - 'raichu-mega-y': 'raichu', - 'sandshrew-alola': 'sandshrew', - 'sandslash-alola': 'sandslash', - 'clefable-mega': 'clefable', - 'vulpix-alola': 'vulpix', - 'ninetales-alola': 'ninetales', - 'diglett-alola': 'diglett', - 'dugtrio-alola': 'dugtrio', - 'meowth-alola': 'meowth', - 'meowth-galar': 'meowth', - 'persian-alola': 'persian', - 'growlithe-hisui': 'growlithe', - 'arcanine-hisui': 'arcanine', - 'alakazam-mega': 'alakazam', - 'victreebel-mega': 'victreebel', - 'geodude-alola': 'geodude', - 'graveler-alola': 'graveler', - 'golem-alola': 'golem', - 'ponyta-galar': 'ponyta', - 'rapidash-galar': 'rapidash', - 'slowpoke-galar': 'slowpoke', - 'slowbro-mega': 'slowbro', - 'slowbro-galar': 'slowbro', - 'farfetchd-galar': 'farfetchd', - 'grimer-alola': 'grimer', - 'muk-alola': 'muk', - 'gengar-mega': 'gengar', - 'voltorb-hisui': 'voltorb', - 'electrode-hisui': 'electrode', - 'exeggutor-alola': 'exeggutor', - 'marowak-alola': 'marowak', - 'marowak-alola-totem': 'marowak-alola', - 'weezing-galar': 'weezing', - 'kangaskhan-mega': 'kangaskhan', - 'starmie-mega': 'starmie', - 'mr-mime-galar': 'mr-mime', - 'pinsir-mega': 'pinsir', - 'tauros-paldea-combat': 'tauros', - 'tauros-paldea-blaze': 'tauros', - 'tauros-paldea-aqua': 'tauros', - 'gyarados-mega': 'gyarados', - 'eevee-starter': 'eevee', - 'aerodactyl-mega': 'aerodactyl', - 'articuno-galar': 'articuno', - 'zapdos-galar': 'zapdos', - 'moltres-galar': 'moltres', - 'dragonite-mega': 'dragonite', - 'mewtwo-mega-x': 'mewtwo', - 'mewtwo-mega-y': 'mewtwo', - 'meganium-mega': 'meganium', - 'typhlosion-hisui': 'typhlosion', - 'feraligatr-mega': 'feraligatr', - 'pichu-spiky-eared': 'pichu', - 'ampharos-mega': 'ampharos', - 'wooper-paldea': 'wooper', - 'slowking-galar': 'slowking', - 'unown-b': 'unown', - 'unown-c': 'unown', - 'unown-d': 'unown', - 'unown-e': 'unown', - 'unown-f': 'unown', - 'unown-g': 'unown', - 'unown-h': 'unown', - 'unown-i': 'unown', - 'unown-j': 'unown', - 'unown-k': 'unown', - 'unown-l': 'unown', - 'unown-m': 'unown', - 'unown-n': 'unown', - 'unown-o': 'unown', - 'unown-p': 'unown', - 'unown-q': 'unown', - 'unown-r': 'unown', - 'unown-s': 'unown', - 'unown-t': 'unown', - 'unown-u': 'unown', - 'unown-v': 'unown', - 'unown-w': 'unown', - 'unown-x': 'unown', - 'unown-y': 'unown', - 'unown-z': 'unown', - 'unown-exclamation': 'unown', - 'unown-question': 'unown', - 'steelix-mega': 'steelix', - 'qwilfish-hisui': 'qwilfish', - 'scizor-mega': 'scizor', - 'heracross-mega': 'heracross', - 'sneasel-hisui': 'sneasel', - 'corsola-galar': 'corsola', - 'skarmory-mega': 'skarmory', - 'houndoom-mega': 'houndoom', - 'tyranitar-mega': 'tyranitar', - 'sceptile-mega': 'sceptile', - 'blaziken-mega': 'blaziken', - 'swampert-mega': 'swampert', - 'zigzagoon-galar': 'zigzagoon', - 'linoone-galar': 'linoone', - 'gardevoir-mega': 'gardevoir', - 'sableye-mega': 'sableye', - 'mawile-mega': 'mawile', - 'aggron-mega': 'aggron', - 'medicham-mega': 'medicham', - 'manectric-mega': 'manectric', - 'sharpedo-mega': 'sharpedo', - 'camerupt-mega': 'camerupt', - 'altaria-mega': 'altaria', - 'castform-sunny': 'castform', - 'castform-rainy': 'castform', - 'castform-snowy': 'castform', - 'banette-mega': 'banette', - 'chimecho-mega': 'chimecho', - 'absol-mega': 'absol', - 'absol-mega-z': 'absol-mega', - 'glalie-mega': 'glalie', - 'salamence-mega': 'salamence', - 'metagross-mega': 'metagross', - 'latias-mega': 'latias', - 'latios-mega': 'latios', - 'kyogre-primal': 'kyogre', - 'groudon-primal': 'groudon', - 'rayquaza-mega': 'rayquaza', - 'deoxys-attack': 'deoxys', - 'deoxys-defense': 'deoxys', - 'deoxys-speed': 'deoxys', - 'staraptor-mega': 'staraptor', - 'burmy-sandy': 'burmy', - 'burmy-trash': 'burmy', - 'wormadam-sandy': 'wormadam', - 'wormadam-trash': 'wormadam', - 'cherrim-sunshine': 'cherrim', - 'shellos-east': 'shellos', - 'gastrodon-east': 'gastrodon', - 'lopunny-mega': 'lopunny', - 'garchomp-mega': 'garchomp', - 'garchomp-mega-z': 'garchomp-mega', - 'lucario-mega': 'lucario', - 'lucario-mega-z': 'lucario-mega', - 'abomasnow-mega': 'abomasnow', - 'gallade-mega': 'gallade', - 'froslass-mega': 'froslass', - 'rotom-heat': 'rotom', - 'rotom-wash': 'rotom', - 'rotom-frost': 'rotom', - 'rotom-fan': 'rotom', - 'rotom-mow': 'rotom', - 'dialga-origin': 'dialga', - 'palkia-origin': 'palkia', - 'heatran-mega': 'heatran', - 'giratina-origin': 'giratina', - 'darkrai-mega': 'darkrai', - 'shaymin-sky': 'shaymin', - 'arceus-fighting': 'arceus', - 'arceus-flying': 'arceus', - 'arceus-poison': 'arceus', - 'arceus-ground': 'arceus', - 'arceus-rock': 'arceus', - 'arceus-bug': 'arceus', - 'arceus-ghost': 'arceus', - 'arceus-steel': 'arceus', - 'arceus-fire': 'arceus', - 'arceus-water': 'arceus', - 'arceus-grass': 'arceus', - 'arceus-electric': 'arceus', - 'arceus-psychic': 'arceus', - 'arceus-ice': 'arceus', - 'arceus-dragon': 'arceus', - 'arceus-dark': 'arceus', - 'arceus-fairy': 'arceus', - 'emboar-mega': 'emboar', - 'samurott-hisui': 'samurott', - 'excadrill-mega': 'excadrill', - 'audino-mega': 'audino', - 'scolipede-mega': 'scolipede', - 'lilligant-hisui': 'lilligant', - 'basculin-blue-striped': 'basculin', - 'basculin-white-striped': 'basculin', - 'darumaka-galar': 'darumaka', - 'darmanitan-zen': 'darmanitan', - 'darmanitan-galar': 'darmanitan', - 'darmanitan-galar-zen': 'darmanitan-galar', - 'scrafty-mega': 'scrafty', - 'yamask-galar': 'yamask', - 'zorua-hisui': 'zorua', - 'zoroark-hisui': 'zoroark', - 'deerling-summer': 'deerling', - 'deerling-autumn': 'deerling', - 'deerling-winter': 'deerling', - 'sawsbuck-summer': 'sawsbuck', - 'sawsbuck-autumn': 'sawsbuck', - 'sawsbuck-winter': 'sawsbuck', - 'eelektross-mega': 'eelektross', - 'chandelure-mega': 'chandelure', - 'stunfisk-galar': 'stunfisk', - 'golurk-mega': 'golurk', - 'braviary-hisui': 'braviary', - 'tornadus-therian': 'tornadus', - 'thundurus-therian': 'thundurus', - 'landorus-therian': 'landorus', - 'kyurem-white': 'kyurem', - 'kyurem-black': 'kyurem', - 'keldeo-resolute': 'keldeo', - 'meloetta-pirouette': 'meloetta', - 'genesect-douse': 'genesect', - 'genesect-shock': 'genesect', - 'genesect-burn': 'genesect', - 'genesect-chill': 'genesect', - 'chesnaught-mega': 'chesnaught', - 'delphox-mega': 'delphox', - 'greninja-bond': 'greninja', - 'greninja-ash': 'greninja', - 'greninja-mega': 'greninja', - 'vivillon-icy-snow': 'vivillon', - 'vivillon-polar': 'vivillon', - 'vivillon-tundra': 'vivillon', - 'vivillon-continental': 'vivillon', - 'vivillon-garden': 'vivillon', - 'vivillon-elegant': 'vivillon', - 'vivillon-modern': 'vivillon', - 'vivillon-marine': 'vivillon', - 'vivillon-archipelago': 'vivillon', - 'vivillon-high-plains': 'vivillon', - 'vivillon-sandstorm': 'vivillon', - 'vivillon-river': 'vivillon', - 'vivillon-monsoon': 'vivillon', - 'vivillon-savanna': 'vivillon', - 'vivillon-sun': 'vivillon', - 'vivillon-ocean': 'vivillon', - 'vivillon-jungle': 'vivillon', - 'vivillon-fancy': 'vivillon', - 'vivillon-pokeball': 'vivillon', - 'pyroar-mega': 'pyroar', - 'flabebe-yellow': 'flabebe', - 'flabebe-orange': 'flabebe', - 'flabebe-blue': 'flabebe', - 'flabebe-white': 'flabebe', - 'floette-yellow': 'floette', - 'floette-orange': 'floette', - 'floette-blue': 'floette', - 'floette-white': 'floette', - 'floette-eternal': 'floette', - 'floette-mega': 'floette', - 'florges-yellow': 'florges', - 'florges-orange': 'florges', - 'florges-blue': 'florges', - 'florges-white': 'florges', - 'furfrou-heart': 'furfrou', - 'furfrou-star': 'furfrou', - 'furfrou-diamond': 'furfrou', - 'furfrou-debutante': 'furfrou', - 'furfrou-matron': 'furfrou', - 'furfrou-dandy': 'furfrou', - 'furfrou-la-reine': 'furfrou', - 'furfrou-kabuki': 'furfrou', - 'furfrou-pharaoh': 'furfrou', - 'meowstic-f': 'meowstic', - 'meowstic-m-mega': 'meowstic', - 'meowstic-f-mega': 'meowstic-f', - 'aegislash-blade': 'aegislash', - 'malamar-mega': 'malamar', - 'barbaracle-mega': 'barbaracle', - 'dragalge-mega': 'dragalge', - 'hawlucha-mega': 'hawlucha', - 'sliggoo-hisui': 'sliggoo', - 'goodra-hisui': 'goodra', - 'pumpkaboo-small': 'pumpkaboo', - 'pumpkaboo-large': 'pumpkaboo', - 'pumpkaboo-super': 'pumpkaboo', - 'gourgeist-small': 'gourgeist', - 'gourgeist-large': 'gourgeist', - 'gourgeist-super': 'gourgeist', - 'avalugg-hisui': 'avalugg', - 'xerneas-neutral': 'xerneas', - 'zygarde-10': 'zygarde', - 'zygarde-complete': 'zygarde', - 'zygarde-mega': 'zygarde', - 'diancie-mega': 'diancie', - 'hoopa-unbound': 'hoopa', - 'decidueye-hisui': 'decidueye', - 'gumshoos-totem': 'gumshoos', - 'vikavolt-totem': 'vikavolt', - 'crabominable-mega': 'crabominable', - 'oricorio-pom-pom': 'oricorio', - 'oricorio-pau': 'oricorio', - 'oricorio-sensu': 'oricorio', - 'ribombee-totem': 'ribombee', - 'rockruff-dusk': 'rockruff', - 'lycanroc-midnight': 'lycanroc', - 'lycanroc-dusk': 'lycanroc', - 'wishiwashi-school': 'wishiwashi', - 'araquanid-totem': 'araquanid', - 'lurantis-totem': 'lurantis', - 'salazzle-totem': 'salazzle', - 'golisopod-mega': 'golisopod', - 'silvally-fighting': 'silvally', - 'silvally-flying': 'silvally', - 'silvally-poison': 'silvally', - 'silvally-ground': 'silvally', - 'silvally-rock': 'silvally', - 'silvally-bug': 'silvally', - 'silvally-ghost': 'silvally', - 'silvally-steel': 'silvally', - 'silvally-fire': 'silvally', - 'silvally-water': 'silvally', - 'silvally-grass': 'silvally', - 'silvally-electric': 'silvally', - 'silvally-psychic': 'silvally', - 'silvally-ice': 'silvally', - 'silvally-dragon': 'silvally', - 'silvally-dark': 'silvally', - 'silvally-fairy': 'silvally', - 'minior-meteor': 'minior', - 'minior-orange': 'minior', - 'minior-yellow': 'minior', - 'minior-green': 'minior', - 'minior-blue': 'minior', - 'minior-indigo': 'minior', - 'minior-violet': 'minior', - 'togedemaru-totem': 'togedemaru', - 'mimikyu-busted': 'mimikyu', - 'mimikyu-totem': 'mimikyu', - 'mimikyu-busted-totem': 'mimikyu-busted', - 'drampa-mega': 'drampa', - 'kommo-o-totem': 'kommo-o', - 'necrozma-dusk-mane': 'necrozma', - 'necrozma-dawn-wings': 'necrozma', - 'necrozma-ultra': 'necrozma', - 'magearna-original': 'magearna', - 'magearna-mega': 'magearna', - 'magearna-original-mega': 'magearna-original', - 'zeraora-mega': 'zeraora', - 'cramorant-gulping': 'cramorant', - 'cramorant-gorging': 'cramorant', - 'toxtricity-low-key': 'toxtricity', - 'sinistea-antique': 'sinistea', - 'polteageist-antique': 'polteageist', - 'alcremie-ruby-cream': 'alcremie', - 'alcremie-matcha-cream': 'alcremie', - 'alcremie-mint-cream': 'alcremie', - 'alcremie-lemon-cream': 'alcremie', - 'alcremie-salted-cream': 'alcremie', - 'alcremie-ruby-swirl': 'alcremie', - 'alcremie-caramel-swirl': 'alcremie', - 'alcremie-rainbow-swirl': 'alcremie', - 'falinks-mega': 'falinks', - 'eiscue-noice': 'eiscue', - 'indeedee-f': 'indeedee', - 'morpeko-hangry': 'morpeko', - 'zacian-crowned': 'zacian', - 'zamazenta-crowned': 'zamazenta', - 'eternatus-eternamax': 'eternatus', - 'urshifu-rapid-strike': 'urshifu', - 'zarude-dada': 'zarude', - 'calyrex-ice': 'calyrex', - 'calyrex-shadow': 'calyrex', - 'ursaluna-bloodmoon': 'ursaluna', - 'basculegion-f': 'basculegion', - 'enamorus-therian': 'enamorus', - 'oinkologne-f': 'oinkologne', - 'maushold-four': 'maushold', - 'squawkabilly-blue': 'squawkabilly', - 'squawkabilly-yellow': 'squawkabilly', - 'squawkabilly-white': 'squawkabilly', - 'scovillain-mega': 'scovillain', - 'palafin-hero': 'palafin', - 'glimmora-mega': 'glimmora', - 'tatsugiri-droopy': 'tatsugiri', - 'tatsugiri-stretchy': 'tatsugiri', - 'tatsugiri-curly-mega': 'tatsugiri', - 'tatsugiri-droopy-mega': 'tatsugiri-droopy', - 'tatsugiri-stretchy-mega': 'tatsugiri-stretchy', - 'dudunsparce-three-segment': 'dudunsparce', - 'baxcalibur-mega': 'baxcalibur', - 'gimmighoul-roaming': 'gimmighoul', - 'poltchageist-artisan': 'poltchageist', - 'sinistcha-masterpiece': 'sinistcha', - 'ogerpon-wellspring': 'ogerpon', - 'ogerpon-hearthflame': 'ogerpon', - 'ogerpon-cornerstone': 'ogerpon', - 'ogerpon-teal-tera': 'ogerpon', - 'ogerpon-wellspring-tera': 'ogerpon-wellspring', - 'ogerpon-hearthflame-tera': 'ogerpon-hearthflame', - 'ogerpon-cornerstone-tera': 'ogerpon-cornerstone', - 'terapagos-terastal': 'terapagos', - 'terapagos-stellar': 'terapagos', - 'crucibelle-mega': 'crucibelle', - 'venomicon-epilogue': 'venomicon', - 'ramnarok-radiant': 'ramnarok', -}; diff --git a/smogon.build.ts b/smogon.build.ts index 91259e7f..ec6ce4ff 100644 --- a/smogon.build.ts +++ b/smogon.build.ts @@ -1,6 +1,4 @@ -import {FORME_PARENTS} from '@smogon/sprite-data/formes.ts'; - import {gen10Modelslike} from './rules/modelslike.ts'; import {type Sprite, publishedNames} from './rules/publish.ts'; import {forEachRule} from './tools/build/artifact.ts'; @@ -76,6 +74,36 @@ let xyIcons = forEachRule('src/minisprites/pokemon/gen6/*.png', { cmds: [trimimg(), compresspng({config: 'MINISPRITE'})], }, '%b'); +// The games drew these formes no icon of their own, so gen 6 has none and +// nothing upstream does either: PS ships icons as one dexnum-indexed sheet, and +// its own copy of this list sits commented out in ps-pokemon.sheet.mjs under +// "alt forms with duplicate icons". Serve each the icon it shares. Only this +// set needs them; xy/ has real art for all 22. +let xyIconAliases: Record = { + 'araquanid-totem': 'araquanid', + 'gourgeist-large': 'gourgeist', + 'gourgeist-small': 'gourgeist', + 'gourgeist-super': 'gourgeist', + 'greninja-bond': 'greninja', + 'gumshoos-totem': 'gumshoos', + 'kommo-o-totem': 'kommo-o', + 'lurantis-totem': 'lurantis', + 'marowak-alola-totem': 'marowak-alola', + 'mimikyu-busted': 'mimikyu', + 'mimikyu-busted-totem': 'mimikyu', + 'mimikyu-totem': 'mimikyu', + 'pichu-spiky-eared': 'pichu', + 'pumpkaboo-large': 'pumpkaboo', + 'pumpkaboo-small': 'pumpkaboo', + 'pumpkaboo-super': 'pumpkaboo', + 'raticate-alola-totem': 'raticate-alola', + 'ribombee-totem': 'ribombee', + 'rockruff-dusk': 'rockruff', + 'salazzle-totem': 'salazzle', + 'togedemaru-totem': 'togedemaru', + 'vikavolt-totem': 'vikavolt', +}; + deploy(ctx => { let byName = new Map(); for (let f of xyIcons) { @@ -83,22 +111,15 @@ deploy(ctx => { byName.set(name, f); } } - // The games drew no icon for some formes, so PS's own sheet sends them to - // the nearest one that has art: Gourgeist-Super to Gourgeist, - // Mimikyu-Busted-Totem to Mimikyu-Busted and on to Mimikyu. Walk the same - // chain, so a name the data knows gets an icon rather than a 404. Only - // this set needs it, since xy/ has real art for every one of them. - for (let name of Object.keys(FORME_PARENTS)) { + for (let [name, from] of Object.entries(xyIconAliases)) { + let f = byName.get(from); + if (f === undefined) { + throw new Error(`No ${from} icon to publish as ${name}`); + } if (byName.has(name)) { - continue; - } - for (let p = FORME_PARENTS[name]; p !== undefined; p = FORME_PARENTS[p]) { - let f = byName.get(p); - if (f) { - byName.set(name, f); - break; - } + throw new Error(`${name} has an icon of its own now; drop the alias`); } + byName.set(name, f); } for (let [name, f] of byName) { smogonSpritecopy(ctx, f, 'xyicons', [name]); diff --git a/tools/spritedata/formes.ts b/tools/spritedata/formes.ts deleted file mode 100644 index 1e6b7f55..00000000 --- a/tools/spritedata/formes.ts +++ /dev/null @@ -1,79 +0,0 @@ -import {encode, publishedName, smogon} from '@smogon/sprite-data/index.ts'; - -import {species} from './pokedex.ts'; - -// Regenerates data/lib/formes.ts from a pokemon-showdown checkout: -// -// node tools/spritedata/formes.ts ~/smogon/pokemon-showdown > data/lib/formes.ts -// -// The games drew some formes no art of their own, and a set that has none -// falls back on the nearest forme it is a refinement of, up to the base -// species: PS's own icon sheet points Gourgeist-Super at Gourgeist's slot and -// Mimikyu-Busted-Totem at Mimikyu's. That chain can't be recovered from a -// published name alone, since a base name carries dashes too (kommo-o, -// mr-mime, porygon-z), so it is written down here. -// -// The parent is the longest run of leading words that names a forme of its -// own, and the base species otherwise. Dropping one word blindly would strand -// Toxtricity-Low-Key on a Toxtricity-Low that does not exist. - -let ps = process.argv[2]; -if (!ps) { - throw new Error('usage: node tools/spritedata/formes.ts '); -} - -// `forme` comes in encoded; `base` does not. -function published(base: string, forme: string): string { - let extra = new Map(); - if (forme) { - extra.set('o', forme); - } - return publishedName({kind: 's', name: encode(base), extra}, smogon); -} - -let all = species(ps); - -// Which formes each base species actually has, so a parent can be checked. -let formes = new Map>(); -for (let {base, forme} of all) { - let set = formes.get(base); - if (!set) { - set = new Set(); - formes.set(base, set); - } - set.add(encode(forme)); -} - -function parent(base: string, forme: string): string { - let words = forme.split('_'); - for (let n = words.length - 1; n > 0; n--) { - let shorter = words.slice(0, n).join('_'); - if (formes.get(base)?.has(shorter)) { - return shorter; - } - } - return ''; -} - -let out = ''; -out += '// Generated by tools/spritedata/formes.ts; do not edit.\n'; -out += "// Each forme's published name -> the name it falls back on for art.\n\n"; -out += 'export const FORME_PARENTS: Record = {\n'; - -let seen = new Set(); -for (let {base, forme} of all) { - if (!forme) { - continue; - } - let name = published(base, encode(forme)); - // Where formeOrder gives one name to several slots, they share a parent. - if (seen.has(name)) { - continue; - } - seen.add(name); - out += ` '${name}': '${published(base, parent(base, encode(forme)))}',\n`; -} - -out += '};\n'; - -process.stdout.write(out);