Plandomizer

From OoT Randomizer Wiki

Plandomizer, often shortened to just Plando, permits total control over item placement. You can place a specific item on any location and locations not specified will be filled following the normal algorithm. Using a .json format text file, referred to as a distribution file when using plandomizer, most aspects of the randomizer can be overwritten.

This can be used to create custom challenges to play through yourself or share with others. The more details defined in a plandomizer, the less the randomizer interferes, though the randomizer will still verify whether it is beatable based on the logic settings, and if it is logically impossible it will refuse to generate a seed.

There is a beta GUI for Plandomizer on the website that can help you with simpler plandomizer ideas, however to truly grasp the power of plandomizer you will have to modify a distribution file yourself. Warning: This is a beta feature and frequently generates JSON files with issues that must be fixed in a text editor prior to use. Please visit the plando-support channel in the discord for help resolving these errors.

Also note that the following are not assignable.

Deliver Letter
Sell Big Poe
Skull Mask
Spooky Mask
Keaton Mask
Bunny Hood
Mask of Truth
Milk
Goron Mask
Zora Mask
Gerudo Mask
Zeldas Letter
Location: HC Zeldas Letter

These items and location are used internally by the logic to handle new item locations becoming available. They are not meant to be used in a plando.

Using a Plandomizer Distribution File on the Generator

Plandomizer's distribution file text box is hidden by default. To enable it go to ROM Options on the generator and turn on the Enable Plandomizer (Optional) setting. Then use the Browse button next to the new text box to find your Plandomizer distribution .json file.

Opening and Editing a Distribution File

Distributions are just normal text files using the .json extension instead of the .txt extension. They can be opened in any text editor that will open .txt files. Even Notepad, TextEdit, and gedit can open these files. The extension is only to help let you know that text within is expected to look a certain way.

Distribution File Format

JSON is a common format used for data that both a human and a computer are intended to read. It's a fairly picky format so it is a good idea to use a text editor that can tell you if you did something wrong through syntax highlighting. Visual Studio Code is such a text editor, and as it is cross-platform and used by many people in the community. It is the one we recommend you use if you go down this path. Alternatively, a validator such as JSONLint can check formatting, if you prefer a text editor without syntax highlighting. A validator may also help identify issues which are harder to understand in VSCode.

The randomizer generator on the website will also display an error if you try to use a distribution file that is not in the proper JSON format. You may wish to use this, JSONLint, and VSCode all together to figure out how to fix any formatting problems.

Understanding a Distribution File

When generating a seed with a spoiler log, that spoiler log is actually a distribution file itself. It can be used directly to generate the exact same seed. Because of this, you can take a look at a spoiler log to help you get familiar with the types of things that can be changed, and how to format the distribution file.

Since a distribution file is in JSON format, it's somewhat rigid about how things can be written.

The Base Dictionary

First, a distribution file starts with a { opening curly brace, and ends with a } closing curly brace. Everything you define must be placed between these braces. These braces mark a Dictionary or an associative array, and while that link has a lot of useful information, you don't really have to understand it. Think of a dictionary data structure like you would a dictionary in the real world. You have a term, then you have the definition of that term. As this is the base dictionary, you don't write a term as the code that reads the JSON file creates its own term for this dictionary.

The Dictionary "Terms"

Within the base dictionary there are many terms, such as :version, file_hash, and locations. If you are viewing a spoiler log you'll notice some of these terms start with a :. These terms are ignored when Plandomizer is used and are autogenerated by the randomizer. When you are creating a distribution file yourself you can delete these terms (or take advantage of this mechanic to put in comments between sections, but note that it cannot be used within {} sections such as Locations or Entrances).

Terms are followed by a : and then some spaces, then their definitions.

Definitions that start and end with " are Strings. They are just text you write, but it is important that they are between quotes.

Definitions starting with [ an open bracket and ending with a ] closing bracket are called Lists. In a distribution file lists will usually only contain strings. However, with other types of JSON files you could see them containing other data structures such as dictionaries, or other lists.

The rest of the definitions are just more dictionaries with their own terms that have definitions. These are the only data structures that you have to keep in mind, and generally they are already defined properly in the spoiler log for you so you can just modify them how you see fit. Just ensure you don't accidentally remove the symbols that go before and after the term.

The Most Common Format/Syntax Issue

You'll notice that each of these terms is followed at the very end by a , comma, except the very last one. This is probably the most common mistake someone will make when making their own distribution file. Each term needs to be separated by a comma, but the last one cannot have a comma after it. This is true for strings inside of lists, and lists, strings, and other dictionaries within a dictionary as well. If you are getting a syntax error, you probably added a comma you shouldn't have, or removed one you need. The generator will tell you that your JSON is invalid if you try to use a distribution file with one of these errors.

What Can Plandomizer Affect

Plandomizer can affect an enormous amount of the resulting seed. Everything from inconsequential things like the File Hash, to the Settings the randomizer uses to fill the world, and even specifically set items in locations that the world fill algorithm will have to work around.

File Hash

The file hash is the 5 icons that are displayed at the top of the file select screen. You can set these to any valid HASH_ICON.

You can set the file_hash definition to a list of up to 5 hash icons. If you do not want to specify an icon for a set position you can either set it to the value null, or if it is after all the ones you do want to set you can just not include it.

Hash Icons

Expand to view the full list of valid hash icons for the current version of the randomizer.

    'Deku Stick',
    'Deku Nut',
    'Bow',
    'Slingshot',
    'Fairy Ocarina',
    'Bombchu',
    'Longshot',
    'Boomerang',
    'Lens of Truth',
    'Beans',
    'Megaton Hammer',
    'Bottled Fish',
    'Bottled Milk',
    'Mask of Truth',
    'SOLD OUT',
    'Cucco',
    'Mushroom',
    'Saw',
    'Frog',
    'Master Sword',
    'Mirror Shield',
    'Kokiri Tunic',
    'Hover Boots',
    'Silver Gauntlets',
    'Gold Scale',
    'Stone of Agony',
    'Skull Token',
    'Heart Container',
    'Boss Key',
    'Compass',
    'Map',
    'Big Magic',

Examples

Set all 5 icons to Deku Nut:

"file_hash": ["Deku Nut", "Deku Nut", "Deku Nut", "Deku Nut", "Deku Nut"]

Set only the first icon to Deku Nut:

"file_hash": ["Deku Nut", null, null, null, null]

or

"file_hash": ["Deku Nut"]

Set only the last icon to Deku Nut:

"file_hash": [null, null, null, null, "Deku Nut"]

Settings

This is a dictionary defining the rules that the randomizer uses to fill the world. Any settings you set here will override the ones set in the GUI. That also means that you can leave some settings out of this dictionary and the person using your distribution file to create a seed can have a small amount of customization they can apply in case they need a little more additional help, or perhaps want to increase the difficulty a little bit.

It is not recommended to set these manually. Instead, you should go to the beta plandomizer maker on the website. You can set all the settings you want on the first tab, then create the JSON file. From here you can copy the settings dictionary from that file into this file and remove any settings you don't want to enforce. Alternatively, if you only want a few settings to be enforced, you can copy only the settings you want from the dictionary in that other JSON file into the settings dictionary in your settings file.

There are two major issues with creating the settings dictionary entirely manually:

  1. If you mistype, or the name of a setting changes between versions, you will not get an error. The randomizer will just ignore this issue entirely.
  2. The process of figuring out the proper name for a setting, and the various values it can hold is tedious.

If you still think you want to try this method, the file in the source code you want to look at to see all this necessary information is SettingsList.py. This is a 3000 line monstrosity that isn't very useful if you're not already pretty familiar with the settings you are looking for in the first place. Each setting has a name that you have to use for a definition inside of the settings dictionary. Then various other variables within the option's object in the settings list file are used to determine what possible definitions you want to use for that setting.

Just using the plandomizer maker on the website is highly recommended over putting yourself through this experience.

Starting Items

The starting items dictionary lets you define what items a player starts with, and how many of them. This includes both items you find in the world, and consumables you would pick up such as ammo and bombs. Any items you start with will be replaced by junk in the item pool. Songs placed here will force an item to be on one of the song locations even if shuffle_song_items is not set. This will completely override the starting items set on the randomizer generator GUI.

The term is the item you want to start with. The definition is how many of that item you want to start with. The number is not a string and should not be put in quotes.

Examples

Start with full wallet without Max Rupees setting:

"starting_items": {
    "Rupees": 99
}

Start with all shields:

"starting_items": {
    "Deku Shield": 1,
    "Hylian Shield": 1,
    "Mirror Shiled": 1
}

Please note there are two starting item sections, this section refers to the one after randomized_settings in a spoiler log. The starting items, starting equipment, and starting songs sections within the settings section have a different format, but as listing what falls under each here would be a long section, please instead generate a spoiler log using the GUI to see where items need to be listed.

Item Pool

This is a dictionary defining every item possible to place in the world. It is highly recommended that you do not set every possible item to a value in this dictionary. Primarily junk items because the randomizer often needs to generate new junk, but will not change any value you manually place in the item pool. This would make your plandomizer very rigid and can cause various issues if you try changing settings that change what, and how many items you start with, or that are available in the base pool.

You can also specify if you want to add to the base number, remove from the base number, or set the base number for the item. The default is to set the value. If you want to use the other options you'll need to set the definition to be another dictionary.

The term is the item you want to specify the number of in the pool. The definition is either:

  1. The number of that item you want in the pool
  2. A dictionary with a term of type set to any of the strings "add", "remove", or "set" and a term of count set to the number to modify by.

Examples

Set Mirror Shield to have 3 copies placed in the world:

"item_pool": {
    "Mirror Shield": 3
}

or

"item_pool": {
    "Mirror Shield": {
        "type": "set",
        "count": 3
    }
}

Add 3 Deku Shields to place in the world in addition to the ones already in the base pool:

"item_pool": {
    "Deku Shield": {
        "type": "add",
        "count": 3
    }
}

Dungeons

This dictionary lets you define which dungeons are vanilla and which are mq (master quest). You will have to set the number of MQ dungeons setting to match at least whatever master quest dungeons you define here. However, you do not have to define all of the dungeons and the rest will be defined by the randomizer generator instead.

The term is the name of the dungeon. The definitions is either the string "vanilla", the string "mq", or the string "random".

Examples

Set only Deku Tree to mq:

"dungeons": {
    "Deku Tree": "mq"
}

Set only Spirit Temple to vanilla, because you don't want to learn the second version of spirit logic:

"dungeons": {
    "Spirit Temple": "vanilla"
}

Set Dodongo's Cavern to random:

"dungeons": {
    "Dodongos Cavern": "random"
}

Trials

You will define which trials are active and which ones are inactive in this dictionary. You will have to set the number of trials to match at least the trials you define here. However, you do not have to define all of the trials and the rest will be defined by the randomizer generator instead.

The term is the name of the trial. The definition is either the string "active", the string "inactive", or the string "random".

Examples

Set forest, fire, and water trials as inactive:

"trials": {
    "Forest": "inactive",
    "Fire": "inactive",
    "Water": "inactive"
}

Set light trial to active, ensuring that 3 strength upgrades are required for fighting Ganon:

"trials": {
    "Light": "active"
}

Set water trial to random:

"trials": {
    "Water": "random"
}

Entrances

This dictionary defines how different entrances are linked together when using entrance randomizer. Entrances must be shuffled among their respective groups so you cannot use plandomizer to force a mixed entrance pool seed. You may wish to generate a entrance randomizer seed and use its spoiler log to ensure you use the correct names for the locations.

The term is the loading zone you pass through. The definition is:

  • For Dungeons and Interiors: a string with the name of the location you end up at
  • For Overworld: a dictionary with a term of region set to a string of the overworld region it leads to and a term of from set to a string of the loading zone in that region that you will appear out of.

Examples

Set Deku Tree entrance to Gerudo Training Grounds:

"entrances": {
    "KF Outside Deku Tree -> Deku Tree Lobby": {"region": "Gerudo Training Grounds Lobby", "from": "Gerudo Fortress"}
}

Set Hyrule Castle exit from Market to Lon Lon Ranch main entrance:

"entrances": {
    "Market -> Castle Grounds": {
        "region": "Lon Lon Ranch", 
        "from": "Hyrule Field"
    }
}

Locations

This dictionary handles what is probably the main feature of plandomizer. You can assign items to any location in the game world here. Which locations are available are heavily influenced by the settings chosen, so ensure you have the proper settings set.

The term is the name of the location. The definition is either:

  • A string of an item to place there.
  • A list containing multiple items to randomly choose from to place there.
  • A dictionary containing the term item containing one of the above two bullet points.
    • If making a multiworld plandomizer: the term player with the world number value of the player the item belongs to.
    • If the location is a shop: the term price with the rupee number value the item should cost. You cannot set scrub prices using plandomizer
    • If the item can be an ice trap: the term model set to a string of the item model it should appear as in the overworld.


Item names can also take advantage of the wildcard * and the not indicator !.

For example, this will guarantee Link starts with a medallion, Spirit Temple will always have a stone, and one of the shields can be found in Mido's House.

"locations": {
   "Links Pocket": "*Medallion",
   "Twinrova": "!Medallion",
   "KF Midos Top Left Chest": "*Shield"
}


Shop Location Numbers

Due to the odd way the shop items are stored in the game files, using shopsanity item placement is not very intuitive.

When using 1 item shopsanity, the number you use is 7 and is the bottom left item on the left side.
When using 2 items shopsanity, you also have number 5 which is the bottom right item on the left side.
When using 3 items shopsanity, you add on the number 8 which is the top left item on the left side.
When using 4 items shopsanity, you can now use all 4 numbers 5-8 for all of the left side items.

Shop Location Prices

When defining a shop location, rather than simply assigning a string of the item name to the location, you must define a dictionary with the properties item (a string of the item name) and price (a number). So for example, a shop item location will look something like this:

"KF Shop Item 7": {
    "item": "Light Arrows", 
    "price": 40
},

Note that, prior to Dev v6.0.41, plando shop prices were not properly considered in logic, so using any price above 99 may be risky.

As of Dev v6.0.41, If you try to set a price higher than 999, it will simply be capped to 999 so it won't be impossible to buy. However, you can actually plando negative prices, which will give the player the absolute value of the price. So if you plando a shop item to be -10 rupees, the player will be able to purchase it with any wallet size and it will give them 10 rupees. Due to reasons related to the binary numbers used to represent the prices in-game, the lowest possible price is -32768.

Special Item Groups

There are shortcut terms you can use for certain items when using plandomizer. They start with the # character. The ones that should work fine are:

#Bottle - Places a bottle and randomly chooses a contents for it
#Junk - Places a junk item (used by exclude locations)
#AdultTrade - Places the adult trade item without specifying which one

If you are feeling a little bit more daring, you can try:

#Vanilla - Places whatever was on that location in the original game (Dev v6.0.54 onwards). Also applies to MQ locations.
#MajorItem - Places a settings-dependent major item at that location (Dev v6.0.24 onwards). (Currently may try to place songs even when not shuffled and so may take a few retries.)
#Song - Places a song item
#NonWarpSong - Places non warp song item
#WarpSong - Places a warp song item
#JunkSong - Places Serenade or Prelude in non-entrance randomizer.
#Spell - Places one of the three spells
#Shield - Deku or Hylian. Doesn't include Mirror.
#HealthUpgrade - Heart Container or Piece of Heart

All of these should work, but only the first list have been extensively tested.

As of Dev v6.0.45, you can also define your own, custom item groups by adding a custom_groups dictionary to your plando. Within this dictionary you can define groups which contain a list of item names in brackets, and then use those group names as you would with other item groups.

Here is such an example, which will place a random sword in Mido's top left chest and a small key for water or shadow temple in his top right chest:

{
  "custom_groups": {
    "CustomList1": [ "Kokiri Sword", "Biggoron Sword", "Giants Knife" ],
    "CustomList2": [ "Small Key (Water Temple)", "Small Key (Shadow Temple)" ]
  },
  "locations": {
    "KF Midos Top Left Chest": "#CustomList1",
    "KF Midos Top Right Chest": "#CustomList2"
  }
}

Note that currently patterns do not work on custom groups (so, for example, you cannot do !#CustomList1) and custom groups cannot be nested.

Examples

Ready to fight Ganon after Mido's:

"locations": {
    "KF Midos Top Left Chest": "Bow",
    "KF Midos Top Right Chest": "Magic Meter",
    "KF Midos Bottom Left Chest": "Light Arrows",
    "KF Midos Bottom Right Chest": "Ice Trap"
}

Bottles in Mido's:

"locations": {
    "KF Midos Top Left Chest": "#Bottle",
    "KF Midos Top Right Chest": "#Bottle",
    "KF Midos Bottom Left Chest": "#Bottle",
    "KF Midos Bottom Right Chest": "#Bottle"
}

One step to fighting Ganon in the Kokiri Sword chest:

"locations": {
    "KF Kokiri Sword Chest": ["Bow", "Magic Meter", "Light Arrows"]
}

Setting shopsanity 1 item in Kokiri Shop to Ice Trap posing as Light Arrows:

"locations": {
    "KF Shop Item 7": {
        "item": "Ice Trap", 
        "price": 60,
        "model": "Light Arrows"
    }
}

Place player 2's Light Arrows in player 1's Kokiri Sword chest:

"locations": {
    "World 1": {
        "KF Kokiri Sword Chest": {
            "item": "Light Arrows",
            "player": 2
        }
    }
}

Hint Distribution Files

Hint distribution file format is similar to the old hard-coded dictionaries, plus new keys to offer finer control of different hint groups. The goal of this change is to facilitate easier sharing and updating of custom hint distributions for the different racing tournaments. An example with the Tournament distribution is provided below.

{
    "name":                  "tournament",
    "gui_name":              "Tournament",
    "description":           "Fixed number of hints for each type, contains duplicates, and only useful hints.",
    "add_locations":         [
        { "location": "Deku Theater Skull Mask", "types": ["always"] }
    ],
    "remove_locations":      [],
    "add_items":             [],
    "remove_items":          [],
    "dungeons_woth_limit":   2,
    "dungeons_barren_limit": 1,
    "named_items_required":  "True",
    "distribution":          {
        "trial":      {"order":  1, "weight": 0.0, "fixed":   0, "copies": 2},
        "always":     {"order":  2, "weight": 0.0, "fixed":   0, "copies": 2},
        "woth":       {"order":  3, "weight": 0.0, "fixed":   5, "copies": 2},
        "barren":     {"order":  4, "weight": 0.0, "fixed":   3, "copies": 2},
        "entrance":   {"order":  5, "weight": 0.0, "fixed":   4, "copies": 2},
        "sometimes":  {"order":  6, "weight": 0.0, "fixed": 100, "copies": 2},
        "random":     {"order":  7, "weight": 9.0, "fixed":   0, "copies": 2},
        "item":       {"order":  0, "weight": 0.0, "fixed":   0, "copies": 2},
        "song":       {"order":  0, "weight": 0.0, "fixed":   0, "copies": 2},
        "overworld":  {"order":  0, "weight": 0.0, "fixed":   0, "copies": 2},
        "dungeon":    {"order":  0, "weight": 0.0, "fixed":   0, "copies": 2},
        "junk":       {"order":  0, "weight": 0.0, "fixed":   0, "copies": 2},
        "named-item": {"order":  0, "weight": 0.0, "fixed":   0, "copies": 2}
    }
}

GUI names and tooltip descriptions are now defined with each distribution file. Tooltips are automatically parsed to add line returns as needed for the GUI.

Hint Type Distribution

The distribution key is a similar format to the previous dictionary. Each hint group must be listed with the following keys:

  • order: Integer to sort hint types from smallest to largest
  • weight: Same as hint type weight in balanced and similar hint distributions
  • fixed: Same as tournament distribution number of hints per world
  • copies: Same as count per hint in predefined distributions

Tournament-style fixed hints and weighted-style hints are defined together in the same distribution. Fixed hints are rolled first. Any remaining gossip stones are filled from a random choice of hint types with assigned weights. Checks exist to make sure there are enough gossip stones left for a given random hint type count per hint. Fixed hints do not have this safeguard and rely on the user not to overfill them. Using the tournament distribution as an example, fixed hints are rolled according to the defined order and fixed number. If any gossip stones remain, the random hint group is rolled as part of the weighted hint types (in this case the only one, so it is guaranteed upon exhaustion of all sometimes hints). Other built-in hint types with no fixed hints have non-zero orders for all types and weights equal to the old style weight, and all types have a fixed value of 0.

Dungeon Limits

Dungeon way of the hero and barren limitations are moved out of the hint generation functions into the distribution files. Values are identical in all built-in distributions except very_strong, which has a limit of 40 for both (equivalent to no limit).

Hint Type Requirements and Exclusions

Four new lists are provided to include or exclude hinted locations from different hint groups, as specified by the location name or filled item name. As seen in the tournament distribution, the add_locations key can be used to force a given location to be hinted by adding it to the always hint type. Locations can be added to (or removed from) any hint type. Likewise, the item keys allow for adding or removing locations to be hinted based on what items they contain. For example, to remove all songs from being hinted as way of the hero, the following would be utilized:

"remove_items": [
    { "item": "Zeldas Lullaby",     "types": ["woth"] },
    { "item": "Eponas Song",        "types": ["woth"] },
    { "item": "Sarias Song",        "types": ["woth"] },
    { "item": "Suns Song",          "types": ["woth"] },
    { "item": "Song of Time",       "types": ["woth"] },
    { "item": "Song of Storms",     "types": ["woth"] },
    { "item": "Minuet of Forest",   "types": ["woth"] },
    { "item": "Bolero of Fire",     "types": ["woth"] },
    { "item": "Serenade of Water",  "types": ["woth"] },
    { "item": "Requiem of Spirit",  "types": ["woth"] },
    { "item": "Nocturne of Shadow", "types": ["woth"] },
    { "item": "Prelude of Light",   "types": ["woth"] }
]

Alternately, if songsanity is disabled, the song locations could be removed from the woth hint type to achieve the same effect.

Way of the Hero and Barren hints cannot have locations added via `add_locations`. Additionally, Barren hints cannot be removed via `remove_locations`. This is to prevent situations where required items are in hinted barren areas. Using the song example again, a foolish Song of Storms that leads to a required item in Bottom of the Well would be confusing to players unfamiliar with the setting. Excluding from way of the hero means it won’t be hinted, not that the game is actively lying to you.

Barren hints can be added or removed from consideration for specific items via the add_items and remove_items lists. This affects not just hints, but also the :barren_regions list in the spoiler log. In contrast, way of the hero items will still be listed in the :woth_locations section regardless of hint distribution changes. Forced barren items that are logically required still show up in the :woth_locations list if required by the seed.

Plando Support

The hint_dist_user setting takes a hint distribution dictionary as defined by the built-in hint distribution files. If specified, it overrides the GUI-selected hint distribution. Internally, the distribution is defined as custom.

Example Plando

The attached plando

  • Requires a “random”-type location hint for the location containing Lens of Truth
  • Adds shooting the sun in Lake Hylia as an always hint with custom text
  • Removes Frog Ocarina Game and 40 Skulls as always hints
  • Keeps other “conditional” always hints from Standard weekly settings, including Skull Mask
  • Adds the location with Zelda’s Lullaby as an always hint
  • Removes all other song locations from way of the hero and sometimes hint types
  • Forces Rutos Letter to be considered foolish, and places it outside Ganon’s Castle to verify
  • Excludes Biggoron Sword from foolish hints, and places it in the Haunted Wasteland to verify

and applies a custom hint distribution as follows:

Fixed Hints

(in order)

  • Always and Trials hints at 2 stones/hint
  • 1 Named Item hint for Lens of Truth at 2 stones/hint (as required by named_items_required)
  • 3 Way of the Hero hints at 2 stones/hint
  • 2 Foolish hints at 1 stone/hint
  • 4 Entrance hints at 2 stones/hint
  • 5 Sometimes hints at 1 stone/hint
Weighted Hints

On weekly settings, this is 27-29 gossip stones filled, depending on if Zelda’s Lullaby is on Ocarina of Time. The remaining 11-13 stones draw hints from weighted hint types as follows:

  • Random (0.5 weight, 2 stones/hint)
  • Item (1.0 weight, 2 stones/hint)
  • Song (2.0 weight, 2 stones/hint)
  • Overworld (3.0 weight, 2 stones/hint)
  • Dungeon (1.0 weight, 2 stones/hint)
  • Junk (0.5 weight, 1 stone/hint)

At least 1 junk hint will be added due to the odd number of remaining stones.

{
  "settings":            {
    "item_hints": [
      "Lens of Truth"
    ],
    "hint_dist_user": {
      "name":                  "custom",
      "gui_name":              "Plando Test Hint Distribution",
      "description":           "for debugging",
      "add_locations":         [
          { "location": "LH Sun",                  "types": ["always"], "text": "those who #blot out the sun# will find" },
          { "location": "Deku Theater Skull Mask", "types": ["always"] }
      ],
      "remove_locations":      [
          { "location": "ZR Frogs Ocarina Game",        "types": ["always"] },
          { "location": "Kak 40 Gold Skulltula Reward", "types": ["always"] }
      ],
      "add_items":             [
          { "item": "Zeldas Lullaby",     "types": ["always"] },
          { "item": "Rutos Letter",       "types": ["barren"] }
      ],
      "remove_items":          [
          { "item": "Eponas Song",        "types": ["woth", "sometimes"] },
          { "item": "Sarias Song",        "types": ["woth", "sometimes"] },
          { "item": "Suns Song",          "types": ["woth", "sometimes"] },
          { "item": "Song of Time",       "types": ["woth", "sometimes"] },
          { "item": "Song of Storms",     "types": ["woth", "sometimes"] },
          { "item": "Minuet of Forest",   "types": ["woth", "sometimes"] },
          { "item": "Bolero of Fire",     "types": ["woth", "sometimes"] },
          { "item": "Serenade of Water",  "types": ["woth", "sometimes"] },
          { "item": "Requiem of Spirit",  "types": ["woth", "sometimes"] },
          { "item": "Nocturne of Shadow", "types": ["woth", "sometimes"] },
          { "item": "Prelude of Light",   "types": ["woth", "sometimes"] },
          { "item": "Biggoron Sword",     "types": ["barren"] }
      ],
      "dungeons_woth_limit":   2,
      "dungeons_barren_limit": 1,
      "named_items_required":  "True",
      "distribution":          {
          "trial":      {"order":  1, "weight": 0.0, "fixed":   0, "copies": 2},
          "always":     {"order":  2, "weight": 0.0, "fixed":   0, "copies": 2},
          "woth":       {"order":  3, "weight": 0.0, "fixed":   3, "copies": 2},
          "barren":     {"order":  4, "weight": 0.0, "fixed":   2, "copies": 1},
          "entrance":   {"order":  5, "weight": 0.0, "fixed":   4, "copies": 2},
          "sometimes":  {"order":  6, "weight": 0.0, "fixed":   5, "copies": 1},
          "random":     {"order":  7, "weight": 0.5, "fixed":   0, "copies": 2},
          "item":       {"order":  8, "weight": 1.0, "fixed":   0, "copies": 2},
          "song":       {"order":  9, "weight": 2.0, "fixed":   0, "copies": 2},
          "overworld":  {"order": 10, "weight": 3.0, "fixed":   0, "copies": 2},
          "dungeon":    {"order": 11, "weight": 1.0, "fixed":   0, "copies": 2},
          "junk":       {"order": 12, "weight": 0.5, "fixed":   0, "copies": 1},
          "named-item": {"order": 13, "weight": 0.0, "fixed":   0, "copies": 2}
      }
    }
  },
  "randomized_settings": {},
  "starting_items":      {},
  "item_pool":           {},
  "entrances":           {},
  "locations":           {
      "OGC Great Fairy Reward": "Rutos Letter",
      "Wasteland Chest": "Biggoron Sword"
  }
}

Item Hints for Bingo

The item_hints plando setting contains a list of items as named in ItemList.py to be added as “random” location hints. This is outside of the hint distribution setting. Built-in hint distributions assume copies per hint is the same as the sometimes category equivalent of the original distribution. The named_items_required hint distribution key controls if named item hints are treated as always hints. In contrast to always hints, an error will be thrown if any required named item hint cannot be placed.

Plando or third party hint distribution files can specify fixed or weighted named-item group hints if named_items_required is false.

Note that add_items provides similar functionality to the item_hints plando key if an item is added to the always group. The reason for duplication of this feature is to provide an easier interface for Bingo races desiring hinted tile goals without building a whole hint distribution from scratch.

Example Bingo Plando

The example plando below:

  • Requires two separate strength upgrades to be hinted
  • Requires Lens of Truth to be hinted
  • Modifies the item pool to contain 3 empty bottles, one of which will be hinted.
{
    "settings": {
      "item_hints": [
            "Progressive Strength Upgrade",
            "Progressive Strength Upgrade",
            "Lens of Truth",
            "Bottle"
        ]
    },
    "randomized_settings": {},
    "starting_items":      {},
    "item_pool":           {
        "Bottle": 3
    },
    "entrances":           {},
    "locations":           {}
}

Gossip Stones

This dictionary is just evil. It lets you replace the Gossip Stone text with any text you wish. Unlike normal randomizer, this text can lie and mislead the player. It is recommended that you use it more for inside jokes, or different types of hints than you'd normally get using the randomizer to keep the plandomizer fun for the player. Gossip stones set here will not be taken into consideration for hints by logic.

The term is the name of the Gossip Stone. The definition is a dictionary with the term text.

  • Any text you surround with # can also be colored. If you wish to do this add another term to the inner dictionary with the term colors and set it to a list containing strings of the colors you wish to use. You can have multiple groups of text surrounded by # and each one can be a different color.

Valid Colors

White
Red
Green
Blue
Light Blue
Pink
Yellow
Black

Special Characters

As of Dev v6.0.50, you can also use some special characters within your hints. In terms of normal characters, you can use within your hint text the following just by putting them within the string as usual: À, Á, Â, Ä, Ç, È, É, Ê, Ë, Ï, Ô, Ö, Ù, Û, Ü, the lowercase versions of all previous characters, and ß.

You can also specify codes for special, in-game button characters using Unicode values. Reference the following table for the value for each button character, and then it can be specified within your hint text with \u00xx, where xx is the value from the table. For example, the A button has a value of 9F, so it would be printed using \u009F within your hint. Here you can see what these characters look like in-game.

Code 9F A0 A1 A2 A3 A4 A5 A6 A7 A8 A9 AA
Button Displayed A B C L R Z C-up C-down C-left C-right Down arrow Joystick


Examples

Just white text:

"gossip_stones": {
    "DMC (Bombable Wall)": {
        "text": "It's hot in here!"
    }
}

Colored text:

"gossip_stones": {
    "DMC (Bombable Wall)": {
        "text": "They say #Luigi# was put in this game instead of Super #Mario# 64",
        "colors": ["Green", "Red"]
    }
}

Helpful Tutorial Message:

"gossip_stones": {
    "KF (Outside Storms)": { "text": "To target, press \u00A4" }
}

Appreciation:

"gossip_stones": {
    "KF (Deku Tree Right)": { "text": "Dampé is a pretty cool guy." }
}

Cosmetics and Sounds

As of version 6.0 users can select both their cosmetics and sounds with a cosmetics plandomizer file. Just like how the spoiler log syntax is used to create a plandomizer file for locations, entrances, etcetera, the cosmetics log syntax is used to create a cosmetics plandomizer file. This plandomizer file has to be inserted separately, because cosmetics and sounds are typically (re-)applied after the patching process. Make sure that the file is saved as a .json file. To insert a cosmetics plando, toggle Enable Cosmetics Plandomizer (Advanced) on the ROM Options tab and insert it in the field that will appear below. Note; if you also toggled Enable Plandomizer (Advanced), then there will be two fields.

Cosmeticsplandoweb.png

Cosmetics

Note: Custom cosmetics colors can be chosen through the GUI as well, so it is not needed to specify these in the plandomizer.

There are two ways in which you can plandomize cosmetics. The first is to specify colors through hex values. This gives you the freedom to select any color in the color spectrum for any of the cosmetics options. The second method is to use presets built into the randomizer. These are the options found in the dropdown bars in the GUI and include options such as "Kokiri Green", "Random Choice" and "Magenta". Keep in mind that each cosmetic option has its own set of preset colors and that they can't be used interchangeably. For example, tunics have the preset color "Majora Purple", but gauntlets do not, so that color cannot be set for gauntlets unless you specify hex values. Because of this limitation it is recommended that users specify hex values. The hex values associated with the preset colors can be found here. The correct formatting for the plandomizer file is to take the three double-character codes that follow an "x" and put them next to each other in the order in which they appear, preceded by a "#". For example the hex value for "Kokiri Green" in the correct format is #1E691B. It's case-insensitive and the order matters.

Some cosmetics can be made to cycle through the colors of the rainbow. This cannot be done with hex values and must be specified using the "Rainbow" preset. This is currently only supported for Navi, Bombchu trail, Boomerang trail and Sword trail cosmetics.

The sword trail duration option is unique in that you don't specify a string but an integer. This integer denotes for how many frames the sword trail will linger with the presets being "Default" (= 4), "Long" (= 10), "Very Long" (= 15) and "Lightsaber" (= 20). Normal gameplay is 20 frames per second, so "Lightsaber" will leave a trail for roughly 1 second. This integer can be set higher than 20, but you can expect lag if the number is set extremely high.

Examples

Set the tunic colors using hex values:

{
  "settings":         {
    "kokiri_color":                "#ffffff",
    "goron_color":                 "#1E691B",
    "zora_color":                  "#AAaaAA"
  }
}

Set tunic colors using built-in color options:

{
  "settings":         {
    "kokiri_color":                "Goron Red",
    "goron_color":                 "Majora Purple",
    "zora_color":                  "Completely Random"
  }
}

Set rainbow sword trail with a duration of 1 second:

{
  "settings":         {
    "sword_trail_color_inner":     "Rainbow",
    "sword_trail_color_outer":     "Rainbow",
    "sword_trail_duration":        20
  }
}

Sounds

To set sound effects, choose the sound you want to use as the value (right column) and the event when it plays as the key (left column). A list of sounds effects can be found here (use the keyword column). Valid strings for the plandomizer file are found in the keyword column. For vanilla sound effects choose default, except for sfx_low_hp and sfx_ocarina where the vanilla sounds are called soft-beep and ocarina respectively. completely-random, random-ear-safe, random-choice, and none are also valid choices.

To set background music, choose the location where you want the music to be played as the key (left column) and the music that will be played as the corresponding value (right column). A list of valid strings can be found here. Note that these strings are valid both as key and value. Use None for no background music.

Examples

Set sound effects:

{
  "settings":         {
    "sfx_low_hp":                  "soft-beep",
    "sfx_navi_overworld":          "bow-twang",
    "sfx_navi_enemy":              "navi-hey",
    "sfx_menu_cursor":             "ruto-wiggle",
    "sfx_menu_select":             "talon-snore",
    "sfx_horse_neigh":             "default",
    "sfx_nightfall":               "completely-random",
    "sfx_hover_boots":             "child-owo",
    "sfx_ocarina":                 "malon"
  }
}

Set background music:

{
  "bgm":         {
    "Hyrule Field":         "None", 
    "Temple of Time":       "Shop",
    "Gerudo Valley":        "Ingo Theme"
  }
}

It is also possible to plando custom music. In this case what you insert as the track name is whatever is on the first line of the .meta file (open with any text editor). If this is done incorrectly, then the randomizer will skip it and not output an error message. This means that some other track will be placed there instead without your knowledge.

Common Errors

You're very likely to run into many errors while trying to make a plandomizer. These explanations should help you with some of the more cryptic ones. You can also narrow down the source of the error code by running small sections of the original plandomizer at a time until you get the error message.

Not A Valid JSON Format

See this section

Game Unbeatable

The randomizer generator could not place items following your defined settings. You've created a situation that is not logically possible to complete.

Sometimes this is just bad luck and you have to try generating again, but if you continuously get the same exact error messages over and over, you most likely need to modify your settings or where items are placed in the world. Think carefully about what logical problems your settings and item placements might have. Refer to the Release logic files or the Dev logic files depending on which one you are using to try to help find any you have forgotten.

Of course you can always come to the #plando-support channel on the Discord to ask for help if you're feeling stuck. We can usually point you in the right direction or find the exact issue causing the error.

Cannot Choose From An Empty Sequence

This means that an item in your locations dictionary was not spelled correctly (e.g. Light Arrow instead of Light Arrows).

My Plandomized Track Is Not Playing

Make sure that there are no spelling errors. If you're using custom music, then make sure that you are using the track name that is inside the .meta file.