diff --git a/BaseClasses.py b/BaseClasses.py index e3b8aaf7..854b34a8 100644 --- a/BaseClasses.py +++ b/BaseClasses.py @@ -6,7 +6,7 @@ import logging import json import functools from collections import OrderedDict, Counter, deque -from typing import List, Dict, Optional, Set, Iterable, Union, Any, Tuple, TypedDict, Callable +from typing import List, Dict, Optional, Set, Iterable, Union, Any, Tuple, TypedDict, Callable, NamedTuple import typing # this can go away when Python 3.8 support is dropped import secrets import random @@ -1458,6 +1458,19 @@ class Spoiler(): AutoWorld.call_all(self.world, "write_spoiler_end", outfile) +class Tutorial(NamedTuple): + """Class to build website tutorial pages from a .md file in the world's /docs folder. Order is as follows. + Name of the tutorial as it will appear on the site. Concise description covering what the guide will entail. + Language the guide is written in. Name of the file ex 'setup_en.md'. Name of the link on the site; game name is + filled automatically so 'setup/en' etc. Author or authors.""" + tutorial_name: str + description: str + language: str + file_name: str + link: str + author: List[str] + + seeddigits = 20 @@ -1470,4 +1483,4 @@ def get_seed(seed=None) -> int: from worlds import AutoWorld -auto_world = AutoWorld.World \ No newline at end of file +auto_world = AutoWorld.World diff --git a/WebHost.py b/WebHost.py index 42547272..dc558a9a 100644 --- a/WebHost.py +++ b/WebHost.py @@ -1,4 +1,5 @@ import os +import sys import multiprocessing import logging import typing @@ -21,6 +22,8 @@ from WebHostLib.autolauncher import autohost, autogen from WebHostLib.lttpsprites import update_sprites_lttp from WebHostLib.options import create as create_options_files +from worlds.AutoWorld import AutoWorldRegister, WebWorld + configpath = os.path.abspath("config.yaml") if not os.path.exists(configpath): # fall back to config.yaml in home configpath = os.path.abspath(Utils.user_path('config.yaml')) @@ -39,17 +42,53 @@ def get_app(): def create_ordered_tutorials_file() -> typing.List[typing.Dict[str, typing.Any]]: import json + import shutil + worlds = {} + data = [] + for game, world in AutoWorldRegister.world_types.items(): + if hasattr(world.web, 'tutorials'): + worlds[game] = world + for game, world in worlds.items(): + # copy files from world's docs folder to the generated folder + source_path = Utils.local_path(os.path.dirname(sys.modules[world.__module__].__file__), 'docs') + target_path = Utils.local_path("WebHostLib", "static", "generated", "docs", game) + files = os.listdir(source_path) + for file in files: + os.makedirs(os.path.dirname(Utils.local_path(target_path, file)), exist_ok=True) + shutil.copyfile(Utils.local_path(source_path, file), Utils.local_path(target_path, file)) + # build a json tutorial dict per game + game_data = {'gameTitle': game, 'tutorials': []} + for tutorial in world.web.tutorials: + # build dict for the json file + current_tutorial = { + 'name': tutorial.tutorial_name, + 'description': tutorial.description, + 'files': [{ + 'language': tutorial.language, + 'filename': game + '/' + tutorial.file_name, + 'link': f'{game}/{tutorial.link}', + 'authors': tutorial.author + }] + } - with open(Utils.local_path("WebHostLib", "static", "assets", "tutorial", "tutorials.json")) as source: - data = json.load(source) + # check if the name of the current guide exists already + for guide in game_data['tutorials']: + if guide and tutorial.tutorial_name == guide['name']: + guide['files'].append(current_tutorial['files'][0]) + added = True + break + else: + game_data['tutorials'].append(current_tutorial) - data = sorted(data, key=lambda entry: entry["gameTitle"].lower()) - - folder = Utils.local_path("WebHostLib", "static", "generated") - os.makedirs(folder, exist_ok=True) - with open(os.path.join(folder, "tutorials.json"), "w") as target: - json.dump(data, target) - return data + data.append(game_data) + with open(Utils.local_path("WebHostLib", "static", "generated", "tutorials.json"), 'w', encoding='utf-8-sig') as json_target: + generic_data = {} + for games in data: + if 'Archipelago' in games['gameTitle']: + generic_data = data.pop(data.index(games)) + sorted_data = [generic_data] + sorted(data, key=lambda entry: entry["gameTitle"].lower()) + json.dump(sorted_data, json_target, indent=2, ensure_ascii=False) + return sorted_data if __name__ == "__main__": diff --git a/WebHostLib/__init__.py b/WebHostLib/__init__.py index d818ffa1..9bb1cb79 100644 --- a/WebHostLib/__init__.py +++ b/WebHostLib/__init__.py @@ -129,6 +129,10 @@ def tutorial(game, file, lang): @app.route('/tutorial/') def tutorial_landing(): + worlds = {} + for game, world in AutoWorldRegister.world_types.items(): + if not world.hidden: + worlds[game] = world return render_template("tutorialLanding.html") diff --git a/WebHostLib/static/assets/gameInfo.js b/WebHostLib/static/assets/gameInfo.js index 5a8a45db..8a9c8b3f 100644 --- a/WebHostLib/static/assets/gameInfo.js +++ b/WebHostLib/static/assets/gameInfo.js @@ -14,7 +14,7 @@ window.addEventListener('load', () => { } resolve(ajax.responseText); }; - ajax.open('GET', `${window.location.origin}/static/assets/gameInfo/` + + ajax.open('GET', `${window.location.origin}/static/generated/docs/${gameInfo.getAttribute('data-game')}/` + `${gameInfo.getAttribute('data-lang')}_${gameInfo.getAttribute('data-game')}.md`, true); ajax.send(); }).then((results) => { diff --git a/WebHostLib/static/assets/tutorial.js b/WebHostLib/static/assets/tutorial.js index e943c629..23d2f076 100644 --- a/WebHostLib/static/assets/tutorial.js +++ b/WebHostLib/static/assets/tutorial.js @@ -14,7 +14,7 @@ window.addEventListener('load', () => { } resolve(ajax.responseText); }; - ajax.open('GET', `${window.location.origin}/static/assets/tutorial/` + + ajax.open('GET', `${window.location.origin}/static/generated/docs/` + `${tutorialWrapper.getAttribute('data-game')}/${tutorialWrapper.getAttribute('data-file')}_` + `${tutorialWrapper.getAttribute('data-lang')}.md`, true); ajax.send(); diff --git a/WebHostLib/static/assets/tutorial/tutorials.json b/WebHostLib/static/assets/tutorial/tutorials.json deleted file mode 100644 index 2c88c125..00000000 --- a/WebHostLib/static/assets/tutorial/tutorials.json +++ /dev/null @@ -1,597 +0,0 @@ -[ - { - "gameTitle": "Archipelago", - "tutorials": [ - { - "name": "Multiworld Setup Tutorial", - "description": "A guide to setting up the Archipelago software to generate and host multiworld games on your computer and using the website.", - "files": [ - { - "language": "English", - "filename": "Archipelago/setup_en.md", - "link": "Archipelago/setup/en", - "authors": [ - "alwaysintreble" - ] - } - ] - }, - { - "name": "Archipelago Website User Guide", - "description": "A guide to using the Archipelago website to generate multiworlds or host pre-generated multiworlds.", - "files": [ - { - "language": "English", - "filename": "Archipelago/using_website.md", - "link": "Archipelago/using_website/en", - "authors": [ - "alwaysintreble" - ] - } - ] - }, - { - "name": "Archipelago Server and Client Commands", - "description": "A guide detailing the commands available to the user when participating in an Archipelago session.", - "files": [ - { - "language": "English", - "filename": "Archipelago/commands_en.md", - "link": "Archipelago/commands/en", - "authors": [ - "jat2980", - "Ijwu" - ] - } - ] - }, - { - "name": "Advanced YAML Guide", - "description": "A guide to reading yaml files and editing them to fully customize your game.", - "files": [ - { - "language": "English", - "filename": "Archipelago/advanced_settings_en.md", - "link": "Archipelago/advanced_settings/en", - "authors": [ - "alwaysintreble", - "Alchav" - ] - } - ] - }, - { - "name": "Archipelago Triggers Guide", - "description": "A guide to setting up and using triggers in your game settings.", - "files": [ - { - "language": "English", - "filename": "Archipelago/triggers_en.md", - "link": "Archipelago/triggers/en", - "authors": [ - "alwaysintreble" - ] - } - ] - }, - { - "name": "Archipelago Plando Guide", - "description": "A guide to understanding and using plando for your game.", - "files": [ - { - "language": "English", - "filename": "Archipelago/plando_en.md", - "link": "Archipelago/plando/en", - "authors": [ - "alwaysintreble", - "Alchav" - ] - } - ] - } - ] - }, - { - "gameTitle": "The Legend of Zelda: A Link to the Past", - "tutorials": [ - { - "name": "Multiworld Setup Tutorial", - "description": "A guide to setting up the Archipelago ALttP software on your computer. This guide covers single-player, multiworld, and related software.", - "files": [ - { - "language": "English", - "filename": "A Link to the Past/multiworld_en.md", - "link": "A Link to the Past/multiworld/en", - "authors": [ - "Farrak Kilhn" - ] - }, - { - "language": "Deutsch", - "filename": "A Link to the Past/multiworld_de.md", - "link": "A Link to the Past/multiworld/de", - "authors": [ - "Fischfilet" - ] - }, - { - "language": "Español", - "filename": "A Link to the Past/multiworld_es.md", - "link": "A Link to the Past/multiworld/es", - "authors": [ - "Edos" - ] - }, - { - "language": "Français", - "filename": "A Link to the Past/multiworld_fr.md", - "link": "A Link to the Past/multiworld/fr", - "authors": [ - "Coxla" - ] - } - ] - }, - { - "name": "MSU-1 Setup Tutorial", - "description": "A guide to setting up MSU-1, which allows for custom in-game music.", - "files": [ - { - "language": "English", - "filename": "A Link to the Past/msu1_en.md", - "link": "A Link to the Past/msu1/en", - "authors": [ - "Farrak Kilhn" - ] - }, - { - "language": "Español", - "filename": "A Link to the Past/msu1_es.md", - "link": "A Link to the Past/msu1/es", - "authors": [ - "Edos" - ] - }, - { - "language": "Français", - "filename": "A Link to the Past/msu1_fr.md", - "link": "A Link to the Past/msu1/fr", - "authors": [ - "Coxla" - ] - } - ] - }, - { - "name": "Plando Tutorial", - "description": "A guide to creating Multiworld Plandos", - "files": [ - { - "language": "English", - "filename": "A Link to the Past/plando_en.md", - "link": "A Link to the Past/plando/en", - "authors": [ - "Berserker" - ] - } - ] - } - ] - }, - { - "gameTitle": "The Legend of Zelda: Ocarina of Time", - "tutorials": [ - { - "name": "Multiworld Setup Tutorial", - "description": "A guide to setting up the Archipelago Ocarina of Time software on your computer.", - "files": [ - { - "language": "English", - "filename": "Ocarina of Time/setup_en.md", - "link": "Ocarina of Time/setup/en", - "authors": [ - "Edos" - ] - }, - { - "language": "Spanish", - "filename": "Ocarina of Time/setup_es.md", - "link": "Ocarina of Time/setup/es", - "authors": [ - "Edos" - ] - } - ] - } - ] - }, - { - "gameTitle": "Factorio", - "tutorials": [ - { - "name": "Multiworld Setup Tutorial", - "description": "A guide to setting up the Archipelago Factorio software on your computer.", - "files": [ - { - "language": "English", - "filename": "Factorio/setup_en.md", - "link": "Factorio/setup/en", - "authors": [ - "Berserker", - "Farrak Kilhn" - ] - } - ] - } - ] - }, - { - "gameTitle": "Meritous", - "tutorials": [ - { - "name": "Meritous Setup Tutorial", - "description": "A guide to setting up the Archipelago Meritous software on your computer.", - "files": [ - { - "language": "English", - "filename": "Meritous/setup_en.md", - "link": "Meritous/setup/en", - "authors": [ - "KewlioMZX" - ] - } - ] - } - ] - }, - { - "gameTitle": "Minecraft", - "tutorials": [ - { - "name": "Multiworld Setup Tutorial", - "description": "A guide to setting up the Archipelago Minecraft software on your computer. This guide covers single-player, multiworld, and related software.", - "files": [ - { - "language": "English", - "filename": "Minecraft/minecraft_en.md", - "link": "Minecraft/minecraft/en", - "authors": [ - "Kono Tyran" - ] - }, - { - "language": "Spanish", - "filename": "Minecraft/minecraft_es.md", - "link": "Minecraft/minecraft/es", - "authors": [ - "Edos" - ] - }, - { - "language": "Swedish", - "filename": "Minecraft/minecraft_sv.md", - "link": "Minecraft/minecraft/sv", - "authors": [ - "Albinum" - ] - } - ] - } - ] - }, - { - "gameTitle": "Risk of Rain 2", - "tutorials": [ - { - "name": "Multiworld Setup Guide", - "description": "A guide to setting up the Risk of Rain 2 integration for Archipelago multiworld games.", - "files": [ - { - "language": "English", - "filename": "Risk of Rain 2/setup_en.md", - "link": "Risk of Rain 2/setup/en", - "authors": [ - "Ijwu" - ] - } - ] - } - ] - }, - { - "gameTitle": "Raft", - "tutorials": [ - { - "name": "Multiworld Setup Guide", - "description": "A guide to setting up Raft integration for Archipelago multiworld games.", - "files": [ - { - "language": "English", - "filename": "Raft/setup_en.md", - "link": "Raft/setup/en", - "authors": [ - "SunnyBat", - "Awareqwx" - ] - } - ] - } - ] - }, - { - "gameTitle": "Timespinner", - "tutorials": [ - { - "name": "Multiworld Setup Guide", - "description": "A guide to setting up the Timespinner randomizer connected to an Archipelago Multiworld", - "files": [ - { - "language": "English", - "filename": "Timespinner/setup_en.md", - "link": "Timespinner/setup/en", - "authors": [ - "Jarno" - ] - }, - { - "language": "German", - "filename": "Timespinner/setup_de.md", - "link": "Timespinner/setup/de", - "authors": [ - "Grrmo", - "Fynxes", - "Blaze0168" - ] - } - ] - } - ] - }, - { - "gameTitle": "SMZ3", - "tutorials": [ - { - "name": "Multiworld Setup Guide", - "description": "A guide to setting up the Archipelago Super Metroid and A Link to the Past Crossover randomizer on your computer. This guide covers single-player, multiworld, and related software.", - "files": [ - { - "language": "English", - "filename": "SMZ3/multiworld_en.md", - "link": "SMZ3/multiworld/en", - "authors": [ - "lordlou" - ] - } - ] - } - ] - }, - { - "gameTitle": "Subnautica", - "tutorials": [ - { - "name": "Multiworld Setup Guide", - "description": "A guide to setting up the Subnautica randomizer connected to an Archipelago Multiworld", - "files": [ - { - "language": "English", - "filename": "Subnautica/setup_en.md", - "link": "Subnautica/setup/en", - "authors": [ - "Berserker" - ] - } - ] - } - ] - }, - { - "gameTitle": "Super Metroid", - "tutorials": [ - { - "name": "Multiworld Setup Guide", - "description": "A guide to setting up the Super Metroid Client on your computer. This guide covers single-player, multiworld, and related software.", - "files": [ - { - "language": "English", - "filename": "Super Metroid/multiworld_en.md", - "link": "Super Metroid/multiworld/en", - "authors": [ - "Farrak Kilhn" - ] - } - ] - } - ] - }, - { - "gameTitle": "Secret of Evermore", - "tutorials": [ - { - "name": "Multiworld Setup Guide", - "description": "A guide to playing Secret of Evermore randomizer. This guide covers single-player, multiworld and related software.", - "files": [ - { - "language": "English", - "filename": "Secret of Evermore/multiworld_en.md", - "link": "Secret of Evermore/multiworld/en", - "authors": [ - "Black Sliver" - ] - } - ] - } - ] - }, - { - "gameTitle": "Final Fantasy", - "tutorials": [ - { - "name": "Multiworld Setup Guide", - "description": "A guide to playing Final Fantasy multiworld. This guide only covers playing multiworld.", - "files": [ - { - "language": "English", - "filename": "Final Fantasy/multiworld_en.md", - "link": "Final Fantasy/multiworld/en", - "authors": [ - "jat2980" - ] - } - ] - } - ] - }, - { - "gameTitle": "Rogue Legacy", - "tutorials": [ - { - "name": "Multiworld Setup Guide", - "description": "A guide to setting up the Rogue Legacy Randomizer software on your computer. This guide covers single-player, multiworld, and related software.", - "files": [ - { - "language": "English", - "filename": "Rogue Legacy/rogue-legacy_en.md", - "link": "Rogue Legacy/rogue-legacy/en", - "authors": [ - "Phar" - ] - } - ] - } - ] - }, - { - "gameTitle": "Slay the Spire", - "tutorials": [ - { - "name": "Multiworld Setup Guide", - "description": "A guide to setting up Slay the Spire for Archipelago. This guide covers single-player, multiworld, and related software.", - "files": [ - { - "language": "English", - "filename": "Slay the Spire/slay-the-spire_en.md", - "link": "Slay the Spire/slay-the-spire/en", - "authors": [ - "Phar" - ] - } - ] - } - ] - }, - { - "gameTitle": "Super Mario 64 EX", - "tutorials": [ - { - "name": "Multiworld Setup Guide", - "description": "A guide to setting up SM64EX for MultiWorld.", - "files": [ - { - "language": "English", - "filename": "Super Mario 64/setup_en.md", - "link": "Super Mario 64/setup/en", - "authors": [ - "N00byKing" - ] - } - ] - } - ] - }, - { - "gameTitle": "VVVVVV", - "tutorials": [ - { - "name": "Multiworld Setup Guide", - "description": "A guide to setting up VVVVVV for MultiWorld.", - "files": [ - { - "language": "English", - "filename": "VVVVVV/setup_en.md", - "link": "VVVVVV/setup/en", - "authors": [ - "N00byKing" - ] - } - ] - } - ] - }, - { - "gameTitle": "ChecksFinder", - "tutorials": [ - { - "name": "Multiworld Setup Tutorial", - "description": "A guide to setting up the Archipelago ChecksFinder software on your computer. This guide covers single-player, multiworld, and related software.", - "files": [ - { - "language": "English", - "filename": "ChecksFinder/checksfinder_en.md", - "link": "ChecksFinder/checksfinder/en", - "authors": [ - "Mewlif" - ] - } - ] - } - ] - }, - { - "gameTitle": "ArchipIDLE", - "tutorials": [ - { - "name": "Setup Guide", - "description": "A guide to playing ArchipIDLE", - "files": [ - { - "language": "English", - "filename": "ArchipIDLE/guide_en.md", - "link": "ArchipIDLE/guide/en", - "authors": [ - "Farrak Kilhn" - ] - } - ] - } - ] - }, - { - "gameTitle": "Hollow Knight", - "tutorials": [ - { - "name": "Mod Setup and Use Guide", - "description": "A guide to playing Hollow Knight with Archipelago.", - "files": [ - { - "language": "English", - "filename": "Hollow Knight/setup_en.md", - "link": "Hollow Knight/setup/en", - "authors": [ - "ijwu" - ] - } - ] - } - ] - }, - { - "gameTitle": "The Witness", - "tutorials": [ - { - "name": "Multiworld Setup Guide", - "description": "A guide to playing The Witness with Archipelago.", - "files": [ - { - "language": "English", - "filename": "The Witness/setup_en.md", - "link": "The Witness/setup/en", - "authors": [ - "NewSoupVi", "Jarno" - ] - } - ] - } - ] - } -] diff --git a/worlds/AutoWorld.py b/worlds/AutoWorld.py index ffd2c6b3..c71642c4 100644 --- a/worlds/AutoWorld.py +++ b/worlds/AutoWorld.py @@ -1,9 +1,9 @@ from __future__ import annotations import logging -from typing import Dict, FrozenSet, Set, Tuple, List, Optional, TextIO, Any, Callable, Union +from typing import Dict, FrozenSet, Set, Tuple, List, Optional, TextIO, Any, Callable, Union, NamedTuple -from BaseClasses import MultiWorld, Item, CollectionState, Location +from BaseClasses import MultiWorld, Item, CollectionState, Location, Tutorial from Options import Option @@ -90,6 +90,13 @@ class WebWorld: # display a settings page. Can be a link to an out-of-ap settings tool too. settings_page: Union[bool, str] = True + # docs folder will be scanned for game info pages using this list in the format '{language}_{game_name}.md' + game_info_languages: List[str] = ['en'] + + # docs folder will also be scanned for tutorial guides given the relevant information in this list. Each Tutorial + # class is to be used for one guide. + tutorials: List[Tutorial] + # Choose a theme for your /game/* pages # Available: dirt, grass, grassFlowers, ice, jungle, ocean, partyTime theme = "grass" diff --git a/worlds/alttp/__init__.py b/worlds/alttp/__init__.py index 9e028b2d..05b42f21 100644 --- a/worlds/alttp/__init__.py +++ b/worlds/alttp/__init__.py @@ -4,9 +4,9 @@ import os import threading import typing -from BaseClasses import Item, CollectionState +from BaseClasses import Item, CollectionState, Tutorial from .SubClasses import ALttPItem -from ..AutoWorld import World, LogicMixin +from ..AutoWorld import World, WebWorld, LogicMixin from .Options import alttp_options, smallkey_shuffle from .Items import as_dict_item_table, item_name_groups, item_table from .Regions import lookup_name_to_id, create_regions, mark_light_world_regions @@ -24,6 +24,82 @@ from .EntranceShuffle import link_entrances, link_inverted_entrances, plando_con lttp_logger = logging.getLogger("A Link to the Past") +class ALTTPWeb(WebWorld): + setup_en = Tutorial( + "Multiworld Setup Tutorial", + "A guide to setting up the Archipelago ALttP Software on your computer. This guide covers single-player, multiworld, and related software.", + "English", + "multiworld_en.md", + "multiworld/en", + ["Farrak Kilhn"] + ) + + setup_de = Tutorial( + setup_en.tutorial_name, + setup_en.description, + "Deutsch", + "multiworld_de.md", + "multiworld/de", + ["Fischfilet"] + ) + + setup_es = Tutorial( + setup_en.tutorial_name, + setup_en.description, + "Español", + "multiworld_es.md", + "multiworld/es", + ["Edos"] + ) + + setup_fr = Tutorial( + setup_en.tutorial_name, + setup_en.description, + "Français", + "multiworld_fr.md", + "multiworld/fr", + ["Coxla"] + ) + + msu = Tutorial( + "MSU-1 Setup Tutorial", + "A guide to setting up MSU-1, which allows for custom in-game music.", + "English", + "msu1_en.md", + "msu1/en", + ["Farrak Kilhn"] + ) + + msu_es = Tutorial( + msu.tutorial_name, + msu.description, + "Español", + "msu1_es.md", + "msu1/en", + ["Edos"] + ) + + msu_fr = Tutorial( + msu.tutorial_name, + msu.description, + "Français", + "msu1_fr.md", + "msu1/fr", + ["Coxla"] + ) + + plando = Tutorial( + "Plando Tutorial", + "A guide to creating Multiworld Plandos with LTTP", + "English", + "plando_en.md", + "plando/en", + ["Berserker"] + ) + + tutorials = [setup_en, setup_de, setup_es, setup_fr, msu, msu_es, msu_fr, plando] + + class ALTTPWorld(World): """ The Legend of Zelda: A Link to the Past is an action/adventure game. Take on the role of @@ -44,6 +120,7 @@ class ALTTPWorld(World): remote_items: bool = False remote_start_inventory: bool = False required_client_version = (0, 3, 2) + web = ALTTPWeb() set_rules = set_rules diff --git a/WebHostLib/static/assets/gameInfo/en_A Link to the Past.md b/worlds/alttp/docs/en_A Link to the Past.md similarity index 100% rename from WebHostLib/static/assets/gameInfo/en_A Link to the Past.md rename to worlds/alttp/docs/en_A Link to the Past.md diff --git a/WebHostLib/static/assets/tutorial/A Link to the Past/msu1_en.md b/worlds/alttp/docs/msu1_en.md similarity index 100% rename from WebHostLib/static/assets/tutorial/A Link to the Past/msu1_en.md rename to worlds/alttp/docs/msu1_en.md diff --git a/WebHostLib/static/assets/tutorial/A Link to the Past/msu1_es.md b/worlds/alttp/docs/msu1_es.md similarity index 100% rename from WebHostLib/static/assets/tutorial/A Link to the Past/msu1_es.md rename to worlds/alttp/docs/msu1_es.md diff --git a/WebHostLib/static/assets/tutorial/A Link to the Past/msu1_fr.md b/worlds/alttp/docs/msu1_fr.md similarity index 100% rename from WebHostLib/static/assets/tutorial/A Link to the Past/msu1_fr.md rename to worlds/alttp/docs/msu1_fr.md diff --git a/WebHostLib/static/assets/tutorial/A Link to the Past/multiworld_de.md b/worlds/alttp/docs/multiworld_de.md similarity index 100% rename from WebHostLib/static/assets/tutorial/A Link to the Past/multiworld_de.md rename to worlds/alttp/docs/multiworld_de.md diff --git a/WebHostLib/static/assets/tutorial/A Link to the Past/multiworld_en.md b/worlds/alttp/docs/multiworld_en.md similarity index 98% rename from WebHostLib/static/assets/tutorial/A Link to the Past/multiworld_en.md rename to worlds/alttp/docs/multiworld_en.md index d9b2625e..3759b93a 100644 --- a/WebHostLib/static/assets/tutorial/A Link to the Past/multiworld_en.md +++ b/worlds/alttp/docs/multiworld_en.md @@ -111,7 +111,7 @@ You only have to do these steps once. 2. Go to Settings --> User Interface. Set "Show Advanced Settings" to ON. 3. Go to Settings --> Network. Set "Network Commands" to ON. (It is found below Request Device 16.) Leave the default Network Command Port at 55355. -![Screenshot of Network Commands setting](/static/assets/tutorial/retroarch-network-commands-en.png) +![Screenshot of Network Commands setting](/static/generated/docs/A_Link_to_the_Past/retroarch-network-commands-en.png) 4. Go to Main Menu --> Online Updater --> Core Downloader. Scroll down and select "Nintendo - SNES / SFC (bsnes-mercury Performance)". diff --git a/WebHostLib/static/assets/tutorial/A Link to the Past/multiworld_es.md b/worlds/alttp/docs/multiworld_es.md similarity index 100% rename from WebHostLib/static/assets/tutorial/A Link to the Past/multiworld_es.md rename to worlds/alttp/docs/multiworld_es.md diff --git a/WebHostLib/static/assets/tutorial/A Link to the Past/multiworld_fr.md b/worlds/alttp/docs/multiworld_fr.md similarity index 100% rename from WebHostLib/static/assets/tutorial/A Link to the Past/multiworld_fr.md rename to worlds/alttp/docs/multiworld_fr.md diff --git a/WebHostLib/static/assets/tutorial/A Link to the Past/plando_en.md b/worlds/alttp/docs/plando_en.md similarity index 100% rename from WebHostLib/static/assets/tutorial/A Link to the Past/plando_en.md rename to worlds/alttp/docs/plando_en.md diff --git a/WebHostLib/static/assets/tutorial/retroarch-network-commands-en.png b/worlds/alttp/docs/retroarch-network-commands-en.png old mode 100755 new mode 100644 similarity index 100% rename from WebHostLib/static/assets/tutorial/retroarch-network-commands-en.png rename to worlds/alttp/docs/retroarch-network-commands-en.png diff --git a/worlds/archipidle/__init__.py b/worlds/archipidle/__init__.py index da6deeb5..859b4d18 100644 --- a/worlds/archipidle/__init__.py +++ b/worlds/archipidle/__init__.py @@ -1,4 +1,4 @@ -from BaseClasses import Item, MultiWorld, Region, Location, Entrance +from BaseClasses import Item, MultiWorld, Region, Location, Entrance, Tutorial from .Items import item_table from .Rules import set_rules from ..AutoWorld import World, WebWorld @@ -6,6 +6,14 @@ from ..AutoWorld import World, WebWorld class ArchipIDLEWebWorld(WebWorld): theme = 'partyTime' + tutorials = [Tutorial( + "Setup Guide", + "A guide to playing ArchipIDLE", + "English", + "guide_en.md", + "guide/en", + ["Farrak Kilhn"] + )] class ArchipIDLEWorld(World): diff --git a/WebHostLib/static/assets/gameInfo/en_ArchipIDLE.md b/worlds/archipidle/docs/en_ArchipIDLE.md similarity index 100% rename from WebHostLib/static/assets/gameInfo/en_ArchipIDLE.md rename to worlds/archipidle/docs/en_ArchipIDLE.md diff --git a/WebHostLib/static/assets/tutorial/ArchipIDLE/guide_en.md b/worlds/archipidle/docs/guide_en.md similarity index 100% rename from WebHostLib/static/assets/tutorial/ArchipIDLE/guide_en.md rename to worlds/archipidle/docs/guide_en.md diff --git a/worlds/checksfinder/__init__.py b/worlds/checksfinder/__init__.py index b3b5d2a7..7b5a61c9 100644 --- a/worlds/checksfinder/__init__.py +++ b/worlds/checksfinder/__init__.py @@ -9,12 +9,25 @@ from .Regions import checksfinder_regions, link_checksfinder_structures from .Rules import set_rules, set_completion_rules from worlds.generic.Rules import exclusion_rules -from BaseClasses import Region, Entrance, Item +from BaseClasses import Region, Entrance, Item, Tutorial from .Options import checksfinder_options -from ..AutoWorld import World +from ..AutoWorld import World, WebWorld client_version = 7 + +class ChecksFinderWeb(WebWorld): + tutorials = [Tutorial( + "Multiworld Setup Tutorial", + "A guide to setting up the Archipelago ChecksFinder software on your computer. This guide covers " + "single-player, multiworld, and related software.", + "English", + "checksfinder_en.md", + "checksfinder/en", + ["Mewlif"] + )] + + class ChecksFinderWorld(World): """ ChecksFinder is a game where you avoid mines and find checks inside the board @@ -23,6 +36,7 @@ class ChecksFinderWorld(World): game: str = "ChecksFinder" options = checksfinder_options topology_present = True + web = ChecksFinderWeb() item_name_to_id = {name: data.code for name, data in item_table.items()} location_name_to_id = {name: data.id for name, data in advancement_table.items()} diff --git a/WebHostLib/static/assets/tutorial/ChecksFinder/checksfinder_en.md b/worlds/checksfinder/docs/checksfinder_en.md similarity index 100% rename from WebHostLib/static/assets/tutorial/ChecksFinder/checksfinder_en.md rename to worlds/checksfinder/docs/checksfinder_en.md diff --git a/WebHostLib/static/assets/gameInfo/en_ChecksFinder.md b/worlds/checksfinder/docs/en_ChecksFinder.md similarity index 100% rename from WebHostLib/static/assets/gameInfo/en_ChecksFinder.md rename to worlds/checksfinder/docs/en_ChecksFinder.md diff --git a/worlds/factorio/__init__.py b/worlds/factorio/__init__.py index 02665391..9ca1156e 100644 --- a/worlds/factorio/__init__.py +++ b/worlds/factorio/__init__.py @@ -1,9 +1,9 @@ import collections import typing -from ..AutoWorld import World +from ..AutoWorld import World, WebWorld -from BaseClasses import Region, Entrance, Location, Item, RegionType +from BaseClasses import Region, Entrance, Location, Item, RegionType, Tutorial from .Technologies import base_tech_table, recipe_sources, base_technology_table, \ all_ingredient_names, all_product_sources, required_technologies, get_rocket_requirements, rocket_recipes, \ progressive_technology_table, common_tech_table, tech_to_progressive_lookup, progressive_tech_table, \ @@ -16,6 +16,17 @@ from .Options import factorio_options, MaxSciencePack, Silo, Satellite, TechTree import logging +class FactorioWeb(WebWorld): + tutorials = [Tutorial( + "Multiworld Setup Tutorial", + "A guide to setting up the Archipelago Factorio software on your computer.", + "English", + "setup_en.md", + "setup/en", + ["Berserker, Farrak Kilhn"] + )] + + class FactorioItem(Item): game = "Factorio" @@ -36,6 +47,8 @@ class Factorio(World): custom_recipes: typing.Dict[str, Recipe] advancement_technologies: typing.Set[str] + web = FactorioWeb() + item_name_to_id = all_items location_name_to_id = base_tech_table item_name_groups = { diff --git a/WebHostLib/static/assets/tutorial/Factorio/connect-to-ap-server.png b/worlds/factorio/docs/connect-to-ap-server.png similarity index 100% rename from WebHostLib/static/assets/tutorial/Factorio/connect-to-ap-server.png rename to worlds/factorio/docs/connect-to-ap-server.png diff --git a/WebHostLib/static/assets/gameInfo/en_Factorio.md b/worlds/factorio/docs/en_Factorio.md similarity index 100% rename from WebHostLib/static/assets/gameInfo/en_Factorio.md rename to worlds/factorio/docs/en_Factorio.md diff --git a/WebHostLib/static/assets/tutorial/Factorio/factorio-download.png b/worlds/factorio/docs/factorio-download.png similarity index 100% rename from WebHostLib/static/assets/tutorial/Factorio/factorio-download.png rename to worlds/factorio/docs/factorio-download.png diff --git a/WebHostLib/static/assets/tutorial/Factorio/setup_en.md b/worlds/factorio/docs/setup_en.md similarity index 97% rename from WebHostLib/static/assets/tutorial/Factorio/setup_en.md rename to worlds/factorio/docs/setup_en.md index b772239c..fc83c190 100644 --- a/WebHostLib/static/assets/tutorial/Factorio/setup_en.md +++ b/worlds/factorio/docs/setup_en.md @@ -91,7 +91,7 @@ potential conflicts with your currently-installed version of Factorio. Download appropriate to your operating system, and extract the folder to a convenient location (we recommend `C:\Factorio` or similar). -![Factorio Download Options](/static/assets/tutorial/Factorio/factorio-download.png) +![Factorio Download Options](/static/generated/docs/Factorio/factorio-download.png) Next, you should launch your Factorio Server by running `factorio.exe`, which is located at: `bin/x64/factorio.exe`. You will be asked to log in to your Factorio account using the same credentials you used on Factorio's website. After you @@ -120,7 +120,7 @@ This allows you to host your own Factorio game. Archipelago if you chose to include it during the installation process. 6. Enter `/connect [server-address]` into the input box at the bottom of the Archipelago Client and press "Enter" -![Factorio Client for Archipelago Connection Command](/static/assets/tutorial/factorio/connect-to-ap-server.png) +![Factorio Client for Archipelago Connection Command](/static/generated/docs/Factorio/connect-to-ap-server.png) 7. Launch your Factorio Client 8. Click on "Multiplayer" in the main menu diff --git a/worlds/ff1/__init__.py b/worlds/ff1/__init__.py index bad40c16..8b100561 100644 --- a/worlds/ff1/__init__.py +++ b/worlds/ff1/__init__.py @@ -1,5 +1,5 @@ from typing import Dict -from BaseClasses import Item, Location, MultiWorld +from BaseClasses import Item, Location, MultiWorld, Tutorial from .Items import ItemData, FF1Items, FF1_STARTER_ITEMS, FF1_PROGRESSION_LIST, FF1_BRIDGE from .Locations import EventId, FF1Locations, generate_rule, CHAOS_TERMINATED_EVENT from .Options import ff1_options @@ -8,6 +8,14 @@ from ..AutoWorld import World, WebWorld class FF1Web(WebWorld): settings_page = "https://finalfantasyrandomizer.com/" + tutorials = [Tutorial( + "Multiworld Setup Guide", + "A guide to playing Final Fantasy multiworld. This guide only covers playing multiworld.", + "English", + "multiworld_en.md", + "multiworld/en", + ["jat2980"] + )] class FF1World(World): diff --git a/WebHostLib/static/assets/gameInfo/en_Final Fantasy.md b/worlds/ff1/docs/en_Final Fantasy.md similarity index 100% rename from WebHostLib/static/assets/gameInfo/en_Final Fantasy.md rename to worlds/ff1/docs/en_Final Fantasy.md diff --git a/WebHostLib/static/assets/tutorial/Final Fantasy/multiworld_en.md b/worlds/ff1/docs/multiworld_en.md similarity index 100% rename from WebHostLib/static/assets/tutorial/Final Fantasy/multiworld_en.md rename to worlds/ff1/docs/multiworld_en.md diff --git a/worlds/generic/__init__.py b/worlds/generic/__init__.py index 926e0e1b..72bedf6b 100644 --- a/worlds/generic/__init__.py +++ b/worlds/generic/__init__.py @@ -1,12 +1,33 @@ from typing import NamedTuple, Union import logging -from BaseClasses import Item +from BaseClasses import Item, Tutorial -from ..AutoWorld import World +from ..AutoWorld import World, WebWorld from NetUtils import SlotType +class GenericWeb(WebWorld): + advanced_settings = Tutorial('Advanced YAML Guide', + 'A guide to reading YAML files and editing them to fully customize your game.', + 'English', 'advanced_settings_en.md', 'advanced_settings/en', + ['alwaysintreble', 'Alchav']) + commands = Tutorial('Archipelago Server and Client Commands', + 'A guide detailing the commands available to the user when participating in an Archipelago session.', + 'English', 'commands_en.md', 'commands/en', ['jat2980', 'Ijwu']) + plando = Tutorial('Archipelago Plando Guide', 'A guide to understanding and using plando for your game.', + 'English', 'plando_en.md', 'plando/en', ['alwaysintreble', 'Alchav']) + setup = Tutorial('Multiworld Setup Tutorial', + 'A guide to setting up the Archipelago software to generate and host multiworld games on your computer.', + 'English', 'setup_en.md', 'setup/en', ['alwaysintreble']) + triggers = Tutorial('Archipelago Triggers Guide', 'A guide to setting up and using triggers in your game settings.', + 'English', 'triggers_en.md', 'triggers/en', ['alwaysintreble']) + using_website = Tutorial('Archipelago Website User Guide', + 'A guide to using the Archipelago website to generate multiworlds or h ost pre-generated multiworlds.', + 'English', 'using_website_en.md', 'using_website/en', ['alwaysintreble']) + tutorials = [setup, using_website, commands, advanced_settings, triggers, plando] + + class GenericWorld(World): game = "Archipelago" topology_present = False @@ -18,6 +39,7 @@ class GenericWorld(World): "Server": -2 } hidden = True + web = GenericWeb() def generate_early(self): self.world.player_types[self.player] = SlotType.spectator # mark as spectator diff --git a/WebHostLib/static/assets/tutorial/Archipelago/advanced_settings_en.md b/worlds/generic/docs/advanced_settings_en.md similarity index 100% rename from WebHostLib/static/assets/tutorial/Archipelago/advanced_settings_en.md rename to worlds/generic/docs/advanced_settings_en.md diff --git a/WebHostLib/static/assets/tutorial/Archipelago/commands_en.md b/worlds/generic/docs/commands_en.md similarity index 100% rename from WebHostLib/static/assets/tutorial/Archipelago/commands_en.md rename to worlds/generic/docs/commands_en.md diff --git a/WebHostLib/static/assets/tutorial/Archipelago/plando_en.md b/worlds/generic/docs/plando_en.md similarity index 100% rename from WebHostLib/static/assets/tutorial/Archipelago/plando_en.md rename to worlds/generic/docs/plando_en.md diff --git a/WebHostLib/static/assets/tutorial/Archipelago/setup_en.md b/worlds/generic/docs/setup_en.md similarity index 100% rename from WebHostLib/static/assets/tutorial/Archipelago/setup_en.md rename to worlds/generic/docs/setup_en.md diff --git a/WebHostLib/static/assets/tutorial/Archipelago/triggers_en.md b/worlds/generic/docs/triggers_en.md similarity index 100% rename from WebHostLib/static/assets/tutorial/Archipelago/triggers_en.md rename to worlds/generic/docs/triggers_en.md diff --git a/WebHostLib/static/assets/tutorial/Archipelago/using_website_en.md b/worlds/generic/docs/using_website_en.md similarity index 100% rename from WebHostLib/static/assets/tutorial/Archipelago/using_website_en.md rename to worlds/generic/docs/using_website_en.md diff --git a/worlds/hk/__init__.py b/worlds/hk/__init__.py index 6fb2cb9c..015cb12c 100644 --- a/worlds/hk/__init__.py +++ b/worlds/hk/__init__.py @@ -14,8 +14,8 @@ from .ExtractedData import locations, starts, multi_locations, location_to_regio event_names, item_effects, connectors, one_ways from .Charms import names as charm_names -from BaseClasses import Region, Entrance, Location, MultiWorld, Item, RegionType -from ..AutoWorld import World, LogicMixin +from BaseClasses import Region, Entrance, Location, MultiWorld, Item, RegionType, Tutorial +from ..AutoWorld import World, LogicMixin, WebWorld white_palace_locations = { "Soul_Totem-Path_of_Pain_Below_Thornskip", @@ -88,6 +88,17 @@ progression_charms = { } +class HKWeb(WebWorld): + tutorials = [Tutorial( + "Mod Setup and Use Guide", + "A guide to playing Hollow Knight with Archipelago.", + "English", + "setup_en.md", + "setup/en", + ["Ijwu"] + )] + + class HKWorld(World): """Beneath the fading town of Dirtmouth sleeps a vast, ancient kingdom. Many are drawn beneath the surface, searching for riches, or glory, or answers to old secrets. @@ -97,6 +108,8 @@ class HKWorld(World): game: str = "Hollow Knight" options = hollow_knight_options + web = HKWeb() + item_name_to_id = {name: data.id for name, data in item_table.items()} location_name_to_id = {location_name: location_id for location_id, location_name in enumerate(locations, start=0x1000000)} diff --git a/WebHostLib/static/assets/gameInfo/en_Hollow Knight.md b/worlds/hk/docs/en_Hollow Knight.md similarity index 100% rename from WebHostLib/static/assets/gameInfo/en_Hollow Knight.md rename to worlds/hk/docs/en_Hollow Knight.md diff --git a/WebHostLib/static/assets/tutorial/Hollow Knight/setup_en.md b/worlds/hk/docs/setup_en.md similarity index 100% rename from WebHostLib/static/assets/tutorial/Hollow Knight/setup_en.md rename to worlds/hk/docs/setup_en.md diff --git a/worlds/meritous/__init__.py b/worlds/meritous/__init__.py index 24b9808b..b2632190 100644 --- a/worlds/meritous/__init__.py +++ b/worlds/meritous/__init__.py @@ -3,18 +3,29 @@ # This software is released under the MIT License. # https://opensource.org/licenses/MIT -from BaseClasses import Item, MultiWorld +from BaseClasses import Item, MultiWorld, Tutorial from Fill import fill_restrictive from .Items import item_table, item_groups, MeritousItem from .Locations import location_table, MeritousLocation from .Options import meritous_options, cost_scales from .Regions import create_regions from .Rules import set_rules -from ..AutoWorld import World +from ..AutoWorld import World, WebWorld client_version = 1 +class MeritousWeb(WebWorld): + tutorials = [Tutorial( + "Meritous Setup Tutorial", + "A guide to setting up the Archipelago Meritous software on your computer.", + "English", + "setup_en.md", + "setup/en", + ["KewlioMZX"] + )] + + class MeritousWorld(World): """ Meritous Gaiden is a procedurally generated bullet-hell dungeon crawl game. @@ -25,6 +36,8 @@ class MeritousWorld(World): game: str = "Meritous" topology_present: False + web = MeritousWeb() + item_name_to_id = item_table location_name_to_id = location_table item_name_groups = item_groups diff --git a/WebHostLib/static/assets/gameInfo/en_Meritous.md b/worlds/meritous/docs/en_Meritous.md similarity index 100% rename from WebHostLib/static/assets/gameInfo/en_Meritous.md rename to worlds/meritous/docs/en_Meritous.md diff --git a/WebHostLib/static/assets/tutorial/Meritous/setup_en.md b/worlds/meritous/docs/setup_en.md similarity index 100% rename from WebHostLib/static/assets/tutorial/Meritous/setup_en.md rename to worlds/meritous/docs/setup_en.md diff --git a/worlds/minecraft/__init__.py b/worlds/minecraft/__init__.py index 27f89554..19cc9ba3 100644 --- a/worlds/minecraft/__init__.py +++ b/worlds/minecraft/__init__.py @@ -9,7 +9,7 @@ from .Regions import mc_regions, link_minecraft_structures, default_connections from .Rules import set_advancement_rules, set_completion_rules from worlds.generic.Rules import exclusion_rules -from BaseClasses import Region, Entrance, Item +from BaseClasses import Region, Entrance, Item, Tutorial from .Options import minecraft_options from ..AutoWorld import World, WebWorld @@ -19,6 +19,36 @@ class MinecraftWebWorld(WebWorld): theme = "jungle" bug_report_page = "https://github.com/KonoTyran/Minecraft_AP_Randomizer/issues/new?assignees=&labels=bug&template=bug_report.yaml&title=%5BBug%5D%3A+Brief+Description+of+bug+here" + setup = Tutorial( + "Multiworld Setup Tutorial", + "A guide to setting up the Archipelago Minecraft software on your computer. This guide covers" + "single-player, multiworkd, and related software.", + "English", + "minecraft_en.md", + "minecraft/en", + ["Kono Tyran"] + ) + + setup_es = Tutorial( + setup.tutorial_name, + setup.description, + "Español", + "minecraft_es.md", + "minecraft/es", + ["Edos"] + ) + + setup_sv = Tutorial( + setup.tutorial_name, + setup.description, + "Swedish", + "minecraft_sv.md", + "minecraft/sv", + ["Albinum"] + ) + + tutorials = [setup, setup_es, setup_sv] + class MinecraftWorld(World): """ diff --git a/WebHostLib/static/assets/gameInfo/en_Minecraft.md b/worlds/minecraft/docs/en_Minecraft.md similarity index 100% rename from WebHostLib/static/assets/gameInfo/en_Minecraft.md rename to worlds/minecraft/docs/en_Minecraft.md diff --git a/WebHostLib/static/assets/tutorial/Minecraft/minecraft_en.md b/worlds/minecraft/docs/minecraft_en.md similarity index 100% rename from WebHostLib/static/assets/tutorial/Minecraft/minecraft_en.md rename to worlds/minecraft/docs/minecraft_en.md diff --git a/WebHostLib/static/assets/tutorial/Minecraft/minecraft_es.md b/worlds/minecraft/docs/minecraft_es.md similarity index 100% rename from WebHostLib/static/assets/tutorial/Minecraft/minecraft_es.md rename to worlds/minecraft/docs/minecraft_es.md diff --git a/WebHostLib/static/assets/tutorial/Minecraft/minecraft_sv.md b/worlds/minecraft/docs/minecraft_sv.md similarity index 100% rename from WebHostLib/static/assets/tutorial/Minecraft/minecraft_sv.md rename to worlds/minecraft/docs/minecraft_sv.md diff --git a/worlds/oot/__init__.py b/worlds/oot/__init__.py index b5dab0d9..7bde676f 100644 --- a/worlds/oot/__init__.py +++ b/worlds/oot/__init__.py @@ -27,11 +27,11 @@ from .HintList import getRequiredHints from .SaveContext import SaveContext from Utils import get_options, output_path -from BaseClasses import MultiWorld, CollectionState, RegionType +from BaseClasses import MultiWorld, CollectionState, RegionType, Tutorial from Options import Range, Toggle, OptionList from Fill import fill_restrictive, FillError from worlds.generic.Rules import exclusion_rules -from ..AutoWorld import World, AutoLogicRegister +from ..AutoWorld import World, AutoLogicRegister, WebWorld location_id_offset = 67000 @@ -66,6 +66,28 @@ class OOTCollectionState(metaclass=AutoLogicRegister): return ret +class OOTWeb(WebWorld): + setup = Tutorial( + "Multiworld Setup Tutorial", + "A guide to setting up the Archipelago Ocarina of Time software on your computer.", + "English", + "setup_en.md", + "setup/en", + ["Edos"] + ) + + setup_es = Tutorial( + setup.tutorial_name, + setup.description, + "Español", + "setup_es.md", + "setup/es", + setup.author + ) + + tutorials = [setup, setup_es] + + class OOTWorld(World): """ The Legend of Zelda: Ocarina of Time is a 3D action/adventure game. Travel through Hyrule in two time periods, @@ -80,6 +102,7 @@ class OOTWorld(World): location_name_to_id = location_name_to_id remote_items: bool = False remote_start_inventory: bool = False + web = OOTWeb() data_version = 2 diff --git a/WebHostLib/static/assets/gameInfo/en_Ocarina of Time.md b/worlds/oot/docs/en_Ocarina of Time.md similarity index 100% rename from WebHostLib/static/assets/gameInfo/en_Ocarina of Time.md rename to worlds/oot/docs/en_Ocarina of Time.md diff --git a/WebHostLib/static/assets/tutorial/Ocarina of Time/setup_en.md b/worlds/oot/docs/setup_en.md similarity index 100% rename from WebHostLib/static/assets/tutorial/Ocarina of Time/setup_en.md rename to worlds/oot/docs/setup_en.md diff --git a/WebHostLib/static/assets/tutorial/Ocarina of Time/setup_es.md b/worlds/oot/docs/setup_es.md similarity index 100% rename from WebHostLib/static/assets/tutorial/Ocarina of Time/setup_es.md rename to worlds/oot/docs/setup_es.md diff --git a/worlds/raft/__init__.py b/worlds/raft/__init__.py index 8a4a6443..5322a7e3 100644 --- a/worlds/raft/__init__.py +++ b/worlds/raft/__init__.py @@ -9,8 +9,20 @@ from .Regions import create_regions, getConnectionName from .Rules import set_rules from .Options import raft_options -from BaseClasses import Region, RegionType, Entrance, Location, MultiWorld, Item -from ..AutoWorld import World +from BaseClasses import Region, RegionType, Entrance, Location, MultiWorld, Item, Tutorial +from ..AutoWorld import World, WebWorld + + +class RaftWeb(WebWorld): + tutorials = [Tutorial( + "Multiworld Setup Guide", + "A guide to setting up Raft integration for Archipelago multiworld games.", + "English", + "setup_en.md", + "setup/en", + ["SunnyBat", "Awareqwx"] + )] + class RaftWorld(World): """ @@ -19,6 +31,7 @@ class RaftWorld(World): islands that you come across. """ game: str = "Raft" + web = RaftWeb() item_name_to_id = items_lookup_name_to_id.copy() lastItemId = max(filter(lambda val: val is not None, item_name_to_id.values())) diff --git a/WebHostLib/static/assets/gameInfo/en_Raft.md b/worlds/raft/docs/en_Raft.md similarity index 100% rename from WebHostLib/static/assets/gameInfo/en_Raft.md rename to worlds/raft/docs/en_Raft.md diff --git a/WebHostLib/static/assets/tutorial/Raft/setup_en.md b/worlds/raft/docs/setup_en.md similarity index 100% rename from WebHostLib/static/assets/tutorial/Raft/setup_en.md rename to worlds/raft/docs/setup_en.md diff --git a/worlds/rogue-legacy/__init__.py b/worlds/rogue-legacy/__init__.py index 32348494..9cff3736 100644 --- a/worlds/rogue-legacy/__init__.py +++ b/worlds/rogue-legacy/__init__.py @@ -1,6 +1,6 @@ import typing -from BaseClasses import Item, MultiWorld +from BaseClasses import Item, MultiWorld, Tutorial from .Items import LegacyItem, ItemData, item_table, vendors_table, static_classes_table, progressive_classes_table, \ skill_unlocks_table, blueprints_table, runes_table, misc_items_table from .Locations import LegacyLocation, location_table, base_location_table @@ -8,7 +8,18 @@ from .Options import legacy_options from .Regions import create_regions from .Rules import set_rules from .Names import ItemName -from ..AutoWorld import World +from ..AutoWorld import World, WebWorld + + +class LegacyWeb(WebWorld): + tutorials = [Tutorial( + "Multiworld Setup Guide", + "A guide to setting up the Rogue Legacy Randomizer software on your computer. This guide covers single-player, multiworld, and related software.", + "English", + "rogue-legacy_en.md", + "rogue-legacy/en", + ["Phar"] + )] class LegacyWorld(World): @@ -22,6 +33,7 @@ class LegacyWorld(World): topology_present = False data_version = 3 required_client_version = (0, 2, 3) + web = LegacyWeb() item_name_to_id = {name: data.code for name, data in item_table.items()} location_name_to_id = location_table diff --git a/WebHostLib/static/assets/gameInfo/en_Rogue Legacy.md b/worlds/rogue-legacy/docs/en_Rogue Legacy.md similarity index 100% rename from WebHostLib/static/assets/gameInfo/en_Rogue Legacy.md rename to worlds/rogue-legacy/docs/en_Rogue Legacy.md diff --git a/WebHostLib/static/assets/tutorial/Rogue Legacy/rogue-legacy_en.md b/worlds/rogue-legacy/docs/rogue-legacy_en.md similarity index 100% rename from WebHostLib/static/assets/tutorial/Rogue Legacy/rogue-legacy_en.md rename to worlds/rogue-legacy/docs/rogue-legacy_en.md diff --git a/worlds/ror2/__init__.py b/worlds/ror2/__init__.py index 0c3f6e33..27011c60 100644 --- a/worlds/ror2/__init__.py +++ b/worlds/ror2/__init__.py @@ -3,13 +3,24 @@ from .Items import RiskOfRainItem, item_table, item_pool_weights from .Locations import location_table, RiskOfRainLocation, base_location_table from .Rules import set_rules -from BaseClasses import Region, Entrance, Item, MultiWorld +from BaseClasses import Region, Entrance, Item, MultiWorld, Tutorial from .Options import ror2_options -from ..AutoWorld import World +from ..AutoWorld import World, WebWorld client_version = 1 +class RiskOfWeb(WebWorld): + tutorials = [Tutorial( + "Multiworld Setup Guide", + "A guide to setting up the Risk of Rain 2 integration for Archipelago multiworld games.", + "English", + "setup_en.md", + "setup/en", + ["Ijwu"] + )] + + class RiskOfRainWorld(World): """ Escape a chaotic alien planet by fighting through hordes of frenzied monsters – with your friends, or on your own. @@ -25,6 +36,7 @@ class RiskOfRainWorld(World): data_version = 3 forced_auto_forfeit = True + web = RiskOfWeb() def generate_basic(self): # shortcut for starting_inventory... The start_with_revive option lets you start with a Dio's Best Friend diff --git a/WebHostLib/static/assets/gameInfo/en_Risk of Rain 2.md b/worlds/ror2/docs/en_Risk of Rain 2.md similarity index 100% rename from WebHostLib/static/assets/gameInfo/en_Risk of Rain 2.md rename to worlds/ror2/docs/en_Risk of Rain 2.md diff --git a/WebHostLib/static/assets/tutorial/Risk of Rain 2/setup_en.md b/worlds/ror2/docs/setup_en.md similarity index 100% rename from WebHostLib/static/assets/tutorial/Risk of Rain 2/setup_en.md rename to worlds/ror2/docs/setup_en.md diff --git a/worlds/sm/__init__.py b/worlds/sm/__init__.py index 50115093..5a958330 100644 --- a/worlds/sm/__init__.py +++ b/worlds/sm/__init__.py @@ -17,8 +17,8 @@ from .Options import sm_options from .Rom import get_base_rom_path, ROM_PLAYER_LIMIT, SMDeltaPatch import Utils -from BaseClasses import Region, Entrance, Location, MultiWorld, Item, RegionType, CollectionState -from ..AutoWorld import World, AutoLogicRegister +from BaseClasses import Region, Entrance, Location, MultiWorld, Item, RegionType, CollectionState, Tutorial +from ..AutoWorld import World, AutoLogicRegister, WebWorld from logic.smboolmanager import SMBoolManager from graph.vanilla.graph_locations import locationsDict @@ -56,6 +56,17 @@ class SMCollectionState(metaclass=AutoLogicRegister): return tuple(player for player in multiword.get_all_ids() if multiword.game[player] == game_name) +class SMWeb(WebWorld): + tutorials = [Tutorial( + "Multiworld Setup Guide", + "A guide to setting up the Super Metroid Client on your computer. This guide covers single-player, multiworld, and related software.", + "English", + "multiworld_en.md", + "multiworld/en", + ["Farrak Kilhn"] + )] + + class SMWorld(World): game: str = "Super Metroid" topology_present = True @@ -65,6 +76,7 @@ class SMWorld(World): location_names: Set[str] = frozenset(locations_lookup_name_to_id) item_name_to_id = items_lookup_name_to_id location_name_to_id = locations_lookup_name_to_id + web = SMWeb() remote_items: bool = False remote_start_inventory: bool = False diff --git a/WebHostLib/static/assets/gameInfo/en_Super Metroid.md b/worlds/sm/docs/en_Super Metroid.md similarity index 100% rename from WebHostLib/static/assets/gameInfo/en_Super Metroid.md rename to worlds/sm/docs/en_Super Metroid.md diff --git a/WebHostLib/static/assets/tutorial/Super Metroid/multiworld_en.md b/worlds/sm/docs/multiworld_en.md similarity index 100% rename from WebHostLib/static/assets/tutorial/Super Metroid/multiworld_en.md rename to worlds/sm/docs/multiworld_en.md diff --git a/worlds/sm64ex/__init__.py b/worlds/sm64ex/__init__.py index 09976b57..7306f286 100644 --- a/worlds/sm64ex/__init__.py +++ b/worlds/sm64ex/__init__.py @@ -6,11 +6,23 @@ from .Locations import location_table, SM64Location from .Options import sm64_options from .Rules import set_rules from .Regions import create_regions, sm64courses -from BaseClasses import Region, RegionType, Entrance, Item, MultiWorld -from ..AutoWorld import World +from BaseClasses import Region, RegionType, Entrance, Item, MultiWorld, Tutorial +from ..AutoWorld import World, WebWorld client_version = 1 + +class SM64Web(WebWorld): + tutorials = [Tutorial( + "Multiworld Setup Guide", + "A guide to setting up SM64EX for MultiWorld.", + "English", + "setup_en.md", + "setup/en", + ["N00byKing"] + )] + + class SM64World(World): """ The first Super Mario game to feature 3D gameplay, it features freedom of movement within a large open world based on polygons, @@ -20,6 +32,8 @@ class SM64World(World): game: str = "Super Mario 64" topology_present = False + web = SM64Web() + item_name_to_id = item_table location_name_to_id = location_table diff --git a/WebHostLib/static/assets/gameInfo/en_Super Mario 64.md b/worlds/sm64ex/docs/en_Super Mario 64.md similarity index 100% rename from WebHostLib/static/assets/gameInfo/en_Super Mario 64.md rename to worlds/sm64ex/docs/en_Super Mario 64.md diff --git a/WebHostLib/static/assets/tutorial/Super Mario 64/setup_en.md b/worlds/sm64ex/docs/setup_en.md similarity index 100% rename from WebHostLib/static/assets/tutorial/Super Mario 64/setup_en.md rename to worlds/sm64ex/docs/setup_en.md diff --git a/worlds/smz3/__init__.py b/worlds/smz3/__init__.py index 8d3cd06b..0c675c9a 100644 --- a/worlds/smz3/__init__.py +++ b/worlds/smz3/__init__.py @@ -5,14 +5,14 @@ import random import threading from typing import Dict, Set, TextIO -from BaseClasses import Region, Entrance, Location, MultiWorld, Item, RegionType, CollectionState +from BaseClasses import Region, Entrance, Location, MultiWorld, Item, RegionType, CollectionState, Tutorial from worlds.generic.Rules import set_rule import worlds.smz3.TotalSMZ3.Item as TotalSMZ3Item from worlds.smz3.TotalSMZ3.World import World as TotalSMZ3World from worlds.smz3.TotalSMZ3.Config import Config, GameMode, GanonInvincible, Goal, KeyShuffle, MorphLocation, SMLogic, SwordLocation, Z3Logic from worlds.smz3.TotalSMZ3.Location import LocationType, locations_start_id, Location as TotalSMZ3Location from worlds.smz3.TotalSMZ3.Patch import Patch as TotalSMZ3Patch, getWord, getWordArray -from ..AutoWorld import World, AutoLogicRegister +from ..AutoWorld import World, AutoLogicRegister, WebWorld from .Rom import get_base_rom_bytes, SMZ3DeltaPatch from .ips import IPS_Patch from .Options import smz3_options @@ -34,6 +34,17 @@ class SMZ3CollectionState(metaclass=AutoLogicRegister): return ret +class SMZ3Web(WebWorld): + tutorials = [Tutorial( + "Multiworld Setup Guide", + "A guide to setting up the Archipelago Super Metroid and A Link to the Past Crossover randomizer on your computer. This guide covers single-player, multiworld, and related software.", + "English", + "multiworld_en.md", + "multiworld/en", + ["lordlou"] + )] + + class SMZ3World(World): """ A python port of Super Metroid & A Link To The Past Crossover Item Randomizer based on v11.2 of Total's SMZ3. @@ -47,6 +58,7 @@ class SMZ3World(World): location_names: Set[str] item_name_to_id = TotalSMZ3Item.lookup_name_to_id location_name_to_id: Dict[str, int] = {key : locations_start_id + value.Id for key, value in TotalSMZ3World(Config({}), "", 0, "").locationLookup.items()} + web = SMZ3Web() remote_items: bool = False remote_start_inventory: bool = False diff --git a/WebHostLib/static/assets/gameInfo/en_SMZ3.md b/worlds/smz3/docs/en_SMZ3.md similarity index 100% rename from WebHostLib/static/assets/gameInfo/en_SMZ3.md rename to worlds/smz3/docs/en_SMZ3.md diff --git a/WebHostLib/static/assets/tutorial/SMZ3/multiworld_en.md b/worlds/smz3/docs/multiworld_en.md similarity index 100% rename from WebHostLib/static/assets/tutorial/SMZ3/multiworld_en.md rename to worlds/smz3/docs/multiworld_en.md diff --git a/worlds/soe/__init__.py b/worlds/soe/__init__.py index fd94ebf2..0f29bad3 100644 --- a/worlds/soe/__init__.py +++ b/worlds/soe/__init__.py @@ -1,6 +1,6 @@ from ..AutoWorld import World, WebWorld from ..generic.Rules import set_rule -from BaseClasses import Region, Location, Entrance, Item, RegionType +from BaseClasses import Region, Location, Entrance, Item, RegionType, Tutorial from Utils import output_path import typing import os @@ -134,6 +134,14 @@ def _get_item_grouping() -> typing.Dict[str, typing.Set[str]]: class SoEWebWorld(WebWorld): theme = 'jungle' + tutorials = [Tutorial( + "Multiworld Setup Guide", + "A guide to playing Secret of Evermore randomizer. This guide covers single-player, multiworld and related software.", + "English", + "multiworld_en.md", + "multiworld/en", + ["Black Sliver"] + )] class SoEWorld(World): diff --git a/WebHostLib/static/assets/gameInfo/en_Secret of Evermore.md b/worlds/soe/docs/en_Secret of Evermore.md similarity index 100% rename from WebHostLib/static/assets/gameInfo/en_Secret of Evermore.md rename to worlds/soe/docs/en_Secret of Evermore.md diff --git a/WebHostLib/static/assets/tutorial/Secret of Evermore/multiworld_en.md b/worlds/soe/docs/multiworld_en.md similarity index 100% rename from WebHostLib/static/assets/tutorial/Secret of Evermore/multiworld_en.md rename to worlds/soe/docs/multiworld_en.md diff --git a/worlds/spire/__init__.py b/worlds/spire/__init__.py index c1f9229c..2b420d62 100644 --- a/worlds/spire/__init__.py +++ b/worlds/spire/__init__.py @@ -1,19 +1,31 @@ import string -from BaseClasses import Item, MultiWorld, Region, Location, Entrance +from BaseClasses import Item, MultiWorld, Region, Location, Entrance, Tutorial from .Items import item_table, item_pool, event_item_pairs from .Locations import location_table from .Regions import create_regions from .Rules import set_rules -from ..AutoWorld import World +from ..AutoWorld import World, WebWorld from .Options import spire_options +class SpireWeb(WebWorld): + tutorials = [Tutorial( + "Multiworld Setup Guide", + "A guide to setting up Slay the Spire for Archipelago. This guide covers single-player, multiworld, and related software.", + "English", + "slay-the-spire_en.md", + "slay-the-spire/en", + ["Phar"] + )] + + class SpireWorld(World): options = spire_options game = "Slay the Spire" topology_present = False data_version = 1 + web = SpireWeb() item_name_to_id = {name: data.code for name, data in item_table.items()} location_name_to_id = location_table diff --git a/WebHostLib/static/assets/gameInfo/en_Slay the Spire.md b/worlds/spire/docs/en_Slay the Spire.md similarity index 100% rename from WebHostLib/static/assets/gameInfo/en_Slay the Spire.md rename to worlds/spire/docs/en_Slay the Spire.md diff --git a/WebHostLib/static/assets/tutorial/Slay the Spire/slay-the-spire_en.md b/worlds/spire/docs/slay-the-spire_en.md similarity index 100% rename from WebHostLib/static/assets/tutorial/Slay the Spire/slay-the-spire_en.md rename to worlds/spire/docs/slay-the-spire_en.md diff --git a/worlds/subnautica/__init__.py b/worlds/subnautica/__init__.py index 92890521..3943ea23 100644 --- a/worlds/subnautica/__init__.py +++ b/worlds/subnautica/__init__.py @@ -11,8 +11,19 @@ from .Regions import create_regions from .Rules import set_rules from .Options import options -from BaseClasses import Region, Entrance, Location, MultiWorld, Item -from ..AutoWorld import World +from BaseClasses import Region, Entrance, Location, MultiWorld, Item, Tutorial +from ..AutoWorld import World, WebWorld + + +class SubnaticaWeb(WebWorld): + tutorials = [Tutorial( + "Multiworld Setup Guide", + "A guide to setting up the Subnautica randomizer connected to an Archipelago Multiworld", + "English", + "setup_en.md", + "setup/en", + ["Berserker"] + )] class SubnauticaWorld(World): @@ -22,6 +33,7 @@ class SubnauticaWorld(World): You must find a cure for yourself, build an escape rocket, and leave the planet. """ game: str = "Subnautica" + web = SubnaticaWeb() item_name_to_id = items_lookup_name_to_id location_name_to_id = locations_lookup_name_to_id diff --git a/WebHostLib/static/assets/gameInfo/en_Subnautica.md b/worlds/subnautica/docs/en_Subnautica.md similarity index 100% rename from WebHostLib/static/assets/gameInfo/en_Subnautica.md rename to worlds/subnautica/docs/en_Subnautica.md diff --git a/WebHostLib/static/assets/tutorial/Subnautica/setup_en.md b/worlds/subnautica/docs/setup_en.md similarity index 100% rename from WebHostLib/static/assets/tutorial/Subnautica/setup_en.md rename to worlds/subnautica/docs/setup_en.md diff --git a/worlds/timespinner/__init__.py b/worlds/timespinner/__init__.py index a3ce4db1..929cd622 100644 --- a/worlds/timespinner/__init__.py +++ b/worlds/timespinner/__init__.py @@ -1,5 +1,5 @@ from typing import Dict, List, Set, Tuple, TextIO -from BaseClasses import Item, MultiWorld, Location +from BaseClasses import Item, MultiWorld, Location, Tutorial from ..AutoWorld import World, WebWorld from .LogicMixin import TimespinnerLogic from .Items import get_item_names_per_category, item_table, starter_melee_weapons, starter_spells, starter_progression_items, filler_items @@ -10,6 +10,25 @@ from .PyramidKeys import get_pyramid_keys_unlock class TimespinnerWebWorld(WebWorld): theme = "ice" + setup = Tutorial( + "Multiworld Setup Guide", + "A guide to setting up the Timespinner randomizer connected to an Archipelago Multiworld", + "English", + "setup_en.md", + "setup/en", + ["Jarno"] + ) + + setup_de = Tutorial( + setup.tutorial_name, + setup.description, + "Deutsch", + "setup_de.md", + "setup/en", + ["Grrmo", "Fynxes", "Blaze0168"] + ) + + tutorials = [setup, setup_de] class TimespinnerWorld(World): """ diff --git a/WebHostLib/static/assets/gameInfo/en_Timespinner.md b/worlds/timespinner/docs/en_Timespinner.md similarity index 100% rename from WebHostLib/static/assets/gameInfo/en_Timespinner.md rename to worlds/timespinner/docs/en_Timespinner.md diff --git a/WebHostLib/static/assets/tutorial/Timespinner/setup_de.md b/worlds/timespinner/docs/setup_de.md similarity index 98% rename from WebHostLib/static/assets/tutorial/Timespinner/setup_de.md rename to worlds/timespinner/docs/setup_de.md index ca430dbc..0fe3fe17 100644 --- a/WebHostLib/static/assets/tutorial/Timespinner/setup_de.md +++ b/worlds/timespinner/docs/setup_de.md @@ -1,50 +1,50 @@ -# Timespinner Randomizer Installationsanweisungen - -## Benötigte Software - -- [Timespinner (Steam)](https://store.steampowered.com/app/368620/Timespinner/) - , [Timespinner (Humble)](https://www.humblebundle.com/store/timespinner) - oder [Timespinner (GOG)](https://www.gog.com/game/timespinner) (andere Versionen werden nicht unterstützt) -- [Timespinner Randomizer](https://github.com/JarnoWesthof/TsRandomizer) - -## Wie funktioniert's? - -Der Timespinner Randomizer lädt die Timespinner.exe im gleichen Verzeichnis und verändert seine Speicherinformationen um -die Randomisierung der Gegenstände zu erlauben - -## Installationsanweisungen - -1. Die aktuellsten Dateien des Randomizers findest du ganz oben auf dieser - Webseite: [Timespinner Randomizer Releases](https://github.com/JarnoWesthof/TsRandomizer/releases). Lade dir unter ' - Assets' die .zip Datei für dein Betriebssystem herunter -2. Entpacke die .zip Datei im Ordner, in dem das Spiel Timespinner installiert ist - -## Den Randomizer starten - -- auf Windows: Starte die Datei TsRandomizer.exe -- auf Linux: Starte die Datei TsRandomizer.bin.x86_64 -- auf Mac: Starte die Datei TsRandomizer.bin.osx - -... im Ordner in dem die Inhalte aus der .zip Datei entpackt wurden - -Weitere Informationen zum Randomizer findest du hier: [ReadMe](https://github.com/JarnoWesthof/TsRandomizer) - -## An einer Multiworld teilnehmen - -1. Starte den Randomizer wie unter [Den Randomizer starten](#Den-Randomizer-starten) beschrieben -2. Wähle "New Game" -3. Wechsle "<< Select Seed >>" zu "<< Archiplago >>" indem du "links" auf deinem Controller oder der Tastatur drückst -4. Wähle "<< Archipelago >>" um ein neues Menu zu öffnen, wo du deine Logininformationen für Archipelago eingeben kannst - * ANMERKUNG: Die Eingabefelder unterstützen das Einfügen von Informationen mittels 'Ctrl + V' -5. Wähle "Connect" -6. Wenn alles funktioniert hat, wechselt das Spiel zurück zur Auswahl des Schwierigkeitsgrads und das Spiel startet, - sobald du einen davon ausgewählt hast - -## Woher bekomme ich eine Konfigurationsdatei? - -Die [Player Settings](https://archipelago.gg/games/Timespinner/player-settings) Seite auf der Website erlaubt dir, -persönliche Einstellungen zu definieren und diese in eine Konfigurationsdatei zu exportieren - -* Die Timespinner Randomizer Option "StinkyMaw" ist in Archipelago Seeds aktuell immer an -* Die Timespinner Randomizer Optionen "ProgressiveVerticalMovement" & "ProgressiveKeycards" werden in Archipelago Seeds - aktuell nicht unterstützt +# Timespinner Randomizer Installationsanweisungen + +## Benötigte Software + +- [Timespinner (Steam)](https://store.steampowered.com/app/368620/Timespinner/) + , [Timespinner (Humble)](https://www.humblebundle.com/store/timespinner) + oder [Timespinner (GOG)](https://www.gog.com/game/timespinner) (andere Versionen werden nicht unterstützt) +- [Timespinner Randomizer](https://github.com/JarnoWesthof/TsRandomizer) + +## Wie funktioniert's? + +Der Timespinner Randomizer lädt die Timespinner.exe im gleichen Verzeichnis und verändert seine Speicherinformationen um +die Randomisierung der Gegenstände zu erlauben + +## Installationsanweisungen + +1. Die aktuellsten Dateien des Randomizers findest du ganz oben auf dieser + Webseite: [Timespinner Randomizer Releases](https://github.com/JarnoWesthof/TsRandomizer/releases). Lade dir unter ' + Assets' die .zip Datei für dein Betriebssystem herunter +2. Entpacke die .zip Datei im Ordner, in dem das Spiel Timespinner installiert ist + +## Den Randomizer starten + +- auf Windows: Starte die Datei TsRandomizer.exe +- auf Linux: Starte die Datei TsRandomizer.bin.x86_64 +- auf Mac: Starte die Datei TsRandomizer.bin.osx + +... im Ordner in dem die Inhalte aus der .zip Datei entpackt wurden + +Weitere Informationen zum Randomizer findest du hier: [ReadMe](https://github.com/JarnoWesthof/TsRandomizer) + +## An einer Multiworld teilnehmen + +1. Starte den Randomizer wie unter [Den Randomizer starten](#Den-Randomizer-starten) beschrieben +2. Wähle "New Game" +3. Wechsle "<< Select Seed >>" zu "<< Archiplago >>" indem du "links" auf deinem Controller oder der Tastatur drückst +4. Wähle "<< Archipelago >>" um ein neues Menu zu öffnen, wo du deine Logininformationen für Archipelago eingeben kannst + * ANMERKUNG: Die Eingabefelder unterstützen das Einfügen von Informationen mittels 'Ctrl + V' +5. Wähle "Connect" +6. Wenn alles funktioniert hat, wechselt das Spiel zurück zur Auswahl des Schwierigkeitsgrads und das Spiel startet, + sobald du einen davon ausgewählt hast + +## Woher bekomme ich eine Konfigurationsdatei? + +Die [Player Settings](https://archipelago.gg/games/Timespinner/player-settings) Seite auf der Website erlaubt dir, +persönliche Einstellungen zu definieren und diese in eine Konfigurationsdatei zu exportieren + +* Die Timespinner Randomizer Option "StinkyMaw" ist in Archipelago Seeds aktuell immer an +* Die Timespinner Randomizer Optionen "ProgressiveVerticalMovement" & "ProgressiveKeycards" werden in Archipelago Seeds + aktuell nicht unterstützt diff --git a/WebHostLib/static/assets/tutorial/Timespinner/setup_en.md b/worlds/timespinner/docs/setup_en.md similarity index 100% rename from WebHostLib/static/assets/tutorial/Timespinner/setup_en.md rename to worlds/timespinner/docs/setup_en.md diff --git a/worlds/v6/__init__.py b/worlds/v6/__init__.py index 1970c482..014b9c88 100644 --- a/worlds/v6/__init__.py +++ b/worlds/v6/__init__.py @@ -5,11 +5,23 @@ from .Locations import location_table, V6Location from .Options import v6_options from .Rules import set_rules from .Regions import create_regions -from BaseClasses import Region, RegionType, Entrance, Item, MultiWorld -from ..AutoWorld import World +from BaseClasses import Region, RegionType, Entrance, Item, MultiWorld, Tutorial +from ..AutoWorld import World, WebWorld client_version = 1 + +class V6Web(WebWorld): + tutorials = [Tutorial( + "Multiworld Setup Guide", + "A guide to setting up VVVVVV for Multiworld.", + "English", + "setup_en.md", + "setup/en", + ["N00byKing"] + )] + + class V6World(World): """ VVVVVV is a platform game all about exploring one simple mechanical idea - what if you reversed gravity instead of jumping? @@ -17,6 +29,7 @@ class V6World(World): game: str = "VVVVVV" topology_present = False + web = V6Web() item_name_to_id = item_table location_name_to_id = location_table diff --git a/WebHostLib/static/assets/gameInfo/en_VVVVVV.md b/worlds/v6/docs/en_VVVVVV.md similarity index 100% rename from WebHostLib/static/assets/gameInfo/en_VVVVVV.md rename to worlds/v6/docs/en_VVVVVV.md diff --git a/WebHostLib/static/assets/tutorial/VVVVVV/setup_en.md b/worlds/v6/docs/setup_en.md similarity index 100% rename from WebHostLib/static/assets/tutorial/VVVVVV/setup_en.md rename to worlds/v6/docs/setup_en.md diff --git a/worlds/witness/__init__.py b/worlds/witness/__init__.py index 6d02e774..76132938 100644 --- a/worlds/witness/__init__.py +++ b/worlds/witness/__init__.py @@ -4,7 +4,7 @@ Archipelago init file for The Witness import typing -from BaseClasses import Region, RegionType, Location, MultiWorld, Item, Entrance +from BaseClasses import Region, RegionType, Location, MultiWorld, Item, Entrance, Tutorial from ..AutoWorld import World, WebWorld from .player_logic import StaticWitnessLogic, WitnessPlayerLogic from .locations import WitnessPlayerLocations, StaticWitnessLocations @@ -17,6 +17,14 @@ from .utils import best_junk_to_add_based_on_weights class WitnessWebWorld(WebWorld): theme = "jungle" + tutorials = [Tutorial( + "Multiworld Setup Guide", + "A guide to playing The Witness with Archipelago.", + "English", + "setup_en.md", + "setup/en", + ["NewSoupVi", "Jarno"] + )] class WitnessWorld(World): diff --git a/WebHostLib/static/assets/gameInfo/en_The Witness.md b/worlds/witness/docs/en_The Witness.md similarity index 100% rename from WebHostLib/static/assets/gameInfo/en_The Witness.md rename to worlds/witness/docs/en_The Witness.md diff --git a/WebHostLib/static/assets/tutorial/The Witness/setup_en.md b/worlds/witness/docs/setup_en.md similarity index 100% rename from WebHostLib/static/assets/tutorial/The Witness/setup_en.md rename to worlds/witness/docs/setup_en.md