From 944347a2b3e917d558dfea3e4bc591131424821f Mon Sep 17 00:00:00 2001 From: Hussein Farran Date: Sun, 29 Aug 2021 14:02:02 -0400 Subject: [PATCH 01/10] Risk of Rain 2 implementation --- worlds/ror2/Items.py | 42 ++++++++++++++++++ worlds/ror2/Locations.py | 23 ++++++++++ worlds/ror2/Options.py | 42 ++++++++++++++++++ worlds/ror2/Rules.py | 32 ++++++++++++++ worlds/ror2/__init__.py | 93 ++++++++++++++++++++++++++++++++++++++++ 5 files changed, 232 insertions(+) create mode 100644 worlds/ror2/Items.py create mode 100644 worlds/ror2/Locations.py create mode 100644 worlds/ror2/Options.py create mode 100644 worlds/ror2/Rules.py create mode 100644 worlds/ror2/__init__.py diff --git a/worlds/ror2/Items.py b/worlds/ror2/Items.py new file mode 100644 index 00000000..35992e1f --- /dev/null +++ b/worlds/ror2/Items.py @@ -0,0 +1,42 @@ +from BaseClasses import Item +import typing + + +class RiskOfRainItem(Item): + game: str = "Risk of Rain 2" + +# 37000 - 38000 +item_table = { + "Dio's Best Friend": 37001, + "Common Item": 37002, + "Uncommon Item": 37003, + "Legendary Item": 37004, + "Boss Item": 37005, + "Lunar Item": 37006, + "Equipment": 37007, + "Item Scrap, White": 37008, + "Item Scrap, Green": 37009, + "Item Scrap, Red": 37010, + "Item Scrap, Yellow": 37011, + "Victory": None, + "Beat Level One": None, + "Beat Level Two": None, + "Beat Level Three": None, + "Beat Level Four": None, + "Beat Level Five": None, +} + +junk_weights = { + "Item Scrap, Green": 16, + "Item Scrap, Red": 4, + "Item Scrap, Yellow": 1, + "Item Scrap, White": 32, + "Common Item": 64, + "Uncommon Item": 32, + "Legendary Item": 8, + "Boss Item": 4, + "Lunar Item": 16, + "Equipment": 32, +} + +lookup_id_to_name: typing.Dict[int, str] = {id: name for name, id in item_table.items() if id} diff --git a/worlds/ror2/Locations.py b/worlds/ror2/Locations.py new file mode 100644 index 00000000..eded4b32 --- /dev/null +++ b/worlds/ror2/Locations.py @@ -0,0 +1,23 @@ +from BaseClasses import Location +import typing + +class RiskOfRainLocation(Location): + game: str = "Risk of Rain 2" + +# 37000 - 38000 +base_location_table = { + "Victory": 37999, + "Level One": 37001, + "Level Two": 37002, + "Level Three": 37003, + "Level Four": 37004, + "Level Five": 37005 +} + +item_pickups = { + f"ItemPickup{i}": 37005+i for i in range(1, 51) +} + +location_table = {**base_location_table, **item_pickups} + +lookup_id_to_name: typing.Dict[int, str] = {id: name for name, id in location_table.items()} diff --git a/worlds/ror2/Options.py b/worlds/ror2/Options.py new file mode 100644 index 00000000..bb11d0bd --- /dev/null +++ b/worlds/ror2/Options.py @@ -0,0 +1,42 @@ +import typing +from Options import Option, Toggle, Range + + +class TotalLocations(Range): + """Number of location checks which are added to the Risk of Rain playthrough.""" + displayname = "Total Locations" + range_start = 10 + range_end = 50 + default = 15 + + +class TotalRevivals(Range): + """Number of `Dio's Best Friend` item put in the item pool.""" + displayname = "Total Revivals Available" + range_start = 0 + range_end = 10 + default = 4 + + +class ItemPickupStep(Range): + """Number of items to pick up before an AP Check is completed. + Setting to 1 means every other pickup. + Setting to 2 means every third pickup. So on...""" + displayname = "Item Pickup Step" + range_start = 0 + range_end = 5 + default = 1 + + +class StartWithRevive(Toggle): + """Start the game with a `Dio's Best Friend` item.""" + displayname = "Start with a Revive" + default = True + + +ror2_options: typing.Dict[str, type(Option)] = { + "total_locations": TotalLocations, + "total_revivals": TotalRevivals, + "start_with_revive": StartWithRevive, + "item_pickup_step": ItemPickupStep +} diff --git a/worlds/ror2/Rules.py b/worlds/ror2/Rules.py new file mode 100644 index 00000000..c1992be5 --- /dev/null +++ b/worlds/ror2/Rules.py @@ -0,0 +1,32 @@ +from BaseClasses import MultiWorld +from ..AutoWorld import LogicMixin +from ..generic.Rules import set_rule + + +class RiskOfRainLogic(LogicMixin): + def _ror_has_items(self, player: int, amount: int) -> bool: + count: int = self.item_count("Common Item", player) + self.item_count("Uncommon Item", player) + \ + self.item_count("Legendary Item", player) + self.item_count("Boss Item", player) + return count >= amount + + +def set_rules(world: MultiWorld, player: int): + total_checks = world.total_locations[player] + # divide by 5 since 5 levels (then commencement) + items_per_level = total_checks / 5 + leftover = total_checks % 5 + + set_rule(world.get_location("Level One", player), + lambda state: state._ror_has_items(player, items_per_level + leftover)) + set_rule(world.get_location("Level Two", player), + lambda state: state._ror_has_items(player, items_per_level) and state.has("Beat Level One", player)) + set_rule(world.get_location("Level Three", player), + lambda state: state._ror_has_items(player, items_per_level) and state.has("Beat Level Two", player)) + set_rule(world.get_location("Level Four", player), + lambda state: state._ror_has_items(player, items_per_level) and state.has("Beat Level Three", player)) + set_rule(world.get_location("Level Five", player), + lambda state: state._ror_has_items(player, items_per_level) and state.has("Beat Level Four", player)) + set_rule(world.get_location("Victory", player), + lambda state: state._ror_has_items(player, items_per_level) and state.has("Beat Level Five", player)) + + world.completion_condition[player] = lambda state: state.has("Victory", player) \ No newline at end of file diff --git a/worlds/ror2/__init__.py b/worlds/ror2/__init__.py new file mode 100644 index 00000000..cb6da6d4 --- /dev/null +++ b/worlds/ror2/__init__.py @@ -0,0 +1,93 @@ +import string +from .Items import RiskOfRainItem, item_table, junk_weights +from .Locations import location_table, RiskOfRainLocation, base_location_table +from .Rules import set_rules + +from BaseClasses import Region, Entrance, Item, MultiWorld +from .Options import ror2_options +from ..AutoWorld import World + +client_version = 1 + + +class RiskOfRainWorld(World): + game: str = "Risk of Rain 2" + options = ror2_options + topology_present = False + + item_name_to_id = {name: data for name, data in item_table.items()} + location_name_to_id = {name: data for name, data in location_table.items()} + + data_version = 1 + + def generate_basic(self): + # shortcut for starting_inventory... The start_with_revive option lets you start with a Dio's Best Friend + if self.world.start_with_revive[self.player].value: + self.world.push_precollected(self.world.create_item("Dio's Best Friend", self.player)) + + # Generate item pool + itempool = [] + junk_pool = junk_weights.copy() + + # Add revive items for the player + itempool += ["Dio's Best Friend"] * self.world.total_revivals[self.player] + + # Fill remaining items with randomly generated junk + itempool += self.world.random.choices(list(junk_pool.keys()), weights=list(junk_pool.values()), + k=self.world.total_locations[self.player] - + self.world.total_revivals[self.player]) + + # Convert itempool into real items + itempool = [item for item in map(lambda name: self.create_item(name), itempool)] + + self.world.itempool += itempool + + def set_rules(self): + set_rules(self.world, self.player) + + def create_regions(self): + create_regions(self.world, self.player) + + def fill_slot_data(self): + return { + "itemPickupStep": self.world.item_pickup_step[self.player].value, + "seed": "".join(self.world.slot_seeds[self.player].choice(string.digits) for i in range(16)), + "totalLocations": self.world.total_locations[self.player].value + } + + def create_item(self, name: str) -> Item: + item_id = item_table[name] + item = RiskOfRainItem(name, True, item_id, self.player) + return item + + +def create_regions(world, player: int): + world.regions += [ + create_region(world, player, 'Menu', None, ['Lobby']), + create_region(world, player, 'Petrichor V', + [location for location in base_location_table] + + [f"ItemPickup{i}" for i in range(1, world.total_locations[player])]) + ] + + world.get_entrance("Lobby", player).connect(world.get_region("Petrichor V", player)) + world.get_location("Level One", player).place_locked_item(RiskOfRainItem("Beat Level One", True, None, player)) + world.get_location("Level Two", player).place_locked_item(RiskOfRainItem("Beat Level Two", True, None, player)) + world.get_location("Level Three", player).place_locked_item(RiskOfRainItem("Beat Level Three", True, None, player)) + world.get_location("Level Four", player).place_locked_item(RiskOfRainItem("Beat Level Four", True, None, player)) + world.get_location("Level Five", player).place_locked_item(RiskOfRainItem("Beat Level Five", True, None, player)) + world.get_location("Victory", player).place_locked_item(RiskOfRainItem("Victory", True, None, player)) + + +def create_region(world: MultiWorld, player: int, name: str, locations=None, exits=None): + ret = Region(name, None, name, player) + ret.world = world + if locations: + for location in locations: + loc_id = location_table.get(location, 0) + location = RiskOfRainLocation(player, location, loc_id, ret) + ret.locations.append(location) + if exits: + for exit in exits: + ret.exits.append(Entrance(player, exit, ret)) + + return ret From 2f28afb46e61e9b14e886f611c39cf7dae1e74c2 Mon Sep 17 00:00:00 2001 From: Hussein Farran Date: Tue, 31 Aug 2021 00:17:08 -0400 Subject: [PATCH 02/10] Add RoR2 Docs --- WebHostLib/__init__.py | 6 ++++ .../static/assets/tutorial/ror2/setup_en.md | 28 +++++++++++++++++++ .../static/assets/tutorial/tutorials.json | 19 +++++++++++++ 3 files changed, 53 insertions(+) create mode 100644 WebHostLib/static/assets/tutorial/ror2/setup_en.md diff --git a/WebHostLib/__init__.py b/WebHostLib/__init__.py index 59091f6a..529bfbe1 100644 --- a/WebHostLib/__init__.py +++ b/WebHostLib/__init__.py @@ -119,6 +119,12 @@ games_list = { the last living Metroid. Go to planet Zebes and search out the abilities you will need to power up your suit and defeat the villainous leader of the space pirates, Mother Brain. """), + "Risk of Rain 2": ("Risk of Rain 2", + """ + Escape a chaotic alien planet by fighting through hordes of frenzied monsters – with your friends + , or on your own. Combine loot in surprising ways and master each character until you become the + havoc you feared upon your first crash landing. + """) # "Ori and the Blind Forest": ("Ori and the Blind Forest", "Coming Soon™"), # "Hollow Knight": ("Hollow Knight", "Coming Soon™"), } diff --git a/WebHostLib/static/assets/tutorial/ror2/setup_en.md b/WebHostLib/static/assets/tutorial/ror2/setup_en.md new file mode 100644 index 00000000..e1c8f041 --- /dev/null +++ b/WebHostLib/static/assets/tutorial/ror2/setup_en.md @@ -0,0 +1,28 @@ +# Risk of Rain 2 Setup Guide + +## Install using r2modman +### Install r2modman +Head on over to the r2modman page on Thunderstore and follow the installation instructions. + +https://thunderstore.io/package/ebkr/r2modman/ + +### Install Archipelago Mod using r2modman +You can install the Archipelago mod using r2modman in one of two ways. +One, you can use the Thunderstore website and click on the "Install with Mod Manager" link. + +https://thunderstore.io/package/ArchipelagoMW/Archipelago/ + +You can also search for the "Archipelago" mod in the r2modman interface. +The mod manager should automatically install all necessary dependencies as well. + +### Running the Modded Game +Click on the "Start modded" button in the top left in r2modman to start the game with the +Archipelago mod installed. + +## Joining an Archipelago Session +There will be a menu button on the right side of the screen in the character select menu. +Click it in order to bring up the in lobby mod config. +From here you can expand the Archipelago sections and fill in the relevant info. +Keep password blank if there is no password on the server. + +Simply check `Enable Archipelago?` and when you start the run it will automatically connect. \ No newline at end of file diff --git a/WebHostLib/static/assets/tutorial/tutorials.json b/WebHostLib/static/assets/tutorial/tutorials.json index 2457e096..4931e4b2 100644 --- a/WebHostLib/static/assets/tutorial/tutorials.json +++ b/WebHostLib/static/assets/tutorial/tutorials.json @@ -139,5 +139,24 @@ ] } ] + }, + { + "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": "ror2/setup_en.md", + "link": "ror2/setup/en", + "authors": [ + "Ijwu" + ] + } + ] + } + ] } ] From 2f4b248a45b5ebc6ea19c7020336514f9fc1b311 Mon Sep 17 00:00:00 2001 From: Hussein Farran Date: Tue, 31 Aug 2021 00:25:48 -0400 Subject: [PATCH 03/10] Add more information to the RoR2 docs. --- .../static/assets/tutorial/ror2/setup_en.md | 34 ++++++++++++++++++- 1 file changed, 33 insertions(+), 1 deletion(-) diff --git a/WebHostLib/static/assets/tutorial/ror2/setup_en.md b/WebHostLib/static/assets/tutorial/ror2/setup_en.md index e1c8f041..5d2d16df 100644 --- a/WebHostLib/static/assets/tutorial/ror2/setup_en.md +++ b/WebHostLib/static/assets/tutorial/ror2/setup_en.md @@ -25,4 +25,36 @@ Click it in order to bring up the in lobby mod config. From here you can expand the Archipelago sections and fill in the relevant info. Keep password blank if there is no password on the server. -Simply check `Enable Archipelago?` and when you start the run it will automatically connect. \ No newline at end of file +Simply check `Enable Archipelago?` and when you start the run it will automatically connect. + +## Gameplay +The Risk of Rain 2 players send checks by causing items to spawn in-game. That means opening chests or killing bosses, generally. +An item check is only sent out after a certain number of items are picked up. This count is configurable in the player's YAML. + +## YAML Settings +An example YAML would look like this: +```yaml +description: Ijwu-ror2 +name: Ijwu + +game: + Risk of Rain 2: 1 + +Risk of Rain 2: + total_locations: 15 + total_revivals: 4 + start_with_revive: true + item_pickup_step: 1 +``` + +| Name | Description | Allowed values | +| ---- | ----------- | -------------- | +| total_locations | The total number of location checks that will be attributed to the Risk of Rain player. | 10 - 50 | +| total_revivals | The total number of items in the Risk of Rain player's item pool (items other players pick up for them) replaced with `Dio's Best Friend`. | 0 - 5 | +| start_with_revive | Starts the player off with a `Dio's Best Friend`. Functionally equivalent to putting a `Dio's Best Friend` in your `starting_inventory`. | true/false | +| item_pickup_step | The number of item pickups which you are allowed to claim before they become an Archipelago location check. | 0 - 5 | + +Using the example YAML above: the Risk of Rain 2 player will have 15 total items which they can pick up for other players (total_locations = 15). +They will complete a location check every second item (item_pickup_step = 1). +They will have 4 of the items which other players can grant them replaced with `Dio's Best Friend`. (total_revivals = 4). +The player will also start with a `Dio's Best Friend`. (start_with_revive = true) \ No newline at end of file From 9115e59f156bb94ed6325e9abbb3ce892ff5f018 Mon Sep 17 00:00:00 2001 From: Hussein Farran Date: Tue, 31 Aug 2021 08:37:01 -0400 Subject: [PATCH 04/10] Add RoR2 to README --- README.md | 1 + 1 file changed, 1 insertion(+) diff --git a/README.md b/README.md index 50551c10..9e0020e7 100644 --- a/README.md +++ b/README.md @@ -8,6 +8,7 @@ Currently, the following games are supported: * Minecraft * Subnautica * Slay the Spire +* Risk of Rain 2 For setup and instructions check out our [tutorials page](http://archipelago.gg:48484/tutorial). Downloads can be found at [Releases](https://github.com/ArchipelagoMW/Archipelago/releases), including compiled From fc8e849db531272403714c5a11d90f489561ee87 Mon Sep 17 00:00:00 2001 From: Hussein Farran Date: Tue, 31 Aug 2021 10:01:09 -0400 Subject: [PATCH 05/10] Remove location id from Victory location. --- worlds/ror2/Locations.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/worlds/ror2/Locations.py b/worlds/ror2/Locations.py index eded4b32..ac314259 100644 --- a/worlds/ror2/Locations.py +++ b/worlds/ror2/Locations.py @@ -6,7 +6,7 @@ class RiskOfRainLocation(Location): # 37000 - 38000 base_location_table = { - "Victory": 37999, + "Victory": None, "Level One": 37001, "Level Two": 37002, "Level Three": 37003, From 3d578bcc9849ab4d7e45cb8c3cfd8a1bce58fb14 Mon Sep 17 00:00:00 2001 From: Hussein Farran Date: Tue, 31 Aug 2021 10:08:19 -0400 Subject: [PATCH 06/10] Set force_auto_forfeit for RoR2 --- worlds/ror2/__init__.py | 1 + 1 file changed, 1 insertion(+) diff --git a/worlds/ror2/__init__.py b/worlds/ror2/__init__.py index cb6da6d4..29db5243 100644 --- a/worlds/ror2/__init__.py +++ b/worlds/ror2/__init__.py @@ -19,6 +19,7 @@ class RiskOfRainWorld(World): location_name_to_id = {name: data for name, data in location_table.items()} data_version = 1 + forced_auto_forfeit = True def generate_basic(self): # shortcut for starting_inventory... The start_with_revive option lets you start with a Dio's Best Friend From cc2a72eb82ba862aaad1790e0043f0e34bcd72e1 Mon Sep 17 00:00:00 2001 From: Hussein Farran Date: Tue, 31 Aug 2021 20:21:52 -0400 Subject: [PATCH 07/10] Locations/Events now None id --- worlds/ror2/Locations.py | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/worlds/ror2/Locations.py b/worlds/ror2/Locations.py index ac314259..56585f5c 100644 --- a/worlds/ror2/Locations.py +++ b/worlds/ror2/Locations.py @@ -7,11 +7,11 @@ class RiskOfRainLocation(Location): # 37000 - 38000 base_location_table = { "Victory": None, - "Level One": 37001, - "Level Two": 37002, - "Level Three": 37003, - "Level Four": 37004, - "Level Five": 37005 + "Level One": None, + "Level Two": None, + "Level Three": None, + "Level Four": None, + "Level Five": None } item_pickups = { From f83ba6e6152fce3e09e116b8ecb5ad80617b3a95 Mon Sep 17 00:00:00 2001 From: Hussein Farran Date: Tue, 31 Aug 2021 20:38:44 -0400 Subject: [PATCH 08/10] Add YAML options and update slot data. Add TotalItems YAML option. Add AllowLunarItems YAML option. Send along TotalRevivals number with slot data. --- worlds/ror2/Options.py | 15 ++++++++++++++- worlds/ror2/__init__.py | 8 ++++++-- 2 files changed, 20 insertions(+), 3 deletions(-) diff --git a/worlds/ror2/Options.py b/worlds/ror2/Options.py index bb11d0bd..a77d7c3f 100644 --- a/worlds/ror2/Options.py +++ b/worlds/ror2/Options.py @@ -9,6 +9,13 @@ class TotalLocations(Range): range_end = 50 default = 15 +class TotalItems(Range): + """Number of items which are added to the multiworld on behalf of the Risk of Rain player.""" + displayname = "Total Items" + range_start = 10 + range_end = 50 + default = 30 + class TotalRevivals(Range): """Number of `Dio's Best Friend` item put in the item pool.""" @@ -27,6 +34,10 @@ class ItemPickupStep(Range): range_end = 5 default = 1 +class AllowLunarItems(Toggle): + """Allows Lunar items in the item pool.""" + displayname = "Enable Lunar Item Shuffling" + default = True class StartWithRevive(Toggle): """Start the game with a `Dio's Best Friend` item.""" @@ -38,5 +49,7 @@ ror2_options: typing.Dict[str, type(Option)] = { "total_locations": TotalLocations, "total_revivals": TotalRevivals, "start_with_revive": StartWithRevive, - "item_pickup_step": ItemPickupStep + "item_pickup_step": ItemPickupStep, + "total_items": TotalItems, + "enable_lunar": AllowLunarItems } diff --git a/worlds/ror2/__init__.py b/worlds/ror2/__init__.py index 29db5243..94857cd9 100644 --- a/worlds/ror2/__init__.py +++ b/worlds/ror2/__init__.py @@ -33,9 +33,12 @@ class RiskOfRainWorld(World): # Add revive items for the player itempool += ["Dio's Best Friend"] * self.world.total_revivals[self.player] + if not self.world.enable_lunar[self.player]: + junk_pool.pop("Lunar Item") + # Fill remaining items with randomly generated junk itempool += self.world.random.choices(list(junk_pool.keys()), weights=list(junk_pool.values()), - k=self.world.total_locations[self.player] - + k=self.world.total_items[self.player] - self.world.total_revivals[self.player]) # Convert itempool into real items @@ -53,7 +56,8 @@ class RiskOfRainWorld(World): return { "itemPickupStep": self.world.item_pickup_step[self.player].value, "seed": "".join(self.world.slot_seeds[self.player].choice(string.digits) for i in range(16)), - "totalLocations": self.world.total_locations[self.player].value + "totalLocations": self.world.total_items[self.player].value, + "totalRevivals": self.world.total_revivals[self.player].value } def create_item(self, name: str) -> Item: From 5188b41ab0258ede78c1158b79475d970cbb2a44 Mon Sep 17 00:00:00 2001 From: Hussein Farran Date: Tue, 31 Aug 2021 20:42:16 -0400 Subject: [PATCH 09/10] Update RoR2 guide. --- WebHostLib/static/assets/tutorial/ror2/setup_en.md | 14 ++++++++++---- 1 file changed, 10 insertions(+), 4 deletions(-) diff --git a/WebHostLib/static/assets/tutorial/ror2/setup_en.md b/WebHostLib/static/assets/tutorial/ror2/setup_en.md index 5d2d16df..a4e317ff 100644 --- a/WebHostLib/static/assets/tutorial/ror2/setup_en.md +++ b/WebHostLib/static/assets/tutorial/ror2/setup_en.md @@ -42,19 +42,25 @@ game: Risk of Rain 2: total_locations: 15 + total_items: 30 total_revivals: 4 start_with_revive: true item_pickup_step: 1 + enable_lunar: true ``` | Name | Description | Allowed values | | ---- | ----------- | -------------- | | total_locations | The total number of location checks that will be attributed to the Risk of Rain player. | 10 - 50 | +| total_items | The total number of items which are added to the multiworld on behalf of the Risk of Rain player. | 10-50 | | total_revivals | The total number of items in the Risk of Rain player's item pool (items other players pick up for them) replaced with `Dio's Best Friend`. | 0 - 5 | | start_with_revive | Starts the player off with a `Dio's Best Friend`. Functionally equivalent to putting a `Dio's Best Friend` in your `starting_inventory`. | true/false | | item_pickup_step | The number of item pickups which you are allowed to claim before they become an Archipelago location check. | 0 - 5 | +| enable_lunar | Allows for lunar items to be shuffled into the item pool on behalf of the Risk of Rain player. | true/false | -Using the example YAML above: the Risk of Rain 2 player will have 15 total items which they can pick up for other players (total_locations = 15). -They will complete a location check every second item (item_pickup_step = 1). -They will have 4 of the items which other players can grant them replaced with `Dio's Best Friend`. (total_revivals = 4). -The player will also start with a `Dio's Best Friend`. (start_with_revive = true) \ No newline at end of file +Using the example YAML above: the Risk of Rain 2 player will have 15 total items which they can pick up for other players. (total_locations = 15) +They will have 30 items which can be granted to them through the multiworld. (total_items = 30) +They will complete a location check every second item. (item_pickup_step = 1) +They will have 4 of the items which other players can grant them replaced with `Dio's Best Friend`. (total_revivals = 4) +The player will also start with a `Dio's Best Friend`. (start_with_revive = true) +The player will have lunar items shuffled into the item pool on their behalf. (enable_lunar = true) \ No newline at end of file From f5ef98287aa927c777bd77067534406a6e320229 Mon Sep 17 00:00:00 2001 From: Hussein Farran Date: Tue, 31 Aug 2021 20:45:09 -0400 Subject: [PATCH 10/10] Add docstring to `RiskOfRainWorld` --- worlds/ror2/__init__.py | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/worlds/ror2/__init__.py b/worlds/ror2/__init__.py index 94857cd9..581ef5ed 100644 --- a/worlds/ror2/__init__.py +++ b/worlds/ror2/__init__.py @@ -11,6 +11,11 @@ client_version = 1 class RiskOfRainWorld(World): + """ + Escape a chaotic alien planet by fighting through hordes of frenzied monsters – with your friends, or on your own. + Combine loot in surprising ways and master each character until you become the havoc you feared upon your + first crash landing. + """ game: str = "Risk of Rain 2" options = ror2_options topology_present = False