#!/usr/bin/env python3
"""achi_hunter: Valheim achievement progress from a .fch save (profile version 46 and up).

Shows what is still missing for crafted items, weapons, cooked food, built pieces, causes of death (incl. tree deaths), enemy/boss/mini-boss kills (any difficulty, Normal+, Hard), fishing and trophies.

Usage: python3 achi_hunter.py [-f] [-o LIST] [file.fch]   (see -h)

File layout (little-endian). Strings are 7-bit-length-prefixed UTF-8. "dict" = int32 count + (string, float32)*count,
"list" = int32 count + string*count. There are no delimiters or magic markers; you find each section by parsing the
previous one.

    int32 payload_len | payload | int32 64 | SHA-512(payload)
    payload:
        int32 version (46), int32 205 (stat count), int32 10 (stat sets)
        10 STAT SETS back to back, indexed by the game's DifficultyRequirement enum:
            0 RawStats  1 Any  2 Hammer  3 Casual  4 VeryEasy  5 Easy  6 Default (Normal)  7 Hard  8 VeryHard  9 Hardcore
            each set:
                float32[205]          PlayerStatType values (deaths by cause, tree/mine counts, ...)
                dict known worlds     world name -> seconds played
                dict known world keys, dict known commands
                int32 5, then 5 enemy-kill dicts: total, unarmed, magic, ranged, melee ($enemy_* -> kills)
                dict items picked up, dict items CRAFTED, dict pickables, dict foods eaten, dict pieces built
        everything after the stat sets (world/map data and the player data: inventory, known recipes, skills, ...)
        is not read. No output needs it, and modded games store their own data there.

Which set an achievement reads (from the game's Achievement code): its difficulty requirement picks the set. "Any" is
set 1; "Default" (Normal) is set 6; "Hard" is set 7. Kills made on a harder difficulty also count in every easier set from
Casual up, so a set means "this difficulty or harder". Set 0 is raw and is never used by achievements.
"""
import json
import re
import struct
import sys



# ---------------------------------------------------------------------------
# What each achievement requires, rebuilt from the game's own rules (Valheim 1.0.16, Deep North included).
# The game fills these lists at start-up from its item database, so they are derived here the same way
# (Achievements.Initialize / ObjectDB in assembly_valheim.dll). Tokens match the keys in the save's stat tables.
# Regenerate after a game update.
# ---------------------------------------------------------------------------

# AllItemCraft: every recipe that needs a crafting station, minus the items the game excludes.
# Station-less hand recipes (stone axe, club, ...), cooked food and smelting do not count here.
CRAFTABLE = {
    '$item_arrow_bloodgold': 'Bloodgold Arrow',
    '$item_arrow_bronze': 'Bronzehead Arrow',
    '$item_arrow_carapace': 'Carapace Arrow',
    '$item_arrow_charred': 'Charred Arrow',
    '$item_arrow_fire': 'Fire Arrow',
    '$item_arrow_flint': 'Flinthead Arrow',
    '$item_arrow_frost': 'Frost Arrow',
    '$item_arrow_iron': 'Ironhead Arrow',
    '$item_arrow_needle': 'Needle Arrow',
    '$item_arrow_obsidian': 'Obsidian Arrow',
    '$item_arrow_poison': 'Poison Arrow',
    '$item_arrow_silver': 'Silver Arrow',
    '$item_arrow_wood': 'Wood Arrow',
    '$item_atgeir_blackmetal': 'Black Metal Atgeir',
    '$item_atgeir_bronze': 'Bronze Atgeir',
    '$item_atgeir_gold': 'Nord Atgeir',
    '$item_atgeir_gold_bloodlightning': 'Thunderblood Atgeir',
    '$item_atgeir_gold_frostfire': 'Frostfire Atgeir',
    '$item_atgeir_gold_uncooked': 'Cast: Nord Atgeir',
    '$item_atgeir_himminafl': 'Himminafl',
    '$item_atgeir_iron': 'Iron Atgeir',
    '$item_axe2h_gold': 'Nord Greataxe',
    '$item_axe2h_gold_bloodlightning': 'Thunderblood Greataxe',
    '$item_axe2h_gold_frostfire': 'Frostfire Greataxe',
    '$item_axe_berzerkr': 'Berserkir Axes',
    '$item_axe_berzerkr_blood': 'Bleeding Berserkir Axes',
    '$item_axe_berzerkr_lightning': 'Thundering Berserkir Axes',
    '$item_axe_berzerkr_nature': 'Primal Berserkir Axes',
    '$item_axe_blackmetal': 'Black Metal Axe',
    '$item_axe_bronze': 'Bronze Axe',
    '$item_axe_early': 'Early Axes',
    '$item_axe_flint': 'Flint Axe',
    '$item_axe_gold': 'Nord Axe',
    '$item_axe_gold_bloodlightning': 'Thunderblood Axe',
    '$item_axe_gold_frostfire': 'Frostfire Axe',
    '$item_axe_gold_uncooked': 'Cast: Nord Axe',
    '$item_axe_iron': 'Iron Axe',
    '$item_axe_jotunbane': 'Jotun Bane',
    '$item_bakedpoteitr_uncooked': 'Unbaked Poteitr',
    '$item_barleywinebase': 'Barley Wine Base: Fire Resistance',
    '$item_battleaxe': 'Battleaxe',
    '$item_battleaxe_blackmetal': 'Black Metal Battleaxe',
    '$item_battleaxe_crystal': 'Crystal Battleaxe',
    '$item_battleaxe_gold_uncooked': 'Cast: Nord Greataxe',
    '$item_battleaxe_skullsplittur': 'Skull Splittur',
    '$item_bell': 'Bell',
    '$item_bilebomb': 'Bile Bomb',
    '$item_blacksoup': 'Black Soup',
    '$item_bloodpudding': 'Blood Pudding',
    '$item_boarjerky': 'Boar Jerky',
    '$item_bolt_blackmetal': 'Black Metal Bolt',
    '$item_bolt_bloodgold': 'Bloodgold Bolt',
    '$item_bolt_bone': 'Bone Bolt',
    '$item_bolt_carapace': 'Carapace Bolt',
    '$item_bolt_charred': 'Charred Bolt',
    '$item_bolt_iron': 'Iron Bolt',
    '$item_bomb_dynamite': 'Ember Charge',
    '$item_bombblob_frost': 'Blob Bomb: Frost',
    '$item_bombblob_lava': 'Blob Bomb: Lava',
    '$item_bombblob_morkhalla': 'Blob Bomb: Pulp',
    '$item_bombblob_poison': 'Blob Bomb: Poison',
    '$item_bombblob_poisonelite': 'Blob Bomb: Elite Poison',
    '$item_bombblob_tar': 'Blob Bomb: Tar',
    '$item_bow': 'Crude Bow',
    '$item_bow_ashlands': 'Ash Fang',
    '$item_bow_ashlandsblood': 'Blood Fang',
    '$item_bow_ashlandsroot': 'Root Fang',
    '$item_bow_ashlandsstorm': 'Storm Fang',
    '$item_bow_draugrfang': 'Draugr Fang',
    '$item_bow_finewood': 'Finewood Bow',
    '$item_bow_gold': 'Nord Bow',
    '$item_bow_gold_bloodlightning': 'Thunderblood Bow',
    '$item_bow_gold_frostfire': 'Frostfire Bow',
    '$item_bow_gold_uncooked': 'Cast: Nord Bow',
    '$item_bow_huntsman': 'Huntsman Bow',
    '$item_bow_snipesnap': 'Spinesnap',
    '$item_breaddough': 'Bread Dough',
    '$item_bronze': 'Bronze',
    '$item_bronzenails': 'Bronze Nails',
    '$item_cape_ash': 'Ashen Cape',
    '$item_cape_asksvin': 'Asksvin Cloak',
    '$item_cape_deepnorth': 'Moose Hide Cape',
    '$item_cape_deepnorth_mage': 'Cape of the Caller',
    '$item_cape_deerhide': 'Deer Hide Cape',
    '$item_cape_feather': 'Feather Cape',
    '$item_cape_linen': 'Linen Cape',
    '$item_cape_lox': 'Lox Cape',
    '$item_cape_trollhide': 'Troll Hide Cape',
    '$item_cape_wolf': 'Wolf Fur Cape',
    '$item_carrotsoup': 'Carrot Soup',
    '$item_catapult_ammo': 'Explosive Payload',
    '$item_catapult_bloodgold_ammo': 'Bloodgold Payload',
    '$item_catapult_training_ammo': 'Grausten Payload',
    '$item_ceramicplate': 'Ceramic Plate',
    '$item_chest_berserker': 'Patterns of the Bear',
    '$item_chest_berserker_undead': 'Vilebone Cage',
    '$item_chest_bronze': 'Bronze Plate Tunic',
    '$item_chest_carapace': 'Carapace Breastplate',
    '$item_chest_fenris': 'Fenris Coat',
    '$item_chest_flametal': 'Flametal Breastplate',
    '$item_chest_heavy_deepnorth': 'Breastplate of the Protector',
    '$item_chest_heavy_gold_uncooked': 'Cast: Breastplate of the Protector',
    '$item_chest_iron': 'Iron Scale Mail',
    '$item_chest_leather': 'Leather Tunic',
    '$item_chest_lox': 'Lox Fur Jacket',
    '$item_chest_mage': 'Eitr-weave Robe',
    '$item_chest_mage_ashlands': 'Robes of Embla',
    '$item_chest_mage_deepnorth': 'Robes of the Caller',
    '$item_chest_mage_gold_uncooked': 'Cast: Robes of the Caller',
    '$item_chest_medium_ashlands': 'Breastplate of Ask',
    '$item_chest_medium_deepnorth': 'Chestpiece of the Vanguard',
    '$item_chest_medium_gold_uncooked': 'Cast: Chestpiece of the Vanguard',
    '$item_chest_pcuirass': 'Padded Cuirass',
    '$item_chest_rags': 'Rag Tunic',
    '$item_chest_root': 'Root Harnesk',
    '$item_chest_trollleather': 'Troll Leather Tunic',
    '$item_chest_wolf': 'Wolf Hide Chestpiece',
    '$item_crossbow_arbalest': 'Arbalest',
    '$item_crossbow_bloodlightning_gold': 'Thunderblood Crossbow',
    '$item_crossbow_frostfire_gold': 'Frostfire Crossbow',
    '$item_crossbow_gold': 'Nord Crossbow',
    '$item_crossbow_gold_uncooked': 'Cast: Nord Crossbow',
    '$item_crossbow_ripper': 'Ripper',
    '$item_crossbow_ripper_blood': 'Wound Ripper',
    '$item_crossbow_ripper_lightning': 'Storm Ripper',
    '$item_crossbow_ripper_nature': 'Root Ripper',
    '$item_cultivator': 'Cultivator',
    '$item_deerstew': 'Deer Stew',
    '$item_demister': 'Wisplight',
    '$item_dvergrkey': 'Sealbreaker',
    '$item_egg_cooked': 'Cooked Egg',
    '$item_eyescream': 'Eyescream',
    '$item_feastashlands': 'Ashlands Gourmet Bowl',
    '$item_feastblackforest': 'Black Forest Buffet Platter',
    '$item_feastdeepnorth': 'Northern Morning Fare',
    '$item_feastmeadows': 'Whole Roasted Meadow Boar',
    '$item_feastmistlands': 'Mushrooms Galore á la Mistlands',
    '$item_feastmountains': "Hearty Mountain Logger's Stew",
    '$item_feastoceans': "Sailor's Bounty",
    '$item_feastplains': 'Plains Pie Picnic',
    '$item_feastswamps': "Swamp Dweller's Delight",
    '$item_fierysvinstew': 'Fiery Svinstew',
    '$item_fireworkrocket_blue': 'Blue Fireworks',
    '$item_fireworkrocket_cyan': 'Cyan Fireworks',
    '$item_fireworkrocket_green': 'Green Fireworks',
    '$item_fireworkrocket_purple': 'Purple Fireworks',
    '$item_fireworkrocket_red': 'Red Fireworks',
    '$item_fireworkrocket_yellow': 'Yellow Fireworks',
    '$item_fish_raw': 'Raw Fish',
    '$item_fishandbreaduncooked': "Uncooked Fish 'n' Bread",
    '$item_fishingbait_ashlands': 'Hot Fishing Bait',
    '$item_fishingbait_cave': 'Cold Fishing Bait',
    '$item_fishingbait_deepnorth': 'Frosty Fishing Bait',
    '$item_fishingbait_forest': 'Mossy Fishing Bait',
    '$item_fishingbait_mistlands': 'Misty Fishing Bait',
    '$item_fishingbait_ocean': 'Heavy Fishing Bait',
    '$item_fishingbait_plains': 'Stingy Fishing Bait',
    '$item_fishingbait_swamp': 'Sticky Fishing Bait',
    '$item_fishsoup': 'Fish Soup',
    '$item_fishwraps': 'Fish Wraps',
    '$item_fistweapon_bjorn': 'Paws of the Bear',
    '$item_fistweapon_bjorn_undead': 'Vilebone Maulclaws',
    '$item_fistweapon_fenris': 'Flesh Rippers',
    '$item_fistweapon_frostfire_gold': 'Frostfire Knucklechains',
    '$item_fistweapon_gold': 'Nord Knucklechains',
    '$item_fistweapon_gold_bloodlightning': 'Thunderblood Knucklechains',
    '$item_fistweapon_gold_uncooked': 'Cast: Nord Knucklechains',
    '$item_frostorbs_uncooked': 'Cast: Northern Vengeance',
    '$item_graplinghook': 'Grappling Hook',
    '$item_helmet_berserker': 'Headdress of the Bear',
    '$item_helmet_berserker_undead': 'Vilebone Visage',
    '$item_helmet_bronze': 'Bronze Helmet',
    '$item_helmet_carapace': 'Carapace Helmet',
    '$item_helmet_celebration': 'Celebratory Cap',
    '$item_helmet_crown_of_valheim': 'Crown of Valheim',
    '$item_helmet_drake': 'Drake Helmet',
    '$item_helmet_fenris': 'Fenris Hood',
    '$item_helmet_fishinghat': 'Fishing Hat',
    '$item_helmet_flametal': 'Flametal Helmet',
    '$item_helmet_heavy_deepnorth': 'Helmet of the Protector',
    '$item_helmet_heavy_gold_uncooked': 'Cast: Helmet of the Protector',
    '$item_helmet_iron': 'Iron Helmet',
    '$item_helmet_leather': 'Leather Helmet',
    '$item_helmet_lox': 'Lox Fur Hood',
    '$item_helmet_mage': 'Eitr-weave Hood',
    '$item_helmet_mage_ashlands': 'Hood of Embla',
    '$item_helmet_mage_deepnorth': 'Headdress of the Caller',
    '$item_helmet_mage_gold_uncooked': 'Cast: Headdress of the Caller',
    '$item_helmet_medium_ashlands': 'Hood of Ask',
    '$item_helmet_medium_deepnorth': 'Hood of the Vanguard',
    '$item_helmet_medium_gold_uncooked': 'Cast: Hood of the Vanguard',
    '$item_helmet_padded': 'Padded Helmet',
    '$item_helmet_root': 'Root Mask',
    '$item_helmet_trollleather': 'Troll Leather Hood',
    '$item_hoe': 'Hoe',
    '$item_honeyglazedchickenuncooked': 'Uncooked Honey Glazed Chicken',
    '$item_ironnails': 'Iron Nails',
    '$item_kalechips_uncooked': 'Raw Kale Chips',
    '$item_keys_gold_uncooked': 'Cast: Intricate Key',
    '$item_knife_blackmetal': 'Black Metal Knife',
    '$item_knife_butcher': 'Butcher Knife',
    '$item_knife_chitin': 'Abyssal Razor',
    '$item_knife_copper': 'Copper Knife',
    '$item_knife_flint': 'Flint Knife',
    '$item_knife_gold': 'Nord Dagger',
    '$item_knife_gold_bloodlightning': 'Thunderblood Dagger',
    '$item_knife_gold_frostfire': 'Frostfire Dagger',
    '$item_knife_gold_uncooked': 'Cast: Nord Dagger',
    '$item_knife_silver': 'Silver Knife',
    '$item_knife_skollandhati': 'Skoll and Hati',
    '$item_legs_berserker': 'Loincloth of the Bear',
    '$item_legs_berserker_undead': 'Vilebone Drapes',
    '$item_legs_bronze': 'Bronze Plate Leggings',
    '$item_legs_carapace': 'Carapace Greaves',
    '$item_legs_fenris': 'Fenris Leggings',
    '$item_legs_flametal': 'Flametal Greaves',
    '$item_legs_heavy_deepnorth': 'Trousers of the Protector',
    '$item_legs_heavy_gold_uncooked': 'Cast: Trousers of the Protector',
    '$item_legs_iron': 'Iron Greaves',
    '$item_legs_leather': 'Leather Trousers',
    '$item_legs_lox': 'Lox Fur Trousers',
    '$item_legs_mage': 'Eitr-weave Trousers',
    '$item_legs_mage_ashlands': 'Trousers of Embla',
    '$item_legs_mage_deepnorth': 'Trousers of the Caller',
    '$item_legs_mage_gold_uncooked': 'Cast: Trousers of the Caller',
    '$item_legs_medium_ashlands': 'Trousers of Ask',
    '$item_legs_medium_deepnorth': 'Trousers of the Vanguard',
    '$item_legs_medium_gold_uncooked': 'Cast: Trousers of the Vanguard',
    '$item_legs_pgreaves': 'Padded Greaves',
    '$item_legs_rags': 'Rag Trousers',
    '$item_legs_root': 'Root Leggings',
    '$item_legs_trollleather': 'Troll Leather Trousers',
    '$item_legs_wolf': 'Wolf Hide Trousers',
    '$item_lingondricka': 'Lingonberry Juice',
    '$item_loxpie_uncooked': 'Unbaked Lox Pie',
    '$item_mace2h_gold_bloodlightning': 'Thunderblood Sledge',
    '$item_mace2h_gold_frostfire': 'Frostfire Sledge',
    '$item_mace_bronze': 'Bronze Mace',
    '$item_mace_eldner': 'Flametal Mace',
    '$item_mace_eldner_blood': 'Bloodgeon',
    '$item_mace_eldner_lightning': 'Storm Star',
    '$item_mace_eldner_nature': 'Klossen',
    '$item_mace_gold': 'Nord Mace',
    '$item_mace_gold_bloodlightning': 'Thunderblood Mace',
    '$item_mace_gold_frostfire': 'Frostfire Mace',
    '$item_mace_gold_uncooked': 'Cast: Nord Mace',
    '$item_mace_iron': 'Iron Mace',
    '$item_mace_needle': 'Porcupine',
    '$item_mace_silver': 'Frostner',
    '$item_magicallystuffedmushroomuncooked': 'Uncooked Stuffed Mushroom',
    '$item_marinatedgreens': 'Marinated Greens',
    '$item_mashedmeat': 'Mashed Meat',
    '$item_meadbasebugrepellent': 'Mead Base: Anti-Sting',
    '$item_meadbasebzerker': 'Mead base: Berserkir',
    '$item_meadbaseeitr': 'Mead Base: Minor Eitr',
    '$item_meadbaseeitr_lingering': 'Mead Base: Lingering Eitr',
    '$item_meadbasefrostresist': 'Mead Base: Frost Resistance',
    '$item_meadbasehasty': 'Mead base: Ratatosk',
    '$item_meadbasehealth': 'Mead Base: Minor Healing',
    '$item_meadbasehealth_lingering': 'Mead Base: Lingering Health',
    '$item_meadbasehealth_major': 'Mead Base: Major Healing',
    '$item_meadbasehealth_medium': 'Mead Base: Medium Healing',
    '$item_meadbaselightfoot': 'Mead Base: Lightfoot',
    '$item_meadbasepoisonresist': 'Mead Base: Poison Resistance',
    '$item_meadbasestamina': 'Mead Base: Minor Stamina',
    '$item_meadbasestamina_lingering': 'Mead Base: Lingering Stamina',
    '$item_meadbasestamina_medium': 'Mead Base: Medium Stamina',
    '$item_meadbasestrength': 'Mead Base: Troll Endurance',
    '$item_meadbaseswimmer': 'Mead Base: Vananidir',
    '$item_meadbasetamer': 'Mead Base: Animal Whispers',
    '$item_meadbasetasty': 'Mead Base: Tasty',
    '$item_meatballsmashedpoteitr': 'Meatballs and Poteitr',
    '$item_meatplatteruncooked': 'Uncooked Meat Platter',
    '$item_mechanicalspring': 'Mechanical Spring',
    '$item_mincemeatsauce': 'Minced Meat Sauce',
    '$item_mistharesupremeuncooked': 'Uncooked Misthare Supreme',
    '$item_moosekebab': 'Meat In Bread',
    '$item_mushroomomelette': 'Mushroom Omelette',
    '$item_oatmeallingonberryjam': 'Oatmeal',
    '$item_oatmilk': 'Oat Milk',
    '$item_onionsoup': 'Onion Soup',
    '$item_oozebomb': 'Ooze Bomb',
    '$item_ovenpancake_uncooked': 'Oven Pancake Batter',
    '$item_pancakes': 'Pancakes',
    '$item_pickaxe_antler': 'Antler Pickaxe',
    '$item_pickaxe_blackmetal': 'Black Metal Pickaxe',
    '$item_pickaxe_bronze': 'Bronze Pickaxe',
    '$item_pickaxe_iron': 'Iron Pickaxe',
    '$item_piquantpie_uncooked': 'Uncooked Piquant Pie',
    '$item_pulledbear': 'Pulled Bear',
    '$item_queensjam': "Queen's Jam",
    '$item_roastedcrustpie_uncooked': 'Uncooked Roasted Crust Pie',
    '$item_saddleasksvin': 'Asksvin Saddle',
    '$item_saddlelox': 'Lox Saddle',
    '$item_saddlemoose': 'Moose Saddle',
    '$item_salad': 'Salad',
    '$item_sausages': 'Sausages',
    '$item_scorchingmedley': 'Scorching Medley',
    '$item_scythe': 'Scythe',
    '$item_sealsoup': 'Seal Meat Soup',
    '$item_seekeraspic': 'Seeker Aspic',
    '$item_serpentstew': 'Serpent Stew',
    '$item_sharpeningstone': 'Sharpening Stone',
    '$item_shield_banded': 'Banded Shield',
    '$item_shield_blackmetal': 'Black Metal Shield',
    '$item_shield_blackmetal_tower': 'Black Metal Tower Shield',
    '$item_shield_bonetower': 'Bone Tower Shield',
    '$item_shield_bronzebuckler': 'Bronze Buckler',
    '$item_shield_buckler_gold_uncooked': 'Cast: Nord Buckler',
    '$item_shield_carapace': 'Carapace Shield',
    '$item_shield_carapacebuckler': 'Carapace Buckler',
    '$item_shield_flametal': 'Flametal Shield',
    '$item_shield_flametal_tower': 'Flametal Tower Shield',
    '$item_shield_gold': 'Nord Shield',
    '$item_shield_gold_tower': 'Nord Greatshield',
    '$item_shield_goldbuckler': 'Nord Buckler',
    '$item_shield_iron_tower': 'Iron Tower Shield',
    '$item_shield_ironbuckler': 'Iron Buckler',
    '$item_shield_roots': 'Shield of Roots',
    '$item_shield_round_gold_uncooked': 'Cast: Nord Shield',
    '$item_shield_serpentscale': 'Serpent Scale Shield',
    '$item_shield_silver': 'Silver Shield',
    '$item_shield_tower_gold_uncooked': 'Cast: Nord Greatshield',
    '$item_shield_wood': 'Wood Shield',
    '$item_shield_woodtower': 'Wood Tower Shield',
    '$item_shieldcore': 'Shield Core',
    '$item_shocklatesmoothie': 'Muckshake',
    '$item_sizzlingberrybroth': 'Sizzling Berry Broth',
    '$item_sledge_demolisher': 'Demolisher',
    '$item_sledge_gold': 'Nord Sledge',
    '$item_sledge_gold_uncooked': 'Cast: Nord Sledge',
    '$item_sledge_iron': 'Iron Sledge',
    '$item_smokedfish': 'Smoked Fish',
    '$item_smokedmoosemeat': 'Smoked Moose Meat',
    '$item_sparklingshroomshake': 'Sparkling Shroomshake',
    '$item_spear_ancientbark': 'Ancient Bark Spear',
    '$item_spear_bronze': 'Bronze Spear',
    '$item_spear_carapace': 'Carapace Spear',
    '$item_spear_chitin': 'Abyssal Harpoon',
    '$item_spear_flint': 'Flint Spear',
    '$item_spear_gold': 'Nord Spear',
    '$item_spear_gold_bloodlightning': 'Thunderblood Spear',
    '$item_spear_gold_frostfire': 'Frostfire Spear',
    '$item_spear_gold_uncooked': 'Cast: Nord Spear',
    '$item_spear_splitner': 'Splitnir',
    '$item_spear_splitner_blood': 'Splitnir the Bleeding',
    '$item_spear_splitner_lightning': 'Splitnir the Storming',
    '$item_spear_splitner_nature': 'Splitnir the Primal',
    '$item_spear_wolffang': 'Fang Spear',
    '$item_spicymarmalade': 'Spicy Marmalade',
    '$item_staff_frostorbs': 'Northern Vengeance',
    '$item_staff_lightning': 'Dundr',
    '$item_staff_orbofahri': 'Echo Spike',
    '$item_staff_orbofahri_uncooked': 'Cast: Echo Spike',
    '$item_staff_spiritcaller': 'Spirit Caller',
    '$item_staff_spiritcaller_uncooked': 'Cast: Spirit Caller',
    '$item_staff_thunderblood': 'Lightning Strike',
    '$item_staff_thunderblood_uncooked': 'Cast: Lightning Strike',
    '$item_staffclusterbomb': 'Staff of Fracturing',
    '$item_stafffireball': 'Staff of Embers',
    '$item_staffgreenroots': 'Staff of the Wild',
    '$item_stafficeshards': 'Staff of Frost',
    '$item_staffredtroll': 'Trollstav',
    '$item_staffshield': 'Staff of Protection',
    '$item_staffskeleton': 'Dead Raiser',
    '$item_stagbreaker': 'Stagbreaker',
    '$item_sword2h_gold': 'Nord Greatsword',
    '$item_sword2h_gold_bloodlightning': 'Thunderblood Greatsword',
    '$item_sword2h_gold_frostfire': 'Frostfire Greatsword',
    '$item_sword2h_gold_uncooked': 'Cast: Nord Greatsword',
    '$item_sword_blackmetal': 'Black Metal Sword',
    '$item_sword_bronze': 'Bronze Sword',
    '$item_sword_dyrnwyn': 'Dyrnwyn',
    '$item_sword_gold': 'Nord Sword',
    '$item_sword_gold_bloodlightning': 'Thunderblood Sword',
    '$item_sword_gold_frostfire': 'Frostfire Sword',
    '$item_sword_gold_uncooked': 'Cast: Nord Sword',
    '$item_sword_iron': 'Iron Sword',
    '$item_sword_krom': 'Krom',
    '$item_sword_mistwalker': 'Mistwalker',
    '$item_sword_niedhogg': 'Nidhögg',
    '$item_sword_niedhogg_blood': 'Nidhögg the Bleeding',
    '$item_sword_niedhogg_lightning': 'Nidhögg the Thundering',
    '$item_sword_niedhogg_nature': 'Nidhögg the Primal',
    '$item_sword_silver': 'Silver Sword',
    '$item_sword_slayer': 'Slayer',
    '$item_sword_slayer_blood': 'Brutal Slayer',
    '$item_sword_slayer_lightning': 'Scourging Slayer',
    '$item_sword_slayer_nature': 'Primal Slayer',
    '$item_sword_wood': 'Wooden Sword',
    '$item_trinketblackdamagedealth': 'Bracelets of the Brave',
    '$item_trinketblackdtamina': 'Evasion Mantle',
    '$item_trinketbloodgoldhealth': 'Neckstabber',
    '$item_trinketbloodgoldstamina': 'Witch Crown',
    '$item_trinketbronzehealth': 'Heart of the Forest',
    '$item_trinketbronzestamina': 'Bronze Pendant',
    '$item_trinketcarapaceeitr': 'Pulsating Earrings',
    '$item_trinketchitinswim': 'Fins of Destiny',
    '$item_trinketflametaleitr': 'Jörmundling',
    '$item_trinketflametalstaminahealth': 'Brimstone',
    '$item_trinketironhealth': 'Iron Brooch',
    '$item_trinketironstamina': 'Nimble Anklet',
    '$item_trinketscalestaminadamage': 'Resounding Shackle',
    '$item_trinketsilverdamage': 'Wolf Sight',
    '$item_trinketsilverresist': 'Crystal Heart',
    '$item_turnipstew': 'Turnip Stew',
    '$item_turretbolt': 'Black Metal Missile',
    '$item_turretbolt_bloodgold': 'Bloodgold Missile',
    '$item_turretbolt_flametal': 'Flametal Missile',
    '$item_turretboltwood': 'Wooden Missile',
    '$item_vikingcupcake_uncooked': 'Unbaked Sweetbread',
    '$item_wolf_skewer': 'Wolf Skewer',
    '$item_wolfjerky': 'Wolf Jerky',
    '$item_yggdrasilporridge': 'Yggdrasil Porridge',
}

# AllBuildPieces: every piece in a build table that allows removing pieces (Hammer), except the repair tool.
# Cultivator and Hoe pieces do not count. Hidden/seasonal pieces do.
BUILDABLE = {
    '$item_hardrock': 'Mysterious Rock',
    '$piece_BlackwoodStakewall': 'Ashwood Stakewall',
    '$piece_archerytarget': 'Archery Target',
    '$piece_armorstand': 'Armour Stand',
    '$piece_artisan_ext1': 'Artisan Press',
    '$piece_artisanstation': 'Artisan Table',
    '$piece_ashwood_archedwall': 'Ashwood Arched Wall',
    '$piece_ashwood_beam_1m': 'Ashwood Beam 1 m',
    '$piece_ashwood_beam_2m': 'Ashwood Beam 2 m',
    '$piece_ashwood_bed': 'Ashwood Bed',
    '$piece_ashwood_decowall': 'Ashwood Decorative Wall',
    '$piece_ashwood_decowall_divider': 'Ashwood Divider',
    '$piece_ashwood_decowall_tree': 'Ashwood Decorative Window',
    '$piece_ashwood_door': 'Ashwood Door',
    '$piece_ashwood_floor_1x1': 'Ashwood Floor 1x1',
    '$piece_ashwood_floor_2x2': 'Ashwood Floor 2x2',
    '$piece_ashwood_floor_deco': 'Ashwood Decorative Floor',
    '$piece_ashwood_halfwall': 'Ashwood Half Wall',
    '$piece_ashwood_pole_1m': 'Ashwood Pole 1 m',
    '$piece_ashwood_pole_2m': 'Ashwood Pole 2 m',
    '$piece_ashwood_quarterwall': 'Ashwood Quarter Wall',
    '$piece_ashwood_wall': 'Ashwood Wall',
    '$piece_ashwoodarch_big': 'Ashwood Arch',
    '$piece_ashwoodbeam26': 'Ashwood Beam 26°',
    '$piece_ashwoodbeam45': 'Ashwood Beam 45°',
    '$piece_ashwoodbeam67': 'Ashwood Beam 67°',
    '$piece_ashwoodcross26': 'Ashwood Roof Cross 26°',
    '$piece_ashwoodcross45': 'Ashwood Roof Cross 45°',
    '$piece_ashwoodstair': 'Ashwood Stair',
    '$piece_ashwoodwallroof67': 'Ashwood Wall 67°',
    '$piece_ashwoodwallroof67upsidedown': 'Ashwood Wall 67° (Inverted)',
    '$piece_ashwoodwallroof_26': 'Ashwood Wall 26°',
    '$piece_ashwoodwallroof_26_upsidedown': 'Ashwood Wall 26° (Inverted)',
    '$piece_ashwoodwallroof_45': 'Ashwood Wall 45°',
    '$piece_ashwoodwallroof_45_upsidedown': 'Ashwood Wall 45° (Inverted)',
    '$piece_ashwoodwallrooftop67': 'Ashwood Roof Cross 67°',
    '$piece_asksvinskeleton': 'Asksvin Skeleton',
    '$piece_banner01': 'Black Banner',
    '$piece_banner02': 'Blue Banner',
    '$piece_banner03': 'White and Red Striped Banner',
    '$piece_banner04': 'Red Banner',
    '$piece_banner05': 'Green Banner',
    '$piece_banner06': 'Blue, Red and White Banner',
    '$piece_banner07': 'White and Blue Striped Banner',
    '$piece_banner08': 'Yellow Banner',
    '$piece_banner09': 'Purple Banner',
    '$piece_banner10': 'Orange Banner',
    '$piece_banner11': 'White Banner',
    '$piece_barber': 'Barber Station',
    '$piece_bathtub': 'Hot Tub',
    '$piece_bed': 'Bed',
    '$piece_bed02': 'Dragon Bed',
    '$piece_beehive': 'Beehive',
    '$piece_bench01': 'Wood Bench',
    '$piece_bench_runed': 'Carved Bench',
    '$piece_benchlog': 'Sitting Log',
    '$piece_birdnest': "Birds' Nest",
    '$piece_blackforge': 'Black Forge',
    '$piece_blackforge_ext1': 'Black Forge Cooler',
    '$piece_blackforge_ext2': 'Vice',
    '$piece_blackforge_ext3': 'Metal Cutter',
    '$piece_blackforge_ext4': 'Gem Cutter',
    '$piece_blackforge_ext5': "Smith's Aprons",
    '$piece_blackmarble1x1': 'Black Marble 1x1x1',
    '$piece_blackmarble2x1x1': 'Black Marble 2x1x1',
    '$piece_blackmarble2x2x2': 'Black Marble 2x2x2',
    '$piece_blackmarble_arch': 'Black Marble Arch',
    '$piece_blackmarble_base1': 'Black Marble Plinth',
    '$piece_blackmarble_basecorner': 'Black Marble Plinth Corner',
    '$piece_blackmarble_bench': 'Black Marble Bench',
    '$piece_blackmarble_column_1': 'Black Marble Column Small',
    '$piece_blackmarble_column_2': 'Black Marble Column Wide',
    '$piece_blackmarble_floor': 'Black Marble Floor',
    '$piece_blackmarble_floor_triangle': 'Black Marble Floor Triangle',
    '$piece_blackmarble_out1': 'Black Marble Cornice',
    '$piece_blackmarble_outcorner': 'Black Marble Cornice Corner',
    '$piece_blackmarble_stair': 'Black Marble Stair',
    '$piece_blackmarble_table': 'Black Marble Table',
    '$piece_blackmarble_throne': 'Black Marble Throne',
    '$piece_blackmarble_tip': 'Black Marble Quarter Spire',
    '$piece_blackmetalbarstack': 'Black Metal Stack',
    '$piece_blackwoodbench01': 'Ashwood Bench',
    '$piece_blackwoodstack': 'Ashwood Stack',
    '$piece_blastfurnace': 'Blast Furnace',
    '$piece_bloodgoldbarstack': 'Bloodgold Stack',
    '$piece_bone_throne': 'Bone Throne',
    '$piece_bonestack': 'Bone Stack',
    '$piece_bonfire': 'Bonfire',
    '$piece_brazierceiling01': 'Hanging Brazier',
    '$piece_brazierfloor01': 'Standing Brazier',
    '$piece_brazierfloor02': 'Blue Standing Brazier',
    '$piece_bronzebarstack': 'Bronze Stack',
    '$piece_candle': 'Resin Candle',
    '$piece_cartographytable': 'Cartography Table',
    '$piece_cauldron': 'Cauldron',
    '$piece_cauldron_ext1_spice': 'Spice Rack',
    '$piece_cauldron_ext3_butchertable': "Butcher's Table",
    '$piece_cauldron_ext4_pans': 'Pots and Pans',
    '$piece_cauldron_ext5_mortarandpestle': 'Mortar and Pestle',
    '$piece_cauldron_ext6_rollingpins': 'Rolling Pins and Cutting Boards',
    '$piece_cauldron_ext7_smoker': 'Smoker',
    '$piece_celebrationgarland': 'Flower Garland',
    '$piece_chair': 'Wood Chair',
    '$piece_chair_runed': 'Carved Chair',
    '$piece_charcoalkiln': 'Charcoal Kiln',
    '$piece_chest': 'Reinforced Chest',
    '$piece_chestbarrel': 'Barrel',
    '$piece_chestblackmetal': 'Black Metal Chest',
    '$piece_chestgrausten': 'Grausten Chest',
    '$piece_chestprivate': 'Personal Chest',
    '$piece_chesttreasure': 'Treasure Chest',
    '$piece_chestwarderobe': 'Wardrobe',
    '$piece_chestwood': 'Chest',
    '$piece_clothdoor': 'Red Jute Curtain',
    '$piece_coalpile': 'Coal Pile',
    '$piece_cookingstation': 'Cooking Station',
    '$piece_cookingstation_iron': 'Iron Cooking Station',
    '$piece_copperbarstack': 'Copper Stack',
    '$piece_crystalwall1x1': 'Crystal Wall 1x1',
    '$piece_darkwoodarch': 'Darkwood Arch',
    '$piece_darkwoodbeam': 'Darkwood Beam 2 m',
    '$piece_darkwoodbeam4': 'Darkwood Beam 4 m',
    '$piece_darkwoodbeam67': 'Darkwood Beam 67°',
    '$piece_darkwoodbeam_26': 'Darkwood Beam 26°',
    '$piece_darkwoodbeam_45': 'Darkwood Beam 45°',
    '$piece_darkwoodchair': 'Darkwood Chair',
    '$piece_darkwooddecowall': 'Carved Darkwood Divider',
    '$piece_darkwoodgate': 'Darkwood Gate',
    '$piece_darkwoodpole': 'Darkwood Pole 2m',
    '$piece_darkwoodpole4': 'Darkwood Pole 4m',
    '$piece_darkwoodraven': 'Raven Adornment',
    '$piece_darkwoodroof26': 'Shingle Roof 26°',
    '$piece_darkwoodroof45': 'Shingle Roof 45°',
    '$piece_darkwoodroof67': 'Shingle Roof 67°',
    '$piece_darkwoodrooficorner': 'Shingle Roof Inner Corner 26°',
    '$piece_darkwoodrooficorner45': 'Shingle Roof Inner Corner 45°',
    '$piece_darkwoodrooficorner67': 'Shingle Roof Inner Corner 67°',
    '$piece_darkwoodroofocorner': 'Shingle Roof Outer Corner 26°',
    '$piece_darkwoodroofocorner45': 'Shingle Roof Outer Corner 45°',
    '$piece_darkwoodroofocorner67': 'Shingle Roof Outer Corner 67°',
    '$piece_darkwoodrooftop': 'Shingle Roof Ridge 26°',
    '$piece_darkwoodrooftop45': 'Shingle Roof Ridge 45°',
    '$piece_darkwoodrooftop67': 'Shingle Roof Ridge 67°',
    '$piece_darkwoodwolf': 'Wolf Adornment',
    '$piece_deco_stave_wall': 'Lathed Timber Wall',
    '$piece_drawbridge_dn': 'Timberwood Drawbridge',
    '$piece_drawbridge_log': 'Rustic Drawbridge',
    '$piece_dvergr_lantern': 'Dvergr Wall Lantern',
    '$piece_dvergr_lantern_pole': 'Dvergr Pole Lantern',
    '$piece_dvergr_metal_wall': 'Dvergr Metal Wall',
    '$piece_dvergr_sharpstakes': 'Dvergr Sharp Stakes',
    '$piece_dvergr_spiralstair': 'Dvergr Spiral Staircase Left',
    '$piece_dvergr_spiralstair_right': 'Dvergr Spiral Staircase Right',
    '$piece_dvergr_stake_wall': 'Dvergr Stakewall',
    '$piece_eitrrefinery': 'Eitr Refinery',
    '$piece_faderember': 'Eternal Pyre',
    '$piece_fairylightgarland': 'Fey Lights',
    '$piece_fermenter': 'Fermenter',
    '$piece_firepit': 'Campfire',
    '$piece_firepit_iron': 'Iron Fire Pit',
    '$piece_flametal_beam': 'Flametal Beam',
    '$piece_flametal_pillar': 'Flametal Pillar',
    '$piece_flametalbarstack': 'Flametal Stack',
    '$piece_flametalgate': 'Flametal Gate',
    '$piece_flintpile': 'Flint Pile',
    '$piece_forge': 'Forge',
    '$piece_forge_ext1': 'Forge Bellows',
    '$piece_forge_ext2': 'Anvils',
    '$piece_forge_ext3': 'Grinding Wheel',
    '$piece_forge_ext4': "Smith's Anvil",
    '$piece_forge_ext5': 'Forge Cooler',
    '$piece_forge_ext6': 'Forge Tool Rack',
    '$piece_frostfoundry': 'Frost Foundry',
    '$piece_frostkiln': 'Frigid Kiln',
    '$piece_grausten_archmedium': 'Grausten Medium Arch',
    '$piece_grausten_archsmall': 'Grausten Small Arch',
    '$piece_grausten_beammedium': 'Grausten Medium Beam',
    '$piece_grausten_beamsmall': 'Grausten Small Beam',
    '$piece_grausten_floor1x1': 'Grausten Floor 1x1',
    '$piece_grausten_floor2x2': 'Grausten Floor 2x2',
    '$piece_grausten_floor4x4': 'Grausten Floor 4x4',
    '$piece_grausten_pillarmedium': 'Grausten Medium Pillar',
    '$piece_grausten_pillarsmall': 'Grausten Small Pillar',
    '$piece_grausten_pillartapered': 'Grausten Tapered Pillar',
    '$piece_grausten_pillartaperedinverted': 'Grausten Tapered Pillar (Inverted)',
    '$piece_grausten_roof45': 'Grausten Roof',
    '$piece_grausten_roof45_arch': 'Grausten Arched Roof',
    '$piece_grausten_roof45_archcorner': 'Grausten Arched Roof Corner',
    '$piece_grausten_roof45_archcorner2': 'Grausten Arched Roof Corner',
    '$piece_grausten_roof45_corner': 'Grausten Roof Corner',
    '$piece_grausten_roof45_corner2': 'Grausten Roof Corner',
    '$piece_grausten_stair': 'Grausten Stairs',
    '$piece_grausten_stoneladder': 'Grausten Steep Stairs',
    '$piece_grausten_wall1x2': 'Grausten Wall 1x2',
    '$piece_grausten_wall2x2': 'Grausten Wall 2x2',
    '$piece_grausten_wall4x2': 'Grausten Wall 4x2',
    '$piece_grausten_wallarch': 'Grausten Wall Arch',
    '$piece_grausten_wallarchinv': 'Grausten Wall Arch (Inverted)',
    '$piece_grausten_window2x2': 'Grausten Window 2x2',
    '$piece_grausten_window4x2': 'Grausten Window 4x2',
    '$piece_graustenpile': 'Grausten Pile',
    '$piece_groundtorch': 'Standing Iron Torch',
    '$piece_groundtorchblue': 'Standing Blue-burning Iron Torch',
    '$piece_groundtorchdemister': 'Wisp Torch',
    '$piece_groundtorchgreen': 'Standing Green-burning Iron Torch',
    '$piece_groundtorchwood': 'Standing Wood Torch',
    '$piece_guardstone': 'Ward',
    '$piece_hanging_cloth_blue1': 'Blue Jute Drapes',
    '$piece_hanging_cloth_blue2': 'Blue Jute Curtain',
    '$piece_hearth': 'Hearth',
    '$piece_hexagonalgate': 'Hexagonal Gate',
    '$piece_hoodedlantern': 'Hooded Lantern',
    '$piece_icecube': 'Ice Block',
    '$piece_incinerator': 'Obliterator',
    '$piece_ironbarstack': 'Iron Stack',
    '$piece_ironfloor': 'Cage Floor 2x2',
    '$piece_ironfloorSmall': 'Cage Floor 1x1',
    '$piece_irongate': 'Iron Gate',
    '$piece_ironwall': 'Cage Wall 2x2',
    '$piece_ironwallSmall': 'Cage Wall 1x1',
    '$piece_ironwoodbeam67': 'Wood Iron Beam 67°',
    '$piece_itemstand': 'Item Stand',
    '$piece_jackoturnip': 'Jack-o-turnip',
    '$piece_jute_carpet': 'Red Jute Carpet',
    '$piece_juteblue_carpet': 'Blue Jute Carpet',
    '$piece_lavalantern': 'Lava Lantern',
    '$piece_logbeam2': 'Log Beam 2 m',
    '$piece_logbeam4': 'Log Beam 4 m',
    '$piece_logpole2': 'Log Pole 2 m',
    '$piece_logpole4': 'Log Pole 4 m',
    '$piece_magetable': 'Galdr Table',
    '$piece_magetable_ext': 'Rune Table',
    '$piece_magetable_ext2': 'Unfading Candles',
    '$piece_magetable_ext3': 'Feathery Wreath',
    '$piece_magetable_ext4': 'Standing Loom',
    '$piece_marblepile': 'Black Marble Pile',
    '$piece_maypole': 'Maypole',
    '$piece_meadcauldron': 'Mead Ketill',
    '$piece_mistletoe': 'Mistletoe',
    '$piece_moose_throne': 'Antler Throne',
    '$piece_oven': 'Stone Oven',
    '$piece_portal': 'Portal',
    '$piece_portal_stone': 'Portal – Stone',
    '$piece_pot_large_green': 'Large Green Pot',
    '$piece_pot_medium_green': 'Medium Green Pot',
    '$piece_pot_small_green': 'Small Green Pot',
    '$piece_preptable': 'Food Preparation Table',
    '$piece_rug_asksvin': 'Asksvin Rug',
    '$piece_rug_bjorn': 'Bearskin Rug',
    '$piece_rug_deer': 'Deer Rug',
    '$piece_rug_hare': 'Hare Rug',
    '$piece_rug_lox': 'Lox Rug',
    '$piece_rug_moose': 'Moose Hide Carpet',
    '$piece_rug_seal': 'Sealskin Rug',
    '$piece_rug_straw': 'Straw',
    '$piece_rug_wolf': 'Wolf Rug',
    '$piece_sapcollector': 'Sap Extractor',
    '$piece_scale_26': 'Scalewood Wall 26° Left',
    '$piece_scale_26_flipped': 'Scalewood Wall 26° Right',
    '$piece_scale_26_upsidedown': 'Scalewood Wall 26° Right (Inverted)',
    '$piece_scale_26_upsidedown_flipped': 'Scalewood Wall 26° Left (Inverted)',
    '$piece_scale_45': 'Scalewood Wall 45° Left',
    '$piece_scale_45_flipped': 'Scalewood Wall 45° Right',
    '$piece_scale_45_upsidedown': 'Scalewood Wall 45° Right (Inverted)',
    '$piece_scale_45_upsidedown_flipped': 'Scalewood Wall 45° Left (Inverted)',
    '$piece_scale_67': 'Scalewood Wall 67° Left',
    '$piece_scale_67_flipped': 'Scalewood Wall 67° Right',
    '$piece_scale_67_upsidedown': 'Scalewood Wall 67° Right (Inverted)',
    '$piece_scale_67_upsidedown_flipped': 'Scalewood Wall 67° Left (Inverted)',
    '$piece_scale_halfwall': 'Scalewood Half Wall',
    '$piece_scale_quarterwall': 'Scalewood Quarter Wall',
    '$piece_scale_wall': 'Scalewood Wall',
    '$piece_sconce': 'Sconce',
    '$piece_sharpstakes': 'Sharp Stakes',
    '$piece_shieldgenerator': 'Shield Generator',
    '$piece_sign': 'Sign',
    '$piece_silverbarstack': 'Silver Stack',
    '$piece_skullpile': 'Pile of Skulls',
    '$piece_smelter': 'Smelter',
    '$piece_snowlantern': 'Snow Lantern',
    '$piece_spinningwheel': 'Spinning Wheel',
    '$piece_stakewall': 'Stakewall',
    '$piece_stave_deco_beam_2m': 'Decorated Timber Beam 2m',
    '$piece_stave_deco_pole_2m': 'Decorated Timber Pole 2m',
    '$piece_stave_pole_2m': 'Timber Pole 2m',
    '$piece_stave_pole_4m': 'Timber Pole 4m',
    '$piece_stave_wall': 'Timber Wall',
    '$piece_stavebeam2': 'Timber Beam 2m',
    '$piece_stavebeam26': 'Timber Beam 26°',
    '$piece_stavebeam4': 'Timber Beam 4m',
    '$piece_stavebeam45': 'Timber Beam 45°',
    '$piece_stavebeam67': 'Timber Beam 67°',
    '$piece_stavecross26': 'Timber Roof Cross 26°',
    '$piece_stavecross45': 'Timber Roof Cross 45°',
    '$piece_stavedecobeam26': 'Decorated Timber Beam 26°',
    '$piece_stavedecobeam45': 'Decorated Timber Beam 45°',
    '$piece_stavedecobeam67': 'Decorated Timber Beam 67°',
    '$piece_stavegate': 'Timberwood Gate',
    '$piece_stavewallrooftop67': 'Timber Roof Cross 67°',
    '$piece_stonearch': 'Stone Arch',
    '$piece_stonecutter': 'Stonecutter',
    '$piece_stonefence': 'Stone Fence',
    '$piece_stonefloor2x2': 'Stone Floor 2x2',
    '$piece_stonepile': 'Stone Pile',
    '$piece_stonepillar': 'Stone Pillar',
    '$piece_stonestair': 'Stone Stair',
    '$piece_stonethrone': 'Stone Throne',
    '$piece_stonewall1x1': 'Stone Wall 1x1',
    '$piece_stonewall2x1': 'Stone Wall 2x1',
    '$piece_stonewall4x2': 'Stone Wall 4x2',
    '$piece_stool': 'Stool',
    '$piece_table': 'Table',
    '$piece_table_oak': 'Long Heavy Table',
    '$piece_table_round': 'Round Table',
    '$piece_table_runed': 'Long Carved Table',
    '$piece_table_runed_small': 'Square Carved Table',
    '$piece_throne01': 'Raven Throne',
    '$piece_tinbarstack': 'Tin Stack',
    '$piece_trainingdummy': 'T.W.I.G.',
    '$piece_trap': 'Trap',
    '$piece_treasure_pile': 'Coin Pile',
    '$piece_treasure_stack': 'Coin Stack',
    '$piece_turret': 'Ballista',
    '$piece_windmill': 'Windmill',
    '$piece_wisplure': 'Wisp Fountain',
    '$piece_woodbeam1': 'Wood Beam 1 m',
    '$piece_woodbeam2': 'Wood Beam 2 m',
    '$piece_woodbeam26': 'Wood Beam 26°',
    '$piece_woodbeam45': 'Wood Beam 45°',
    '$piece_woodbeam67': 'Wood Beam 67°',
    '$piece_woodcorestack': 'Corewood Stack',
    '$piece_wooddoor': 'Wood Door',
    '$piece_wooddragon': 'Wood Dragon Adornment',
    '$piece_woodfence': 'Roundpole Fence',
    '$piece_woodfencegate': 'Roundpole Gate',
    '$piece_woodfinestack': 'Finewood Stack',
    '$piece_woodfloor1x1': 'Wood Floor 1x1',
    '$piece_woodfloor2x2': 'Wood Floor 2x2',
    '$piece_woodfroststack': 'Timberwood Stack',
    '$piece_woodgate': 'Wood Gate',
    '$piece_woodironbeam': 'Wood Iron Beam',
    '$piece_woodironbeam_26': 'Wood Iron Beam 26°',
    '$piece_woodironbeam_45': 'Wood Iron Beam 45°',
    '$piece_woodironpole': 'Wood Iron Pole',
    '$piece_woodlog26': 'Log Beam 26°',
    '$piece_woodlog45': 'Log Beam 45°',
    '$piece_woodlog67': 'Log Beam 67°',
    '$piece_woodpole': 'Wood Pole 1 m',
    '$piece_woodpole2': 'Wood Pole 2 m',
    '$piece_woodroof26': 'Thatch Roof 26°',
    '$piece_woodroof45': 'Thatch Roof 45°',
    '$piece_woodroof67': 'Thatch Roof 67°',
    '$piece_woodrooficorner': 'Thatch Roof Inner Corner 26°',
    '$piece_woodrooficorner45': 'Thatch Roof Inner Corner 45°',
    '$piece_woodrooficorner67': 'Thatch Roof Inner Corner 67°',
    '$piece_woodroofocorner': 'Thatch Roof Outer Corner 26°',
    '$piece_woodroofocorner45': 'Thatch Roof Outer Corner 45°',
    '$piece_woodroofocorner67': 'Thatch Roof Outer Corner 67°',
    '$piece_woodrooftop': 'Thatch Roof Ridge 26°',
    '$piece_woodrooftop45': 'Thatch Roof Ridge 45°',
    '$piece_woodrooftop67': 'Thatch Roof Ridge 67°',
    '$piece_woodstack': 'Wood Stack',
    '$piece_woodstair': 'Wood Stairs',
    '$piece_woodstepladder': 'Wood Ladder',
    '$piece_woodwall': 'Wood Wall',
    '$piece_woodwallhalf': 'Wood Wall Half',
    '$piece_woodwallquarter': 'Wood Wall 1x1',
    '$piece_woodwallroof': 'Wood Wall 26°',
    '$piece_woodwallroof45': 'Wood Wall 45°',
    '$piece_woodwallroof45_upsidedown': 'Wood Wall 45° (Inverted)',
    '$piece_woodwallroof67': 'Wood Wall 67°',
    '$piece_woodwallroof67upsidedown': 'Wood Wall 67° (Inverted)',
    '$piece_woodwallroof_upsidedown': 'Wood Wall 26° (Inverted)',
    '$piece_woodwallrooftop': 'Wood Roof Cross 26°',
    '$piece_woodwallrooftop45': 'Wood Roof Cross 45°',
    '$piece_woodwallrooftop67': 'Wood Roof Cross 67°',
    '$piece_woodwindowshutter': 'Wood Shutter',
    '$piece_workbench': 'Workbench',
    '$piece_workbench_ext1': 'Chopping Block',
    '$piece_workbench_ext2': 'Tanning Rack',
    '$piece_workbench_ext3': 'Adze',
    '$piece_workbench_ext4': 'Tool Shelf',
    '$piece_yggdrasilstack': 'Yggdrasil Wood Stack',
    '$piece_yulecrown': 'Yule Wreath',
    '$piece_yulegarland': 'Yule Garland',
    '$piece_yuleklapp': 'Yuleklapp',
    '$piece_yuletree': 'Yule Tree',
    '$ship_karve': 'Karve',
    '$ship_longship': 'Longship',
    '$ship_longship_ashlands': 'Drakkar',
    '$ship_raft': 'Raft',
    '$tool_batteringram': 'Battering Ram',
    '$tool_cart': 'Cart',
    '$tool_catapult': 'Catapult',
}

# KillAllCreatures / KillAllCreaturesHard: every character the game flags as "killed for achievements",
# bosses split out into BOSSES below (the game lists them together, 108 in total).
ENEMIES = {
    '$enemy_abomination': 'Abomination',
    '$enemy_asksvin': 'Asksvin',
    '$enemy_asksvin_hatchling': 'Asksvin Hatchling',
    '$enemy_aspect_bonemass': 'Aspect of the Writhing Dead',
    '$enemy_aspect_dragon': 'Aspect of the Dragon Mother',
    '$enemy_aspect_eikthyr': 'Aspect of the Lightning Stag',
    '$enemy_aspect_fader': 'Aspect of the Emerald Flame',
    '$enemy_aspect_gdking': 'Aspect of the Living Forest',
    '$enemy_aspect_goblinking': 'Aspect of the Twisted Soul',
    '$enemy_aspect_seekerqueen': 'Aspect of the Crawling Matriarch',
    '$enemy_babyseeker': 'Seeker Brood',
    '$enemy_barka': 'Barka',
    '$enemy_bat': 'Bat',
    '$enemy_bjorn': 'Bear',
    '$enemy_blob': 'Blob',
    '$enemy_blobelite': 'Oozer',
    '$enemy_blobfrost': 'Frost Blob',
    '$enemy_bloblava': 'Lava Blob',
    '$enemy_blobmork': 'Shapeless Pulp',
    '$enemy_blobmorkmini': 'Tiny Pulp',
    '$enemy_blobtar': 'Growth',
    '$enemy_boar': 'Boar',
    '$enemy_boarpiggy': 'Piggy',
    '$enemy_bonemawserpent': 'Bonemaw',
    '$enemy_charred_archer': 'Charred Marksman',
    '$enemy_charred_mage': 'Charred Warlock',
    '$enemy_charred_melee': 'Charred Warrior',
    '$enemy_charred_melee_Dyrnwyn': 'Lord Reto',
    '$enemy_charred_melee_Fader': 'Summoned Charred Warrior',
    '$enemy_charred_twitcher': 'Charred Twitcher',
    '$enemy_charred_twitcher_summoned': 'Summoned Twitcher',
    '$enemy_chicken': 'Chicken',
    '$enemy_deathsquito': 'Deathsquito',
    '$enemy_deer': 'Deer',
    '$enemy_drake': 'Drake',
    '$enemy_draugr': 'Draugr',
    '$enemy_draugrelite': 'Draugr Elite',
    '$enemy_dvergr': 'Dvergr Rogue',
    '$enemy_dvergr_deepnorth': 'Imprisoned Dvergr',
    '$enemy_dvergr_mage': 'Dvergr Mage',
    '$enemy_elaking': 'Elaking',
    '$enemy_elakingmole': 'Eyeless One',
    '$enemy_fallenvalkyrie': 'Fallen Valkyrie',
    '$enemy_fallenwarrior': 'Fallen Warrior',
    '$enemy_fenring': 'Fenring',
    '$enemy_fenringcultist': 'Cultist',
    '$enemy_fenringcultist_hildir': 'Geirrhafa',
    '$enemy_frozenking': 'Kall Fimbulbringer',
    '$enemy_ghost': 'Ghost',
    '$enemy_gjall': 'Gjall',
    '$enemy_goblin': 'Fuling',
    '$enemy_goblin_deepnorth': 'Captive Fuling',
    '$enemy_goblin_hildir': 'Zil',
    '$enemy_goblinbrute': 'Fuling Berserker',
    '$enemy_goblinbrute_hildircombined': 'Zil & Thungr',
    '$enemy_goblinshaman': 'Fuling Shaman',
    '$enemy_greydwarf': 'Greydwarf',
    '$enemy_greydwarfbrute': 'Greydwarf Brute',
    '$enemy_greydwarfshaman': 'Greydwarf Shaman',
    '$enemy_greyling': 'Greyling',
    '$enemy_hare': 'Hare',
    '$enemy_hen': 'Hen',
    '$enemy_jotun_warrior': 'Krigen',
    '$enemy_jotun_witch': 'Hexen',
    '$enemy_kvastur': 'Kvastur',
    '$enemy_leech': 'Leech',
    '$enemy_lox': 'Lox',
    '$enemy_loxcalf': 'Lox Calf',
    '$enemy_moose': 'Moose',
    '$enemy_moosecalf': 'Moose Calf',
    '$enemy_morgen': 'Morgen',
    '$enemy_neck': 'Neck',
    '$enemy_root': 'Root',
    '$enemy_seal': 'Seal',
    '$enemy_seal_baby': 'Baby Seal',
    '$enemy_seeker': 'Seeker',
    '$enemy_seekerbrute': 'Seeker Soldier',
    '$enemy_serpent': 'Serpent',
    '$enemy_skeleton': 'Skeleton',
    '$enemy_skeleton_summoned': 'Skelett',
    '$enemy_skeletonfire': 'Brenna',
    '$enemy_skeletonpoison': 'Rancid Remains',
    '$enemy_stonegolem': 'Stone Golem',
    '$enemy_summonedtroll': 'Summoned Troll',
    '$enemy_surtling': 'Surtling',
    '$enemy_tick': 'Tick',
    '$enemy_troll': 'Troll',
    '$enemy_trollfrost': 'Gammeltroll',
    '$enemy_ulv': 'Ulv',
    '$enemy_unbjorn': 'Vile',
    '$enemy_volture': 'Volture',
    '$enemy_wolf': 'Wolf',
    '$enemy_wolfcub': 'Wolf Cub',
    '$enemy_wraith': 'Wraith',
    '$enemy_writhan': 'Writhan',
    '$piece_trainingdummy': 'T.W.I.G.',
    '$spiritcaller_bjorn': 'Spirit Bear',
    '$spiritcaller_boar': 'Spirit Boar',
    '$spiritcaller_moose': 'Spirit Moose',
    '$spiritcaller_wolf': 'Spirit Wolf',
}

# AllBosses / AllBossesNormal / AllBossesHard (identical list; Frozen King counts via its phase 3 form)
BOSSES = {
    '$enemy_eikthyr': 'Eikthyr',
    '$enemy_gdking': 'The Elder',
    '$enemy_bonemass': 'Bonemass',
    '$enemy_dragon': 'Moder',
    '$enemy_goblinking': 'Yagluth',
    '$enemy_seekerqueen': 'The Queen',
    '$enemy_fader': 'Fader',
    '$enemy_frozenking_p3': 'Kall Fimbulbringer',
}

# FindAllTrophies: every trophy item (one per name) minus excluded ones. Counted from the item pick-up stats.
TROPHIES = {
    '$enemy_kvastur': 'Kvastur',
    '$item_trophy_abomination': 'Abomination Trophy',
    '$item_trophy_asksvin': 'Asksvin Trophy',
    '$item_trophy_barka': 'Barka Trophy',
    '$item_trophy_bjorn': 'Bear Trophy',
    '$item_trophy_bjorn_undead': 'Vile Trophy',
    '$item_trophy_blob': 'Blob Trophy',
    '$item_trophy_blob_frost': 'Frost Blob Trophy',
    '$item_trophy_blob_lava': 'Lava Blob Trophy',
    '$item_trophy_blob_morkhalla': 'Pulp Trophy',
    '$item_trophy_boar': 'Boar Trophy',
    '$item_trophy_bonemass': 'Bonemass Trophy',
    '$item_trophy_bonemaw': 'Bonemaw Trophy',
    '$item_trophy_brutebro': 'Thungr Trophy',
    '$item_trophy_charredarcher': 'Marksman Trophy',
    '$item_trophy_charredmage': 'Warlock Trophy',
    '$item_trophy_charredmelee': 'Warrior Trophy',
    '$item_trophy_cultist': 'Cultist Trophy',
    '$item_trophy_cultist_hildir': 'Geirrhafa Trophy',
    '$item_trophy_deathsquito': 'Deathsquito Trophy',
    '$item_trophy_deer': 'Deer Trophy',
    '$item_trophy_dragonqueen': 'Moder Trophy',
    '$item_trophy_draugr': 'Draugr Trophy',
    '$item_trophy_draugrelite': 'Draugr Elite Trophy',
    '$item_trophy_dvergr': 'Dvergr Trophy',
    '$item_trophy_eikthyr': 'Eikthyr Trophy',
    '$item_trophy_elaking': 'Elaking Trophy',
    '$item_trophy_elder': 'The Elder Trophy',
    '$item_trophy_fader': 'Fader Trophy',
    '$item_trophy_fallenvalkyrie': 'Fallen Valkyrie Trophy',
    '$item_trophy_fenring': 'Fenring Trophy',
    '$item_trophy_ghost': 'Ghost Trophy',
    '$item_trophy_gjall': 'Gjall Trophy',
    '$item_trophy_goblin': 'Fuling Trophy',
    '$item_trophy_goblinbrute': 'Fuling Berserker Trophy',
    '$item_trophy_goblinking': 'Yagluth Trophy',
    '$item_trophy_goblinshaman': 'Fuling Shaman Trophy',
    '$item_trophy_greydwarf': 'Greydwarf Trophy',
    '$item_trophy_greydwarfbrute': 'Greydwarf Brute Trophy',
    '$item_trophy_greydwarfshaman': 'Greydwarf Shaman Trophy',
    '$item_trophy_growth': 'Growth Trophy',
    '$item_trophy_hare': 'Hare Trophy',
    '$item_trophy_hatchling': 'Drake Trophy',
    '$item_trophy_jotunwarrior': 'Krigen Trophy',
    '$item_trophy_jotunwitch': 'Hexen Trophy',
    '$item_trophy_leech': 'Leech Trophy',
    '$item_trophy_lox': 'Lox Trophy',
    '$item_trophy_mole': 'Eyeless One Trophy',
    '$item_trophy_moose': 'Moose Trophy',
    '$item_trophy_morgen': 'Morgen Trophy',
    '$item_trophy_neck': 'Neck Trophy',
    '$item_trophy_seal': 'Seal Trophy',
    '$item_trophy_seeker': 'Seeker Trophy',
    '$item_trophy_seeker_brute': 'Seeker Soldier Trophy',
    '$item_trophy_seekerqueen': 'The Queen Trophy',
    '$item_trophy_serpent': 'Serpent Trophy',
    '$item_trophy_sgolem': 'Stone Golem Trophy',
    '$item_trophy_shamanbro': 'Zil Trophy',
    '$item_trophy_skeleton': 'Skeleton Trophy',
    '$item_trophy_skeleton_hildir': 'Brenna Trophy',
    '$item_trophy_skeletonpoison': 'Rancid Remains Trophy',
    '$item_trophy_surtling': 'Surtling Trophy',
    '$item_trophy_tick': 'Tick Trophy',
    '$item_trophy_ulv': 'Ulv Trophy',
    '$item_trophy_volture': 'Volture Trophy',
    '$item_trophy_wolf': 'Wolf Trophy',
    '$item_trophy_wraith': 'Wraith Trophy',
    '$item_trophy_writhan': 'Writhan Trophy',
}

# AllWeaponCraft: every weapon (1h, 2h, bows, torches) with a recipe, minus excluded items. Hand recipes with no station count here.
CRAFTABLE_WEAPONS = {
    '$item_atgeir_blackmetal': 'Black Metal Atgeir',
    '$item_atgeir_bronze': 'Bronze Atgeir',
    '$item_atgeir_gold': 'Nord Atgeir',
    '$item_atgeir_gold_bloodlightning': 'Thunderblood Atgeir',
    '$item_atgeir_gold_frostfire': 'Frostfire Atgeir',
    '$item_atgeir_himminafl': 'Himminafl',
    '$item_atgeir_iron': 'Iron Atgeir',
    '$item_axe2h_gold': 'Nord Greataxe',
    '$item_axe2h_gold_bloodlightning': 'Thunderblood Greataxe',
    '$item_axe2h_gold_frostfire': 'Frostfire Greataxe',
    '$item_axe_berzerkr': 'Berserkir Axes',
    '$item_axe_berzerkr_blood': 'Bleeding Berserkir Axes',
    '$item_axe_berzerkr_lightning': 'Thundering Berserkir Axes',
    '$item_axe_berzerkr_nature': 'Primal Berserkir Axes',
    '$item_axe_blackmetal': 'Black Metal Axe',
    '$item_axe_bronze': 'Bronze Axe',
    '$item_axe_early': 'Early Axes',
    '$item_axe_flint': 'Flint Axe',
    '$item_axe_gold': 'Nord Axe',
    '$item_axe_gold_bloodlightning': 'Thunderblood Axe',
    '$item_axe_gold_frostfire': 'Frostfire Axe',
    '$item_axe_iron': 'Iron Axe',
    '$item_axe_jotunbane': 'Jotun Bane',
    '$item_axe_stone': 'Stone Axe',
    '$item_battleaxe': 'Battleaxe',
    '$item_battleaxe_blackmetal': 'Black Metal Battleaxe',
    '$item_battleaxe_crystal': 'Crystal Battleaxe',
    '$item_battleaxe_skullsplittur': 'Skull Splittur',
    '$item_bilebomb': 'Bile Bomb',
    '$item_bomb_dynamite': 'Ember Charge',
    '$item_bombblob_frost': 'Blob Bomb: Frost',
    '$item_bombblob_lava': 'Blob Bomb: Lava',
    '$item_bombblob_morkhalla': 'Blob Bomb: Pulp',
    '$item_bombblob_poison': 'Blob Bomb: Poison',
    '$item_bombblob_poisonelite': 'Blob Bomb: Elite Poison',
    '$item_bombblob_tar': 'Blob Bomb: Tar',
    '$item_bow': 'Crude Bow',
    '$item_bow_ashlands': 'Ash Fang',
    '$item_bow_ashlandsblood': 'Blood Fang',
    '$item_bow_ashlandsroot': 'Root Fang',
    '$item_bow_ashlandsstorm': 'Storm Fang',
    '$item_bow_draugrfang': 'Draugr Fang',
    '$item_bow_finewood': 'Finewood Bow',
    '$item_bow_gold': 'Nord Bow',
    '$item_bow_gold_bloodlightning': 'Thunderblood Bow',
    '$item_bow_gold_frostfire': 'Frostfire Bow',
    '$item_bow_huntsman': 'Huntsman Bow',
    '$item_bow_snipesnap': 'Spinesnap',
    '$item_club': 'Club',
    '$item_crossbow_arbalest': 'Arbalest',
    '$item_crossbow_bloodlightning_gold': 'Thunderblood Crossbow',
    '$item_crossbow_frostfire_gold': 'Frostfire Crossbow',
    '$item_crossbow_gold': 'Nord Crossbow',
    '$item_crossbow_ripper': 'Ripper',
    '$item_crossbow_ripper_blood': 'Wound Ripper',
    '$item_crossbow_ripper_lightning': 'Storm Ripper',
    '$item_crossbow_ripper_nature': 'Root Ripper',
    '$item_fistweapon_bjorn': 'Paws of the Bear',
    '$item_fistweapon_bjorn_undead': 'Vilebone Maulclaws',
    '$item_fistweapon_fenris': 'Flesh Rippers',
    '$item_fistweapon_frostfire_gold': 'Frostfire Knucklechains',
    '$item_fistweapon_gold': 'Nord Knucklechains',
    '$item_fistweapon_gold_bloodlightning': 'Thunderblood Knucklechains',
    '$item_graplinghook': 'Grappling Hook',
    '$item_knife_blackmetal': 'Black Metal Knife',
    '$item_knife_butcher': 'Butcher Knife',
    '$item_knife_chitin': 'Abyssal Razor',
    '$item_knife_copper': 'Copper Knife',
    '$item_knife_flint': 'Flint Knife',
    '$item_knife_gold': 'Nord Dagger',
    '$item_knife_gold_bloodlightning': 'Thunderblood Dagger',
    '$item_knife_gold_frostfire': 'Frostfire Dagger',
    '$item_knife_silver': 'Silver Knife',
    '$item_knife_skollandhati': 'Skoll and Hati',
    '$item_mace2h_gold_bloodlightning': 'Thunderblood Sledge',
    '$item_mace2h_gold_frostfire': 'Frostfire Sledge',
    '$item_mace_bronze': 'Bronze Mace',
    '$item_mace_eldner': 'Flametal Mace',
    '$item_mace_eldner_blood': 'Bloodgeon',
    '$item_mace_eldner_lightning': 'Storm Star',
    '$item_mace_eldner_nature': 'Klossen',
    '$item_mace_gold': 'Nord Mace',
    '$item_mace_gold_bloodlightning': 'Thunderblood Mace',
    '$item_mace_gold_frostfire': 'Frostfire Mace',
    '$item_mace_iron': 'Iron Mace',
    '$item_mace_needle': 'Porcupine',
    '$item_mace_silver': 'Frostner',
    '$item_oozebomb': 'Ooze Bomb',
    '$item_pickaxe_antler': 'Antler Pickaxe',
    '$item_pickaxe_blackmetal': 'Black Metal Pickaxe',
    '$item_pickaxe_bronze': 'Bronze Pickaxe',
    '$item_pickaxe_iron': 'Iron Pickaxe',
    '$item_scythe': 'Scythe',
    '$item_sledge_demolisher': 'Demolisher',
    '$item_sledge_gold': 'Nord Sledge',
    '$item_sledge_iron': 'Iron Sledge',
    '$item_spear_ancientbark': 'Ancient Bark Spear',
    '$item_spear_bronze': 'Bronze Spear',
    '$item_spear_carapace': 'Carapace Spear',
    '$item_spear_chitin': 'Abyssal Harpoon',
    '$item_spear_flint': 'Flint Spear',
    '$item_spear_gold': 'Nord Spear',
    '$item_spear_gold_bloodlightning': 'Thunderblood Spear',
    '$item_spear_gold_frostfire': 'Frostfire Spear',
    '$item_spear_splitner': 'Splitnir',
    '$item_spear_splitner_blood': 'Splitnir the Bleeding',
    '$item_spear_splitner_lightning': 'Splitnir the Storming',
    '$item_spear_splitner_nature': 'Splitnir the Primal',
    '$item_spear_wolffang': 'Fang Spear',
    '$item_staff_frostorbs': 'Northern Vengeance',
    '$item_staff_lightning': 'Dundr',
    '$item_staff_orbofahri': 'Echo Spike',
    '$item_staff_spiritcaller': 'Spirit Caller',
    '$item_staff_thunderblood': 'Lightning Strike',
    '$item_staffclusterbomb': 'Staff of Fracturing',
    '$item_stafffireball': 'Staff of Embers',
    '$item_staffgreenroots': 'Staff of the Wild',
    '$item_stafficeshards': 'Staff of Frost',
    '$item_staffredtroll': 'Trollstav',
    '$item_staffshield': 'Staff of Protection',
    '$item_staffskeleton': 'Dead Raiser',
    '$item_stagbreaker': 'Stagbreaker',
    '$item_sword2h_gold': 'Nord Greatsword',
    '$item_sword2h_gold_bloodlightning': 'Thunderblood Greatsword',
    '$item_sword2h_gold_frostfire': 'Frostfire Greatsword',
    '$item_sword_blackmetal': 'Black Metal Sword',
    '$item_sword_bronze': 'Bronze Sword',
    '$item_sword_dyrnwyn': 'Dyrnwyn',
    '$item_sword_gold': 'Nord Sword',
    '$item_sword_gold_bloodlightning': 'Thunderblood Sword',
    '$item_sword_gold_frostfire': 'Frostfire Sword',
    '$item_sword_iron': 'Iron Sword',
    '$item_sword_krom': 'Krom',
    '$item_sword_mistwalker': 'Mistwalker',
    '$item_sword_niedhogg': 'Nidhögg',
    '$item_sword_niedhogg_blood': 'Nidhögg the Bleeding',
    '$item_sword_niedhogg_lightning': 'Nidhögg the Thundering',
    '$item_sword_niedhogg_nature': 'Nidhögg the Primal',
    '$item_sword_silver': 'Silver Sword',
    '$item_sword_slayer': 'Slayer',
    '$item_sword_slayer_blood': 'Brutal Slayer',
    '$item_sword_slayer_lightning': 'Scourging Slayer',
    '$item_sword_slayer_nature': 'Primal Slayer',
    '$item_sword_wood': 'Wooden Sword',
    '$item_torch': 'Torch',
}

# AllFoodCooked: every food with a recipe, plus every food a cooking station/oven can produce.
COOKED_FOOD = {
    '$item_asksvin_meat_cooked': 'Cooked Asksvin Tail',
    '$item_bakedpoteitr': 'Baked Poteitr',
    '$item_bakedpoteitr_uncooked': 'Unbaked Poteitr',
    '$item_bjorn_meat_cooked': 'Cooked Bear Meat',
    '$item_blacksoup': 'Black Soup',
    '$item_bloodpudding': 'Blood Pudding',
    '$item_blubber_cooked': 'Cooked Seal Blubber',
    '$item_boar_meat_cooked': 'Cooked Boar Meat',
    '$item_boarjerky': 'Boar Jerky',
    '$item_bonemawmeat_cooked': 'Cooked Bonemaw Meat',
    '$item_bread': 'Bread',
    '$item_breaddough': 'Bread Dough',
    '$item_bug_meat_cooked': 'Cooked Seeker Meat',
    '$item_carrotsoup': 'Carrot Soup',
    '$item_chicken_meat_cooked': 'Cooked Chicken Meat',
    '$item_deer_meat_cooked': 'Cooked Deer Meat',
    '$item_deerstew': 'Deer Stew',
    '$item_egg_cooked': 'Cooked Egg',
    '$item_eyescream': 'Eyescream',
    '$item_fierysvinstew': 'Fiery Svinstew',
    '$item_fish_cooked': 'Cooked Fish',
    '$item_fish_raw': 'Raw Fish',
    '$item_fishandbread': "Fish 'n' Bread",
    '$item_fishandbreaduncooked': "Uncooked Fish 'n' Bread",
    '$item_fishsoup': 'Fish Soup',
    '$item_fishwraps': 'Fish Wraps',
    '$item_hare_meat_cooked': 'Cooked Hare Meat',
    '$item_honeyglazedchicken': 'Honey Glazed Chicken',
    '$item_honeyglazedchickenuncooked': 'Uncooked Honey Glazed Chicken',
    '$item_kalechips': 'Kale Chips',
    '$item_kalechips_uncooked': 'Raw Kale Chips',
    '$item_lingondricka': 'Lingonberry Juice',
    '$item_loxmeat_cooked': 'Cooked Lox Meat',
    '$item_loxpie': 'Lox Meat Pie',
    '$item_loxpie_uncooked': 'Unbaked Lox Pie',
    '$item_magicallystuffedmushroom': 'Stuffed Mushroom',
    '$item_magicallystuffedmushroomuncooked': 'Uncooked Stuffed Mushroom',
    '$item_marinatedgreens': 'Marinated Greens',
    '$item_mashedmeat': 'Mashed Meat',
    '$item_meatballsmashedpoteitr': 'Meatballs and Poteitr',
    '$item_meatplatter': 'Meat Platter',
    '$item_meatplatteruncooked': 'Uncooked Meat Platter',
    '$item_mincemeatsauce': 'Minced Meat Sauce',
    '$item_mistharesupreme': 'Misthare Supreme',
    '$item_mistharesupremeuncooked': 'Uncooked Misthare Supreme',
    '$item_moose_meat_cooked': 'Cooked Moose Meat',
    '$item_moosekebab': 'Meat In Bread',
    '$item_mushroomomelette': 'Mushroom Omelette',
    '$item_necktailgrilled': 'Grilled Neck Tail',
    '$item_oatmeallingonberryjam': 'Oatmeal',
    '$item_oatmilk': 'Oat Milk',
    '$item_onionsoup': 'Onion Soup',
    '$item_ovenpancake': 'Oven Pancake',
    '$item_ovenpancake_uncooked': 'Oven Pancake Batter',
    '$item_pancakes': 'Pancakes',
    '$item_piquantpie': 'Piquant Pie',
    '$item_piquantpie_uncooked': 'Uncooked Piquant Pie',
    '$item_pulledbear': 'Pulled Bear',
    '$item_queensjam': "Queen's Jam",
    '$item_roastedcrustpie': 'Roasted Crust Pie',
    '$item_roastedcrustpie_uncooked': 'Uncooked Roasted Crust Pie',
    '$item_salad': 'Salad',
    '$item_sausages': 'Sausages',
    '$item_scorchingmedley': 'Scorching Medley',
    '$item_sealsoup': 'Seal Meat Soup',
    '$item_seekeraspic': 'Seeker Aspic',
    '$item_serpentmeatcooked': 'Cooked Serpent Meat',
    '$item_serpentstew': 'Serpent Stew',
    '$item_shocklatesmoothie': 'Muckshake',
    '$item_sizzlingberrybroth': 'Sizzling Berry Broth',
    '$item_smokedfish': 'Smoked Fish',
    '$item_smokedmoosemeat': 'Smoked Moose Meat',
    '$item_sparklingshroomshake': 'Sparkling Shroomshake',
    '$item_spicymarmalade': 'Spicy Marmalade',
    '$item_turnipstew': 'Turnip Stew',
    '$item_vikingcupcake': 'Frosted Sweetbread',
    '$item_vikingcupcake_uncooked': 'Unbaked Sweetbread',
    '$item_volture_meat_cooked': 'Cooked Volture Meat',
    '$item_wolf_meat_cooked': 'Cooked Wolf Meat',
    '$item_wolf_skewer': 'Wolf Skewer',
    '$item_wolfjerky': 'Wolf Jerky',
    '$item_yggdrasilporridge': 'Yggdrasil Porridge',
}

# AllMiniBosses (any difficulty): the five Hildir mini-bosses and Dyrnwyn-related fights
MINIBOSSES = {
    '$enemy_fenringcultist_hildir': 'Geirrhafa',
    '$enemy_skeletonfire': 'Brenna',
    '$enemy_charred_melee_Dyrnwyn': 'Lord Reto',
    '$enemy_goblinbrute_hildircombined': 'Zil & Thungr',
    '$enemy_goblin_hildir': 'Zil',
}

# GrindFish: every fish species must be caught (reeled in) once. Counted in the pickables table, not by picking the fish up.
FISH = {
    '$animal_fish1': 'Perch',
    '$animal_fish2': 'Pike',
    '$animal_fish3': 'Tuna',
    '$animal_fish4': 'Tetra',
    '$animal_fish5': 'Trollfish',
    '$animal_fish6': 'Giant Herring',
    '$animal_fish7': 'Grouper',
    '$animal_fish8': 'Coral Cod',
    '$animal_fish9': 'Anglerfish',
    '$animal_fish10': 'Northern Salmon',
    '$animal_fish11': 'Magmafish',
    '$animal_fish12': 'Pufferfish',
}

# Death achievements, from the game's Achievement assets (stat -> index into the 205 PlayerStatType values).
# "DeathByAllTypes" needs all 16 of these kinds at least once.
DEATH_KINDS = {"EnemyHit": 56, "Fall": 58, "Drowning": 59, "Burning": 60, "Freezing": 61, "Poisoned": 62,
               "Smoke": 63, "EdgeOfWorld": 65, "Tree": 68, "Turret": 71, "Stalagtite": 73, "Catapult": 105,
               "AshlandsOcean": 107, "Incinerator": 108, "DrawBridge": 203, "AshlandsLava": 204}
# "DeathByTree" needs DeathByTree (index 68). "DeathByTreeAll" needs a death by each of these 10 tree varieties
# (the stats are named Tree* in the game, but they count deaths for this achievement).
DEATH_BY_TREE = 68
TREE_VARIETIES = {"Fir": 193, "Oak": 194, "Pine": 195, "Ashlands": 196, "YggdrasilShoot": 197, "Swamp": 198,
                  "Beech": 199, "Birch": 200, "SnowFir": 201, "SnowPine": 202}


# Oldest profile version known to have this layout, newest one checked against it, and the stat/set counts the
# stat indices above depend on. A different count means the game's stat list changed and the indices are wrong.
MIN_PROFILE_VERSION = 46
TESTED_PROFILE_VERSION = 47
STAT_COUNT = 205
SET_COUNT = 10
GAME = "Valheim 1.0.16"


# Earliest biome in which each death can happen (stated by hand, not read from the game files). Enemy hit, fall,
# drowning, burning and smoke are possible from the start; poison needs a Greydwarf Shaman (Black Forest), freezing
# needs the cold of the Mountain, and the edge of the world is reached by sailing.
DEATH_BIOME = {"EnemyHit": "Meadows", "Fall": "Meadows", "Drowning": "Meadows", "Burning": "Meadows",
               "Smoke": "Meadows", "Poisoned": "Black Forest", "Freezing": "Mountain", "EdgeOfWorld": "Ocean",
               "Tree": "Meadows", "Turret": "Mistlands", "Stalagtite": "Mountain", "Catapult": "Ashlands",
               "AshlandsOcean": "Ashlands", "Incinerator": "Swamp", "DrawBridge": "Mountain", "AshlandsLava": "Ashlands"}
# Where each tree can be cut down (Beech, Birch and Oak can be cut with the early axes).
TREE_BIOME = {"Beech": "Meadows", "Birch": "Meadows", "Oak": "Meadows", "Pine": "Black Forest", "Fir": "Black Forest",
              "Ashlands": "Ashlands", "SnowFir": "Deep North", "SnowPine": "Deep North", "Swamp": "Swamp",
              "YggdrasilShoot": "Mistlands"}


# BEGIN GENERATED BIOMES (tools/update_script_biomes.py rewrites everything up to END GENERATED BIOMES)
# Earliest biome per token, in progression order below. Craft = where the item can be made, Piece = where a build
# piece can be built, Found = where a trophy or fish can be obtained, Creature = where a creature lives.
BIOME_ORDER = ['Meadows', 'Black Forest', 'Ocean', 'Swamp', 'Mountain', 'Plains', 'Mistlands', 'Ashlands', 'Deep North']
BIOME_CRAFT = {
    '$item_arrow_bloodgold': 'Deep North',
    '$item_arrow_bronze': 'Black Forest',
    '$item_arrow_carapace': 'Mistlands',
    '$item_arrow_charred': 'Ashlands',
    '$item_arrow_fire': 'Meadows',
    '$item_arrow_flint': 'Meadows',
    '$item_arrow_frost': 'Mountain',
    '$item_arrow_iron': 'Swamp',
    '$item_arrow_needle': 'Plains',
    '$item_arrow_obsidian': 'Mountain',
    '$item_arrow_poison': 'Mountain',
    '$item_arrow_silver': 'Mountain',
    '$item_arrow_wood': 'Meadows',
    '$item_asksvin_meat_cooked': 'Ashlands',
    '$item_atgeir_blackmetal': 'Plains',
    '$item_atgeir_bronze': 'Black Forest',
    '$item_atgeir_gold': 'Deep North',
    '$item_atgeir_gold_bloodlightning': 'Deep North',
    '$item_atgeir_gold_frostfire': 'Deep North',
    '$item_atgeir_gold_uncooked': 'Deep North',
    '$item_atgeir_himminafl': 'Mistlands',
    '$item_atgeir_iron': 'Swamp',
    '$item_axe2h_gold': 'Deep North',
    '$item_axe2h_gold_bloodlightning': 'Deep North',
    '$item_axe2h_gold_frostfire': 'Deep North',
    '$item_axe_berzerkr': 'Ashlands',
    '$item_axe_berzerkr_blood': 'Ashlands',
    '$item_axe_berzerkr_lightning': 'Ashlands',
    '$item_axe_berzerkr_nature': 'Ashlands',
    '$item_axe_blackmetal': 'Plains',
    '$item_axe_bronze': 'Black Forest',
    '$item_axe_early': 'Meadows',
    '$item_axe_flint': 'Meadows',
    '$item_axe_gold': 'Deep North',
    '$item_axe_gold_bloodlightning': 'Deep North',
    '$item_axe_gold_frostfire': 'Deep North',
    '$item_axe_gold_uncooked': 'Deep North',
    '$item_axe_iron': 'Swamp',
    '$item_axe_jotunbane': 'Mistlands',
    '$item_axe_stone': 'Meadows',
    '$item_bakedpoteitr': 'Deep North',
    '$item_bakedpoteitr_uncooked': 'Deep North',
    '$item_barleywinebase': 'Plains',
    '$item_battleaxe': 'Swamp',
    '$item_battleaxe_blackmetal': 'Plains',
    '$item_battleaxe_crystal': 'Mountain',
    '$item_battleaxe_gold_uncooked': 'Deep North',
    '$item_battleaxe_skullsplittur': 'Mistlands',
    '$item_bell': 'Ashlands',
    '$item_bilebomb': 'Mistlands',
    '$item_bjorn_meat_cooked': 'Black Forest',
    '$item_blacksoup': 'Swamp',
    '$item_bloodpudding': 'Plains',
    '$item_blubber_cooked': 'Deep North',
    '$item_boar_meat_cooked': 'Meadows',
    '$item_boarjerky': 'Black Forest',
    '$item_bolt_blackmetal': 'Mistlands',
    '$item_bolt_bloodgold': 'Deep North',
    '$item_bolt_bone': 'Mistlands',
    '$item_bolt_carapace': 'Mistlands',
    '$item_bolt_charred': 'Ashlands',
    '$item_bolt_iron': 'Mistlands',
    '$item_bomb_dynamite': 'Deep North',
    '$item_bombblob_frost': 'Mountain',
    '$item_bombblob_lava': 'Ashlands',
    '$item_bombblob_morkhalla': 'Deep North',
    '$item_bombblob_poison': 'Swamp',
    '$item_bombblob_poisonelite': 'Swamp',
    '$item_bombblob_tar': 'Plains',
    '$item_bonemawmeat_cooked': 'Ashlands',
    '$item_bow': 'Meadows',
    '$item_bow_ashlands': 'Ashlands',
    '$item_bow_ashlandsblood': 'Ashlands',
    '$item_bow_ashlandsroot': 'Ashlands',
    '$item_bow_ashlandsstorm': 'Ashlands',
    '$item_bow_draugrfang': 'Mountain',
    '$item_bow_finewood': 'Black Forest',
    '$item_bow_gold': 'Deep North',
    '$item_bow_gold_bloodlightning': 'Deep North',
    '$item_bow_gold_frostfire': 'Deep North',
    '$item_bow_gold_uncooked': 'Deep North',
    '$item_bow_huntsman': 'Swamp',
    '$item_bow_snipesnap': 'Mistlands',
    '$item_bread': 'Plains',
    '$item_breaddough': 'Plains',
    '$item_bronze': 'Black Forest',
    '$item_bronzenails': 'Black Forest',
    '$item_bug_meat_cooked': 'Mistlands',
    '$item_cape_ash': 'Ashlands',
    '$item_cape_asksvin': 'Ashlands',
    '$item_cape_deepnorth': 'Deep North',
    '$item_cape_deepnorth_mage': 'Deep North',
    '$item_cape_deerhide': 'Meadows',
    '$item_cape_feather': 'Mistlands',
    '$item_cape_linen': 'Plains',
    '$item_cape_lox': 'Plains',
    '$item_cape_trollhide': 'Black Forest',
    '$item_cape_wolf': 'Mountain',
    '$item_carrotsoup': 'Black Forest',
    '$item_catapult_ammo': 'Ashlands',
    '$item_catapult_bloodgold_ammo': 'Deep North',
    '$item_catapult_training_ammo': 'Ashlands',
    '$item_ceramicplate': 'Mistlands',
    '$item_chest_berserker': 'Black Forest',
    '$item_chest_berserker_undead': 'Plains',
    '$item_chest_bronze': 'Black Forest',
    '$item_chest_carapace': 'Mistlands',
    '$item_chest_fenris': 'Mountain',
    '$item_chest_flametal': 'Ashlands',
    '$item_chest_heavy_deepnorth': 'Deep North',
    '$item_chest_heavy_gold_uncooked': 'Deep North',
    '$item_chest_iron': 'Swamp',
    '$item_chest_leather': 'Meadows',
    '$item_chest_lox': 'Plains',
    '$item_chest_mage': 'Mistlands',
    '$item_chest_mage_ashlands': 'Ashlands',
    '$item_chest_mage_deepnorth': 'Deep North',
    '$item_chest_mage_gold_uncooked': 'Deep North',
    '$item_chest_medium_ashlands': 'Ashlands',
    '$item_chest_medium_deepnorth': 'Deep North',
    '$item_chest_medium_gold_uncooked': 'Deep North',
    '$item_chest_pcuirass': 'Plains',
    '$item_chest_rags': 'Meadows',
    '$item_chest_root': 'Swamp',
    '$item_chest_trollleather': 'Black Forest',
    '$item_chest_wolf': 'Mountain',
    '$item_chicken_meat_cooked': 'Plains',
    '$item_club': 'Meadows',
    '$item_crossbow_arbalest': 'Mistlands',
    '$item_crossbow_bloodlightning_gold': 'Deep North',
    '$item_crossbow_frostfire_gold': 'Deep North',
    '$item_crossbow_gold': 'Deep North',
    '$item_crossbow_gold_uncooked': 'Deep North',
    '$item_crossbow_ripper': 'Ashlands',
    '$item_crossbow_ripper_blood': 'Ashlands',
    '$item_crossbow_ripper_lightning': 'Ashlands',
    '$item_crossbow_ripper_nature': 'Ashlands',
    '$item_cultivator': 'Black Forest',
    '$item_deer_meat_cooked': 'Meadows',
    '$item_deerstew': 'Black Forest',
    '$item_demister': 'Plains',
    '$item_dvergrkey': 'Mistlands',
    '$item_egg_cooked': 'Plains',
    '$item_eyescream': 'Mountain',
    '$item_feastashlands': 'Ashlands',
    '$item_feastblackforest': 'Swamp',
    '$item_feastdeepnorth': 'Deep North',
    '$item_feastmeadows': 'Swamp',
    '$item_feastmistlands': 'Mistlands',
    '$item_feastmountains': 'Mountain',
    '$item_feastoceans': 'Swamp',
    '$item_feastplains': 'Plains',
    '$item_feastswamps': 'Swamp',
    '$item_fierysvinstew': 'Ashlands',
    '$item_fireworkrocket_blue': 'Plains',
    '$item_fireworkrocket_cyan': 'Plains',
    '$item_fireworkrocket_green': 'Plains',
    '$item_fireworkrocket_purple': 'Plains',
    '$item_fireworkrocket_red': 'Plains',
    '$item_fireworkrocket_yellow': 'Plains',
    '$item_fish_cooked': 'Swamp',
    '$item_fish_raw': 'Swamp',
    '$item_fishandbread': 'Mistlands',
    '$item_fishandbreaduncooked': 'Mistlands',
    '$item_fishingbait_ashlands': 'Ashlands',
    '$item_fishingbait_cave': 'Mountain',
    '$item_fishingbait_deepnorth': 'Mountain',
    '$item_fishingbait_forest': 'Swamp',
    '$item_fishingbait_mistlands': 'Plains',
    '$item_fishingbait_ocean': 'Swamp',
    '$item_fishingbait_plains': 'Plains',
    '$item_fishingbait_swamp': 'Swamp',
    '$item_fishsoup': 'Deep North',
    '$item_fishwraps': 'Plains',
    '$item_fistweapon_bjorn': 'Black Forest',
    '$item_fistweapon_bjorn_undead': 'Plains',
    '$item_fistweapon_fenris': 'Mountain',
    '$item_fistweapon_frostfire_gold': 'Deep North',
    '$item_fistweapon_gold': 'Deep North',
    '$item_fistweapon_gold_bloodlightning': 'Deep North',
    '$item_fistweapon_gold_uncooked': 'Deep North',
    '$item_frostorbs_uncooked': 'Deep North',
    '$item_graplinghook': 'Mistlands',
    '$item_hare_meat_cooked': 'Mistlands',
    '$item_helmet_berserker': 'Black Forest',
    '$item_helmet_berserker_undead': 'Plains',
    '$item_helmet_bronze': 'Black Forest',
    '$item_helmet_carapace': 'Mistlands',
    '$item_helmet_celebration': 'Black Forest',
    '$item_helmet_crown_of_valheim': 'Deep North',
    '$item_helmet_drake': 'Mountain',
    '$item_helmet_fenris': 'Mountain',
    '$item_helmet_fishinghat': 'Deep North',
    '$item_helmet_flametal': 'Ashlands',
    '$item_helmet_heavy_deepnorth': 'Deep North',
    '$item_helmet_heavy_gold_uncooked': 'Deep North',
    '$item_helmet_iron': 'Swamp',
    '$item_helmet_leather': 'Meadows',
    '$item_helmet_lox': 'Plains',
    '$item_helmet_mage': 'Mistlands',
    '$item_helmet_mage_ashlands': 'Ashlands',
    '$item_helmet_mage_deepnorth': 'Deep North',
    '$item_helmet_mage_gold_uncooked': 'Deep North',
    '$item_helmet_medium_ashlands': 'Ashlands',
    '$item_helmet_medium_deepnorth': 'Deep North',
    '$item_helmet_medium_gold_uncooked': 'Deep North',
    '$item_helmet_padded': 'Plains',
    '$item_helmet_root': 'Swamp',
    '$item_helmet_trollleather': 'Black Forest',
    '$item_hoe': 'Meadows',
    '$item_honeyglazedchicken': 'Mistlands',
    '$item_honeyglazedchickenuncooked': 'Mistlands',
    '$item_ironnails': 'Swamp',
    '$item_kalechips': 'Deep North',
    '$item_kalechips_uncooked': 'Deep North',
    '$item_keys_gold_uncooked': 'Deep North',
    '$item_knife_blackmetal': 'Plains',
    '$item_knife_butcher': 'Black Forest',
    '$item_knife_chitin': 'Ocean',
    '$item_knife_copper': 'Black Forest',
    '$item_knife_flint': 'Meadows',
    '$item_knife_gold': 'Deep North',
    '$item_knife_gold_bloodlightning': 'Deep North',
    '$item_knife_gold_frostfire': 'Deep North',
    '$item_knife_gold_uncooked': 'Deep North',
    '$item_knife_silver': 'Mountain',
    '$item_knife_skollandhati': 'Mistlands',
    '$item_legs_berserker': 'Black Forest',
    '$item_legs_berserker_undead': 'Plains',
    '$item_legs_bronze': 'Black Forest',
    '$item_legs_carapace': 'Mistlands',
    '$item_legs_fenris': 'Mountain',
    '$item_legs_flametal': 'Ashlands',
    '$item_legs_heavy_deepnorth': 'Deep North',
    '$item_legs_heavy_gold_uncooked': 'Deep North',
    '$item_legs_iron': 'Swamp',
    '$item_legs_leather': 'Meadows',
    '$item_legs_lox': 'Plains',
    '$item_legs_mage': 'Mistlands',
    '$item_legs_mage_ashlands': 'Ashlands',
    '$item_legs_mage_deepnorth': 'Deep North',
    '$item_legs_mage_gold_uncooked': 'Deep North',
    '$item_legs_medium_ashlands': 'Ashlands',
    '$item_legs_medium_deepnorth': 'Deep North',
    '$item_legs_medium_gold_uncooked': 'Deep North',
    '$item_legs_pgreaves': 'Plains',
    '$item_legs_rags': 'Meadows',
    '$item_legs_root': 'Swamp',
    '$item_legs_trollleather': 'Black Forest',
    '$item_legs_wolf': 'Mountain',
    '$item_lingondricka': 'Deep North',
    '$item_loxmeat_cooked': 'Plains',
    '$item_loxpie': 'Plains',
    '$item_loxpie_uncooked': 'Plains',
    '$item_mace2h_gold_bloodlightning': 'Deep North',
    '$item_mace2h_gold_frostfire': 'Deep North',
    '$item_mace_bronze': 'Black Forest',
    '$item_mace_eldner': 'Ashlands',
    '$item_mace_eldner_blood': 'Ashlands',
    '$item_mace_eldner_lightning': 'Ashlands',
    '$item_mace_eldner_nature': 'Ashlands',
    '$item_mace_gold': 'Deep North',
    '$item_mace_gold_bloodlightning': 'Deep North',
    '$item_mace_gold_frostfire': 'Deep North',
    '$item_mace_gold_uncooked': 'Deep North',
    '$item_mace_iron': 'Swamp',
    '$item_mace_needle': 'Plains',
    '$item_mace_silver': 'Mountain',
    '$item_magicallystuffedmushroom': 'Mistlands',
    '$item_magicallystuffedmushroomuncooked': 'Mistlands',
    '$item_marinatedgreens': 'Ashlands',
    '$item_mashedmeat': 'Ashlands',
    '$item_meadbasebugrepellent': 'Plains',
    '$item_meadbasebzerker': 'Mountain',
    '$item_meadbaseeitr': 'Mistlands',
    '$item_meadbaseeitr_lingering': 'Ashlands',
    '$item_meadbasefrostresist': 'Swamp',
    '$item_meadbasehasty': 'Swamp',
    '$item_meadbasehealth': 'Black Forest',
    '$item_meadbasehealth_lingering': 'Ashlands',
    '$item_meadbasehealth_major': 'Mistlands',
    '$item_meadbasehealth_medium': 'Swamp',
    '$item_meadbaselightfoot': 'Mistlands',
    '$item_meadbasepoisonresist': 'Black Forest',
    '$item_meadbasestamina': 'Black Forest',
    '$item_meadbasestamina_lingering': 'Mistlands',
    '$item_meadbasestamina_medium': 'Plains',
    '$item_meadbasestrength': 'Swamp',
    '$item_meadbaseswimmer': 'Swamp',
    '$item_meadbasetamer': 'Mountain',
    '$item_meadbasetasty': 'Black Forest',
    '$item_meatballsmashedpoteitr': 'Deep North',
    '$item_meatplatter': 'Mistlands',
    '$item_meatplatteruncooked': 'Mistlands',
    '$item_mechanicalspring': 'Mistlands',
    '$item_mincemeatsauce': 'Black Forest',
    '$item_mistharesupreme': 'Mistlands',
    '$item_mistharesupremeuncooked': 'Mistlands',
    '$item_moose_meat_cooked': 'Deep North',
    '$item_moosekebab': 'Deep North',
    '$item_mushroomomelette': 'Mistlands',
    '$item_necktailgrilled': 'Meadows',
    '$item_oatmeallingonberryjam': 'Deep North',
    '$item_oatmilk': 'Deep North',
    '$item_onionsoup': 'Mountain',
    '$item_oozebomb': 'Swamp',
    '$item_ovenpancake': 'Deep North',
    '$item_ovenpancake_uncooked': 'Deep North',
    '$item_pancakes': 'Deep North',
    '$item_pickaxe_antler': 'Meadows',
    '$item_pickaxe_blackmetal': 'Mistlands',
    '$item_pickaxe_bronze': 'Black Forest',
    '$item_pickaxe_iron': 'Swamp',
    '$item_piquantpie': 'Ashlands',
    '$item_piquantpie_uncooked': 'Ashlands',
    '$item_pulledbear': 'Black Forest',
    '$item_queensjam': 'Black Forest',
    '$item_roastedcrustpie': 'Ashlands',
    '$item_roastedcrustpie_uncooked': 'Ashlands',
    '$item_saddleasksvin': 'Ashlands',
    '$item_saddlelox': 'Plains',
    '$item_saddlemoose': 'Deep North',
    '$item_salad': 'Mistlands',
    '$item_sausages': 'Swamp',
    '$item_scorchingmedley': 'Ashlands',
    '$item_scythe': 'Mountain',
    '$item_sealsoup': 'Deep North',
    '$item_seekeraspic': 'Mistlands',
    '$item_serpentmeatcooked': 'Swamp',
    '$item_serpentstew': 'Swamp',
    '$item_sharpeningstone': 'Swamp',
    '$item_shield_banded': 'Swamp',
    '$item_shield_blackmetal': 'Plains',
    '$item_shield_blackmetal_tower': 'Plains',
    '$item_shield_bonetower': 'Meadows',
    '$item_shield_bronzebuckler': 'Black Forest',
    '$item_shield_buckler_gold_uncooked': 'Deep North',
    '$item_shield_carapace': 'Mistlands',
    '$item_shield_carapacebuckler': 'Mistlands',
    '$item_shield_flametal': 'Ashlands',
    '$item_shield_flametal_tower': 'Ashlands',
    '$item_shield_gold': 'Deep North',
    '$item_shield_gold_tower': 'Deep North',
    '$item_shield_goldbuckler': 'Deep North',
    '$item_shield_iron_tower': 'Swamp',
    '$item_shield_ironbuckler': 'Swamp',
    '$item_shield_roots': 'Swamp',
    '$item_shield_round_gold_uncooked': 'Deep North',
    '$item_shield_serpentscale': 'Swamp',
    '$item_shield_silver': 'Mountain',
    '$item_shield_tower_gold_uncooked': 'Deep North',
    '$item_shield_wood': 'Meadows',
    '$item_shield_woodtower': 'Meadows',
    '$item_shieldcore': 'Mistlands',
    '$item_shocklatesmoothie': 'Swamp',
    '$item_sizzlingberrybroth': 'Ashlands',
    '$item_sledge_demolisher': 'Mistlands',
    '$item_sledge_gold': 'Deep North',
    '$item_sledge_gold_uncooked': 'Deep North',
    '$item_sledge_iron': 'Swamp',
    '$item_smokedfish': 'Deep North',
    '$item_smokedmoosemeat': 'Deep North',
    '$item_sparklingshroomshake': 'Ashlands',
    '$item_spear_ancientbark': 'Swamp',
    '$item_spear_bronze': 'Black Forest',
    '$item_spear_carapace': 'Mistlands',
    '$item_spear_chitin': 'Ocean',
    '$item_spear_flint': 'Meadows',
    '$item_spear_gold': 'Deep North',
    '$item_spear_gold_bloodlightning': 'Deep North',
    '$item_spear_gold_frostfire': 'Deep North',
    '$item_spear_gold_uncooked': 'Deep North',
    '$item_spear_splitner': 'Ashlands',
    '$item_spear_splitner_blood': 'Ashlands',
    '$item_spear_splitner_lightning': 'Ashlands',
    '$item_spear_splitner_nature': 'Ashlands',
    '$item_spear_wolffang': 'Mountain',
    '$item_spicymarmalade': 'Ashlands',
    '$item_staff_frostorbs': 'Deep North',
    '$item_staff_lightning': 'Ashlands',
    '$item_staff_orbofahri': 'Deep North',
    '$item_staff_orbofahri_uncooked': 'Deep North',
    '$item_staff_spiritcaller': 'Deep North',
    '$item_staff_spiritcaller_uncooked': 'Deep North',
    '$item_staff_thunderblood': 'Deep North',
    '$item_staff_thunderblood_uncooked': 'Deep North',
    '$item_staffclusterbomb': 'Ashlands',
    '$item_stafffireball': 'Mistlands',
    '$item_staffgreenroots': 'Ashlands',
    '$item_stafficeshards': 'Mistlands',
    '$item_staffredtroll': 'Ashlands',
    '$item_staffshield': 'Mistlands',
    '$item_staffskeleton': 'Mistlands',
    '$item_stagbreaker': 'Black Forest',
    '$item_sword2h_gold': 'Deep North',
    '$item_sword2h_gold_bloodlightning': 'Deep North',
    '$item_sword2h_gold_frostfire': 'Deep North',
    '$item_sword2h_gold_uncooked': 'Deep North',
    '$item_sword_blackmetal': 'Plains',
    '$item_sword_bronze': 'Black Forest',
    '$item_sword_dyrnwyn': 'Ashlands',
    '$item_sword_gold': 'Deep North',
    '$item_sword_gold_bloodlightning': 'Deep North',
    '$item_sword_gold_frostfire': 'Deep North',
    '$item_sword_gold_uncooked': 'Deep North',
    '$item_sword_iron': 'Swamp',
    '$item_sword_krom': 'Mistlands',
    '$item_sword_mistwalker': 'Mistlands',
    '$item_sword_niedhogg': 'Ashlands',
    '$item_sword_niedhogg_blood': 'Ashlands',
    '$item_sword_niedhogg_lightning': 'Ashlands',
    '$item_sword_niedhogg_nature': 'Ashlands',
    '$item_sword_silver': 'Mountain',
    '$item_sword_slayer': 'Ashlands',
    '$item_sword_slayer_blood': 'Ashlands',
    '$item_sword_slayer_lightning': 'Ashlands',
    '$item_sword_slayer_nature': 'Ashlands',
    '$item_sword_wood': 'Black Forest',
    '$item_torch': 'Meadows',
    '$item_trinketblackdamagedealth': 'Plains',
    '$item_trinketblackdtamina': 'Plains',
    '$item_trinketbloodgoldhealth': 'Deep North',
    '$item_trinketbloodgoldstamina': 'Deep North',
    '$item_trinketbronzehealth': 'Black Forest',
    '$item_trinketbronzestamina': 'Black Forest',
    '$item_trinketcarapaceeitr': 'Mistlands',
    '$item_trinketchitinswim': 'Ocean',
    '$item_trinketflametaleitr': 'Ashlands',
    '$item_trinketflametalstaminahealth': 'Ashlands',
    '$item_trinketironhealth': 'Swamp',
    '$item_trinketironstamina': 'Swamp',
    '$item_trinketscalestaminadamage': 'Mistlands',
    '$item_trinketsilverdamage': 'Mountain',
    '$item_trinketsilverresist': 'Mountain',
    '$item_turnipstew': 'Swamp',
    '$item_turretbolt': 'Plains',
    '$item_turretbolt_bloodgold': 'Deep North',
    '$item_turretbolt_flametal': 'Ashlands',
    '$item_turretboltwood': 'Mountain',
    '$item_vikingcupcake': 'Plains',
    '$item_vikingcupcake_uncooked': 'Plains',
    '$item_volture_meat_cooked': 'Ashlands',
    '$item_wolf_meat_cooked': 'Mountain',
    '$item_wolf_skewer': 'Mountain',
    '$item_wolfjerky': 'Mountain',
    '$item_yggdrasilporridge': 'Mistlands',
}
BIOME_PIECE = {
    '$item_hardrock': 'Black Forest',
    '$piece_BlackwoodStakewall': 'Ashlands',
    '$piece_archerytarget': 'Meadows',
    '$piece_armorstand': 'Swamp',
    '$piece_artisan_ext1': 'Mistlands',
    '$piece_artisanstation': 'Mountain',
    '$piece_ashwood_archedwall': 'Ashlands',
    '$piece_ashwood_beam_1m': 'Ashlands',
    '$piece_ashwood_beam_2m': 'Ashlands',
    '$piece_ashwood_bed': 'Ashlands',
    '$piece_ashwood_decowall': 'Ashlands',
    '$piece_ashwood_decowall_divider': 'Ashlands',
    '$piece_ashwood_decowall_tree': 'Ashlands',
    '$piece_ashwood_door': 'Ashlands',
    '$piece_ashwood_floor_1x1': 'Ashlands',
    '$piece_ashwood_floor_2x2': 'Ashlands',
    '$piece_ashwood_floor_deco': 'Ashlands',
    '$piece_ashwood_halfwall': 'Ashlands',
    '$piece_ashwood_pole_1m': 'Ashlands',
    '$piece_ashwood_pole_2m': 'Ashlands',
    '$piece_ashwood_quarterwall': 'Ashlands',
    '$piece_ashwood_wall': 'Ashlands',
    '$piece_ashwoodarch_big': 'Ashlands',
    '$piece_ashwoodbeam26': 'Ashlands',
    '$piece_ashwoodbeam45': 'Ashlands',
    '$piece_ashwoodbeam67': 'Ashlands',
    '$piece_ashwoodcross26': 'Ashlands',
    '$piece_ashwoodcross45': 'Ashlands',
    '$piece_ashwoodstair': 'Ashlands',
    '$piece_ashwoodwallroof67': 'Ashlands',
    '$piece_ashwoodwallroof67upsidedown': 'Ashlands',
    '$piece_ashwoodwallroof_26': 'Ashlands',
    '$piece_ashwoodwallroof_26_upsidedown': 'Ashlands',
    '$piece_ashwoodwallroof_45': 'Ashlands',
    '$piece_ashwoodwallroof_45_upsidedown': 'Ashlands',
    '$piece_ashwoodwallrooftop67': 'Ashlands',
    '$piece_asksvinskeleton': 'Ashlands',
    '$piece_banner01': 'Black Forest',
    '$piece_banner02': 'Black Forest',
    '$piece_banner03': 'Meadows',
    '$piece_banner04': 'Swamp',
    '$piece_banner05': 'Swamp',
    '$piece_banner06': 'Plains',
    '$piece_banner07': 'Plains',
    '$piece_banner08': 'Black Forest',
    '$piece_banner09': 'Black Forest',
    '$piece_banner10': 'Plains',
    '$piece_banner11': 'Plains',
    '$piece_barber': 'Black Forest',
    '$piece_bathtub': 'Plains',
    '$piece_bed': 'Meadows',
    '$piece_bed02': 'Mountain',
    '$piece_beehive': 'Meadows',
    '$piece_bench01': 'Meadows',
    '$piece_bench_runed': 'Deep North',
    '$piece_benchlog': 'Black Forest',
    '$piece_birdnest': 'Swamp',
    '$piece_blackforge': 'Mistlands',
    '$piece_blackforge_ext1': 'Mistlands',
    '$piece_blackforge_ext2': 'Mistlands',
    '$piece_blackforge_ext3': 'Ashlands',
    '$piece_blackforge_ext4': 'Ashlands',
    '$piece_blackforge_ext5': 'Deep North',
    '$piece_blackmarble1x1': 'Mistlands',
    '$piece_blackmarble2x1x1': 'Mistlands',
    '$piece_blackmarble2x2x2': 'Mistlands',
    '$piece_blackmarble_arch': 'Mistlands',
    '$piece_blackmarble_base1': 'Mistlands',
    '$piece_blackmarble_basecorner': 'Mistlands',
    '$piece_blackmarble_bench': 'Mistlands',
    '$piece_blackmarble_column_1': 'Mistlands',
    '$piece_blackmarble_column_2': 'Mistlands',
    '$piece_blackmarble_floor': 'Mistlands',
    '$piece_blackmarble_floor_triangle': 'Mistlands',
    '$piece_blackmarble_out1': 'Mistlands',
    '$piece_blackmarble_outcorner': 'Mistlands',
    '$piece_blackmarble_stair': 'Mistlands',
    '$piece_blackmarble_table': 'Mistlands',
    '$piece_blackmarble_throne': 'Mistlands',
    '$piece_blackmarble_tip': 'Mistlands',
    '$piece_blackmetalbarstack': 'Plains',
    '$piece_blackwoodbench01': 'Ashlands',
    '$piece_blackwoodstack': 'Ashlands',
    '$piece_blastfurnace': 'Mountain',
    '$piece_bloodgoldbarstack': 'Deep North',
    '$piece_bone_throne': 'Ashlands',
    '$piece_bonestack': 'Meadows',
    '$piece_bonfire': 'Swamp',
    '$piece_brazierceiling01': 'Swamp',
    '$piece_brazierfloor01': 'Mountain',
    '$piece_brazierfloor02': 'Mountain',
    '$piece_bronzebarstack': 'Black Forest',
    '$piece_candle': 'Swamp',
    '$piece_cartographytable': 'Black Forest',
    '$piece_cauldron': 'Black Forest',
    '$piece_cauldron_ext1_spice': 'Swamp',
    '$piece_cauldron_ext3_butchertable': 'Mountain',
    '$piece_cauldron_ext4_pans': 'Plains',
    '$piece_cauldron_ext5_mortarandpestle': 'Mistlands',
    '$piece_cauldron_ext6_rollingpins': 'Ashlands',
    '$piece_cauldron_ext7_smoker': 'Deep North',
    '$piece_celebrationgarland': 'Meadows',
    '$piece_chair': 'Meadows',
    '$piece_chair_runed': 'Deep North',
    '$piece_charcoalkiln': 'Black Forest',
    '$piece_chest': 'Swamp',
    '$piece_chestbarrel': 'Black Forest',
    '$piece_chestblackmetal': 'Plains',
    '$piece_chestgrausten': 'Ashlands',
    '$piece_chestprivate': 'Swamp',
    '$piece_chesttreasure': 'Mountain',
    '$piece_chestwarderobe': 'Deep North',
    '$piece_chestwood': 'Meadows',
    '$piece_clothdoor': 'Mountain',
    '$piece_coalpile': 'Black Forest',
    '$piece_cookingstation': 'Meadows',
    '$piece_cookingstation_iron': 'Swamp',
    '$piece_copperbarstack': 'Black Forest',
    '$piece_crystalwall1x1': 'Mountain',
    '$piece_darkwoodarch': 'Plains',
    '$piece_darkwoodbeam': 'Plains',
    '$piece_darkwoodbeam4': 'Plains',
    '$piece_darkwoodbeam67': 'Plains',
    '$piece_darkwoodbeam_26': 'Plains',
    '$piece_darkwoodbeam_45': 'Plains',
    '$piece_darkwoodchair': 'Plains',
    '$piece_darkwooddecowall': 'Plains',
    '$piece_darkwoodgate': 'Plains',
    '$piece_darkwoodpole': 'Plains',
    '$piece_darkwoodpole4': 'Plains',
    '$piece_darkwoodraven': 'Plains',
    '$piece_darkwoodroof26': 'Plains',
    '$piece_darkwoodroof45': 'Plains',
    '$piece_darkwoodroof67': 'Plains',
    '$piece_darkwoodrooficorner': 'Plains',
    '$piece_darkwoodrooficorner45': 'Plains',
    '$piece_darkwoodrooficorner67': 'Plains',
    '$piece_darkwoodroofocorner': 'Plains',
    '$piece_darkwoodroofocorner45': 'Plains',
    '$piece_darkwoodroofocorner67': 'Plains',
    '$piece_darkwoodrooftop': 'Plains',
    '$piece_darkwoodrooftop45': 'Plains',
    '$piece_darkwoodrooftop67': 'Plains',
    '$piece_darkwoodwolf': 'Plains',
    '$piece_deco_stave_wall': 'Deep North',
    '$piece_drawbridge_dn': 'Deep North',
    '$piece_drawbridge_log': 'Mountain',
    '$piece_dvergr_lantern': 'Mistlands',
    '$piece_dvergr_lantern_pole': 'Mistlands',
    '$piece_dvergr_metal_wall': 'Mistlands',
    '$piece_dvergr_sharpstakes': 'Mistlands',
    '$piece_dvergr_spiralstair': 'Mistlands',
    '$piece_dvergr_spiralstair_right': 'Mistlands',
    '$piece_dvergr_stake_wall': 'Mistlands',
    '$piece_eitrrefinery': 'Mistlands',
    '$piece_faderember': 'Ashlands',
    '$piece_fairylightgarland': 'Black Forest',
    '$piece_fermenter': 'Black Forest',
    '$piece_firepit': 'Meadows',
    '$piece_firepit_iron': 'Meadows',
    '$piece_flametal_beam': 'Ashlands',
    '$piece_flametal_pillar': 'Ashlands',
    '$piece_flametalbarstack': 'Ashlands',
    '$piece_flametalgate': 'Ashlands',
    '$piece_flintpile': 'Meadows',
    '$piece_forge': 'Black Forest',
    '$piece_forge_ext1': 'Swamp',
    '$piece_forge_ext2': 'Black Forest',
    '$piece_forge_ext3': 'Swamp',
    '$piece_forge_ext4': 'Swamp',
    '$piece_forge_ext5': 'Black Forest',
    '$piece_forge_ext6': 'Swamp',
    '$piece_frostfoundry': 'Deep North',
    '$piece_frostkiln': 'Deep North',
    '$piece_grausten_archmedium': 'Ashlands',
    '$piece_grausten_archsmall': 'Ashlands',
    '$piece_grausten_beammedium': 'Ashlands',
    '$piece_grausten_beamsmall': 'Ashlands',
    '$piece_grausten_floor1x1': 'Ashlands',
    '$piece_grausten_floor2x2': 'Ashlands',
    '$piece_grausten_floor4x4': 'Ashlands',
    '$piece_grausten_pillarmedium': 'Ashlands',
    '$piece_grausten_pillarsmall': 'Ashlands',
    '$piece_grausten_pillartapered': 'Ashlands',
    '$piece_grausten_pillartaperedinverted': 'Ashlands',
    '$piece_grausten_roof45': 'Ashlands',
    '$piece_grausten_roof45_arch': 'Ashlands',
    '$piece_grausten_roof45_archcorner': 'Ashlands',
    '$piece_grausten_roof45_archcorner2': 'Ashlands',
    '$piece_grausten_roof45_corner': 'Ashlands',
    '$piece_grausten_roof45_corner2': 'Ashlands',
    '$piece_grausten_stair': 'Ashlands',
    '$piece_grausten_stoneladder': 'Ashlands',
    '$piece_grausten_wall1x2': 'Ashlands',
    '$piece_grausten_wall2x2': 'Ashlands',
    '$piece_grausten_wall4x2': 'Ashlands',
    '$piece_grausten_wallarch': 'Ashlands',
    '$piece_grausten_wallarchinv': 'Ashlands',
    '$piece_grausten_window2x2': 'Ashlands',
    '$piece_grausten_window4x2': 'Ashlands',
    '$piece_graustenpile': 'Ashlands',
    '$piece_groundtorch': 'Swamp',
    '$piece_groundtorchblue': 'Swamp',
    '$piece_groundtorchdemister': 'Mistlands',
    '$piece_groundtorchgreen': 'Swamp',
    '$piece_groundtorchwood': 'Meadows',
    '$piece_guardstone': 'Black Forest',
    '$piece_hanging_cloth_blue1': 'Mistlands',
    '$piece_hanging_cloth_blue2': 'Mistlands',
    '$piece_hearth': 'Swamp',
    '$piece_hexagonalgate': 'Mistlands',
    '$piece_hoodedlantern': 'Deep North',
    '$piece_icecube': 'Deep North',
    '$piece_incinerator': 'Swamp',
    '$piece_ironbarstack': 'Swamp',
    '$piece_ironfloor': 'Swamp',
    '$piece_ironfloorSmall': 'Swamp',
    '$piece_irongate': 'Swamp',
    '$piece_ironwall': 'Swamp',
    '$piece_ironwallSmall': 'Swamp',
    '$piece_ironwoodbeam67': 'Swamp',
    '$piece_itemstand': 'Black Forest',
    '$piece_jackoturnip': 'Swamp',
    '$piece_jute_carpet': 'Mountain',
    '$piece_juteblue_carpet': 'Mistlands',
    '$piece_lavalantern': 'Ashlands',
    '$piece_logbeam2': 'Black Forest',
    '$piece_logbeam4': 'Black Forest',
    '$piece_logpole2': 'Black Forest',
    '$piece_logpole4': 'Black Forest',
    '$piece_magetable': 'Mistlands',
    '$piece_magetable_ext': 'Mistlands',
    '$piece_magetable_ext2': 'Mistlands',
    '$piece_magetable_ext3': 'Ashlands',
    '$piece_magetable_ext4': 'Deep North',
    '$piece_marblepile': 'Mistlands',
    '$piece_maypole': 'Black Forest',
    '$piece_meadcauldron': 'Black Forest',
    '$piece_mistletoe': 'Mountain',
    '$piece_moose_throne': 'Deep North',
    '$piece_oven': 'Mountain',
    '$piece_portal': 'Black Forest',
    '$piece_portal_stone': 'Ashlands',
    '$piece_pot_large_green': 'Ashlands',
    '$piece_pot_medium_green': 'Ashlands',
    '$piece_pot_small_green': 'Ashlands',
    '$piece_preptable': 'Swamp',
    '$piece_rug_asksvin': 'Ashlands',
    '$piece_rug_bjorn': 'Black Forest',
    '$piece_rug_deer': 'Meadows',
    '$piece_rug_hare': 'Mistlands',
    '$piece_rug_lox': 'Plains',
    '$piece_rug_moose': 'Deep North',
    '$piece_rug_seal': 'Deep North',
    '$piece_rug_straw': 'Plains',
    '$piece_rug_wolf': 'Mountain',
    '$piece_sapcollector': 'Mistlands',
    '$piece_scale_26': 'Deep North',
    '$piece_scale_26_flipped': 'Deep North',
    '$piece_scale_26_upsidedown': 'Deep North',
    '$piece_scale_26_upsidedown_flipped': 'Deep North',
    '$piece_scale_45': 'Deep North',
    '$piece_scale_45_flipped': 'Deep North',
    '$piece_scale_45_upsidedown': 'Deep North',
    '$piece_scale_45_upsidedown_flipped': 'Deep North',
    '$piece_scale_67': 'Deep North',
    '$piece_scale_67_flipped': 'Deep North',
    '$piece_scale_67_upsidedown': 'Deep North',
    '$piece_scale_67_upsidedown_flipped': 'Deep North',
    '$piece_scale_halfwall': 'Deep North',
    '$piece_scale_quarterwall': 'Deep North',
    '$piece_scale_wall': 'Deep North',
    '$piece_sconce': 'Black Forest',
    '$piece_sharpstakes': 'Black Forest',
    '$piece_shieldgenerator': 'Mistlands',
    '$piece_sign': 'Black Forest',
    '$piece_silverbarstack': 'Mountain',
    '$piece_skullpile': 'Ashlands',
    '$piece_smelter': 'Black Forest',
    '$piece_snowlantern': 'Deep North',
    '$piece_spinningwheel': 'Mountain',
    '$piece_stakewall': 'Meadows',
    '$piece_stave_deco_beam_2m': 'Deep North',
    '$piece_stave_deco_pole_2m': 'Deep North',
    '$piece_stave_pole_2m': 'Deep North',
    '$piece_stave_pole_4m': 'Deep North',
    '$piece_stave_wall': 'Deep North',
    '$piece_stavebeam2': 'Deep North',
    '$piece_stavebeam26': 'Deep North',
    '$piece_stavebeam4': 'Deep North',
    '$piece_stavebeam45': 'Deep North',
    '$piece_stavebeam67': 'Deep North',
    '$piece_stavecross26': 'Deep North',
    '$piece_stavecross45': 'Deep North',
    '$piece_stavedecobeam26': 'Deep North',
    '$piece_stavedecobeam45': 'Deep North',
    '$piece_stavedecobeam67': 'Deep North',
    '$piece_stavegate': 'Deep North',
    '$piece_stavewallrooftop67': 'Deep North',
    '$piece_stonearch': 'Swamp',
    '$piece_stonecutter': 'Swamp',
    '$piece_stonefence': 'Meadows',
    '$piece_stonefloor2x2': 'Swamp',
    '$piece_stonepile': 'Meadows',
    '$piece_stonepillar': 'Swamp',
    '$piece_stonestair': 'Swamp',
    '$piece_stonethrone': 'Mountain',
    '$piece_stonewall1x1': 'Swamp',
    '$piece_stonewall2x1': 'Swamp',
    '$piece_stonewall4x2': 'Swamp',
    '$piece_stool': 'Meadows',
    '$piece_table': 'Meadows',
    '$piece_table_oak': 'Plains',
    '$piece_table_round': 'Plains',
    '$piece_table_runed': 'Deep North',
    '$piece_table_runed_small': 'Deep North',
    '$piece_throne01': 'Swamp',
    '$piece_tinbarstack': 'Black Forest',
    '$piece_trainingdummy': 'Black Forest',
    '$piece_trap': 'Mistlands',
    '$piece_treasure_pile': 'Meadows',
    '$piece_treasure_stack': 'Meadows',
    '$piece_turret': 'Mistlands',
    '$piece_windmill': 'Mountain',
    '$piece_wisplure': 'Plains',
    '$piece_woodbeam1': 'Meadows',
    '$piece_woodbeam2': 'Meadows',
    '$piece_woodbeam26': 'Meadows',
    '$piece_woodbeam45': 'Meadows',
    '$piece_woodbeam67': 'Meadows',
    '$piece_woodcorestack': 'Black Forest',
    '$piece_wooddoor': 'Meadows',
    '$piece_wooddragon': 'Meadows',
    '$piece_woodfence': 'Meadows',
    '$piece_woodfencegate': 'Meadows',
    '$piece_woodfinestack': 'Meadows',
    '$piece_woodfloor1x1': 'Meadows',
    '$piece_woodfloor2x2': 'Meadows',
    '$piece_woodfroststack': 'Deep North',
    '$piece_woodgate': 'Meadows',
    '$piece_woodironbeam': 'Swamp',
    '$piece_woodironbeam_26': 'Swamp',
    '$piece_woodironbeam_45': 'Swamp',
    '$piece_woodironpole': 'Swamp',
    '$piece_woodlog26': 'Black Forest',
    '$piece_woodlog45': 'Black Forest',
    '$piece_woodlog67': 'Black Forest',
    '$piece_woodpole': 'Meadows',
    '$piece_woodpole2': 'Meadows',
    '$piece_woodroof26': 'Meadows',
    '$piece_woodroof45': 'Meadows',
    '$piece_woodroof67': 'Meadows',
    '$piece_woodrooficorner': 'Meadows',
    '$piece_woodrooficorner45': 'Meadows',
    '$piece_woodrooficorner67': 'Meadows',
    '$piece_woodroofocorner': 'Meadows',
    '$piece_woodroofocorner45': 'Meadows',
    '$piece_woodroofocorner67': 'Meadows',
    '$piece_woodrooftop': 'Meadows',
    '$piece_woodrooftop45': 'Meadows',
    '$piece_woodrooftop67': 'Meadows',
    '$piece_woodstack': 'Meadows',
    '$piece_woodstair': 'Meadows',
    '$piece_woodstepladder': 'Meadows',
    '$piece_woodwall': 'Meadows',
    '$piece_woodwallhalf': 'Meadows',
    '$piece_woodwallquarter': 'Meadows',
    '$piece_woodwallroof': 'Meadows',
    '$piece_woodwallroof45': 'Meadows',
    '$piece_woodwallroof45_upsidedown': 'Meadows',
    '$piece_woodwallroof67': 'Meadows',
    '$piece_woodwallroof67upsidedown': 'Meadows',
    '$piece_woodwallroof_upsidedown': 'Meadows',
    '$piece_woodwallrooftop': 'Meadows',
    '$piece_woodwallrooftop45': 'Meadows',
    '$piece_woodwallrooftop67': 'Meadows',
    '$piece_woodwindowshutter': 'Black Forest',
    '$piece_workbench': 'Meadows',
    '$piece_workbench_ext1': 'Meadows',
    '$piece_workbench_ext2': 'Meadows',
    '$piece_workbench_ext3': 'Black Forest',
    '$piece_workbench_ext4': 'Mountain',
    '$piece_yggdrasilstack': 'Mistlands',
    '$piece_yulecrown': 'Mountain',
    '$piece_yulegarland': 'Black Forest',
    '$piece_yuleklapp': 'Meadows',
    '$piece_yuletree': 'Black Forest',
    '$ship_karve': 'Black Forest',
    '$ship_longship': 'Swamp',
    '$ship_longship_ashlands': 'Mistlands',
    '$ship_raft': 'Meadows',
    '$tool_batteringram': 'Ashlands',
    '$tool_cart': 'Black Forest',
    '$tool_catapult': 'Ashlands',
}
BIOME_FOUND = {
    '$animal_fish1': 'Meadows',
    '$animal_fish10': 'Deep North',
    '$animal_fish11': 'Ashlands',
    '$animal_fish12': 'Ocean',
    '$animal_fish2': 'Meadows',
    '$animal_fish3': 'Ocean',
    '$animal_fish4': 'Mountain',
    '$animal_fish5': 'Black Forest',
    '$animal_fish6': 'Swamp',
    '$animal_fish7': 'Plains',
    '$animal_fish8': 'Ocean',
    '$animal_fish9': 'Mistlands',
    '$enemy_kvastur': 'Swamp',
    '$item_trophy_abomination': 'Swamp',
    '$item_trophy_asksvin': 'Ashlands',
    '$item_trophy_barka': 'Deep North',
    '$item_trophy_bjorn': 'Black Forest',
    '$item_trophy_bjorn_undead': 'Plains',
    '$item_trophy_blob': 'Swamp',
    '$item_trophy_blob_frost': 'Mountain',
    '$item_trophy_blob_lava': 'Ashlands',
    '$item_trophy_blob_morkhalla': 'Deep North',
    '$item_trophy_boar': 'Meadows',
    '$item_trophy_bonemass': 'Swamp',
    '$item_trophy_bonemaw': 'Ashlands',
    '$item_trophy_brutebro': 'Plains',
    '$item_trophy_charredarcher': 'Ashlands',
    '$item_trophy_charredmage': 'Ashlands',
    '$item_trophy_charredmelee': 'Ashlands',
    '$item_trophy_cultist': 'Mountain',
    '$item_trophy_cultist_hildir': 'Mountain',
    '$item_trophy_deathsquito': 'Plains',
    '$item_trophy_deer': 'Meadows',
    '$item_trophy_dragonqueen': 'Mountain',
    '$item_trophy_draugr': 'Swamp',
    '$item_trophy_draugrelite': 'Swamp',
    '$item_trophy_dvergr': 'Mistlands',
    '$item_trophy_eikthyr': 'Meadows',
    '$item_trophy_elaking': 'Deep North',
    '$item_trophy_elder': 'Black Forest',
    '$item_trophy_fader': 'Ashlands',
    '$item_trophy_fallenvalkyrie': 'Ashlands',
    '$item_trophy_fenring': 'Mountain',
    '$item_trophy_ghost': 'Black Forest',
    '$item_trophy_gjall': 'Mistlands',
    '$item_trophy_goblin': 'Plains',
    '$item_trophy_goblinbrute': 'Plains',
    '$item_trophy_goblinking': 'Plains',
    '$item_trophy_goblinshaman': 'Plains',
    '$item_trophy_greydwarf': 'Meadows',
    '$item_trophy_greydwarfbrute': 'Black Forest',
    '$item_trophy_greydwarfshaman': 'Black Forest',
    '$item_trophy_growth': 'Plains',
    '$item_trophy_hare': 'Mistlands',
    '$item_trophy_hatchling': 'Mountain',
    '$item_trophy_jotunwarrior': 'Deep North',
    '$item_trophy_jotunwitch': 'Deep North',
    '$item_trophy_leech': 'Swamp',
    '$item_trophy_lox': 'Plains',
    '$item_trophy_mole': 'Deep North',
    '$item_trophy_moose': 'Deep North',
    '$item_trophy_morgen': 'Ashlands',
    '$item_trophy_neck': 'Meadows',
    '$item_trophy_seal': 'Deep North',
    '$item_trophy_seeker': 'Mistlands',
    '$item_trophy_seeker_brute': 'Mistlands',
    '$item_trophy_seekerqueen': 'Mistlands',
    '$item_trophy_serpent': 'Ocean',
    '$item_trophy_sgolem': 'Mountain',
    '$item_trophy_shamanbro': 'Plains',
    '$item_trophy_skeleton': 'Meadows',
    '$item_trophy_skeleton_hildir': 'Black Forest',
    '$item_trophy_skeletonpoison': 'Black Forest',
    '$item_trophy_surtling': 'Swamp',
    '$item_trophy_tick': 'Mistlands',
    '$item_trophy_ulv': 'Mountain',
    '$item_trophy_volture': 'Ashlands',
    '$item_trophy_wolf': 'Mountain',
    '$item_trophy_wraith': 'Swamp',
    '$item_trophy_writhan': 'Swamp',
}
BIOME_CREATURE = {
    '$enemy_abomination': 'Swamp',
    '$enemy_asksvin': 'Ashlands',
    '$enemy_asksvin_hatchling': 'Ashlands',
    '$enemy_aspect_bonemass': 'Deep North',
    '$enemy_aspect_dragon': 'Deep North',
    '$enemy_aspect_eikthyr': 'Deep North',
    '$enemy_aspect_fader': 'Deep North',
    '$enemy_aspect_gdking': 'Deep North',
    '$enemy_aspect_goblinking': 'Deep North',
    '$enemy_aspect_seekerqueen': 'Deep North',
    '$enemy_babyseeker': 'Mistlands',
    '$enemy_barka': 'Deep North',
    '$enemy_bat': 'Mountain',
    '$enemy_bjorn': 'Black Forest',
    '$enemy_blob': 'Swamp',
    '$enemy_blobelite': 'Swamp',
    '$enemy_blobfrost': 'Mountain',
    '$enemy_bloblava': 'Ashlands',
    '$enemy_blobmork': 'Deep North',
    '$enemy_blobmorkmini': 'Deep North',
    '$enemy_blobtar': 'Plains',
    '$enemy_boar': 'Meadows',
    '$enemy_boarpiggy': 'Meadows',
    '$enemy_bonemass': 'Swamp',
    '$enemy_bonemawserpent': 'Ashlands',
    '$enemy_charred_archer': 'Ashlands',
    '$enemy_charred_mage': 'Ashlands',
    '$enemy_charred_melee': 'Ashlands',
    '$enemy_charred_melee_Dyrnwyn': 'Ashlands',
    '$enemy_charred_melee_Fader': 'Ashlands',
    '$enemy_charred_twitcher': 'Ashlands',
    '$enemy_charred_twitcher_summoned': 'Ashlands',
    '$enemy_chicken': 'Plains',
    '$enemy_deathsquito': 'Plains',
    '$enemy_deer': 'Meadows',
    '$enemy_dragon': 'Mountain',
    '$enemy_drake': 'Mountain',
    '$enemy_draugr': 'Swamp',
    '$enemy_draugrelite': 'Swamp',
    '$enemy_dvergr': 'Mistlands',
    '$enemy_dvergr_deepnorth': 'Deep North',
    '$enemy_dvergr_mage': 'Mistlands',
    '$enemy_eikthyr': 'Meadows',
    '$enemy_elaking': 'Deep North',
    '$enemy_elakingmole': 'Deep North',
    '$enemy_fader': 'Ashlands',
    '$enemy_fallenvalkyrie': 'Ashlands',
    '$enemy_fallenwarrior': 'Deep North',
    '$enemy_fenring': 'Mountain',
    '$enemy_fenringcultist': 'Mountain',
    '$enemy_fenringcultist_hildir': 'Mountain',
    '$enemy_frozenking': 'Deep North',
    '$enemy_frozenking_p3': 'Deep North',
    '$enemy_gdking': 'Black Forest',
    '$enemy_ghost': 'Black Forest',
    '$enemy_gjall': 'Mistlands',
    '$enemy_goblin': 'Plains',
    '$enemy_goblin_deepnorth': 'Deep North',
    '$enemy_goblin_hildir': 'Plains',
    '$enemy_goblinbrute': 'Plains',
    '$enemy_goblinbrute_hildircombined': 'Plains',
    '$enemy_goblinking': 'Plains',
    '$enemy_goblinshaman': 'Plains',
    '$enemy_greydwarf': 'Meadows',
    '$enemy_greydwarfbrute': 'Black Forest',
    '$enemy_greydwarfshaman': 'Black Forest',
    '$enemy_greyling': 'Meadows',
    '$enemy_hare': 'Mistlands',
    '$enemy_hen': 'Plains',
    '$enemy_jotun_warrior': 'Deep North',
    '$enemy_jotun_witch': 'Deep North',
    '$enemy_kvastur': 'Swamp',
    '$enemy_leech': 'Swamp',
    '$enemy_lox': 'Plains',
    '$enemy_loxcalf': 'Plains',
    '$enemy_moose': 'Deep North',
    '$enemy_moosecalf': 'Deep North',
    '$enemy_morgen': 'Ashlands',
    '$enemy_neck': 'Meadows',
    '$enemy_root': 'Black Forest',
    '$enemy_seal': 'Deep North',
    '$enemy_seal_baby': 'Deep North',
    '$enemy_seeker': 'Mistlands',
    '$enemy_seekerbrute': 'Mistlands',
    '$enemy_seekerqueen': 'Mistlands',
    '$enemy_serpent': 'Ocean',
    '$enemy_skeleton': 'Meadows',
    '$enemy_skeleton_summoned': 'Mistlands',
    '$enemy_skeletonfire': 'Black Forest',
    '$enemy_skeletonpoison': 'Black Forest',
    '$enemy_stonegolem': 'Mountain',
    '$enemy_summonedtroll': 'Ashlands',
    '$enemy_surtling': 'Swamp',
    '$enemy_tick': 'Mistlands',
    '$enemy_troll': 'Black Forest',
    '$enemy_trollfrost': 'Deep North',
    '$enemy_ulv': 'Mountain',
    '$enemy_unbjorn': 'Plains',
    '$enemy_volture': 'Ashlands',
    '$enemy_wolf': 'Mountain',
    '$enemy_wolfcub': 'Mountain',
    '$enemy_wraith': 'Swamp',
    '$enemy_writhan': 'Swamp',
    '$piece_trainingdummy': 'Black Forest',
    '$spiritcaller_bjorn': 'Deep North',
    '$spiritcaller_boar': 'Deep North',
    '$spiritcaller_moose': 'Deep North',
    '$spiritcaller_wolf': 'Deep North',
}
FOOD_EATEN = {   # The Gourmet: every food that has to be eaten once
    '$item_asksvin_meat_cooked': 'Cooked Asksvin Tail',
    '$item_bakedpoteitr': 'Baked Poteitr',
    '$item_bjorn_meat_cooked': 'Cooked Bear Meat',
    '$item_blacksoup': 'Black Soup',
    '$item_bloodpudding': 'Blood Pudding',
    '$item_blubber_cooked': 'Cooked Seal Blubber',
    '$item_blueberries': 'Blueberries',
    '$item_boar_meat_cooked': 'Cooked Boar Meat',
    '$item_boarjerky': 'Boar Jerky',
    '$item_bonemawmeat_cooked': 'Cooked Bonemaw Meat',
    '$item_bread': 'Bread',
    '$item_bug_meat_cooked': 'Cooked Seeker Meat',
    '$item_carrot': 'Carrot',
    '$item_carrotsoup': 'Carrot Soup',
    '$item_chicken_meat_cooked': 'Cooked Chicken Meat',
    '$item_cloudberries': 'Cloudberries',
    '$item_deer_meat_cooked': 'Cooked Deer Meat',
    '$item_deerstew': 'Deer Stew',
    '$item_egg_cooked': 'Cooked Egg',
    '$item_eyescream': 'Eyescream',
    '$item_feastashlands': 'Ashlands Gourmet Bowl',
    '$item_feastblackforest': 'Black Forest Buffet Platter',
    '$item_feastdeepnorth': 'Northern Morning Fare',
    '$item_feastmeadows': 'Whole Roasted Meadow Boar',
    '$item_feastmistlands': 'Mushrooms Galore á la Mistlands',
    '$item_feastmountains': "Hearty Mountain Logger's Stew",
    '$item_feastoceans': "Sailor's Bounty",
    '$item_feastplains': 'Plains Pie Picnic',
    '$item_feastswamps': "Swamp Dweller's Delight",
    '$item_fiddleheadfern': 'Fiddlehead',
    '$item_fierysvinstew': 'Fiery Svinstew',
    '$item_fish_cooked': 'Cooked Fish',
    '$item_fishandbread': "Fish 'n' Bread",
    '$item_fishsoup': 'Fish Soup',
    '$item_fishwraps': 'Fish Wraps',
    '$item_glowworm': 'Luminous Larva',
    '$item_hare_meat_cooked': 'Cooked Hare Meat',
    '$item_honey': 'Honey',
    '$item_honeyglazedchicken': 'Honey Glazed Chicken',
    '$item_jotunpuffs': 'Jotun Puffs',
    '$item_kale': 'Kale',
    '$item_kalechips': 'Kale Chips',
    '$item_lingonberries': 'Lingonberries',
    '$item_lingondricka': 'Lingonberry Juice',
    '$item_loxmeat_cooked': 'Cooked Lox Meat',
    '$item_loxpie': 'Lox Meat Pie',
    '$item_magecap': 'Magecap',
    '$item_magicallystuffedmushroom': 'Stuffed Mushroom',
    '$item_marinatedgreens': 'Marinated Greens',
    '$item_mashedmeat': 'Mashed Meat',
    '$item_meatballsmashedpoteitr': 'Meatballs and Poteitr',
    '$item_meatplatter': 'Meat Platter',
    '$item_mincemeatsauce': 'Minced Meat Sauce',
    '$item_mistharesupreme': 'Misthare Supreme',
    '$item_moose_meat_cooked': 'Cooked Moose Meat',
    '$item_moosekebab': 'Meat In Bread',
    '$item_mushroomcommon': 'Mushroom',
    '$item_mushroomomelette': 'Mushroom Omelette',
    '$item_mushroomyellow': 'Yellow Mushroom',
    '$item_necktailgrilled': 'Grilled Neck Tail',
    '$item_oat': 'Oats',
    '$item_oatmeallingonberryjam': 'Oatmeal',
    '$item_oatmilk': 'Oat Milk',
    '$item_onion': 'Onion',
    '$item_onionsoup': 'Onion Soup',
    '$item_ovenpancake': 'Oven Pancake',
    '$item_pancakes': 'Pancakes',
    '$item_piquantpie': 'Piquant Pie',
    '$item_poteitr': 'Poteitr',
    '$item_pulledbear': 'Pulled Bear',
    '$item_queensjam': "Queen's Jam",
    '$item_raspberries': 'Raspberries',
    '$item_roastedcrustpie': 'Roasted Crust Pie',
    '$item_royaljelly': 'Royal Jelly',
    '$item_salad': 'Salad',
    '$item_sausages': 'Sausages',
    '$item_scorchingmedley': 'Scorching Medley',
    '$item_sealsoup': 'Seal Meat Soup',
    '$item_seekeraspic': 'Seeker Aspic',
    '$item_serpentmeatcooked': 'Cooked Serpent Meat',
    '$item_serpentstew': 'Serpent Stew',
    '$item_shocklatesmoothie': 'Muckshake',
    '$item_sizzlingberrybroth': 'Sizzling Berry Broth',
    '$item_smokedfish': 'Smoked Fish',
    '$item_smokedmoosemeat': 'Smoked Moose Meat',
    '$item_smokepuff': 'Smoke Puff',
    '$item_sparklingshroomshake': 'Sparkling Shroomshake',
    '$item_spicymarmalade': 'Spicy Marmalade',
    '$item_turnipstew': 'Turnip Stew',
    '$item_vikingcupcake': 'Frosted Sweetbread',
    '$item_vineberry': 'Vineberry Cluster',
    '$item_volture_meat_cooked': 'Cooked Volture Meat',
    '$item_wolf_meat_cooked': 'Cooked Wolf Meat',
    '$item_wolf_skewer': 'Wolf Skewer',
    '$item_wolfjerky': 'Wolf Jerky',
    '$item_yggdrasilporridge': 'Yggdrasil Porridge',
}
BIOME_FOOD = {
    '$item_asksvin_meat_cooked': 'Ashlands',
    '$item_bakedpoteitr': 'Deep North',
    '$item_bjorn_meat_cooked': 'Black Forest',
    '$item_blacksoup': 'Swamp',
    '$item_bloodpudding': 'Plains',
    '$item_blubber_cooked': 'Deep North',
    '$item_blueberries': 'Black Forest',
    '$item_boar_meat_cooked': 'Meadows',
    '$item_boarjerky': 'Black Forest',
    '$item_bonemawmeat_cooked': 'Ashlands',
    '$item_bread': 'Plains',
    '$item_bug_meat_cooked': 'Mistlands',
    '$item_carrot': 'Black Forest',
    '$item_carrotsoup': 'Black Forest',
    '$item_chicken_meat_cooked': 'Plains',
    '$item_cloudberries': 'Plains',
    '$item_deer_meat_cooked': 'Meadows',
    '$item_deerstew': 'Black Forest',
    '$item_egg_cooked': 'Plains',
    '$item_eyescream': 'Mountain',
    '$item_feastashlands': 'Ashlands',
    '$item_feastblackforest': 'Swamp',
    '$item_feastdeepnorth': 'Deep North',
    '$item_feastmeadows': 'Swamp',
    '$item_feastmistlands': 'Mistlands',
    '$item_feastmountains': 'Mountain',
    '$item_feastoceans': 'Swamp',
    '$item_feastplains': 'Plains',
    '$item_feastswamps': 'Swamp',
    '$item_fiddleheadfern': 'Ashlands',
    '$item_fierysvinstew': 'Ashlands',
    '$item_fish_cooked': 'Swamp',
    '$item_fishandbread': 'Mistlands',
    '$item_fishsoup': 'Deep North',
    '$item_fishwraps': 'Plains',
    '$item_glowworm': 'Deep North',
    '$item_hare_meat_cooked': 'Mistlands',
    '$item_honey': 'Meadows',
    '$item_honeyglazedchicken': 'Mistlands',
    '$item_jotunpuffs': 'Mistlands',
    '$item_kale': 'Deep North',
    '$item_kalechips': 'Deep North',
    '$item_lingonberries': 'Deep North',
    '$item_lingondricka': 'Deep North',
    '$item_loxmeat_cooked': 'Plains',
    '$item_loxpie': 'Plains',
    '$item_magecap': 'Mistlands',
    '$item_magicallystuffedmushroom': 'Mistlands',
    '$item_marinatedgreens': 'Ashlands',
    '$item_mashedmeat': 'Ashlands',
    '$item_meatballsmashedpoteitr': 'Deep North',
    '$item_meatplatter': 'Mistlands',
    '$item_mincemeatsauce': 'Black Forest',
    '$item_mistharesupreme': 'Mistlands',
    '$item_moose_meat_cooked': 'Deep North',
    '$item_moosekebab': 'Deep North',
    '$item_mushroomcommon': 'Meadows',
    '$item_mushroomomelette': 'Mistlands',
    '$item_mushroomyellow': 'Black Forest',
    '$item_necktailgrilled': 'Meadows',
    '$item_oat': 'Deep North',
    '$item_oatmeallingonberryjam': 'Deep North',
    '$item_oatmilk': 'Deep North',
    '$item_onion': 'Mountain',
    '$item_onionsoup': 'Mountain',
    '$item_ovenpancake': 'Deep North',
    '$item_pancakes': 'Deep North',
    '$item_piquantpie': 'Ashlands',
    '$item_poteitr': 'Deep North',
    '$item_pulledbear': 'Black Forest',
    '$item_queensjam': 'Black Forest',
    '$item_raspberries': 'Meadows',
    '$item_roastedcrustpie': 'Ashlands',
    '$item_royaljelly': 'Mistlands',
    '$item_salad': 'Mistlands',
    '$item_sausages': 'Swamp',
    '$item_scorchingmedley': 'Ashlands',
    '$item_sealsoup': 'Deep North',
    '$item_seekeraspic': 'Mistlands',
    '$item_serpentmeatcooked': 'Swamp',
    '$item_serpentstew': 'Swamp',
    '$item_shocklatesmoothie': 'Swamp',
    '$item_sizzlingberrybroth': 'Ashlands',
    '$item_smokedfish': 'Deep North',
    '$item_smokedmoosemeat': 'Deep North',
    '$item_smokepuff': 'Ashlands',
    '$item_sparklingshroomshake': 'Ashlands',
    '$item_spicymarmalade': 'Ashlands',
    '$item_turnipstew': 'Swamp',
    '$item_vikingcupcake': 'Plains',
    '$item_vineberry': 'Ashlands',
    '$item_volture_meat_cooked': 'Ashlands',
    '$item_wolf_meat_cooked': 'Mountain',
    '$item_wolf_skewer': 'Mountain',
    '$item_wolfjerky': 'Mountain',
    '$item_yggdrasilporridge': 'Mistlands',
}
# END GENERATED BIOMES


class Reader:
    def __init__(self, data, pos=0):
        self.d, self.p = data, pos

    def i32(self):
        v = struct.unpack_from("<i", self.d, self.p)[0]
        self.p += 4
        return v

    def string(self):
        n = shift = 0
        while True:
            b = self.d[self.p]
            self.p += 1
            n |= (b & 0x7F) << shift
            shift += 7
            if b < 0x80:
                break
        s = self.d[self.p:self.p + n].decode("utf8")
        self.p += n
        return s

    def sdict(self):
        out = {}
        for _ in range(self.i32()):
            k = self.string()
            out[k] = struct.unpack_from("<f", self.d, self.p)[0]
            self.p += 4
        return out


class SaveError(Exception):
    """The input is not a save this tool can read."""


def parse(source):
    """Parse a .fch save given as a path or as bytes."""
    raw = bytes(source) if isinstance(source, (bytes, bytearray)) else open(source, "rb").read()
    data = raw[4:4 + struct.unpack_from("<i", raw, 0)[0]]
    r = Reader(data)
    version = r.i32()
    if not 1 <= version <= 1000:
        raise SaveError("this is not a supported Valheim .fch character file")
    if version < MIN_PROFILE_VERSION:
        raise SaveError(f"this save uses profile version {version}, which is older than the oldest supported "
                        f"version {MIN_PROFILE_VERSION} ({GAME})")
    n_stats = r.i32()
    n_sets = r.i32()
    if (n_stats, n_sets) != (STAT_COUNT, SET_COUNT):
        raise SaveError(f"this save has {n_stats} stats in {n_sets} sets, but this script expects {STAT_COUNT} in "
                        f"{SET_COUNT}: the game's save layout changed and the script needs updating")
    sets = []
    for _ in range(n_sets):
        st = {"stats": struct.unpack_from(f"<{n_stats}f", data, r.p)}
        r.p += 4 * n_stats
        st["worlds"] = r.sdict()
        r.sdict()                   # known world keys
        r.sdict()                   # known commands
        enemy = [r.sdict() for _ in range(r.i32())]
        st["kills"] = enemy[0]      # MixedAndTotal; 1-4 = unarmed, magic, ranged, melee
        st["picked_up"] = r.sdict()
        st["crafted"] = r.sdict()
        st["pickables"] = r.sdict()
        st["foods_eaten"] = r.sdict()
        st["pieces_built"] = r.sdict()
        sets.append(st)
    return {"version": version, "sets": sets}


def strip(k):
    for pre in ("$enemy_", "$item_", "$piece_"):
        if k.startswith(pre):
            return k[len(pre):]
    return k


# Stat sets in the file, indexed by the game's DifficultyRequirement enum. Each kill/craft is added to set 0 (raw,
# includes cheated and pre-tracking data) and, when achievements are allowed, to set 1 (Any) and to every set from
# 3 (Casual) up to the difficulty it happened on. Achievements read these sets, never set 0.
SET_ANY, SET_NORMAL, SET_HARD = 1, 6, 7

# which biome table belongs to which list
SECTION_BIOMES = {"crafted": BIOME_CRAFT, "weapons": BIOME_CRAFT, "cooked": BIOME_CRAFT, "built": BIOME_PIECE,
                  "enemies": BIOME_CREATURE, "enemies-hard": BIOME_CREATURE,
                  "bosses-any": BIOME_CREATURE, "bosses-normal": BIOME_CREATURE, "bosses-hard": BIOME_CREATURE, "minibosses": BIOME_CREATURE, "fishing": BIOME_FOUND,
                  "trophies": BIOME_FOUND, "deaths": DEATH_BIOME, "tree-deaths": TREE_BIOME, "food-eaten": BIOME_FOOD}


def build_sections(s):
    """Compare a parsed save with the achievement lists. One dict per list, in display order.

    Each section has: id, title, hint, universe ({token: display name}), done ({token: count}),
    biomes ({token: earliest biome}), cli_names (print display names instead of stripped tokens in the terminal)."""
    sets = s["sets"]
    anyd, normal, hard = sets[SET_ANY], sets[SET_NORMAL], sets[SET_HARD]
    stats = anyd["stats"]
    kind = lambda table: {k: stats[i] for k, i in table.items() if stats[i] > 0}
    names = {"EdgeOfWorld": "Edge of the world", "Incinerator": "Obliterator", "SnowFir": "Snow fir (Timber Tree)", "SnowPine": "Snow pine (Timber Tree)"}
    nice = lambda table: {k: names.get(k) or re.sub(r"(?<=[a-z])([A-Z])", lambda m: " " + m[1].lower(), k) for k in table}
    sections = [
        dict(id="crafted", title="Items crafted (any difficulty)", hint="Recipes that need a crafting station.",
             universe=CRAFTABLE, done=anyd["crafted"]),
        dict(id="weapons", title="Weapons crafted (any difficulty)", hint="Includes hand-made weapons.",
             universe=CRAFTABLE_WEAPONS, done=anyd["crafted"]),
        dict(id="cooked", title="Food cooked/crafted (any difficulty)", hint="Includes fire and oven food.",
             universe=COOKED_FOOD, done=anyd["crafted"]),
        # The Gourmet: the game counts every food once it has been eaten (the foods-eaten table, any difficulty)
        dict(id="food-eaten", title="Food eaten (The Gourmet)",
             hint="Eat every food once. Raw and cooked versions are separate foods.",
             universe=FOOD_EATEN, done=anyd["foods_eaten"]),
        dict(id="built", title="Pieces built (any difficulty)", hint="Hammer menu pieces.",
             universe=BUILDABLE, done=anyd["pieces_built"]),
        dict(id="deaths", title="Ways to die", hint="Any difficulty.", cli_names=True,
             universe=nice(DEATH_KINDS), done=kind(DEATH_KINDS)),
        dict(id="tree-deaths", title="Killed by each tree variety",
             hint="Any difficulty. Snow fir and snow pine are two different trees that are both called Timber Tree in game.",
             cli_names=True,
             universe=nice(TREE_VARIETIES), done=kind(TREE_VARIETIES)),
        dict(id="enemies", title="Enemies killed (any difficulty)", hint="Bosses are listed separately.",
             universe=ENEMIES, done=anyd["kills"]),
        dict(id="enemies-hard", title="Enemies killed (Hard)", hint="Hard difficulty.",
             universe=ENEMIES, done=hard["kills"]),
        # the three boss achievements: any difficulty, Normal or higher, and Hard
        dict(id="bosses-any", title="Bosses killed (any difficulty)", hint="Any difficulty.",
             universe=BOSSES, done=anyd["kills"]),
        dict(id="bosses-normal", title="Bosses killed (Normal or higher)", hint="Normal difficulty or higher.",
             universe=BOSSES, done=normal["kills"]),
        dict(id="bosses-hard", title="Bosses killed (Hard)", hint="Hard difficulty.",
             universe=BOSSES, done=hard["kills"]),
        dict(id="minibosses", title="Mini-bosses killed (any difficulty)", hint="Any difficulty.",
             universe=MINIBOSSES, done=anyd["kills"]),
        # fish only count when reeled in (pickables table); picking one up by hand does not
        dict(id="fishing", title="Fish caught", hint="Reel the fish in. Picking one up does not count.",
             cli_names=True, universe=FISH, done=anyd["pickables"]),
        # the game counts a trophy once it has been picked up while achievements were allowed
        dict(id="trophies", title="Trophies collected",
             hint="Counted when picked up. Trophies from before tracking began may need picking up again.",
             universe=TROPHIES, done=anyd["picked_up"]),
    ]
    for sec in sections:
        sec["biomes"] = SECTION_BIOMES.get(sec["id"], {})
    return sections


SECTIONS = ["crafted", "weapons", "cooked", "food-eaten", "built", "deaths", "tree-deaths", "enemies", "enemies-hard",
            "bosses-any", "bosses-normal", "bosses-hard", "minibosses", "fishing", "trophies"]
SECTION_ALIASES = {"bosses": "bosses-normal"}   # the old name of the Normal-or-higher list


def analyze(source, only=None):
    """Run the whole analysis on a save (path or bytes) and return plain data (JSON-serialisable).

    Raises SaveError when the input is not a supported save."""
    try:
        s = parse(source)
    except SaveError:
        raise
    except (struct.error, IndexError, UnicodeDecodeError, AssertionError, ValueError):
        raise SaveError("this is not a supported Valheim .fch character file, or its layout changed and the script needs updating")
    out = []
    for sec in build_sections(s):
        if only and sec["id"] not in only:
            continue
        entries = [{"token": t, "name": sec["universe"][t] or strip(t), "count": int(sec["done"].get(t, 0)),
                    "biome": sec["biomes"].get(t, "")} for t in sec["universe"]]
        entries.sort(key=lambda e: e["name"].lower())
        out.append({"id": sec["id"], "title": sec["title"], "hint": sec["hint"], "total": len(entries),
                    "done": sum(1 for e in entries if e["count"] > 0), "entries": entries})
    warning = (f"This save is profile version {s['version']}, newer than the newest tested ({TESTED_PROFILE_VERSION}). "
               "It was read without problems, but check that the numbers look right."
               if s["version"] > TESTED_PROFILE_VERSION else "")
    return {"game": GAME, "profileVersion": s["version"], "warning": warning, "worlds": list(s["sets"][0]["worlds"]),
            "biomes": BIOME_ORDER, "sections": out}


def analyze_json(data):
    """Entry point for the web page (Pyodide): bytes in, JSON text out. Errors come back as {"error": ...}."""
    if hasattr(data, "to_py"):
        data = data.to_py()
    try:
        return json.dumps(analyze(bytes(data)))
    except SaveError as e:
        return json.dumps({"error": str(e)})


def show(sec, full=False):
    """Print one section: the missing entries, plus completed ones when full=True."""
    universe, done = sec["universe"], sec["done"]
    label = (lambda k: universe[k]) if sec.get("cli_names") else strip
    biome = lambda k: sec["biomes"].get(k, "")
    done_in = {k: v for k, v in done.items() if k in universe}
    # earliest biome first (so the next things to do come on top), then by name; entries without a biome go last
    order = lambda k: (BIOME_ORDER.index(biome(k)) if biome(k) in BIOME_ORDER else len(BIOME_ORDER), label(k))
    print(f"\n== {sec['title']}: {len(done_in)} / {len(universe)} ==")
    if full:
        for k, v in sorted(done_in.items(), key=lambda kv: order(kv[0])):
            print(f"  [x] {label(k):38s} x{int(v):<5d} {biome(k)}".rstrip())
    for k in sorted(set(universe) - set(done), key=order):
        print(f"  [ ] {label(k):38s} {biome(k)}".rstrip())


def main(argv=None):
    import argparse
    ap = argparse.ArgumentParser(
        description="Show Valheim character progress (crafting, kills, trophies) from a .fch save. "
                    "By default only what is still missing is listed.")
    ap.add_argument("save", help="path to the .fch file")
    ap.add_argument("-f", "--full", action="store_true", help="also list completed entries, with counts")
    ap.add_argument("-o", "--only", metavar="LIST", action="append",
                    help="only show these lists (comma-separated or repeat the option); one of: " + ", ".join(SECTIONS))
    ap.add_argument("--json", action="store_true",
                    help="print the result as JSON (every entry with its count) instead of text")
    args = ap.parse_args(argv)

    wanted = SECTIONS
    if args.only:
        wanted = [SECTION_ALIASES.get(x.strip(), x.strip()) for part in args.only for x in part.split(",") if x.strip()]
        bad = [x for x in wanted if x not in SECTIONS]
        if bad:
            ap.error(f"unknown list(s): {', '.join(bad)} (choose from {', '.join(SECTIONS)})")

    try:
        if args.json:
            print(json.dumps(analyze(args.save, only=set(wanted)), indent=2))
            return
        s = parse(args.save)
    except FileNotFoundError:
        ap.error(f"file not found: {args.save}")
    except OSError as e:
        ap.error(f"cannot read {args.save}: {e.strerror or e}")
    except SaveError as e:
        ap.error(f"{args.save}: {e}")
    except (struct.error, IndexError, UnicodeDecodeError, AssertionError, ValueError):
        ap.error(f"{args.save} is not a supported Valheim .fch character file, or its layout changed and the script needs updating")

    if s["version"] > TESTED_PROFILE_VERSION:
        print(f"warning: profile version {s['version']} is newer than the newest tested ({TESTED_PROFILE_VERSION}); "
              "the save was read without problems, but check that the numbers look right.", file=sys.stderr)
    print(f"{args.save}: profile v{s['version']}, worlds: {', '.join(s['sets'][0]['worlds'])}")
    for sec in build_sections(s):
        if sec["id"] in wanted:
            show(sec, args.full)


if __name__ == "__main__":
    main()
