This commit is contained in:
Chris Wilson 2021-06-15 21:18:24 -04:00
commit 3ee88fd8fe
7 changed files with 569 additions and 602 deletions

View File

@ -23,7 +23,9 @@ from worlds.alttp.Items import item_name_groups, item_table
from worlds.alttp import Bosses from worlds.alttp import Bosses
from worlds.alttp.Text import TextTable from worlds.alttp.Text import TextTable
from worlds.alttp.Regions import location_table, key_drop_data from worlds.alttp.Regions import location_table, key_drop_data
from worlds.AutoWorld import AutoWorldRegister
categories = set(AutoWorldRegister.world_types)
def mystery_argparse(): def mystery_argparse():
parser = argparse.ArgumentParser(add_help=False) parser = argparse.ArgumentParser(add_help=False)
@ -61,9 +63,11 @@ def mystery_argparse():
args.plando: typing.Set[str] = {arg.strip().lower() for arg in args.plando.split(",")} args.plando: typing.Set[str] = {arg.strip().lower() for arg in args.plando.split(",")}
return args return args
def get_seed_name(random): def get_seed_name(random):
return f"{random.randint(0, pow(10, seeddigits) - 1)}".zfill(seeddigits) return f"{random.randint(0, pow(10, seeddigits) - 1)}".zfill(seeddigits)
def main(args=None, callback=ERmain): def main(args=None, callback=ERmain):
if not args: if not args:
args = mystery_argparse() args = mystery_argparse()
@ -79,14 +83,14 @@ def main(args=None, callback=ERmain):
weights_cache = {} weights_cache = {}
if args.weights: if args.weights:
try: try:
weights_cache[args.weights] = get_weights(args.weights) weights_cache[args.weights] = read_weights_yaml(args.weights)
except Exception as e: except Exception as e:
raise ValueError(f"File {args.weights} is destroyed. Please fix your yaml.") from e raise ValueError(f"File {args.weights} is destroyed. Please fix your yaml.") from e
print(f"Weights: {args.weights} >> " print(f"Weights: {args.weights} >> "
f"{get_choice('description', weights_cache[args.weights], 'No description specified')}") f"{get_choice('description', weights_cache[args.weights], 'No description specified')}")
if args.meta: if args.meta:
try: try:
weights_cache[args.meta] = get_weights(args.meta) weights_cache[args.meta] = read_weights_yaml(args.meta)
except Exception as e: except Exception as e:
raise ValueError(f"File {args.meta} is destroyed. Please fix your yaml.") from e raise ValueError(f"File {args.meta} is destroyed. Please fix your yaml.") from e
meta_weights = weights_cache[args.meta] meta_weights = weights_cache[args.meta]
@ -99,7 +103,7 @@ def main(args=None, callback=ERmain):
if path: if path:
try: try:
if path not in weights_cache: if path not in weights_cache:
weights_cache[path] = get_weights(path) weights_cache[path] = read_weights_yaml(path)
print(f"P{player} Weights: {path} >> " print(f"P{player} Weights: {path} >> "
f"{get_choice('description', weights_cache[path], 'No description specified')}") f"{get_choice('description', weights_cache[path], 'No description specified')}")
@ -254,7 +258,7 @@ def main(args=None, callback=ERmain):
callback(erargs, seed) callback(erargs, seed)
def get_weights(path): def read_weights_yaml(path):
try: try:
if urllib.parse.urlparse(path).scheme: if urllib.parse.urlparse(path).scheme:
yaml = str(urllib.request.urlopen(path).read(), "utf-8") yaml = str(urllib.request.urlopen(path).read(), "utf-8")
@ -342,19 +346,6 @@ goals = {
'ice_rod_hunt': 'icerodhunt', 'ice_rod_hunt': 'icerodhunt',
} }
# remove sometime before 1.0.0, warn before
legacy_boss_shuffle_options = {
# legacy, will go away:
'simple': 'basic',
'random': 'full',
'normal': 'full'
}
legacy_goals = {
'dungeons': 'bosses',
'fast_ganon': 'crystals',
}
def roll_percentage(percentage: typing.Union[int, float]) -> bool: def roll_percentage(percentage: typing.Union[int, float]) -> bool:
"""Roll a percentage chance. """Roll a percentage chance.
@ -382,13 +373,12 @@ def roll_linked_options(weights: dict) -> dict:
try: try:
if roll_percentage(option_set["percentage"]): if roll_percentage(option_set["percentage"]):
logging.debug(f"Linked option {option_set['name']} triggered.") logging.debug(f"Linked option {option_set['name']} triggered.")
if "options" in option_set: new_options = option_set["options"]
weights = update_weights(weights, option_set["options"], "Linked", option_set["name"]) for category_name, category_options in new_options.items():
if "rom_options" in option_set: currently_targeted_weights = weights
rom_weights = weights.get("rom", dict()) if category_name:
rom_weights = update_weights(rom_weights, option_set["rom_options"], "Linked Rom", currently_targeted_weights = currently_targeted_weights[category_name]
option_set["name"]) update_weights(currently_targeted_weights, category_options, "Linked", option_set["name"])
weights["rom"] = rom_weights
else: else:
logging.debug(f"linked option {option_set['name']} skipped.") logging.debug(f"linked option {option_set['name']} skipped.")
except Exception as e: except Exception as e:
@ -402,36 +392,32 @@ def roll_triggers(weights: dict) -> dict:
weights["_Generator_Version"] = "Archipelago" # Some means for triggers to know if the seed is on main or doors. weights["_Generator_Version"] = "Archipelago" # Some means for triggers to know if the seed is on main or doors.
for i, option_set in enumerate(weights["triggers"]): for i, option_set in enumerate(weights["triggers"]):
try: try:
currently_targeted_weights = weights
category = option_set.get("option_category", None)
if category:
currently_targeted_weights = currently_targeted_weights[category]
key = get_choice("option_name", option_set) key = get_choice("option_name", option_set)
if key not in weights: if key not in currently_targeted_weights:
logging.warning(f'Specified option name {option_set["option_name"]} did not ' logging.warning(f'Specified option name {option_set["option_name"]} did not '
f'match with a root option. ' f'match with a root option. '
f'This is probably in error.') f'This is probably in error.')
trigger_result = get_choice("option_result", option_set) trigger_result = get_choice("option_result", option_set)
result = get_choice(key, weights) result = get_choice(key, currently_targeted_weights)
weights[key] = result currently_targeted_weights[key] = result
if result == trigger_result and roll_percentage(get_choice("percentage", option_set, 100)): if result == trigger_result and roll_percentage(get_choice("percentage", option_set, 100)):
if "options" in option_set: for category_name, category_options in option_set["options"].items():
weights = update_weights(weights, option_set["options"], "Triggered", option_set["option_name"]) currently_targeted_weights = weights
if category_name:
if "rom_options" in option_set: currently_targeted_weights = currently_targeted_weights[category_name]
rom_weights = weights.get("rom", dict()) update_weights(currently_targeted_weights, category_options, "Triggered", option_set["option_name"])
rom_weights = update_weights(rom_weights, option_set["rom_options"], "Triggered Rom",
option_set["option_name"])
weights["rom"] = rom_weights
except Exception as e: except Exception as e:
raise ValueError(f"Your trigger number {i+1} is destroyed. " raise ValueError(f"Your trigger number {i + 1} is destroyed. "
f"Please fix your triggers.") from e f"Please fix your triggers.") from e
return weights return weights
def get_plando_bosses(boss_shuffle: str, plando_options: typing.Set[str]) -> str: def get_plando_bosses(boss_shuffle: str, plando_options: typing.Set[str]) -> str:
if boss_shuffle in legacy_boss_shuffle_options:
new_boss_shuffle = legacy_boss_shuffle_options[boss_shuffle]
logging.warning(f"Boss shuffle {boss_shuffle} is deprecated, "
f"please use {new_boss_shuffle} instead")
return new_boss_shuffle
if boss_shuffle in boss_shuffle_options: if boss_shuffle in boss_shuffle_options:
return boss_shuffle_options[boss_shuffle] return boss_shuffle_options[boss_shuffle]
elif "bosses" in plando_options: elif "bosses" in plando_options:
@ -439,10 +425,6 @@ def get_plando_bosses(boss_shuffle: str, plando_options: typing.Set[str]) -> str
remainder_shuffle = "none" # vanilla remainder_shuffle = "none" # vanilla
bosses = [] bosses = []
for boss in options: for boss in options:
if boss in legacy_boss_shuffle_options:
remainder_shuffle = legacy_boss_shuffle_options[boss_shuffle]
logging.warning(f"Boss shuffle {boss} is deprecated, "
f"please use {remainder_shuffle} instead")
if boss in boss_shuffle_options: if boss in boss_shuffle_options:
remainder_shuffle = boss_shuffle_options[boss] remainder_shuffle = boss_shuffle_options[boss]
elif "-" in boss: elif "-" in boss:
@ -512,10 +494,12 @@ def roll_settings(weights: dict, plando_options: typing.Set[str] = frozenset(("b
ret.name = get_choice('name', weights) ret.name = get_choice('name', weights)
ret.accessibility = get_choice('accessibility', weights) ret.accessibility = get_choice('accessibility', weights)
ret.progression_balancing = get_choice('progression_balancing', weights, True) ret.progression_balancing = get_choice('progression_balancing', weights, True)
ret.game = get_choice("game", weights, "A Link to the Past") ret.game = get_choice("game", weights)
if ret.game not in weights:
raise Exception(f"No game options for selected game \"{ret.game}\" found.")
game_weights = weights[ret.game]
ret.local_items = set() ret.local_items = set()
for item_name in weights.get('local_items', []): for item_name in game_weights.get('local_items', []):
items = item_name_groups.get(item_name, {item_name}) items = item_name_groups.get(item_name, {item_name})
for item in items: for item in items:
if item in lookup_any_item_name_to_id: if item in lookup_any_item_name_to_id:
@ -524,7 +508,7 @@ def roll_settings(weights: dict, plando_options: typing.Set[str] = frozenset(("b
raise Exception(f"Could not force item {item} to be world-local, as it was not recognized.") raise Exception(f"Could not force item {item} to be world-local, as it was not recognized.")
ret.non_local_items = set() ret.non_local_items = set()
for item_name in weights.get('non_local_items', []): for item_name in game_weights.get('non_local_items', []):
items = item_name_groups.get(item_name, {item_name}) items = item_name_groups.get(item_name, {item_name})
for item in items: for item in items:
if item in lookup_any_item_name_to_id: if item in lookup_any_item_name_to_id:
@ -532,7 +516,7 @@ def roll_settings(weights: dict, plando_options: typing.Set[str] = frozenset(("b
else: else:
raise Exception(f"Could not force item {item} to be world-non-local, as it was not recognized.") raise Exception(f"Could not force item {item} to be world-non-local, as it was not recognized.")
inventoryweights = weights.get('startinventory', {}) inventoryweights = game_weights.get('start_inventory', {})
startitems = [] startitems = []
for item in inventoryweights.keys(): for item in inventoryweights.keys():
itemvalue = get_choice(item, inventoryweights) itemvalue = get_choice(item, inventoryweights)
@ -542,33 +526,32 @@ def roll_settings(weights: dict, plando_options: typing.Set[str] = frozenset(("b
elif itemvalue: elif itemvalue:
startitems.append(item) startitems.append(item)
ret.startinventory = startitems ret.startinventory = startitems
ret.start_hints = set(weights.get('start_hints', [])) ret.start_hints = set(game_weights.get('start_hints', []))
if ret.game == "A Link to the Past": if ret.game == "A Link to the Past":
roll_alttp_settings(ret, weights, plando_options) roll_alttp_settings(ret, game_weights, plando_options)
elif ret.game == "Hollow Knight": elif ret.game == "Hollow Knight":
for option_name, option in Options.hollow_knight_options.items(): for option_name, option in Options.hollow_knight_options.items():
setattr(ret, option_name, option.from_any(get_choice(option_name, weights, True))) setattr(ret, option_name, option.from_any(get_choice(option_name, game_weights, True)))
elif ret.game == "Factorio": elif ret.game == "Factorio":
for option_name, option in Options.factorio_options.items(): for option_name, option in Options.factorio_options.items():
if option_name in weights: if option_name in game_weights:
if issubclass(option, Options.OptionDict): # get_choice should probably land in the Option class if issubclass(option, Options.OptionDict): # get_choice should probably land in the Option class
setattr(ret, option_name, option.from_any(weights[option_name])) setattr(ret, option_name, option.from_any(game_weights[option_name]))
else: else:
setattr(ret, option_name, option.from_any(get_choice(option_name, weights))) setattr(ret, option_name, option.from_any(get_choice(option_name, game_weights)))
else: else:
setattr(ret, option_name, option(option.default)) setattr(ret, option_name, option(option.default))
elif ret.game == "Minecraft": elif ret.game == "Minecraft":
for option_name, option in Options.minecraft_options.items(): for option_name, option in Options.minecraft_options.items():
if option_name in weights: if option_name in game_weights:
setattr(ret, option_name, option.from_any(get_choice(option_name, weights))) setattr(ret, option_name, option.from_any(get_choice(option_name, game_weights)))
else: else:
setattr(ret, option_name, option(option.default)) setattr(ret, option_name, option(option.default))
# bad hardcoded behavior to make this work for now # bad hardcoded behavior to make this work for now
ret.plando_connections = [] ret.plando_connections = []
if "connections" in plando_options: if "connections" in plando_options:
options = weights.get("plando_connections", []) options = game_weights.get("plando_connections", [])
for placement in options: for placement in options:
if roll_percentage(get_choice("percentage", placement, 100)): if roll_percentage(get_choice("percentage", placement, 100)):
ret.plando_connections.append(PlandoConnection( ret.plando_connections.append(PlandoConnection(
@ -630,9 +613,6 @@ def roll_alttp_settings(ret: argparse.Namespace, weights, plando_options):
goal = get_choice('goals', weights, 'ganon') goal = get_choice('goals', weights, 'ganon')
if goal in legacy_goals:
logging.warning(f"Goal {goal} is depcrecated, please use {legacy_goals[goal]} instead.")
goal = legacy_goals[goal]
ret.goal = goals[goal] ret.goal = goals[goal]
# TODO consider moving open_pyramid to an automatic variable in the core roller, set to True when # TODO consider moving open_pyramid to an automatic variable in the core roller, set to True when
@ -649,7 +629,8 @@ def roll_alttp_settings(ret: argparse.Namespace, weights, plando_options):
ret.triforce_pieces_available = int(round(ret.triforce_pieces_required * percentage, 0)) ret.triforce_pieces_available = int(round(ret.triforce_pieces_required * percentage, 0))
# vanilla mode (specify how many pieces are) # vanilla mode (specify how many pieces are)
elif extra_pieces == 'available': elif extra_pieces == 'available':
ret.triforce_pieces_available = Options.TriforcePieces.from_any(get_choice('triforce_pieces_available', weights, 30)) ret.triforce_pieces_available = Options.TriforcePieces.from_any(
get_choice('triforce_pieces_available', weights, 30))
# required pieces + fixed extra # required pieces + fixed extra
elif extra_pieces == 'extra': elif extra_pieces == 'extra':
extra_pieces = max(0, int(get_choice('triforce_pieces_extra', weights, 10))) extra_pieces = max(0, int(get_choice('triforce_pieces_extra', weights, 10)))
@ -678,7 +659,6 @@ def roll_alttp_settings(ret: argparse.Namespace, weights, plando_options):
ret.enemy_shuffle = bool(get_choice('enemy_shuffle', weights, False)) ret.enemy_shuffle = bool(get_choice('enemy_shuffle', weights, False))
ret.killable_thieves = get_choice('killable_thieves', weights, False) ret.killable_thieves = get_choice('killable_thieves', weights, False)
ret.tile_shuffle = get_choice('tile_shuffle', weights, False) ret.tile_shuffle = get_choice('tile_shuffle', weights, False)
ret.bush_shuffle = get_choice('bush_shuffle', weights, False) ret.bush_shuffle = get_choice('bush_shuffle', weights, False)
@ -790,49 +770,43 @@ def roll_alttp_settings(ret: argparse.Namespace, weights, plando_options):
get_choice("direction", placement, "both") get_choice("direction", placement, "both")
)) ))
if 'rom' in weights:
romweights = weights['rom']
ret.sprite_pool = romweights['sprite_pool'] if 'sprite_pool' in romweights else [] ret.sprite_pool = weights.get('sprite_pool', [])
ret.sprite = get_choice('sprite', romweights, "Link") ret.sprite = get_choice('sprite', weights, "Link")
if 'random_sprite_on_event' in romweights: if 'random_sprite_on_event' in weights:
randomoneventweights = romweights['random_sprite_on_event'] randomoneventweights = weights['random_sprite_on_event']
if get_choice('enabled', randomoneventweights, False): if get_choice('enabled', randomoneventweights, False):
ret.sprite = 'randomon' ret.sprite = 'randomon'
ret.sprite += '-hit' if get_choice('on_hit', randomoneventweights, True) else '' ret.sprite += '-hit' if get_choice('on_hit', randomoneventweights, True) else ''
ret.sprite += '-enter' if get_choice('on_enter', randomoneventweights, False) else '' ret.sprite += '-enter' if get_choice('on_enter', randomoneventweights, False) else ''
ret.sprite += '-exit' if get_choice('on_exit', randomoneventweights, False) else '' ret.sprite += '-exit' if get_choice('on_exit', randomoneventweights, False) else ''
ret.sprite += '-slash' if get_choice('on_slash', randomoneventweights, False) else '' ret.sprite += '-slash' if get_choice('on_slash', randomoneventweights, False) else ''
ret.sprite += '-item' if get_choice('on_item', randomoneventweights, False) else '' ret.sprite += '-item' if get_choice('on_item', randomoneventweights, False) else ''
ret.sprite += '-bonk' if get_choice('on_bonk', randomoneventweights, False) else '' ret.sprite += '-bonk' if get_choice('on_bonk', randomoneventweights, False) else ''
ret.sprite = 'randomonall' if get_choice('on_everything', randomoneventweights, False) else ret.sprite ret.sprite = 'randomonall' if get_choice('on_everything', randomoneventweights, False) else ret.sprite
ret.sprite = 'randomonnone' if ret.sprite == 'randomon' else ret.sprite ret.sprite = 'randomonnone' if ret.sprite == 'randomon' else ret.sprite
if (not ret.sprite_pool or get_choice('use_weighted_sprite_pool', randomoneventweights, False)) \ if (not ret.sprite_pool or get_choice('use_weighted_sprite_pool', randomoneventweights, False)) \
and 'sprite' in romweights: # Use sprite as a weighted sprite pool, if a sprite pool is not already defined. and 'sprite' in weights: # Use sprite as a weighted sprite pool, if a sprite pool is not already defined.
for key, value in romweights['sprite'].items(): for key, value in weights['sprite'].items():
if key.startswith('random'): if key.startswith('random'):
ret.sprite_pool += ['random'] * int(value) ret.sprite_pool += ['random'] * int(value)
else: else:
ret.sprite_pool += [key] * int(value) ret.sprite_pool += [key] * int(value)
ret.disablemusic = get_choice('disablemusic', romweights, False) ret.disablemusic = get_choice('disablemusic', weights, False)
ret.triforcehud = get_choice('triforcehud', romweights, 'hide_goal') ret.triforcehud = get_choice('triforcehud', weights, 'hide_goal')
ret.quickswap = get_choice('quickswap', romweights, True) ret.quickswap = get_choice('quickswap', weights, True)
ret.fastmenu = get_choice('menuspeed', romweights, "normal") ret.fastmenu = get_choice('menuspeed', weights, "normal")
ret.reduceflashing = get_choice('reduceflashing', romweights, False) ret.reduceflashing = get_choice('reduceflashing', weights, False)
ret.heartcolor = get_choice('heartcolor', romweights, "red") ret.heartcolor = get_choice('heartcolor', weights, "red")
ret.heartbeep = convert_to_on_off(get_choice('heartbeep', romweights, "normal")) ret.heartbeep = convert_to_on_off(get_choice('heartbeep', weights, "normal"))
ret.ow_palettes = get_choice('ow_palettes', romweights, "default") ret.ow_palettes = get_choice('ow_palettes', weights, "default")
ret.uw_palettes = get_choice('uw_palettes', romweights, "default") ret.uw_palettes = get_choice('uw_palettes', weights, "default")
ret.hud_palettes = get_choice('hud_palettes', romweights, "default") ret.hud_palettes = get_choice('hud_palettes', weights, "default")
ret.sword_palettes = get_choice('sword_palettes', romweights, "default") ret.sword_palettes = get_choice('sword_palettes', weights, "default")
ret.shield_palettes = get_choice('shield_palettes', romweights, "default") ret.shield_palettes = get_choice('shield_palettes', weights, "default")
ret.link_palettes = get_choice('link_palettes', romweights, "default") ret.link_palettes = get_choice('link_palettes', weights, "default")
else:
ret.quickswap = True
ret.sprite = "Link"
if __name__ == '__main__': if __name__ == '__main__':

View File

@ -66,7 +66,7 @@ original_tech = technologies["{{original_tech_name}}"]
new_tree_copy = table.deepcopy(template_tech) new_tree_copy = table.deepcopy(template_tech)
new_tree_copy.name = "ap-{{ tech_table[original_tech_name] }}-"{# use AP ID #} new_tree_copy.name = "ap-{{ tech_table[original_tech_name] }}-"{# use AP ID #}
prep_copy(new_tree_copy, original_tech) prep_copy(new_tree_copy, original_tech)
{% if tech_cost != 1 %} {% if tech_cost_scale != 1 %}
new_tree_copy.unit.count = math.max(1, math.floor(new_tree_copy.unit.count * {{ tech_cost_scale }})) new_tree_copy.unit.count = math.max(1, math.floor(new_tree_copy.unit.count * {{ tech_cost_scale }}))
{% endif %} {% endif %}
{%- if item_name in tech_table and visibility -%} {%- if item_name in tech_table and visibility -%}

103
meta.yaml
View File

@ -11,54 +11,55 @@
# inverted # inverted
# This means, if mode is meta-rolled and the result happens to be inverted, then defer to the player's yaml instead. # This means, if mode is meta-rolled and the result happens to be inverted, then defer to the player's yaml instead.
meta_description: Meta-Mystery file with the intention of having similar-length completion times for a hopefully better experience meta_description: Meta-Mystery file with the intention of having similar-length completion times for a hopefully better experience
progression_balancing: # Progression balancing tries to make sure that the player has *something* towards any players goal in each "sphere" null:
on: 0 # Force every player into progression balancing progression_balancing: # Progression balancing tries to make sure that the player has *something* towards any players goal in each "sphere"
off: 0 # Force every player out of progression balancing, then prepare for a lot of logical BK on: 0 # Force every player into progression balancing
null: 1 # Let players decide via their own progression_balancing flag in their yaml, defaulting to on off: 0 # Force every player out of progression balancing, then prepare for a lot of logical BK
goals: null: 1 # Let players decide via their own progression_balancing flag in their yaml, defaulting to on
ganon: 100 # Climb GT, defeat Agahnim 2, and then kill Ganon A Link to the Past:
fast_ganon: 250 # Only killing Ganon is required. The hole is always open. However, items may still be placed in GT goals:
dungeons: 50 # Defeat the boss of all dungeons, including Agahnim's tower and GT (Aga 2) ganon: 100 # Climb GT, defeat Agahnim 2, and then kill Ganon
pedestal: 100 # Pull the Triforce from the Master Sword pedestal fast_ganon: 250 # Only killing Ganon is required. The hole is always open. However, items may still be placed in GT
triforce-hunt: 5 # Collect 20 of 30 Triforce pieces spread throughout the worlds, then turn them in to Murahadala in front of Hyrule Castle dungeons: 50 # Defeat the boss of all dungeons, including Agahnim's tower and GT (Aga 2)
local_triforce_hunt: 5 # Collect 20 of 30 Triforce pieces spread throughout your world, then turn them in to Murahadala in front of Hyrule Castle pedestal: 100 # Pull the Triforce from the Master Sword pedestal
ganon_triforce_hunt: 10 # Collect 20 of 30 Triforce pieces spread throughout the worlds, then kill Ganon triforce-hunt: 5 # Collect 20 of 30 Triforce pieces spread throughout the worlds, then turn them in to Murahadala in front of Hyrule Castle
local_ganon_triforce_hunt: 10 # Collect 20 of 30 Triforce pieces spread throughout your world, then kill Ganon local_triforce_hunt: 5 # Collect 20 of 30 Triforce pieces spread throughout your world, then turn them in to Murahadala in front of Hyrule Castle
ganon_pedestal: 10 # Pull the Master Sword pedestal, then kill Ganon ganon_triforce_hunt: 10 # Collect 20 of 30 Triforce pieces spread throughout the worlds, then kill Ganon
null: 0 # Maintain individual goals local_ganon_triforce_hunt: 10 # Collect 20 of 30 Triforce pieces spread throughout your world, then kill Ganon
mode: ganon_pedestal: 10 # Pull the Master Sword pedestal, then kill Ganon
standard: 10 null: 0 # Maintain individual goals
open: 60 mode:
inverted: 10 standard: 10
null: 10 # Maintain individual world states open: 60
tower_open: inverted: 10
'0': 8 null: 10 # Maintain individual world states
'1': 7 tower_open:
'2': 6 '0': 8
'3': 5 '1': 7
'4': 4 '2': 6
'5': 3 '3': 5
'6': 2 '4': 4
'7': 1 '5': 3
random: 10 # A different GT open time should not usually result in a vastly different completion time, unless ganon goal and tower_open > ganon_open '6': 2
ganon_open: '7': 1
'0': 3 random: 10 # A different GT open time should not usually result in a vastly different completion time, unless ganon goal and tower_open > ganon_open
'1': 4 ganon_open:
'2': 5 '0': 3
'3': 6 '1': 4
'4': 7 '2': 5
'5': 8 '3': 6
'6': 9 '4': 7
'7': 10 '5': 8
random: 5 # This will mean differing completion times. But leaving it for that surprise effect '6': 9
triforce_pieces_mode: #Determine how to calculate the extra available triforce pieces. '7': 10
extra: 0 # available = triforce_pieces_extra + triforce_pieces_required random: 5 # This will mean differing completion times. But leaving it for that surprise effect
percentage: 0 # available = (triforce_pieces_percentage /100) * triforce_pieces_required triforce_pieces_mode: #Determine how to calculate the extra available triforce pieces.
available: 50 # available = triforce_pieces_available extra: 0 # available = triforce_pieces_extra + triforce_pieces_required
triforce_pieces_available: # Set to how many triforces pieces are available to collect in the world. Default is 30. Max is 90, Min is 1 percentage: 0 # available = (triforce_pieces_percentage /100) * triforce_pieces_required
# Format "pieces: chance" available: 50 # available = triforce_pieces_available
30: 50 triforce_pieces_available: # Set to how many triforces pieces are available to collect in the world. Default is 30. Max is 90, Min is 1
triforce_pieces_required: # Set to how many out of X triforce pieces you need to win the game in a triforce hunt. Default is 20. Max is 90, Min is 1 # Format "pieces: chance"
# Format "pieces: chance" 30: 50
25: 50 triforce_pieces_required: # Set to how many out of X triforce pieces you need to win the game in a triforce hunt. Default is 20. Max is 90, Min is 1
# Do not use meta rom options at this time # Format "pieces: chance"
25: 50

View File

@ -35,8 +35,8 @@ accessibility:
progression_balancing: progression_balancing:
on: 50 # A system to reduce BK, as in times during which you can't do anything by moving your items into an earlier access sphere to make it likely you have stuff to do on: 50 # A system to reduce BK, as in times during which you can't do anything by moving your items into an earlier access sphere to make it likely you have stuff to do
off: 0 # Turn this off if you don't mind a longer multiworld, or can glitch/sequence break around missing items. off: 0 # Turn this off if you don't mind a longer multiworld, or can glitch/sequence break around missing items.
# Can be uncommented to use it # The following 4 options can be uncommented and moved into a game's section they should affect
# startinventory: # Begin the file with the listed items/upgrades # start_inventory: # Begin the file with the listed items/upgrades
# Please only use items for the correct game, use triggers if need to be have seperated lists. # Please only use items for the correct game, use triggers if need to be have seperated lists.
# Pegasus Boots: on # Pegasus Boots: on
# Bomb Upgrade (+10): 4 # Bomb Upgrade (+10): 4
@ -50,441 +50,332 @@ progression_balancing:
# non_local_items: # Force certain items to appear outside your world only, unless in single-player. Recognizes some group names, like "Swords" # non_local_items: # Force certain items to appear outside your world only, unless in single-player. Recognizes some group names, like "Swords"
# - "Progressive Weapons" # - "Progressive Weapons"
# Factorio options: Factorio:
tech_tree_layout: tech_tree_layout:
single: 1 single: 1
small_diamonds: 1 small_diamonds: 1
medium_diamonds: 1 medium_diamonds: 1
large_diamonds: 1 large_diamonds: 1
small_pyramids: 1 small_pyramids: 1
medium_pyramids: 1 medium_pyramids: 1
large_pyramids: 1 large_pyramids: 1
small_funnels: 1 small_funnels: 1
medium_funnels: 1 medium_funnels: 1
large_funnels: 1 large_funnels: 1
recipe_time: # randomize the time it takes for any recipe to craft, this includes smelting, chemical lab, hand crafting etc. recipe_time: # randomize the time it takes for any recipe to craft, this includes smelting, chemical lab, hand crafting etc.
vanilla: 1 vanilla: 1
fast: 0 # 25% to 100% of original time fast: 0 # 25% to 100% of original time
normal: 0 # 50 % to 200% of original time normal: 0 # 50 % to 200% of original time
slow: 0 # 100% to 400% of original time slow: 0 # 100% to 400% of original time
chaos: 0 # 25% to 400% of original time chaos: 0 # 25% to 400% of original time
max_science_pack: max_science_pack:
automation_science_pack: 0 automation_science_pack: 0
logistic_science_pack: 0 logistic_science_pack: 0
military_science_pack: 0 military_science_pack: 0
chemical_science_pack: 0 chemical_science_pack: 0
production_science_pack: 0 production_science_pack: 0
utility_science_pack: 0 utility_science_pack: 0
space_science_pack: 1 space_science_pack: 1
tech_cost: tech_cost:
very_easy : 0 very_easy : 0
easy : 0 easy : 0
kind : 0 kind : 0
normal : 1 normal : 1
hard : 0 hard : 0
very_hard : 0 very_hard : 0
insane : 0 insane : 0
free_samples: free_samples:
none: 1 none: 1
single_craft: 0 single_craft: 0
half_stack: 0 half_stack: 0
stack: 0 stack: 0
visibility: visibility:
none: 0 none: 0
sending: 1 sending: 1
random_tech_ingredients: random_tech_ingredients:
on: 1 on: 1
off: 0 off: 0
starting_items: starting_items:
burner-mining-drill: 19 burner-mining-drill: 19
stone-furnace: 19 stone-furnace: 19
# Minecraft options: Minecraft:
advancement_goal: # Number of advancements required (out of 92 total) to spawn the Ender Dragon and complete the game. advancement_goal: # Number of advancements required (out of 92 total) to spawn the Ender Dragon and complete the game.
few: 0 # 30 advancements few: 0 # 30 advancements
normal: 1 # 50 normal: 1 # 50
many: 0 # 70 many: 0 # 70
combat_difficulty: # Modifies the level of items logically required for exploring dangerous areas and fighting bosses. combat_difficulty: # Modifies the level of items logically required for exploring dangerous areas and fighting bosses.
easy: 0 easy: 0
normal: 1 normal: 1
hard: 0 hard: 0
include_hard_advancements: # Junk-fills certain RNG-reliant or tedious advancements with XP rewards. include_hard_advancements: # Junk-fills certain RNG-reliant or tedious advancements with XP rewards.
on: 0 on: 0
off: 1 off: 1
include_insane_advancements: # Junk-fills extremely difficult advancements; this is only How Did We Get Here? and Adventuring Time. include_insane_advancements: # Junk-fills extremely difficult advancements; this is only How Did We Get Here? and Adventuring Time.
on: 0 on: 0
off: 1 off: 1
include_postgame_advancements: # Some advancements require defeating the Ender Dragon; this will junk-fill them so you won't have to finish to send some items. include_postgame_advancements: # Some advancements require defeating the Ender Dragon; this will junk-fill them so you won't have to finish to send some items.
on: 0 on: 0
off: 1 off: 1
shuffle_structures: # CURRENTLY DISABLED; enables shuffling of villages, outposts, fortresses, bastions, and end cities. shuffle_structures: # CURRENTLY DISABLED; enables shuffling of villages, outposts, fortresses, bastions, and end cities.
on: 0 on: 0
off: 1 off: 1
# A Link to the Past options: A Link to the Past:
### Logic Section ### ### Logic Section ###
# Warning: overworld_glitches is not available and minor_glitches is only partially implemented on the door-rando version glitches_required: # Determine the logic required to complete the seed
glitches_required: # Determine the logic required to complete the seed none: 50 # No glitches required
none: 50 # No glitches required minor_glitches: 0 # Puts fake flipper, waterwalk, super bunny shenanigans, and etc into logic
minor_glitches: 0 # Puts fake flipper, waterwalk, super bunny shenanigans, and etc into logic overworld_glitches: 0 # Assumes the player has knowledge of both overworld major glitches (boots clips, mirror clips) and minor glitches
overworld_glitches: 0 # Assumes the player has knowledge of both overworld major glitches (boots clips, mirror clips) and minor glitches no_logic: 0 # Your own items are placed with no regard to any logic; such as your Fire Rod can be on your Trinexx.
no_logic: 0 # Your own items are placed with no regard to any logic; such as your Fire Rod can be on your Trinexx. # Other players items are placed into your world under OWG logic
# Other players items are placed into your world under OWG logic dark_room_logic: # Logic for unlit dark rooms
dark_room_logic: # Logic for unlit dark rooms lamp: 50 # require the Lamp for these rooms to be considered accessible.
lamp: 50 # require the Lamp for these rooms to be considered accessible. torches: 0 # in addition to lamp, allow the fire rod and presence of easily accessible torches for access
torches: 0 # in addition to lamp, allow the fire rod and presence of easily accessible torches for access none: 0 # all dark rooms are always considered doable, meaning this may force completion of rooms in complete darkness
none: 0 # all dark rooms are always considered doable, meaning this may force completion of rooms in complete darkness restrict_dungeon_item_on_boss: # aka ambrosia boss items
restrict_dungeon_item_on_boss: # aka ambrosia boss items on: 0 # prevents unshuffled compasses, maps and keys to be boss drops, they can still drop keysanity and other players' items
on: 0 # prevents unshuffled compasses, maps and keys to be boss drops, they can still drop keysanity and other players' items off: 50
off: 50 ### End of Logic Section ###
### End of Logic Section ### map_shuffle: # Shuffle dungeon maps into the world and other dungeons, including other players' worlds
map_shuffle: # Shuffle dungeon maps into the world and other dungeons, including other players' worlds on: 0
on: 0 off: 50
off: 50 compass_shuffle: # Shuffle compasses into the world and other dungeons, including other players' worlds
compass_shuffle: # Shuffle compasses into the world and other dungeons, including other players' worlds on: 0
on: 0 off: 50
off: 50 smallkey_shuffle: # Shuffle small keys into the world and other dungeons, including other players' worlds
smallkey_shuffle: # Shuffle small keys into the world and other dungeons, including other players' worlds on: 0
on: 0 universal: 0 # allows small keys to be used in any dungeon and adds shops to buy more
universal: 0 # allows small keys to be used in any dungeon and adds shops to buy more off: 50
off: 50 bigkey_shuffle: # Shuffle big keys into the world and other dungeons, including other players' worlds
bigkey_shuffle: # Shuffle big keys into the world and other dungeons, including other players' worlds on: 0
on: 0 off: 50
off: 50 local_keys: # Keep small keys and big keys local to your world
local_keys: # Keep small keys and big keys local to your world on: 0
on: 0 off: 50
off: 50 dungeon_items: # Alternative to the 4 shuffles and local_keys above this, does nothing until the respective 4 shuffles and local_keys above are deleted
dungeon_items: # Alternative to the 4 shuffles and local_keys above this, does nothing until the respective 4 shuffles and local_keys above are deleted mc: 0 # Shuffle maps and compasses
mc: 0 # Shuffle maps and compasses none: 50 # Shuffle none of the 4
none: 50 # Shuffle none of the 4 mcsb: 0 # Shuffle all of the 4, any combination of m, c, s and b will shuffle the respective item, or not if it's missing, so you can add more options here
mcsb: 0 # Shuffle all of the 4, any combination of m, c, s and b will shuffle the respective item, or not if it's missing, so you can add more options here lmcsb: 0 # Like mcsb above, but with keys kept local to your world. l is what makes your keys local, or not if it's missing
lmcsb: 0 # Like mcsb above, but with keys kept local to your world. l is what makes your keys local, or not if it's missing ub: 0 # universal small keys and shuffled big keys
ub: 0 # universal small keys and shuffled big keys # you can add more combos of these letters here
# you can add more combos of these letters here dungeon_counters:
dungeon_counters: on: 0 # Always display amount of items checked in a dungeon
on: 0 # Always display amount of items checked in a dungeon pickup: 50 # Show when compass is picked up
pickup: 50 # Show when compass is picked up default: 0 # Show when compass is picked up if the compass itself is shuffled
default: 0 # Show when compass is picked up if the compass itself is shuffled off: 0 # Never show item count in dungeons
off: 0 # Never show item count in dungeons progressive: # Enable or disable progressive items (swords, shields, bow)
progressive: # Enable or disable progressive items (swords, shields, bow) on: 50 # All items are progressive
on: 50 # All items are progressive off: 0 # No items are progressive
off: 0 # No items are progressive random: 0 # Randomly decides for all items. Swords could be progressive, shields might not be
random: 0 # Randomly decides for all items. Swords could be progressive, shields might not be entrance_shuffle:
entrance_shuffle: none: 50 # Vanilla game map. All entrances and exits lead to their original locations. You probably want this option
none: 50 # Vanilla game map. All entrances and exits lead to their original locations. You probably want this option dungeonssimple: 0 # Shuffle just dungeons amongst each other, swapping dungeons entirely, so Hyrule Castle is always 1 dungeon
dungeonssimple: 0 # Shuffle just dungeons amongst each other, swapping dungeons entirely, so Hyrule Castle is always 1 dungeon dungeonsfull: 0 # Shuffle any dungeon entrance with any dungeon interior, so Hyrule Castle can be 4 different dungeons, but keep dungeons to a specific world
dungeonsfull: 0 # Shuffle any dungeon entrance with any dungeon interior, so Hyrule Castle can be 4 different dungeons, but keep dungeons to a specific world dungeonscrossed: 0 # like dungeonsfull, but allow cross-world traversal through a dungeon. Warning: May force repeated dungeon traversal
dungeonscrossed: 0 # like dungeonsfull, but allow cross-world traversal through a dungeon. Warning: May force repeated dungeon traversal simple: 0 # Entrances are grouped together before being randomized. Simple uses the most strict grouping rules
simple: 0 # Entrances are grouped together before being randomized. Simple uses the most strict grouping rules restricted: 0 # Less strict than simple
restricted: 0 # Less strict than simple full: 0 # Less strict than restricted
full: 0 # Less strict than restricted crossed: 0 # Less strict than full
crossed: 0 # Less strict than full insanity: 0 # Very few grouping rules. Good luck
insanity: 0 # Very few grouping rules. Good luck # you can also define entrance shuffle seed, like so:
# you can also define entrance shuffle seed, like so: crossed-1000: 0 # using this method, you can have the same layout as another player and share entrance information
crossed-1000: 0 # using this method, you can have the same layout as another player and share entrance information # however, many other settings like logic, world state, retro etc. may affect the shuffle result as well.
# however, many other settings like logic, world state, retro etc. may affect the shuffle result as well. crossed-group-myfriends: 0 # using this method, everyone with "group-myfriends" will share the same seed
crossed-group-myfriends: 0 # using this method, everyone with "group-myfriends" will share the same seed goals:
goals: ganon: 50 # Climb GT, defeat Agahnim 2, and then kill Ganon
ganon: 50 # Climb GT, defeat Agahnim 2, and then kill Ganon crystals: 0 # Only killing Ganon is required. However, items may still be placed in GT
crystals: 0 # Only killing Ganon is required. However, items may still be placed in GT bosses: 0 # Defeat the boss of all dungeons, including Agahnim's tower and GT (Aga 2)
bosses: 0 # Defeat the boss of all dungeons, including Agahnim's tower and GT (Aga 2) pedestal: 0 # Pull the Triforce from the Master Sword pedestal
pedestal: 0 # Pull the Triforce from the Master Sword pedestal ganon_pedestal: 0 # Pull the Master Sword pedestal, then kill Ganon
ganon_pedestal: 0 # Pull the Master Sword pedestal, then kill Ganon triforce_hunt: 0 # Collect 20 of 30 Triforce pieces spread throughout the worlds, then turn them in to Murahadala in front of Hyrule Castle
triforce_hunt: 0 # Collect 20 of 30 Triforce pieces spread throughout the worlds, then turn them in to Murahadala in front of Hyrule Castle local_triforce_hunt: 0 # Collect 20 of 30 Triforce pieces spread throughout your world, then turn them in to Murahadala in front of Hyrule Castle
local_triforce_hunt: 0 # Collect 20 of 30 Triforce pieces spread throughout your world, then turn them in to Murahadala in front of Hyrule Castle ganon_triforce_hunt: 0 # Collect 20 of 30 Triforce pieces spread throughout the worlds, then kill Ganon
ganon_triforce_hunt: 0 # Collect 20 of 30 Triforce pieces spread throughout the worlds, then kill Ganon local_ganon_triforce_hunt: 0 # Collect 20 of 30 Triforce pieces spread throughout your world, then kill Ganon
local_ganon_triforce_hunt: 0 # Collect 20 of 30 Triforce pieces spread throughout your world, then kill Ganon ice_rod_hunt: 0 # You start with everything needed to 216 the seed. Find the Ice rod, then kill Trinexx at Turtle rock.
ice_rod_hunt: 0 # You start with everything needed to 216 the seed. Find the Ice rod, then kill Trinexx at Turtle rock. open_pyramid:
open_pyramid: goal: 50 # Opens the pyramid if the goal requires you to kill Ganon, unless the goal is Slow Ganon or All Dungeons
goal: 50 # Opens the pyramid if the goal requires you to kill Ganon, unless the goal is Slow Ganon or All Dungeons auto: 0 # Same as Goal, but also is closed if holes are shuffled and ganon is part of the shuffle pool
auto: 0 # Same as Goal, but also is closed if holes are shuffled and ganon is part of the shuffle pool yes: 0 # Pyramid hole is always open. Ganon's vulnerable condition is still required before he can he hurt
yes: 0 # Pyramid hole is always open. Ganon's vulnerable condition is still required before he can he hurt no: 0 # Pyramid hole is always closed until you defeat Agahnim atop Ganon's Tower
no: 0 # Pyramid hole is always closed until you defeat Agahnim atop Ganon's Tower triforce_pieces_mode: #Determine how to calculate the extra available triforce pieces.
triforce_pieces_mode: #Determine how to calculate the extra available triforce pieces. extra: 0 # available = triforce_pieces_extra + triforce_pieces_required
extra: 0 # available = triforce_pieces_extra + triforce_pieces_required percentage: 0 # available = (triforce_pieces_percentage /100) * triforce_pieces_required
percentage: 0 # available = (triforce_pieces_percentage /100) * triforce_pieces_required available: 50 # available = triforce_pieces_available
available: 50 # available = triforce_pieces_available triforce_pieces_extra: # Set to how many extra triforces pieces are available to collect in the world.
triforce_pieces_extra: # Set to how many extra triforces pieces are available to collect in the world. # Format "pieces: chance"
# Format "pieces: chance" 0: 0
0: 0 5: 50
5: 50 10: 50
10: 50 15: 0
15: 0 20: 0
20: 0 triforce_pieces_percentage: # Set to how many triforce pieces according to a percentage of the required ones, are available to collect in the world.
triforce_pieces_percentage: # Set to how many triforce pieces according to a percentage of the required ones, are available to collect in the world. # Format "pieces: chance"
# Format "pieces: chance" 100: 0 #No extra
100: 0 #No extra 150: 50 #Half the required will be added as extra
150: 50 #Half the required will be added as extra 200: 0 #There are the double of the required ones available.
200: 0 #There are the double of the required ones available. triforce_pieces_available: # Set to how many triforces pieces are available to collect in the world. Default is 30. Max is 90, Min is 1
triforce_pieces_available: # Set to how many triforces pieces are available to collect in the world. Default is 30. Max is 90, Min is 1 # Format "pieces: chance"
# Format "pieces: chance" 25: 0
25: 0 30: 50
30: 50 40: 0
40: 0 50: 0
50: 0 triforce_pieces_required: # Set to how many out of X triforce pieces you need to win the game in a triforce hunt. Default is 20. Max is 90, Min is 1
triforce_pieces_required: # Set to how many out of X triforce pieces you need to win the game in a triforce hunt. Default is 20. Max is 90, Min is 1 # Format "pieces: chance"
# Format "pieces: chance" 15: 0
15: 0 20: 50
20: 50 30: 0
30: 0 40: 0
40: 0 50: 0
50: 0 crystals_needed_for_gt: # Crystals required to open GT
crystals_needed_for_gt: # Crystals required to open GT 0: 0
0: 0 1: 0
1: 0 2: 0
2: 0 3: 0
3: 0 4: 0
4: 0 5: 0
5: 0 6: 0
6: 0 7: 0
7: 0 random: 0
random: 0 random-low: 50 # any valid number, weighted towards the lower end
random-low: 50 # any valid number, weighted towards the lower end random-middle: 0 # any valid number, weighted towards the central range
random-middle: 0 # any valid number, weighted towards the central range random-high: 0 # any valid number, weighted towards the higher end
random-high: 0 # any valid number, weighted towards the higher end crystals_needed_for_ganon: # Crystals required to hurt Ganon
crystals_needed_for_ganon: # Crystals required to hurt Ganon 0: 0
0: 0 1: 0
1: 0 2: 0
2: 0 3: 0
3: 0 4: 0
4: 0 5: 0
5: 0 6: 0
6: 0 7: 0
7: 0 random: 0
random: 0 random-low: 0
random-low: 0 random-middle: 0
random-middle: 0 random-high: 50
random-high: 50
mode:
standard: 50 # Begin the game by rescuing Zelda from her cell and escorting her to the Sanctuary
open: 50 # Begin the game from your choice of Link's House or the Sanctuary
inverted: 0 # Begin in the Dark World. The Moon Pearl is required to avoid bunny-state in Light World, and the Light World game map is altered
retro:
on: 0 # you must buy a quiver to use the bow, take-any caves and an old-man cave are added to the world. You may need to find your sword from the old man's cave
off: 50
hints:
'on': 50 # Hint tiles sometimes give item location hints
'off': 0 # Hint tiles provide gameplay tips
swordless:
on: 0 # Your swords are replaced by rupees. Gameplay changes have been made to accommodate this change
off: 1
item_pool:
easy: 0 # Doubled upgrades, progressives, and etc
normal: 50 # Item availability remains unchanged from vanilla game
hard: 0 # Reduced upgrade availability (max: 14 hearts, blue mail, tempered sword, fire shield, no silvers unless swordless)
expert: 0 # Minimum upgrade availability (max: 8 hearts, green mail, master sword, fighter shield, no silvers unless swordless)
item_functionality:
easy: 0 # Allow Hammer to damage ganon, Allow Hammer tablet collection, Allow swordless medallion use everywhere.
normal: 50 # Vanilla item functionality
hard: 0 # Reduced helpfulness of items (potions less effective, can't catch faeries, cape uses double magic, byrna does not grant invulnerability, boomerangs do not stun, silvers disabled outside ganon)
expert: 0 # Vastly reduces the helpfulness of items (potions barely effective, can't catch faeries, cape uses double magic, byrna does not grant invulnerability, boomerangs and hookshot do not stun, silvers disabled outside ganon)
tile_shuffle: # Randomize the tile layouts in flying tile rooms
on: 0
off: 50
misery_mire_medallion: # required medallion to open Misery Mire front entrance
random: 50
Ether: 0
Bombos: 0
Quake: 0
turtle_rock_medallion: # required medallion to open Turtle Rock front entrance
random: 50
Ether: 0
Bombos: 0
Quake: 0
### Enemizer Section ###
boss_shuffle:
none: 50 # Vanilla bosses
basic: 0 # Existing bosses except Ganon and Agahnim are shuffled throughout dungeons
normal: 0 # 3 bosses can occur twice
chaos: 0 # Any boss can appear any amount of times
singularity: 0 # Picks a boss, tries to put it everywhere that works, if there's spaces remaining it picks a boss to fill those
enemy_shuffle: # Randomize enemy placement
on: 0
off: 50
killable_thieves: # Make thieves killable
on: 0 # Usually turned on together with enemy_shuffle to make annoying thief placement more manageable
off: 50
bush_shuffle: # Randomize the chance that bushes have enemies and the enemies under said bush
on: 0
off: 50
enemy_damage:
default: 50 # Vanilla enemy damage
shuffled: 0 # Enemies deal 0 to 4 hearts and armor helps
random: 0 # Enemies deal 0 to 8 hearts and armor just reshuffles the damage
enemy_health:
default: 50 # Vanilla enemy HP
easy: 0 # Enemies have reduced health
hard: 0 # Enemies have increased health
expert: 0 # Enemies have greatly increased health
pot_shuffle:
'on': 0 # Keys, items, and buttons hidden under pots in dungeons are shuffled with other pots in their supertile
'off': 50 # Default pot item locations
### End of Enemizer Section ###
beemizer: # Remove items from the global item pool and replace them with single bees (fill bottles) and bee traps
0: 50 # No bee traps are placed
1: 0 # 25% of rupees, bombs and arrows are replaced with bees, of which 60% are traps and 40% single bees
2: 0 # 50% of rupees, bombs and arrows are replaced with bees, of which 70% are traps and 30% single bees
3: 0 # 75% of rupees, bombs and arrows are replaced with bees, of which 80% are traps and 20% single bees
4: 0 # 100% of rupees, bombs and arrows are replaced with bees, of which 90% are traps and 10% single bees
5: 0 # 100% of rupees, bombs and arrows are replaced with bees, of which 100% are traps and 0% single bees
### Shop Settings ###
shop_item_slots: # Maximum amount of shop slots to be filled with regular item pool items (such as Moon Pearl)
0: 50
5: 0
15: 0
30: 0
random: 0 # 0 to 30 evenly distributed
shop_shuffle:
none: 50
g: 0 # Generate new default inventories for overworld/underworld shops, and unique shops
f: 0 # Generate new default inventories for every shop independently
i: 0 # Shuffle default inventories of the shops around
p: 0 # Randomize the prices of the items in shop inventories
u: 0 # Shuffle capacity upgrades into the item pool (and allow them to traverse the multiworld)
w: 0 # Consider witch's hut like any other shop and shuffle/randomize it too
ip: 0 # Shuffle inventories and randomize prices
fpu: 0 # Generate new inventories, randomize prices and shuffle capacity upgrades into item pool
uip: 0 # Shuffle inventories, randomize prices and shuffle capacity upgrades into the item pool
# You can add more combos
### End of Shop Section ###
shuffle_prizes: # aka drops
none: 0 # do not shuffle prize packs
g: 50 # shuffle "general" prize packs, as in enemy, tree pull, dig etc.
b: 0 # shuffle "bonk" prize packs
bg: 0 # shuffle both
timer:
none: 50 # No timer will be displayed.
timed: 0 # Starts with clock at zero. Green clocks subtract 4 minutes (total 20). Blue clocks subtract 2 minutes (total 10). Red clocks add two minutes (total 10). Winner is the player with the lowest time at the end.
timed_ohko: 0 # Starts the clock at ten minutes. Green clocks add five minutes (total 25). As long as the clock as at zero, Link will die in one hit.
ohko: 0 # Timer always at zero. Permanent OHKO.
timed_countdown: 0 # Starts the clock with forty minutes. Same clocks as timed mode, but if the clock hits zero you lose. You can still keep playing, though.
display: 0 # Displays a timer, but otherwise does not affect gameplay or the item pool.
countdown_start_time: # For timed_ohko and timed_countdown timer modes, the amount of time in minutes to start with
0: 0 # For timed_ohko, starts in OHKO mode when starting the game
10: 50
20: 0
30: 0
60: 0
red_clock_time: # For all timer modes, the amount of time in minutes to gain or lose when picking up a red clock
-2: 50
1: 0
blue_clock_time: # For all timer modes, the amount of time in minutes to gain or lose when picking up a blue clock
1: 0
2: 50
green_clock_time: # For all timer modes, the amount of time in minutes to gain or lose when picking up a green clock
4: 50
10: 0
15: 0
glitch_boots:
on: 50 # Start with Pegasus Boots in any glitched logic mode that makes use of them
off: 0
# meta_ignore, linked_options and triggers work for any game
meta_ignore: # Nullify options specified in the meta.yaml file. Adding an option here guarantees it will not occur in your seed, even if the .yaml file specifies it
mode: mode:
- inverted # Never play inverted seeds standard: 50 # Begin the game by rescuing Zelda from her cell and escorting her to the Sanctuary
open: 50 # Begin the game from your choice of Link's House or the Sanctuary
inverted: 0 # Begin in the Dark World. The Moon Pearl is required to avoid bunny-state in Light World, and the Light World game map is altered
retro: retro:
- on # Never play retro seeds on: 0 # you must buy a quiver to use the bow, take-any caves and an old-man cave are added to the world. You may need to find your sword from the old man's cave
off: 50
hints:
'on': 50 # Hint tiles sometimes give item location hints
'off': 0 # Hint tiles provide gameplay tips
swordless: swordless:
- on # Never play a swordless seed on: 0 # Your swords are replaced by rupees. Gameplay changes have been made to accommodate this change
linked_options: off: 1
- name: crosskeys item_pool:
options: # These overwrite earlier options if the percentage chance triggers easy: 0 # Doubled upgrades, progressives, and etc
entrance_shuffle: crossed normal: 50 # Item availability remains unchanged from vanilla game
bigkey_shuffle: true hard: 0 # Reduced upgrade availability (max: 14 hearts, blue mail, tempered sword, fire shield, no silvers unless swordless)
compass_shuffle: true expert: 0 # Minimum upgrade availability (max: 8 hearts, green mail, master sword, fighter shield, no silvers unless swordless)
map_shuffle: true item_functionality:
smallkey_shuffle: true easy: 0 # Allow Hammer to damage ganon, Allow Hammer tablet collection, Allow swordless medallion use everywhere.
percentage: 0 # Set this to the percentage chance you want crosskeys normal: 50 # Vanilla item functionality
- name: localcrosskeys hard: 0 # Reduced helpfulness of items (potions less effective, can't catch faeries, cape uses double magic, byrna does not grant invulnerability, boomerangs do not stun, silvers disabled outside ganon)
options: # These overwrite earlier options if the percentage chance triggers expert: 0 # Vastly reduces the helpfulness of items (potions barely effective, can't catch faeries, cape uses double magic, byrna does not grant invulnerability, boomerangs and hookshot do not stun, silvers disabled outside ganon)
entrance_shuffle: crossed tile_shuffle: # Randomize the tile layouts in flying tile rooms
bigkey_shuffle: true on: 0
compass_shuffle: true off: 50
map_shuffle: true misery_mire_medallion: # required medallion to open Misery Mire front entrance
smallkey_shuffle: true random: 50
local_items: # Forces keys to be local to your own world Ether: 0
- "Small Keys" Bombos: 0
- "Big Keys" Quake: 0
percentage: 0 # Set this to the percentage chance you want local crosskeys turtle_rock_medallion: # required medallion to open Turtle Rock front entrance
- name: enemizer random: 50
options: Ether: 0
boss_shuffle: # Subchances can be injected too, which then get rolled Bombos: 0
basic: 1 Quake: 0
full: 1 ### Enemizer Section ###
chaos: 1 boss_shuffle:
singularity: 1 none: 50 # Vanilla bosses
enemy_damage: basic: 0 # Existing bosses except Ganon and Agahnim are shuffled throughout dungeons
shuffled: 1 full: 0 # 3 bosses can occur twice
random: 1 chaos: 0 # Any boss can appear any amount of times
enemy_health: singularity: 0 # Picks a boss, tries to put it everywhere that works, if there's spaces remaining it picks a boss to fill those
easy: 1 enemy_shuffle: # Randomize enemy placement
hard: 1 on: 0
expert: 1 off: 50
percentage: 0 # Set this to the percentage chance you want enemizer killable_thieves: # Make thieves killable
# triggers that replace options upon rolling certain options on: 0 # Usually turned on together with enemy_shuffle to make annoying thief placement more manageable
legacy_weapons: # this is not an actual option, just a set of weights to trigger from off: 50
trigger_disabled: 50 bush_shuffle: # Randomize the chance that bushes have enemies and the enemies under said bush
randomized: 0 # Swords are placed randomly throughout the world on: 0
assured: 0 # Begin with a sword, the rest are placed randomly throughout the world off: 50
vanilla: 0 # Swords are placed in vanilla locations in your own game (Uncle, Pyramid Fairy, Smiths, Pedestal) enemy_damage:
swordless: 0 # swordless mode default: 50 # Vanilla enemy damage
triggers: shuffled: 0 # Enemies deal 0 to 4 hearts and armor helps
# trigger block for legacy weapons mode, to enable these add weights to legacy_weapons random: 0 # Enemies deal 0 to 8 hearts and armor just reshuffles the damage
- option_name: legacy_weapons enemy_health:
option_result: randomized default: 50 # Vanilla enemy HP
options: easy: 0 # Enemies have reduced health
swordless: off hard: 0 # Enemies have increased health
- option_name: legacy_weapons expert: 0 # Enemies have greatly increased health
option_result: assured pot_shuffle:
options: 'on': 0 # Keys, items, and buttons hidden under pots in dungeons are shuffled with other pots in their supertile
swordless: off 'off': 50 # Default pot item locations
startinventory: ### End of Enemizer Section ###
Progressive Sword: 1 beemizer: # Remove items from the global item pool and replace them with single bees (fill bottles) and bee traps
- option_name: legacy_weapons 0: 50 # No bee traps are placed
option_result: vanilla 1: 0 # 25% of rupees, bombs and arrows are replaced with bees, of which 60% are traps and 40% single bees
options: 2: 0 # 50% of rupees, bombs and arrows are replaced with bees, of which 70% are traps and 30% single bees
swordless: off 3: 0 # 75% of rupees, bombs and arrows are replaced with bees, of which 80% are traps and 20% single bees
plando_items: 4: 0 # 100% of rupees, bombs and arrows are replaced with bees, of which 90% are traps and 10% single bees
- items: 5: 0 # 100% of rupees, bombs and arrows are replaced with bees, of which 100% are traps and 0% single bees
Progressive Sword: 4 ### Shop Settings ###
locations: shop_item_slots: # Maximum amount of shop slots to be filled with regular item pool items (such as Moon Pearl)
- Master Sword Pedestal 0: 50
- Pyramid Fairy - Left 5: 0
- Blacksmith 15: 0
- Link's Uncle 30: 0
- option_name: legacy_weapons random: 0 # 0 to 30 evenly distributed
option_result: swordless shop_shuffle:
options: none: 50
swordless: on g: 0 # Generate new default inventories for overworld/underworld shops, and unique shops
# end of legacy weapons block f: 0 # Generate new default inventories for every shop independently
- option_name: enemy_damage # targets enemy_damage i: 0 # Shuffle default inventories of the shops around
option_result: shuffled # if it rolls shuffled p: 0 # Randomize the prices of the items in shop inventories
percentage: 0 # AND has a 0 percent chance (meaning this is default disabled, just to show how it works) u: 0 # Shuffle capacity upgrades into the item pool (and allow them to traverse the multiworld)
options: # then inserts these options w: 0 # Consider witch's hut like any other shop and shuffle/randomize it too
swordless: off ip: 0 # Shuffle inventories and randomize prices
### door rando only options (not supported at all yet on this branch) ### fpu: 0 # Generate new inventories, randomize prices and shuffle capacity upgrades into item pool
door_shuffle: # Only available if the host uses the doors branch, it is ignored otherwise uip: 0 # Shuffle inventories, randomize prices and shuffle capacity upgrades into the item pool
vanilla: 50 # Everything should be like in vanilla # You can add more combos
basic: 0 # Dungeons are shuffled within themselves ### End of Shop Section ###
crossed: 0 # Dungeons are shuffled across each other shuffle_prizes: # aka drops
# you can also define door shuffle seed, like so: none: 0 # do not shuffle prize packs
crossed-1000: 0 # using this method, you can have the same dungeon layout as another player and share dungeon layout information. g: 50 # shuffle "general" prize packs, as in enemy, tree pull, dig etc.
# however, other settings like intensity, universal keys, etc. may affect the shuffle result as well. b: 0 # shuffle "bonk" prize packs
crossed-group-myfriends: 0 # using this method, everyone with "group-myfriends" will share the same seed bg: 0 # shuffle both
intensity: # Only available if the host uses the doors branch, it is ignored otherwise timer:
1: 50 # Shuffles normal doors and spiral staircases none: 50 # No timer will be displayed.
2: 0 # And shuffles open edges and straight staircases timed: 0 # Starts with clock at zero. Green clocks subtract 4 minutes (total 20). Blue clocks subtract 2 minutes (total 10). Red clocks add two minutes (total 10). Winner is the player with the lowest time at the end.
3: 0 # And shuffles dungeon lobbies timed_ohko: 0 # Starts the clock at ten minutes. Green clocks add five minutes (total 25). As long as the clock as at zero, Link will die in one hit.
random: 0 # Picks one of those at random ohko: 0 # Timer always at zero. Permanent OHKO.
key_drop_shuffle: # Only available if the host uses the doors branch, it is ignored otherwise timed_countdown: 0 # Starts the clock with forty minutes. Same clocks as timed mode, but if the clock hits zero you lose. You can still keep playing, though.
on: 0 # Enables the small keys dropped by enemies or under pots, and the big key dropped by the Ball & Chain guard to be shuffled into the pool. This extends the number of checks to 249. display: 0 # Displays a timer, but otherwise does not affect gameplay or the item pool.
off: 50 countdown_start_time: # For timed_ohko and timed_countdown timer modes, the amount of time in minutes to start with
experimental: # Only available if the host uses the doors branch, it is ignored otherwise 0: 0 # For timed_ohko, starts in OHKO mode when starting the game
on: 0 # Enables experimental features. 10: 50
off: 50 20: 0
debug: # Only available if the host uses the doors branch, it is ignored otherwise 30: 0
on: 0 # Enables debugging features. Currently, these are the Item collection counter. (overwrites total triforce pieces) and Castle Gate closed indicator. 60: 0
off: 50 red_clock_time: # For all timer modes, the amount of time in minutes to gain or lose when picking up a red clock
### end of door rando only options ### -2: 50
rom: 1: 0
blue_clock_time: # For all timer modes, the amount of time in minutes to gain or lose when picking up a blue clock
1: 0
2: 50
green_clock_time: # For all timer modes, the amount of time in minutes to gain or lose when picking up a green clock
4: 50
10: 0
15: 0
glitch_boots:
on: 50 # Start with Pegasus Boots in any glitched logic mode that makes use of them
off: 0
# rom options section
random_sprite_on_event: # An alternative to specifying randomonhit / randomonexit / etc... in sprite down below. random_sprite_on_event: # An alternative to specifying randomonhit / randomonexit / etc... in sprite down below.
enabled: # If enabled, sprite down below is ignored completely, (although it may become the sprite pool) enabled: # If enabled, sprite down below is ignored completely, (although it may become the sprite pool)
on: 0 on: 0
@ -526,7 +417,7 @@ rom:
randomonslash: 0 # Random sprite on sword slashes randomonslash: 0 # Random sprite on sword slashes
randomonitem: 0 # Random sprite on getting items. randomonitem: 0 # Random sprite on getting items.
randomonbonk: 0 # Random sprite on bonk. randomonbonk: 0 # Random sprite on bonk.
# You can combine these events like this. randomonhit-enter-exit if you want it on hit, enter, exit. # You can combine these events like this. randomonhit-enter-exit if you want it on hit, enter, exit.
randomonall: 0 # Random sprite on any and all currently supported events. Refer to above for the supported events. randomonall: 0 # Random sprite on any and all currently supported events. Refer to above for the supported events.
Link: 50 # To add other sprites: open the gui/Creator, go to adjust, select a sprite and write down the name the gui calls it Link: 50 # To add other sprites: open the gui/Creator, go to adjust, select a sprite and write down the name the gui calls it
disablemusic: # If "on", all in-game music will be disabled disablemusic: # If "on", all in-game music will be disabled
@ -612,3 +503,102 @@ rom:
dizzy: 0 dizzy: 0
sick: 0 sick: 0
puke: 0 puke: 0
# triggers that replace options upon rolling certain options
legacy_weapons: # this is not an actual option, just a set of weights to trigger from
trigger_disabled: 50
randomized: 0 # Swords are placed randomly throughout the world
assured: 0 # Begin with a sword, the rest are placed randomly throughout the world
vanilla: 0 # Swords are placed in vanilla locations in your own game (Uncle, Pyramid Fairy, Smiths, Pedestal)
swordless: 0 # swordless mode
# meta_ignore, linked_options and triggers work for any game
meta_ignore: # Nullify options specified in the meta.yaml file. Adding an option here guarantees it will not occur in your seed, even if the .yaml file specifies it
mode:
- inverted # Never play inverted seeds
retro:
- on # Never play retro seeds
swordless:
- on # Never play a swordless seed
linked_options:
- name: crosskeys
options: # These overwrite earlier options if the percentage chance triggers
A Link to the Past:
entrance_shuffle: crossed
bigkey_shuffle: true
compass_shuffle: true
map_shuffle: true
smallkey_shuffle: true
percentage: 0 # Set this to the percentage chance you want crosskeys
- name: localcrosskeys
options: # These overwrite earlier options if the percentage chance triggers
A Link to the Past:
entrance_shuffle: crossed
bigkey_shuffle: true
compass_shuffle: true
map_shuffle: true
smallkey_shuffle: true
local_items: # Forces keys to be local to your own world
- "Small Keys"
- "Big Keys"
percentage: 0 # Set this to the percentage chance you want local crosskeys
- name: enemizer
options:
A Link to the Past:
boss_shuffle: # Subchances can be injected too, which then get rolled
basic: 1
full: 1
chaos: 1
singularity: 1
enemy_damage:
shuffled: 1
random: 1
enemy_health:
easy: 1
hard: 1
expert: 1
percentage: 0 # Set this to the percentage chance you want enemizer
triggers:
# trigger block for legacy weapons mode, to enable these add weights to legacy_weapons
- option_name: legacy_weapons
option_result: randomized
option_category: A Link to the Past
options:
A Link to the Past:
swordless: off
- option_name: legacy_weapons
option_result: assured
option_category: A Link to the Past
options:
A Link to the Past:
swordless: off
start_inventory:
Progressive Sword: 1
- option_name: legacy_weapons
option_result: vanilla
option_category: A Link to the Past
options:
A Link to the Past:
swordless: off
plando_items:
- items:
Progressive Sword: 4
locations:
- Master Sword Pedestal
- Pyramid Fairy - Left
- Blacksmith
- Link's Uncle
- option_name: legacy_weapons
option_result: swordless
option_category: A Link to the Past
options:
A Link to the Past:
swordless: on
# end of legacy weapons block
- option_name: enemy_damage # targets enemy_damage
option_category: A Link to the Past
option_result: shuffled # if it rolls shuffled
percentage: 0 # AND has a 0 percent chance (meaning this is default disabled, just to show how it works)
options: # then inserts these options
A Link to the Past:
swordless: off

View File

@ -60,16 +60,17 @@ def generate_mod(world: MultiWorld, player: int):
if location.address: if location.address:
locations.append((location.name, location.item.name, location.item.player, location.item.advancement)) locations.append((location.name, location.item.name, location.item.player, location.item.advancement))
mod_name = f"AP-{world.seed_name}-P{player}-{world.player_names[player][0]}" mod_name = f"AP-{world.seed_name}-P{player}-{world.player_names[player][0]}"
tech_cost = {0: 0.1, tech_cost_scale = {0: 0.1,
1: 0.25, 1: 0.25,
2: 0.5, 2: 0.5,
3: 1, 3: 1,
4: 2, 4: 2,
5: 5, 5: 5,
6: 10}[world.tech_cost[player].value] 6: 10}[world.tech_cost[player].value]
template_data = {"locations": locations, "player_names": player_names, "tech_table": tech_table, template_data = {"locations": locations, "player_names": player_names, "tech_table": tech_table,
"mod_name": mod_name, "allowed_science_packs": world.max_science_pack[player].get_allowed_packs(), "mod_name": mod_name, "allowed_science_packs": world.max_science_pack[player].get_allowed_packs(),
"tech_cost_scale": tech_cost, "custom_technologies": world.worlds[player].custom_technologies, "tech_cost_scale": tech_cost_scale, "custom_technologies": world.worlds[player].custom_technologies,
"tech_tree_layout_prerequisites": world.tech_tree_layout_prerequisites[player], "tech_tree_layout_prerequisites": world.tech_tree_layout_prerequisites[player],
"rocket_recipe": rocket_recipes[world.max_science_pack[player].value], "rocket_recipe": rocket_recipes[world.max_science_pack[player].value],
"slot_name": world.player_names[player][0], "seed_name": world.seed_name, "slot_name": world.player_names[player][0], "seed_name": world.seed_name,

View File

@ -66,7 +66,7 @@ class CustomTechnology(Technology):
def __init__(self, origin: Technology, world, allowed_packs: Set[str], player: int): def __init__(self, origin: Technology, world, allowed_packs: Set[str], player: int):
ingredients = origin.ingredients & allowed_packs ingredients = origin.ingredients & allowed_packs
self.player = player self.player = player
if world.random_tech_ingredients[player]: if world.random_tech_ingredients[player] and origin.name not in world.worlds[player].static_nodes:
ingredients = list(ingredients) ingredients = list(ingredients)
ingredients.sort() # deterministic sample ingredients.sort() # deterministic sample
ingredients = world.random.sample(ingredients, world.random.randint(1, len(ingredients))) ingredients = world.random.sample(ingredients, world.random.randint(1, len(ingredients)))

View File

@ -9,11 +9,12 @@ from .Mod import generate_mod
class Factorio(World): class Factorio(World):
game: str = "Factorio" game: str = "Factorio"
static_nodes = {"automation", "logistics"} static_nodes = {"automation", "logistics", "rocket-silo"}
def generate_basic(self): def generate_basic(self):
victory_tech_names = get_rocket_requirements( victory_tech_names = get_rocket_requirements(
frozenset(rocket_recipes[self.world.max_science_pack[self.player].value])) frozenset(rocket_recipes[self.world.max_science_pack[self.player].value]))
for tech_name, tech_id in tech_table.items(): for tech_name, tech_id in tech_table.items():
tech_item = Item(tech_name, tech_name in advancement_technologies or tech_name in victory_tech_names, tech_item = Item(tech_name, tech_name in advancement_technologies or tech_name in victory_tech_names,
tech_id, self.player) tech_id, self.player)