Skip to content

Instantly share code, notes, and snippets.

@exp111
Last active December 27, 2024 11:03
Show Gist options
  • Save exp111/47b6f5759840241a3466baa62a5b1bf7 to your computer and use it in GitHub Desktop.
Save exp111/47b6f5759840241a3466baa62a5b1bf7 to your computer and use it in GitHub Desktop.
MC JSON Translation Diff

This is a small tool to diff the current english data with the (default: german) translation. It checks if:

  • files exist (meaning that no one has started translating the file yet)
  • entry codes exist (meaning that someone started translating but didnt finish. ignores entries that are duplicates of other entries)
  • (optionally via arguments) the attributes of entries are different (meaning that someone added the entry but didnt fully translate it)

How to run:

See diff.py -h for arguments.

import argparse
import html
import json
import os
import textwrap
def directory(raw_path: str):
raw_path = raw_path.replace("\"", "").replace("'", "").strip()
if not os.path.isdir(raw_path):
raise argparse.ArgumentTypeError('"{}" is not an existing directory'.format(raw_path))
return os.path.abspath(raw_path)
parser = argparse.ArgumentParser(
prog='Marvel Champions Translation Diff',
description='Checks the Marvel Champions JSON Repo for missing translations')
parser.add_argument("-l", "--lang", default="de", help="The language code for the translation")
parser.add_argument("-a", "--attributes", action="store_true", help="If used also compares the object keys for equalness. May lead to false positives as values may be the same in the two languages.") # flag
parser.add_argument("-v", "--verbose", action="store_true", help="Show verbose output") # flag
parser.add_argument("-i", "--input", nargs="?", default=os.path.curdir, type=directory, help="The directory of the repo. Defaults to the current path.")
parser.add_argument("-o", "--output", nargs="?", default=os.path.curdir, type=directory, help="The directory where the output is writtent to. Defaults to the current path.")
args = parser.parse_args()
# args
lang = args.lang
listAttributes = args.attributes
verbose = args.verbose
inputDir = args.input
outputDir = args.output
def vprint(text: str):
if verbose:
print(text)
def write(text: str = "", out=None):
print(text, file=out)
vprint(text)
vprint("Args:")
vprint(args)
# consts
baseDir = inputDir
translationBaseDir = "translations"
packSubDir = "pack"
# whitelisted files. are not checked
whitelist = ["package.json", "settypes.json"]
attributes = ["flavor", "text"] # "name", "traits" not included
class MissingInfoEntry:
code: str
name: str
def __init__(self, code, name):
self.code = code
self.name = name
class MissingInfoAttribute:
code: str
attribute: str
value: str
def __init__(self, code, attribute, value):
self.code = code
self.attribute = attribute
self.value = value
class MissingInfo:
file: str
entries: list[MissingInfoEntry]
attributes: list[MissingInfoAttribute]
def __init__(self, name):
self.file = name
self.entries = []
self.attributes = []
# for each json in basedir and packSubDir:
# check if file exists in translationDir:
# if no:
# mark as missing
# else:
# check object keys + values for diff (whitelist keys per file):
# if different:
# -- do nothing as it was changed. maybe check if german language
# if not different:
# mark as missing
queue = []
def isValid(entry: os.DirEntry):
return entry.is_file() and entry.name.endswith(".json") and entry.name not in whitelist
vprint("Checking original files")
# check if the folder structure is somewhat right
if not os.path.exists(os.path.join(baseDir, translationBaseDir)):
print("No translations directory was found. Did you select the right directory?")
exit(1)
# get all existing original files
for entry in os.scandir(baseDir):
# if the entry is the pack dir, add all valid files in there to the queue
if entry.is_dir() and entry.name == packSubDir:
for entry2 in os.scandir(entry.path):
if isValid(entry2):
queue.append(entry2)
# and all top level valid files
if isValid(entry):
queue.append(entry)
# check if any files were found
if len(queue) == 0:
print("No files found.")
exit(0)
missingFiles: list[str] = []
missingInfos: list[MissingInfo] = []
# checks the attribute on the original and translated object and returns true/false depending on if the attrib has been translated
def checkAttrib(orig, trans, attrib):
if attrib in orig:
if attrib in trans:
oVal = orig[attrib]
tVal = trans[attrib]
if oVal == tVal:
# value the same => not translated?
return False
else:
# value different => (probably) translated
return True
else:
# missing key??
return False
# key not found, so ignore
return True
vprint(f"{len(queue)} files found. Now checking if translated files for lang \"{lang}\" exist.")
for entry in queue:
relPath = os.path.relpath(entry.path, baseDir)
langPath = os.path.join(baseDir, translationBaseDir, lang, relPath)
if not os.path.exists(langPath):
# file is missing completely
missingFiles.append(entry.name)
else:
info = MissingInfo(entry.name)
# read both files
with open(entry.path, "r", encoding="utf-8") as file:
original = json.load(file)
with open(langPath, "r", encoding="utf-8") as file:
translation = json.load(file)
# iterate through original file and check
for obj in original:
# we dont need to translate duplicates
if "duplicate_of" in obj:
continue
# find entry in translation
result = next((t for t in translation if t["code"] == obj["code"]), None)
if not result:
# missing entry (not translated)
info.entries.append(MissingInfoEntry(obj["code"], obj["name"]))
else:
if listAttributes:
for a in attributes:
if not checkAttrib(obj, result, a):
info.attributes.append(MissingInfoAttribute(obj["code"], a, obj[a]))
# only add if something was found
if len(info.attributes) > 0 or len(info.entries) > 0:
missingInfos.append(info)
outputPath = os.path.join(outputDir, f"output_{lang}.md")
vprint(f"Writing {len(missingFiles)} + {len(missingInfos)} entries to output file:")
vprint(outputPath)
with open(outputPath, "w", encoding="utf-8") as out:
write(f"Missing Files ({len(missingFiles)}):", out)
for file in missingFiles:
write(f"- {file}", out)
write(f"Missing Entries ({len(missingInfos)}):", out)
for info in missingInfos:
# wrap in spoiler
write("<details>", out)
write(f"<summary>{info.file} ({len(info.entries) + len(info.attributes)})</summary>", out)
write(out=out) # empty line needed
for entry in info.entries:
write(f"- Entry: {entry.code} ({html.escape(entry.name)})", out)
for attrib in info.attributes:
write(f"- Attribut: {attrib.code} ({attrib.attribute}, {textwrap.shorten(html.escape(attrib.value), width=100)})", out)
write("</details>", out)

Missing Files (7):

  • hood_encounter.json
  • magneto.json
  • magneto_encounter.json
  • mojo_encounter.json
  • ron_encounter.json
  • toafk_encounter.json
  • twc_encounter.json Missing Entries (18):
factions.json (1)
  • Entry: pool ('Pool)
aoa.json (7)
  • Entry: 45171a (Mission Team)
  • Entry: 45171b (Mission Team)
  • Entry: 45172 (Destiny)
  • Entry: 45173 (Blink)
  • Entry: 45174 (Morph)
  • Entry: 45175 (X-Man)
  • Entry: 45176 (Desperate Measures)
aoa_encounter.json (153)
  • Entry: 45059 (Unus)
  • Entry: 45060 (Unus)
  • Entry: 45061 (Unus)
  • Entry: 45062a (Hunting Gene Traitors)
  • Entry: 45062b (Hunting Gene Traitors)
  • Entry: 45063 (Prelate Sidearm)
  • Entry: 45064 (Prelate Armor)
  • Entry: 45065 (Infinite Hunter)
  • Entry: 45066 (Genetic Experiments)
  • Entry: 45067 (Infinite Prelate)
  • Entry: 45068 (Endless Ranks)
  • Entry: 45069 (Infinite Soldier)
  • Entry: 45070 (Culling the Weak)
  • Entry: 45071 (Gene Pool)
  • Entry: 45072 (Hunted)
  • Entry: 45073 (War-Weary)
  • Entry: 45074 (Targeted for Extermination)
  • Entry: 45075a (Pursued by the Past)
  • Entry: 45075b (Pursued by the Past)
  • Entry: 45076 (Dark Design)
  • Entry: 45077 (Sinister Strike)
  • Entry: 45078 (Evil Alliance)
  • Entry: 45079 (Nowhere is Safe)
  • Entry: 45080 (Drawing Near)
  • Entry: 45081a (War)
  • Entry: 45081b (War)
  • Entry: 45082a (Famine)
  • Entry: 45082b (Famine)
  • Entry: 45083a (Pestilence)
  • Entry: 45083b (Pestilence)
  • Entry: 45084a (Death)
  • Entry: 45084b (Death)
  • Entry: 45085a (The Horsemen of Apocalypse)
  • Entry: 45085b (The Horsemen of Apocalypse)
  • Entry: 45086 (The Ravages of War)
  • Entry: 45087 (A Time of Famine)
  • Entry: 45088 (Plague and Pestilence)
  • Entry: 45089 (The Specter of Death)
  • Entry: 45090 (Golden Horse)
  • Entry: 45091 (Metal Wings)
  • Entry: 45092 (Horseman of War)
  • Entry: 45093 (Horseman of Famine)
  • Entry: 45094 (Horseman of Pestilence)
  • Entry: 45095 (Horseman of Death)
  • Entry: 45096 (Rough Riders)
  • Entry: 45097 (Ahab)
  • Entry: 45098 (Hound)
  • Entry: 45099 (Ahab's Energy Spear)
  • Entry: 45100 (Release the Hounds)
  • Entry: 45101a (Apocalypse)
  • Entry: 45101b (Apocalypse)
  • Entry: 45102a (Apocalypse)
  • Entry: 45102b (Apocalypse)
  • Entry: 45103a (The Age of Apocalypse)
  • Entry: 45103b (The Age of Apocalypse)
  • Entry: 45104a (Heart of the Empire)
  • Entry: 45104b (The Towering Citadel)
  • Entry: 45105a (The Tyrant's Throne)
  • Entry: 45105b (No Longer Worthy)
  • Entry: 45106 (Cyberpathy)
  • Entry: 45107 (Biomorphing)
  • Entry: 45108 (Molecular Control)
  • Entry: 45109 (The Fittest)
  • Entry: 45110 (Wolf Among Sheep)
  • Entry: 45111 (The Apocalypse Solution)
  • Entry: 45112 (Gauntlet)
  • Entry: 45113 (Barrage)
  • Entry: 45114 (Hard-Drive)
  • Entry: 45115 (Tusk)
  • Entry: 45116 (Psynapse)
  • Entry: 45117 (The Dark Riders)
  • Entry: 45118 (Dark Beast)
  • Entry: 45119 (Dark Beast)
  • Entry: 45120 (Dark Beast)
  • Entry: 45121a (Dark Beast's Bogus Journey)
  • Entry: 45121b (Dark Beast's Bogus Journey)
  • Entry: 45122 (High-Tech Goggles)
  • Entry: 45123 (Genetic Enhancement)
  • Entry: 45124 (Cruel Experiment)
  • Entry: 45125 (Evil Genius)
  • Entry: 45126 (Time-Travel Shenanigans)
  • Entry: 45127 (The Savage Land)
  • Entry: 45128 (Pterosaur)
  • Entry: 45129 (Velociraptor)
  • Entry: 45130 (Giant Ape)
  • Entry: 45131 (Land Out of Time)
  • Entry: 45132 (Village Under Attack)
  • Entry: 45133 (Genosha)
  • Entry: 45134 (Magistrate)
  • Entry: 45135 (Armored Unibike)
  • Entry: 45136 (Genoshan Mech)
  • Entry: 45137 (Escaped Mutant)
  • Entry: 45138 (Police State)
  • Entry: 45139 (Blue Area of the Moon)
  • Entry: 45140 (Gladiator)
  • Entry: 45141 (Oracle)
  • Entry: 45142 (Manta)
  • Entry: 45143 (Earthquake)
  • Entry: 45144 (Warstar)
  • Entry: 45145 (Imperial Guardsman)
  • Entry: 45146 (Trial by Combat)
  • Entry: 45147a (En Sabah Nur's Pyramid)
  • Entry: 45147b (En Sabah Nur's Pyramid)
  • Entry: 45148a (The Rise of Apocalypse)
  • Entry: 45148b (The Rise of Apocalypse)
  • Entry: 45149 (Staggering Strength)
  • Entry: 45150 (Biomorphic Blast)
  • Entry: 45151 (Technological Interface)
  • Entry: 45152 (Giant-Sized Despot)
  • Entry: 45153 (Source of Power)
  • Entry: 45154 (Plugged In)
  • Entry: 45155 (Giant Growth)
  • Entry: 45156 (Celestial Armor)
  • Entry: 45157 (Celestial Weapon)
  • Entry: 45158 (Celestial Tech)
  • Entry: 45159 (Ozymandias)
  • Entry: 45160 (Scarab)
  • Entry: 45161 (Clan Akkaba Zealot)
  • Entry: 45162 (Tyrant Worship)
  • Entry: 45163 (Ancient Ritual)
  • Entry: 45164 (Agent of Apocalypse)
  • Entry: 45165 (Worldwide Crisis)
  • Entry: 45166a (Liberate the Seattle Core)
  • Entry: 45166b (Liberate the Seattle Core)
  • Entry: 45167a (Evacuate Survivors)
  • Entry: 45167b (Evacuate Survivors)
  • Entry: 45168a (Sabotage the Sea Wall)
  • Entry: 45168b (Sabotage the Sea Wall)
  • Entry: 45169a (Find Lost Mutants)
  • Entry: 45169b (Find Lost Mutants)
  • Entry: 45170a (Protect the Professor)
  • Entry: 45170b (Protect the Professor)
  • Entry: 45177 (North American Sea Wall)
  • Entry: 45178 (Panicked Refugees)
  • Entry: 45179a (Mister Sinister)
  • Entry: 45179b (Mister Sinister)
  • Entry: 45180a (The Shadow King)
  • Entry: 45180b (The Shadow King)
  • Entry: 45181a (Abyss)
  • Entry: 45181b (Abyss)
  • Entry: 45182a (Sugar Man)
  • Entry: 45182b (Sugar Man)
  • Entry: 45183a (Mikhail Rasputin)
  • Entry: 45183b (Mikhail Rasputin)
  • Entry: 45184a (Apocalypse)
  • Entry: 45184b (Apocalypse)
  • Entry: 45184c (Apocalypse)
  • Entry: 45185a (Apocalypse)
  • Entry: 45185b (Apocalypse)
  • Entry: 45185c (Apocalypse)
  • Entry: 45186a (Apocalypse)
  • Entry: 45186b (Apocalypse)
  • Entry: 45186c (Apocalypse)
deadpool_encounter.json (6)
  • Entry: 44037 (Crisis of Infinite Deadpools)
  • Entry: 44038 (Dreadpool)
  • Entry: 44039 (Dreadful Deeds)
  • Entry: 44040 (Anti-Regeneration Ray)
  • Entry: 44041 ('Pool-ized)
  • Entry: 44042 (Metacidal Tendencies)
gob_encounter.json (8)
  • Entry: 02004a (Hostile Takeover)
  • Entry: 02004b (Hostile Takeover)
  • Entry: 02005a (Corporate Acquisition)
  • Entry: 02005b (Corporate Acquisition)
  • Entry: 02017a (Unleashing the Mutagen)
  • Entry: 02017b (Unleashing the Mutagen)
  • Entry: 02018a (Mutagen Cloud)
  • Entry: 02018b (Mutagen Cloud)
iceman_encounter.json (4)
  • Entry: 46029 (Sauron)
  • Entry: 46030 (Sauron Lives!)
  • Entry: 46031 (Life Drain)
  • Entry: 46032 (The Eye of Sauron)
ironheart_encounter.json (5)
  • Entry: 29036 (Feedback Loop)
  • Entry: 29037 (Zzzax)
  • Entry: 29038 (Haywire)
  • Entry: 29039 (Air Static)
  • Entry: 29040 (Zzzap!)
jubilee_encounter.json (5)
  • Entry: 47030 (Arcade)
  • Entry: 47031 (Welcome to Murderworld)
  • Entry: 47032 (Arcade's Funhouse)
  • Entry: 47033 (Hall of Mirrors)
  • Entry: 47034 (Elaborate Trap)
ncrawler_encounter.json (6)
  • Entry: 48033 (The Crazy Gang)
  • Entry: 48034 (Queen of Hearts)
  • Entry: 48035 (Jester)
  • Entry: 48036 (Executioner)
  • Entry: 48037 (Tweedledope)
  • Entry: 48038 ("Off with His Head!")
next_evol.json (14)
  • Entry: 40190a (Assemble the Team)
  • Entry: 40190b (Team Assembled)
  • Entry: 40191a (Establish Safehouse)
  • Entry: 40191b (Safehouse Established)
  • Entry: 40192a (Gear Up)
  • Entry: 40192b (Geared Up)
  • Entry: 40193a (Mission Prep)
  • Entry: 40193b (Mission Prepped)
  • Entry: 40194a (Practice Maneuvers)
  • Entry: 40194b (Practiced Maneuvers)
  • Entry: 40195a (Prepare Defenses)
  • Entry: 40195b (Prepared Defenses)
  • Entry: 40196 (Pouches)
  • Entry: 40197 (Safehouse)
next_evol_encounter.json (149)
  • Entry: 40070a (Arclight)
  • Entry: 40070b (Arclight)
  • Entry: 40071a (Blockbuster)
  • Entry: 40071b (Blockbuster)
  • Entry: 40072a (Chimera)
  • Entry: 40072b (Chimera)
  • Entry: 40073a (Greycrow)
  • Entry: 40073b (Greycrow)
  • Entry: 40074a (Harpoon)
  • Entry: 40074b (Harpoon)
  • Entry: 40075a (Riptide)
  • Entry: 40075b (Riptide)
  • Entry: 40076a (Vertigo)
  • Entry: 40076b (Vertigo)
  • Entry: 40077a (Knock, Knock)
  • Entry: 40077b (Knock, Knock)
  • Entry: 40078a (Mutant Massacre)
  • Entry: 40078b (Mutant Massacre)
  • Entry: 40079 (Morlock)
  • Entry: 40080 (Hide!)
  • Entry: 40081a (Routed)
  • Entry: 40081b (Routed)
  • Entry: 40082 (Bolstered by Wrath)
  • Entry: 40083 (Pushed to the Limit)
  • Entry: 40084 (By Any Means)
  • Entry: 40085 (In the Midst of Chaos)
  • Entry: 40086 (Maraudin' Ain't Easy)
  • Entry: 40087 (Territorial Control)
  • Entry: 40088 (Back in Action)
  • Entry: 40089 (Seek the Weak)
  • Entry: 40090 (Heavy Armament)
  • Entry: 40091 (Titanium Exoskeleton)
  • Entry: 40092 (Inhibitor Collar)
  • Entry: 40093 (The Senator's Support)
  • Entry: 40094 (Arclight)
  • Entry: 40095 (Blockbuster)
  • Entry: 40096 (Chimera)
  • Entry: 40097 (Greycrow)
  • Entry: 40098 (Harpoon)
  • Entry: 40099 (Riptide)
  • Entry: 40100 (Vertigo)
  • Entry: 40101 (Mutant Slayers)
  • Entry: 40102 (Bound by Business)
  • Entry: 40103a (Gotta Get Away)
  • Entry: 40103b (Gotta Get Away)
  • Entry: 40104a (Escaping with Hope)
  • Entry: 40104b (Escaping with Hope)
  • Entry: 40105a (Hope's Captor)
  • Entry: 40105b (Hope's Captor)
  • Entry: 40106 (Hidden in the Clutter)
  • Entry: 40107 (Favored Weapon)
  • Entry: 40108 (Bushwhack)
  • Entry: 40109 (Pure Force)
  • Entry: 40110 (Dizzying Deeds)
  • Entry: 40111 (Tag Team)
  • Entry: 40112 (Gorgeous George)
  • Entry: 40113 (Hairbag)
  • Entry: 40114 (Ramrod)
  • Entry: 40115 (Ruckus)
  • Entry: 40116 (Slab)
  • Entry: 40117 (Get Nasty)
  • Entry: 40118 (Juggernaut)
  • Entry: 40119 (Juggernaut)
  • Entry: 40120 (Juggernaut)
  • Entry: 40121a (The Unstoppable Juggernaut)
  • Entry: 40121b (The Unstoppable Juggernaut)
  • Entry: 40122a (Juggernaut's Helmet)
  • Entry: 40122b (Juggernaut Exposed)
  • Entry: 40123 (Head of Steam)
  • Entry: 40124 (Building Momentum)
  • Entry: 40125 (Breakthrough)
  • Entry: 40126 (Flatten)
  • Entry: 40127 (Ground Pound)
  • Entry: 40128 (Trample)
  • Entry: 40129 (Cyttorak's Exemplar)
  • Entry: 40130 (Hope Summers)
  • Entry: 40131 (Captive Hope)
  • Entry: 40132 (Black Tom Cassidy)
  • Entry: 40133 (Creeping Willow)
  • Entry: 40134 (Making Green)
  • Entry: 40135 (A Sound Thrashing)
  • Entry: 40136 (Mister Sinister)
  • Entry: 40137 (Mister Sinister)
  • Entry: 40138 (Mister Sinister)
  • Entry: 40139a (Sinister Intent)
  • Entry: 40139b (Sinister Intent)
  • Entry: 40140a (Taking Off)
  • Entry: 40140b (Taking Off)
  • Entry: 40141a (Bulking Up)
  • Entry: 40141b (Bulking Up)
  • Entry: 40142a (Focusing In)
  • Entry: 40142b (Focusing In)
  • Entry: 40143a (Sinister Ends)
  • Entry: 40143b (Sinister Ends)
  • Entry: 40144 (Sinister Disguise)
  • Entry: 40145 (Sinister Soldier)
  • Entry: 40146 (Teleported Away)
  • Entry: 40147 (Genetic Mastery)
  • Entry: 40148 (Molecular Control)
  • Entry: 40149 (Sinister Schemes)
  • Entry: 40150 (Sinister Strike)
  • Entry: 40151 (Flight)
  • Entry: 40152 (Aerial Bombardment)
  • Entry: 40153 (Out of Reach)
  • Entry: 40154 (High Ground)
  • Entry: 40155 (Super Strength)
  • Entry: 40156 (Impervious)
  • Entry: 40157 (Thrown Object)
  • Entry: 40158 ("I'll Take That")
  • Entry: 40159 (Telepathy)
  • Entry: 40160 (Manufactured Drama)
  • Entry: 40161 (Sowing Discord)
  • Entry: 40162 (One Step Ahead)
  • Entry: 40163 (Stryfe)
  • Entry: 40164 (Stryfe)
  • Entry: 40165 (Stryfe)
  • Entry: 40166a (Uncontrollable Power)
  • Entry: 40166b (Uncontrollable Power)
  • Entry: 40167a (Left to Your Fate)
  • Entry: 40167b (Left to Your Fate)
  • Entry: 40168a (Stryfe's Grasp)
  • Entry: 40168b (Living Bomb)
  • Entry: 40169 (Mental Transferal)
  • Entry: 40170 (Mind Alteration)
  • Entry: 40171 (Mind Trap)
  • Entry: 40172 (Psionic Amnesia)
  • Entry: 40173 (Psychic Inertia)
  • Entry: 40174 (Zero)
  • Entry: 40175 (Cerebral Erasure)
  • Entry: 40176 (Telepathic Camouflage)
  • Entry: 40177 (Psionic Surge)
  • Entry: 40178 (Psychic Override)
  • Entry: 40179 (Telekinetic Wave)
  • Entry: 40180 (Strobe)
  • Entry: 40181 (Tempo)
  • Entry: 40182 (Thumbelina)
  • Entry: 40183 (Wildside)
  • Entry: 40184 (Extreme Measures)
  • Entry: 40185 (Dragoness)
  • Entry: 40186 (Forearm)
  • Entry: 40187 (Reaper)
  • Entry: 40188 (Samurai)
  • Entry: 40189 (Mutant Insurrection)
  • Entry: 40198 (Lady Mastermind)
  • Entry: 40199 (Malice)
  • Entry: 40200 (Scrambler)
  • Entry: 40201 (Vanisher)
  • Entry: 40202 (Under Pressure)
  • Entry: 40203 (Overburdened)
nova_encounter.json (5)
  • Entry: 28028 (Armored Assault)
  • Entry: 28029 (Armadillo)
  • Entry: 28030 (Rollin', Rollin')
  • Entry: 28031 (Tough and Tumble)
  • Entry: 28032 (Tough It Out)
spdr_encounter.json (8)
  • Entry: 31030 (Grand Larceny)
  • Entry: 31031 (Bombshell)
  • Entry: 31032 (Electro)
  • Entry: 31033 (Hobgoblin)
  • Entry: 31034 (Iron Spider)
  • Entry: 31035 (Sandman)
  • Entry: 31036 (Spot)
  • Entry: 31037 (Surge in Crime)
spiderham_encounter.json (9)
  • Entry: 30030 (Hunting the Spider-Totems)
  • Entry: 30031 (Bora)
  • Entry: 30032 (Brix)
  • Entry: 30033 (Daemos)
  • Entry: 30034 (Jennix)
  • Entry: 30035 (Karn)
  • Entry: 30036 (Morlun)
  • Entry: 30037 (Solus)
  • Entry: 30038 (Verna)
storm_encounter.json (4)
  • Entry: 36036 (The Shadow King)
  • Entry: 36037 (Ruler of the Astral Plane)
  • Entry: 36038 (Possessed)
  • Entry: 36039 (Astral Attack)
packs.json (30)
  • Entry: stld (Star-Lord)
  • Entry: gam (Gamora)
  • Entry: drax (Drax)
  • Entry: nebu (Nebula)
  • Entry: warm (War Machine)
  • Entry: hood (The Hood)
  • Entry: valk (Valkyrie)
  • Entry: sm (Sinister Motives)
  • Entry: nova (Nova)
  • Entry: ironheart (Ironheart)
  • Entry: spiderham (Spider-Ham)
  • Entry: spdr (SP//dr)
  • Entry: mut_gen (Mutant Genesis)
  • Entry: cyclops (Cyclops)
  • Entry: phoenix (Phoenix)
  • Entry: wolv (Wolverine)
  • Entry: storm (Storm)
  • Entry: gambit (Gambit)
  • Entry: rogue (Rogue)
  • Entry: mojo (Mojo Mania)
  • Entry: next_evol (NeXt Evolution)
  • Entry: psylocke (Psylocke)
  • Entry: angel (Angel)
  • Entry: x23 (X-23)
  • Entry: deadpool (Deadpool)
  • Entry: aoa (Age of Apocalypse)
  • Entry: iceman (Iceman)
  • Entry: jubilee (Jubilee)
  • Entry: ncrawler (Nightcrawler)
  • Entry: magneto (Magneto)
sets.json (167)
  • Entry: nebu (Nebula)
  • Entry: nebu_nemesis (Nebula Nemesis)
  • Entry: warm (War Machine)
  • Entry: warm_nemesis (War Machine Nemesis)
  • Entry: the_hood (The Hood)
  • Entry: beasty_boys (Beasty Boys)
  • Entry: brothers_grimm (Brothers Grimm)
  • Entry: crossfire_crew (Crossfire's Crew)
  • Entry: mister_hyde (Mister Hyde)
  • Entry: ransacked_armory (Ransacked Armory)
  • Entry: state_of_emergency (State of Emergency)
  • Entry: streets_of_mayhem (Streets of Mayhem)
  • Entry: sinister_syndicate (Sinister Syndicate)
  • Entry: wrecking_crew_modular (Wrecking Crew)
  • Entry: standard_ii (Standard II)
  • Entry: expert_ii (Expert II)
  • Entry: valk (Valkyrie)
  • Entry: valk_nemesis (Valkyrie Nemesis)
  • Entry: ghost_spider (Ghost-Spider)
  • Entry: ghost_spider_nemesis (Ghost-Spider Nemesis)
  • Entry: spider_man_morales (Spider-Man - Miles Morales)
  • Entry: spider_man_morales_nemesis (Spider-Man - Morales Nemesis)
  • Entry: sandman (Sandman)
  • Entry: venom (Venom)
  • Entry: mysterio (Mysterio)
  • Entry: sinister_six (Sinister Six)
  • Entry: venom_goblin (Venom Goblin)
  • Entry: city_in_chaos (City in Chaos)
  • Entry: down_to_earth (Down to Earth)
  • Entry: goblin_gear (Goblin Gear)
  • Entry: guerrilla_tactics (Guerrilla Tactics)
  • Entry: osborn_tech (Osborn Tech)
  • Entry: personal_nightmare (Personal Nightmare)
  • Entry: sinister_assault (Sinister Assault)
  • Entry: symbiotic_strength (Symbiotic Strength)
  • Entry: whispers_of_paranoia (Whispers of Paranoia)
  • Entry: bad_publicity (Bad Publicity)
  • Entry: community_service (Community Service)
  • Entry: snitches_get_stitches (Snitches get Stitches)
  • Entry: shield_tech (Shield Tech)
  • Entry: nova (Nova)
  • Entry: nova_nemesis (Nova Nemesis)
  • Entry: armadillo (Armadillo)
  • Entry: ironheart (Ironheart)
  • Entry: ironheart_nemesis (Ironheart Nemesis)
  • Entry: zzzax (Zzzax)
  • Entry: spiderham (Spider-Ham)
  • Entry: spiderham_nemesis (Spider-Ham Nemesis)
  • Entry: inheritors (The Inheritors)
  • Entry: spdr (SP//dr)
  • Entry: spdr_nemesis (SP//dr Nemesis)
  • Entry: ironspider_sinister (Iron Spider's Sinister Six)
  • Entry: colossus (Colossus)
  • Entry: colossus_nemesis (Colossus Nemesis)
  • Entry: shadowcat (Shadowcat)
  • Entry: shadowcat_nemesis (Shadowcat Nemesis)
  • Entry: sabretooth (Sabretooth)
  • Entry: project_wideawake (Project Wideawake)
  • Entry: master_mold (Master Mold)
  • Entry: mansion_attack (Mansion Attack)
  • Entry: magneto_villain (Magneto)
  • Entry: brotherhood (Brotherhood)
  • Entry: mystique (Mystique)
  • Entry: zero_tolerance (Zero Tolerance)
  • Entry: sentinels (Sentinels)
  • Entry: acolytes (Acolytes)
  • Entry: future_past (Future Past)
  • Entry: mut_gen_campaign (Mutant Genesis Campaign)
  • Entry: brawler (Brawler)
  • Entry: commander (Commander)
  • Entry: defender (Defender)
  • Entry: peacekeeper (Peacekeeper)
  • Entry: cyclops (Cyclops)
  • Entry: cyclops_nemesis (Cyclops Nemesis)
  • Entry: phoenix (Phoenix)
  • Entry: phoenix_nemesis (Phoenix Nemesis)
  • Entry: wolverine (Wolverine)
  • Entry: wolverine_nemesis (Wolverine Nemesis)
  • Entry: deathstrike (Deathstrike)
  • Entry: storm (Storm)
  • Entry: weather (Weather)
  • Entry: storm_nemesis (Storm Nemesis)
  • Entry: shadow_king (Shadow King)
  • Entry: magog (Magog)
  • Entry: spiral (Spiral)
  • Entry: mojo (Mojo)
  • Entry: crime (Crime)
  • Entry: fantasy (Fantasy)
  • Entry: horror (Horror)
  • Entry: sci-fi (Sci-Fi)
  • Entry: sitcom (Sitcom)
  • Entry: western (Western)
  • Entry: longshot (Longshot)
  • Entry: gambit (Gambit)
  • Entry: gambit_nemesis (Gambit Nemesis)
  • Entry: exodus (Exodus)
  • Entry: rogue (Rogue)
  • Entry: rogue_nemesis (Rogue Nemesis)
  • Entry: reavers (Reavers)
  • Entry: cable (Cable)
  • Entry: cable_nemesis (Cable Nemesis)
  • Entry: domino (Domino)
  • Entry: domino_nemesis (Domino Nemesis)
  • Entry: marauders (Marauders)
  • Entry: morlock_siege (Morlock Siege)
  • Entry: military_grade (Military Grade)
  • Entry: mutant_slayers (Mutant Slayers)
  • Entry: on_the_run (On the Run)
  • Entry: nasty_boys (Nasty Boys)
  • Entry: juggernaut (Juggernaut)
  • Entry: hope_summers (Hope Summers)
  • Entry: black_tom_cassidy (Black Tom Cassidy)
  • Entry: mister_sinister (Mister Sinister)
  • Entry: flight (Flight)
  • Entry: super_strength (Super Strength)
  • Entry: telepathy (Telepathy)
  • Entry: stryfe (Stryfe)
  • Entry: extreme_measures (Extreme Measures)
  • Entry: mutant_insurrection (Mutant Insurrection)
  • Entry: next_evol_campaign (Next Evolution Campaign)
  • Entry: psylocke (Psylocke)
  • Entry: psylocke_nemesis (Psylocke Nemesis)
  • Entry: angel (Angel)
  • Entry: angel_nemesis (Angel Nemesis)
  • Entry: x23 (X-23)
  • Entry: x23_nemesis (X-23 Nemesis)
  • Entry: deadpool (Deadpool)
  • Entry: deadpool_nemesis (Deadpool Nemesis)
  • Entry: dreadpool (Dreadpool)
  • Entry: bishop (Bishop)
  • Entry: bishop_nemesis (Bishop Nemesis)
  • Entry: magik (Magik)
  • Entry: magik_nemesis (Magik Nemesis)
  • Entry: unus (Unus)
  • Entry: infinites (Infinites)
  • Entry: dystopian_nightmare (Dystopian Nightmare)
  • Entry: standard_iii (Standard III)
  • Entry: four_horsemen (Four Horsemen)
  • Entry: hounds (Hounds)
  • Entry: apocalypse (Apocalypse)
  • Entry: dark_riders (Dark Riders)
  • Entry: dark_beast (Dark Beast)
  • Entry: savage_land (Savage Land)
  • Entry: genosha (Genosha)
  • Entry: blue_moon (Blue Moon)
  • Entry: en_sabah_nur (En Sabah Nur)
  • Entry: celestial_tech (Celestial Tech)
  • Entry: clan_akkaba (Clan Akkaba)
  • Entry: age_of_apocalypse (Age of Apocalypse)
  • Entry: aoa_mission (Mission)
  • Entry: aoa_basic_campaign (Campaign)
  • Entry: aoa_campaign (Campaign)
  • Entry: overseer (Overseer)
  • Entry: prelates (Prelates)
  • Entry: iceman (Iceman)
  • Entry: frostbite (Frostbite)
  • Entry: iceman_nemesis (Iceman Nemesis)
  • Entry: sauron (Sauron)
  • Entry: jubilee (Jubilee)
  • Entry: jubilee_nemesis (Jubilee Nemesis)
  • Entry: arcade (Arcade)
  • Entry: nightcrawler (Nightcrawler)
  • Entry: nightcrawler_nemesis (Nightcrawler Nemesis)
  • Entry: crazy_gang (Crazy Gang)
  • Entry: magneto (Magneto)
  • Entry: magneto_nemesis (Magneto Nemesis)
  • Entry: hellfire (Hellfire)
types.json (1)
  • Entry: player_side_scheme (Player Side Scheme)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment