Docs: adding games rework (#2892)

* Docs: complete adding games.md rework

* remove all the now unused images

* review changes

* address medic's review

* address more comments
This commit is contained in:
Aaron Wagener 2024-03-28 19:31:59 -05:00 committed by GitHub
parent 9dc708978b
commit 301d9de975
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
7 changed files with 82 additions and 274 deletions

View File

@ -1,269 +1,78 @@
# How do I add a game to Archipelago? # Adding Games
This guide is going to try and be a broad summary of how you can do just that. Adding a new game to Archipelago has two major parts:
There are two key steps to incorporating a game into Archipelago:
* Game Modification to communicate with Archipelago server (hereafter referred to as "client")
- Game Modification * Archipelago Generation and Server integration plugin (hereafter referred to as "world")
- Archipelago Server Integration
This document will attempt to illustrate the bare minimum requirements and expectations of both parts of a new world
Refer to the following documents as well: integration. As game modification wildly varies by system and engine, and has no bearing on the Archipelago protocol,
it will not be detailed here.
- [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. ## Client
# Game Modification 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
One half of the work required to integrate a game into Archipelago is the development of the game client. This is must fulfill a few requirements in order to function as expected. The specific requirements the game client must follow
typically done through a modding API or other modification process, described further down. to behave as expected are:
As an example, modifications to a game typically include (more on this later): * 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
- Hooking into when a 'location check' is completed. * Receive and parse network packets when the player receives an item from the server, and reward it to the player on
- Networking with the Archipelago server. demand
- Optionally, UI or HUD updates to show status of the multiworld session or Archipelago server connection. * **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
In order to determine how to modify a game, refer to the following sections. * 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
## Engine Identification * 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
This is a good way to make the modding process much easier. Being able to identify what engine a game was made in is privilege can be lost, requiring the room to be moved to a new port
critical. The first step is to look at a game's files. Let's go over what some game files might look like. Its * Reconnect if the connection is unstable and lost while playing
important that you be able to see file extensions, so be sure to enable that feature in your file viewer of choice. * Keep an index for items received in order to resync. The ItemsReceived Packets are a single list with guaranteed
Examples are provided below. order.
* Receive items that were sent to the player while they were not connected to the server
### Creepy Castle * The player being able to complete checks while offline and sending them when reconnecting is a good bonus, but not
strictly required
![Creepy Castle Root Directory in Windows Explorer](/docs/img/creepy-castle-directory.png) * Send a status update packet alerting the server that the player has completed their goal
This is the delightful title Creepy Castle, which is a fantastic game that I highly recommend. Its also your worst-case Libraries for most modern languages and the spec for various packets can be found in the
scenario as a modder. All thats present here is an executable file and some meta-information that Steam uses. You have [network protocol](/docs/network%20protocol.md) API reference document.
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. Lets look at some other ## World
examples of game releases.
The world is your game integration for the Archipelago generator, webhost, and multiworld server. It contains all the
### Heavy Bullets 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
![Heavy Bullets Root Directory in Window's Explorer](/docs/img/heavy-bullets-directory.png) 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
Heres the release files for another game, Heavy Bullets. We see a .exe file, like expected, and a few more files. following requirements:
“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 * A folder within `/worlds/` that contains an `__init__.py`
information, credits, and general info about the game. You usually wont find anything too helpful here, but it never * A `World` subclass where you create your world and define all of its rules
hurts to check. In this case, it contains some credits and a changelog for the game, so nothing too important. * A unique game name
“steam_api.dll” is a file you can safely ignore, its just some code used to interface with Steam. * For webhost documentation and behaviors, a `WebWorld` subclass that must be instantiated in the `World` class
The directory “HEAVY_BULLETS_Data”, however, has some good news. definition
* The game_info doc must follow the format `{language_code}_{game_name}.md`
![Heavy Bullets Data Directory in Window's Explorer](/docs/img/heavy-bullets-data-directory.png) * 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.
Jackpot! It might not be obvious what youre looking at here, but I can instantly tell from this folders contents that * Create an item when `create_item` is called both by your code and externally
what we have is a game made in the Unity Engine. If you look in the sub-folders, youll seem some .dll files which * An `options_dataclass` defining the options players have available to them
affirm our suspicions. Telltale signs for this are directories titled “Managed” and “Mono”, as well as the numbered, * A `Region` for your player with the name "Menu" to start from
extension-less level files and the sharedassets files. If you've identified the game as a Unity game, some useful tools * Create a non-zero number of locations and add them to your regions
and information to help you on your journey can be found at this * Create a non-zero number of items **equal** to the number of locations and add them to the multiworld itempool
[Unity Game Hacking guide.](https://github.com/imadr/Unity-game-hacking) * 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.
### Stardew Valley
Notable caveats:
![Stardew Valley Root Directory in Window's Explorer](/docs/img/stardew-valley-directory.png) * 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
This is the game contents of Stardew Valley. A lot more to look at here, but some key takeaways. start of the game from anywhere
Notice the .dll files which include “CSharp” in their name. This tells us that the game was made in C#, which is good * When submitting regions or items to the multiworld (multiworld.regions and multiworld.itempool respectively), use
news. Many games made in C# can be modified using the same tools found in our Unity game hacking toolset; namely BepInEx `append`, `extend`, or `+=`. **Do not use `=`**
and MonoMod. * 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.
### Gato Roboto
The base World class can be found in [AutoWorld](/worlds/AutoWorld.py). Methods available for your world to call during
![Gato Roboto Root Directory in Window's Explorer](/docs/img/gato-roboto-directory.png) 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).
Our last example is the game Gato Roboto. This game is made in GameMaker, which is another green flag to look out for. Before publishing, make sure to also check out [world maintainer.md](/docs/world%20maintainer.md).
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 whats 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 games 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 isnt that old, its 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
Thats 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 consoles secrets.
Look for debugging tools, but be ready to learn assembly.
Old consoles usually have their own unique dialects of ASM youll need to get used to.
Also make sure theres a good way to interface with a running emulator, since thats 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. Its 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 youd 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 cant 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 elses original work.
Users who have a copy of the game just need to apply the patch, and those who dont 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 mods 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.

Binary file not shown.

Before

Width:  |  Height:  |  Size: 35 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 79 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 56 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 38 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 65 KiB

View File

@ -10,10 +10,9 @@ Archipelago will be abbreviated as "AP" from now on.
## Option Definitions ## Option Definitions
Option parsing in AP is done using different Option classes. For each option you would like to have in your game, you 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: need to create:
- A new option class with a docstring detailing what the option will do to your user. - A new option class, with a docstring detailing what the option does, to be exposed to the user.
- A `display_name` to be displayed on the webhost. - A new entry in the `options_dataclass` definition for your World.
- A new entry in the `option_definitions` dict for your World. By style and convention, the dataclass attributes should be `snake_case`.
By style and convention, the internal names should be snake_case.
### Option Creation ### Option Creation
- If the option supports having multiple sub_options, such as Choice options, these can be defined with - 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): class StartingSword(Toggle):
"""Adds a sword to your starting inventory.""" """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): class Difficulty(Choice):