diff --git a/docs/adding games.md b/docs/adding games.md index e9f7860fc650..9d2860b4a196 100644 --- a/docs/adding games.md +++ b/docs/adding games.md @@ -1,269 +1,78 @@ -# How do I add a game to Archipelago? - -This guide is going to try and be a broad summary of how you can do just that. -There are two key steps to incorporating a game into Archipelago: - -- Game Modification -- Archipelago Server Integration - -Refer to the following documents as well: - -- [network protocol.md](/docs/network%20protocol.md) for network communication between client and server. -- [world api.md](/docs/world%20api.md) for documentation on server side code and creating a world package. - -# Game Modification - -One half of the work required to integrate a game into Archipelago is the development of the game client. This is -typically done through a modding API or other modification process, described further down. - -As an example, modifications to a game typically include (more on this later): - -- Hooking into when a 'location check' is completed. -- Networking with the Archipelago server. -- Optionally, UI or HUD updates to show status of the multiworld session or Archipelago server connection. - -In order to determine how to modify a game, refer to the following sections. - -## Engine Identification - -This is a good way to make the modding process much easier. Being able to identify what engine a game was made in is -critical. The first step is to look at a game's files. Let's go over what some game files might look like. It’s -important that you be able to see file extensions, so be sure to enable that feature in your file viewer of choice. -Examples are provided below. - -### Creepy Castle - -![Creepy Castle Root Directory in Windows Explorer](/docs/img/creepy-castle-directory.png) - -This is the delightful title Creepy Castle, which is a fantastic game that I highly recommend. It’s also your worst-case -scenario as a modder. All that’s present here is an executable file and some meta-information that Steam uses. You have -basically nothing here to work with. If you want to change this game, the only option you have is to do some pretty -nasty disassembly and reverse engineering work, which is outside the scope of this tutorial. Let’s look at some other -examples of game releases. - -### Heavy Bullets - -![Heavy Bullets Root Directory in Window's Explorer](/docs/img/heavy-bullets-directory.png) - -Here’s the release files for another game, Heavy Bullets. We see a .exe file, like expected, and a few more files. -“hello.txt” is a text file, which we can quickly skim in any text editor. Many games have them in some form, usually -with a name like README.txt, and they may contain information about a game, such as a EULA, terms of service, licensing -information, credits, and general info about the game. You usually won’t find anything too helpful here, but it never -hurts to check. In this case, it contains some credits and a changelog for the game, so nothing too important. -“steam_api.dll” is a file you can safely ignore, it’s just some code used to interface with Steam. -The directory “HEAVY_BULLETS_Data”, however, has some good news. - -![Heavy Bullets Data Directory in Window's Explorer](/docs/img/heavy-bullets-data-directory.png) - -Jackpot! It might not be obvious what you’re looking at here, but I can instantly tell from this folder’s contents that -what we have is a game made in the Unity Engine. If you look in the sub-folders, you’ll seem some .dll files which -affirm our suspicions. Telltale signs for this are directories titled “Managed” and “Mono”, as well as the numbered, -extension-less level files and the sharedassets files. If you've identified the game as a Unity game, some useful tools -and information to help you on your journey can be found at this -[Unity Game Hacking guide.](https://github.com/imadr/Unity-game-hacking) - -### Stardew Valley - -![Stardew Valley Root Directory in Window's Explorer](/docs/img/stardew-valley-directory.png) - -This is the game contents of Stardew Valley. A lot more to look at here, but some key takeaways. -Notice the .dll files which include “CSharp” in their name. This tells us that the game was made in C#, which is good -news. Many games made in C# can be modified using the same tools found in our Unity game hacking toolset; namely BepInEx -and MonoMod. - -### Gato Roboto - -![Gato Roboto Root Directory in Window's Explorer](/docs/img/gato-roboto-directory.png) - -Our last example is the game Gato Roboto. This game is made in GameMaker, which is another green flag to look out for. -The giveaway is the file titled "data.win". This immediately tips us off that this game was made in GameMaker. For -modifying GameMaker games the [Undertale Mod Tool](https://github.com/krzys-h/UndertaleModTool) is incredibly helpful. - -This isn't all you'll ever see looking at game files, but it's a good place to start. -As a general rule, the more files a game has out in plain sight, the more you'll be able to change. -This especially applies in the case of code or script files - always keep a lookout for anything you can use to your -advantage! - -## Open or Leaked Source Games - -As a side note, many games have either been made open source, or have had source files leaked at some point. -This can be a boon to any would-be modder, for obvious reasons. Always be sure to check - a quick internet search for -"(Game) Source Code" might not give results often, but when it does, you're going to have a much better time. - -Be sure never to distribute source code for games that you decompile or find if you do not have express permission to do -so, or to redistribute any materials obtained through similar methods, as this is illegal and unethical. - -## Modifying Release Versions of Games - -However, for now we'll assume you haven't been so lucky, and have to work with only what’s sitting in your install -directory. Some developers are kind enough to deliberately leave you ways to alter their games, like modding tools, -but these are often not geared to the kind of work you'll be doing and may not help much. - -As a general rule, any modding tool that lets you write actual code is something worth using. - -### Research - -The first step is to research your game. Even if you've been dealt the worst hand in terms of engine modification, -it's possible other motivated parties have concocted useful tools for your game already. -Always be sure to search the Internet for the efforts of other modders. - -### Other helpful tools - -Depending on the game’s underlying engine, there may be some tools you can use either in lieu of or in addition to -existing game tools. - -#### [CheatEngine](https://cheatengine.org/) - -CheatEngine is a tool with a very long and storied history. -Be warned that because it performs live modifications to the memory of other processes, it will likely be flagged as -malware (because this behavior is most commonly found in malware and rarely used by other programs). -If you use CheatEngine, you need to have a deep understanding of how computers work at the nuts and bolts level, -including binary data formats, addressing, and assembly language programming. - -The tool itself is highly complex and even I have not yet charted its expanses. -However, it can also be a very powerful tool in the right hands, allowing you to query and modify gamestate without ever -modifying the actual game itself. -In theory it is compatible with any piece of software you can run on your computer, but there is no "easy way" to do -anything with it. - -### What Modifications You Should Make to the Game - -We talked about this briefly in [Game Modification](#game-modification) section. -The next step is to know what you need to make the game do now that you can modify it. Here are your key goals: - -- Know when the player has checked a location, and react accordingly -- Be able to receive items from the server on the fly -- Keep an index for items received in order to resync from disconnections -- Add interface for connecting to the Archipelago server with passwords and sessions -- Add commands for manually rewarding, re-syncing, releasing, and other actions - -Refer to the [Network Protocol documentation](/docs/network%20protocol.md) for how to communicate with Archipelago's -servers. - -## But my Game is a console game. Can I still add it? - -That depends – what console? - -### My Game is a recent game for the PS4/Xbox-One/Nintendo Switch/etc - -Most games for recent generations of console platforms are inaccessible to the typical modder. It is generally advised -that you do not attempt to work with these games as they are difficult to modify and are protected by their copyright -holders. Most modern AAA game studios will provide a modding interface or otherwise deny modifications for their console -games. - -### My Game isn’t that old, it’s for the Wii/PS2/360/etc - -This is very complex, but doable. -If you don't have good knowledge of stuff like Assembly programming, this is not where you want to learn it. -There exist many disassembly and debugging tools, but more recent content may have lackluster support. - -### My Game is a classic for the SNES/Sega Genesis/etc - -That’s a lot more feasible. -There are many good tools available for understanding and modifying games on these older consoles, and the emulation -community will have figured out the bulk of the console’s secrets. -Look for debugging tools, but be ready to learn assembly. -Old consoles usually have their own unique dialects of ASM you’ll need to get used to. - -Also make sure there’s a good way to interface with a running emulator, since that’s the only way you can connect these -older consoles to the Internet. -There are also hardware mods and flash carts, which can do the same things an emulator would when connected to a -computer, but these will require the same sort of interface software to be written in order to work properly; from your -perspective the two won't really look any different. - -### My Game is an exclusive for the Super Baby Magic Dream Boy. It’s this console from the Soviet Union that- - -Unless you have a circuit schematic for the Super Baby Magic Dream Boy sitting on your desk, no. -Obscurity is your enemy – there will likely be little to no emulator or modding information, and you’d essentially be -working from scratch. - -## How to Distribute Game Modifications - -**NEVER EVER distribute anyone else's copyrighted work UNLESS THEY EXPLICITLY GIVE YOU PERMISSION TO DO SO!!!** - -This is a good way to get any project you're working on sued out from under you. -The right way to distribute modified versions of a game's binaries, assuming that the licensing terms do not allow you -to copy them wholesale, is as patches. - -There are many patch formats, which I'll cover in brief. The common theme is that you can’t distribute anything that -wasn't made by you. Patches are files that describe how your modified file differs from the original one, thus avoiding -the issue of distributing someone else’s original work. - -Users who have a copy of the game just need to apply the patch, and those who don’t are unable to play. - -### Patches - -#### IPS - -IPS patches are a simple list of chunks to replace in the original to generate the output. It is not possible to encode -moving of a chunk, so they may inadvertently contain copyrighted material and should be avoided unless you know it's -fine. - -#### UPS, BPS, VCDIFF (xdelta), bsdiff - -Other patch formats generate the difference between two streams (delta patches) with varying complexity. This way it is -possible to insert bytes or move chunks without including any original data. Bsdiff is highly optimized and includes -compression, so this format is used by APBP. - -Only a bsdiff module is integrated into AP. If the final patch requires or is based on any other patch, convert them to -bsdiff or APBP before adding it to the AP source code as "basepatch.bsdiff4" or "basepatch.apbp". - -#### APBP Archipelago Binary Patch - -Starting with version 4 of the APBP format, this is a ZIP file containing metadata in `archipelago.json` and additional -files required by the game / patching process. For ROM-based games the ZIP will include a `delta.bsdiff4` which is the -bsdiff between the original and the randomized ROM. - -To make using APBP easy, they can be generated by inheriting from `worlds.Files.APDeltaPatch`. - -### Mod files - -Games which support modding will usually just let you drag and drop the mod’s files into a folder somewhere. -Mod files come in many forms, but the rules about not distributing other people's content remain the same. -They can either be generic and modify the game using a seed or `slot_data` from the AP websocket, or they can be -generated per seed. If at all possible, it's generally best practice to collect your world information from `slot_data` -so that the users don't have to move files around in order to play. - -If the mod is generated by AP and is installed from a ZIP file, it may be possible to include APBP metadata for easy -integration into the Webhost by inheriting from `worlds.Files.APContainer`. - -## Archipelago Integration - -In order for your game to communicate with the Archipelago server and generate the necessary randomized information, -you must create a world package in the main Archipelago repo. This section will cover the requisites and expectations -and show the basics of a world. More in depth documentation on the available API can be read in -the [world api doc.](/docs/world%20api.md) -For setting up your working environment with Archipelago refer -to [running from source](/docs/running%20from%20source.md) and the [style guide](/docs/style.md). - -### Requirements - -A world implementation requires a few key things from its implementation - -- A folder within `worlds` that contains an `__init__.py` - - This is what defines it as a Python package and how it's able to be imported - into Archipelago's generation system. During generation time only code that is - defined within this file will be run. It's suggested to split up your information - into more files to improve readability, but all of that information can be - imported at its base level within your world. -- A `World` subclass where you create your world and define all of its rules - and the following requirements: - - Your items and locations need a `item_name_to_id` and `location_name_to_id`, - respectively, mapping. - - An `option_definitions` mapping of your game options with the format - `{name: Class}`, where `name` uses Python snake_case. - - You must define your world's `create_item` method, because this may be called - by the generator in certain circumstances - - When creating your world you submit items and regions to the Multiworld. - - These are lists of said objects which you can access at - `self.multiworld.itempool` and `self.multiworld.regions`. Best practice for - adding to these lists is with either `append` or `extend`, where `append` is a - single object and `extend` is a list. - - Do not use `=` as this will delete other worlds' items and regions. - - Regions are containers for holding your world's Locations. - - Locations are where players will "check" for items and must exist within - a region. It's also important for your world's submitted items to be the same as - its submitted locations count. - - You must always have a "Menu" Region from which the generation algorithm - uses to enter the game and access locations. -- Make sure to check out [world maintainer.md](/docs/world%20maintainer.md) before publishing. \ No newline at end of file +# Adding Games + +Adding a new game to Archipelago has two major parts: + +* Game Modification to communicate with Archipelago server (hereafter referred to as "client") +* Archipelago Generation and Server integration plugin (hereafter referred to as "world") + +This document will attempt to illustrate the bare minimum requirements and expectations of both parts of a new world +integration. As game modification wildly varies by system and engine, and has no bearing on the Archipelago protocol, +it will not be detailed here. + +## Client + +The client is an intermediary program between the game and the Archipelago server. This can either be a direct +modification to the game, an external program, or both. This can be implemented in nearly any modern language, but it +must fulfill a few requirements in order to function as expected. The specific requirements the game client must follow +to behave as expected are: + +* Handle both secure and unsecure websocket connections +* Detect and react when a location has been "checked" by the player by sending a network packet to the server +* Receive and parse network packets when the player receives an item from the server, and reward it to the player on +demand + * **Any** of your items can be received any number of times, up to and far surpassing those that the game might +normally expect from features such as starting inventory, item link replacement, or item cheating + * Players and the admin can cheat items to the player at any time with a server command, and these items may not have +a player or location attributed to them +* Be able to change the port for saved connection info + * Rooms hosted on the website attempt to reserve their port, but since there are a limited number of ports, this +privilege can be lost, requiring the room to be moved to a new port +* Reconnect if the connection is unstable and lost while playing +* Keep an index for items received in order to resync. The ItemsReceived Packets are a single list with guaranteed +order. +* Receive items that were sent to the player while they were not connected to the server + * The player being able to complete checks while offline and sending them when reconnecting is a good bonus, but not +strictly required +* Send a status update packet alerting the server that the player has completed their goal + +Libraries for most modern languages and the spec for various packets can be found in the +[network protocol](/docs/network%20protocol.md) API reference document. + +## World + +The world is your game integration for the Archipelago generator, webhost, and multiworld server. It contains all the +information necessary for creating the items and locations to be randomized, the logic for item placement, the +datapackage information so other game clients can recognize your game data, and documentation. Your world must be +written as a Python package to be loaded by Archipelago. This is currently done by creating a fork of the Archipelago +repository and creating a new world package in `/worlds/`. A bare minimum world implementation must satisfy the +following requirements: + +* A folder within `/worlds/` that contains an `__init__.py` +* A `World` subclass where you create your world and define all of its rules +* A unique game name +* For webhost documentation and behaviors, a `WebWorld` subclass that must be instantiated in the `World` class +definition + * The game_info doc must follow the format `{language_code}_{game_name}.md` +* A mapping for items and locations defining their names and ids for clients to be able to identify them. These are +`item_name_to_id` and `location_name_to_id`, respectively. +* Create an item when `create_item` is called both by your code and externally +* An `options_dataclass` defining the options players have available to them +* A `Region` for your player with the name "Menu" to start from +* Create a non-zero number of locations and add them to your regions +* Create a non-zero number of items **equal** to the number of locations and add them to the multiworld itempool +* All items submitted to the multiworld itempool must not be manually placed by the World. If you need to place specific +items, there are multiple ways to do so, but they should not be added to the multiworld itempool. + +Notable caveats: +* The "Menu" region will always be considered the "start" for the player +* The "Menu" region is *always* considered accessible; i.e. the player is expected to always be able to return to the +start of the game from anywhere +* When submitting regions or items to the multiworld (multiworld.regions and multiworld.itempool respectively), use +`append`, `extend`, or `+=`. **Do not use `=`** +* Regions are simply containers for locations that share similar access rules. They do not have to map to +concrete, physical areas within your game and can be more abstract like tech trees or a questline. + +The base World class can be found in [AutoWorld](/worlds/AutoWorld.py). Methods available for your world to call during +generation can be found in [BaseClasses](/BaseClasses.py) and [Fill](/Fill.py). Some examples and documentation +regarding the API can be found in the [world api doc](/docs/world%20api.md). +Before publishing, make sure to also check out [world maintainer.md](/docs/world%20maintainer.md). diff --git a/docs/img/creepy-castle-directory.png b/docs/img/creepy-castle-directory.png deleted file mode 100644 index af4fdc584dc0..000000000000 Binary files a/docs/img/creepy-castle-directory.png and /dev/null differ diff --git a/docs/img/gato-roboto-directory.png b/docs/img/gato-roboto-directory.png deleted file mode 100644 index fda0eb5ff992..000000000000 Binary files a/docs/img/gato-roboto-directory.png and /dev/null differ diff --git a/docs/img/heavy-bullets-data-directory.png b/docs/img/heavy-bullets-data-directory.png deleted file mode 100644 index 9fdcba1ca02a..000000000000 Binary files a/docs/img/heavy-bullets-data-directory.png and /dev/null differ diff --git a/docs/img/heavy-bullets-directory.png b/docs/img/heavy-bullets-directory.png deleted file mode 100644 index 8bc14836c601..000000000000 Binary files a/docs/img/heavy-bullets-directory.png and /dev/null differ diff --git a/docs/img/stardew-valley-directory.png b/docs/img/stardew-valley-directory.png deleted file mode 100644 index 64bbf66ec299..000000000000 Binary files a/docs/img/stardew-valley-directory.png and /dev/null differ diff --git a/docs/options api.md b/docs/options api.md index 6205089f3dc3..f1c01ac7e7e9 100644 --- a/docs/options api.md +++ b/docs/options api.md @@ -10,10 +10,9 @@ Archipelago will be abbreviated as "AP" from now on. ## Option Definitions Option parsing in AP is done using different Option classes. For each option you would like to have in your game, you need to create: -- A new option class with a docstring detailing what the option will do to your user. -- A `display_name` to be displayed on the webhost. -- A new entry in the `option_definitions` dict for your World. -By style and convention, the internal names should be snake_case. +- A new option class, with a docstring detailing what the option does, to be exposed to the user. +- A new entry in the `options_dataclass` definition for your World. +By style and convention, the dataclass attributes should be `snake_case`. ### Option Creation - If the option supports having multiple sub_options, such as Choice options, these can be defined with @@ -43,7 +42,7 @@ from Options import Toggle, Range, Choice, PerGameCommonOptions class StartingSword(Toggle): """Adds a sword to your starting inventory.""" - display_name = "Start With Sword" + display_name = "Start With Sword" # this is the option name as it's displayed to the user on the webhost and in the spoiler log class Difficulty(Choice):