163 lines
3.7 KiB
Markdown
163 lines
3.7 KiB
Markdown
# Archipelago World Tester
|
||
|
||
This project checks whether community Archipelago worlds can generate a seed.
|
||
|
||
It reads the community worlds spreadsheet, downloads each world's newest `.apworld` file, and runs Archipelago's generator against it in a Docker container.
|
||
|
||
Each world is tested five ways:
|
||
|
||
- by itself
|
||
- with two players of the same game
|
||
- with 2–5 of Archipelago's built-in worlds
|
||
- by itself with its options randomized
|
||
- with other worlds and its options randomized
|
||
|
||
Each test is repeated with different seeds. The results are combined into one of six stability values:
|
||
|
||
| Value | Meaning |
|
||
| --- | --- |
|
||
| Stable | Every attempt succeeded |
|
||
| Minor issues | Solo and multiworld tests worked, but a randomized test failed |
|
||
| Flaky | Some attempts succeeded and others failed |
|
||
| Solo only | Works by itself, but fails with other worlds |
|
||
| Broken | Could not generate at all |
|
||
| Unknown | No usable result, for example because the `.apworld` was missing or a ROM was required |
|
||
|
||
A successful test means the world loaded, generated a seed, and computed the spoiler log at the configured level. With the default `playthrough` level, this also checks that the seed is completable.
|
||
|
||
## Requirements
|
||
|
||
- **Python 3.10 or newer**
|
||
- **Git** — used to clone Archipelago and check out the version being tested
|
||
- **Docker** — must be usable by your user without `sudo`
|
||
- **A GitHub token** — required to access the GitHub API. It does not need any scopes
|
||
- **Base ROMs** — optional; some worlds cannot generate without them
|
||
|
||
## Installation
|
||
|
||
### System packages
|
||
|
||
On Ubuntu or Debian:
|
||
|
||
```sh
|
||
sudo apt update
|
||
sudo apt install -y git python3 python3-venv
|
||
```
|
||
|
||
Install Docker:
|
||
|
||
```sh
|
||
curl -fsSL https://get.docker.com | sudo sh
|
||
sudo usermod -aG docker "$USER"
|
||
newgrp docker
|
||
docker run --rm hello-world
|
||
```
|
||
|
||
The last command should work without `sudo`.
|
||
|
||
### Install the package
|
||
|
||
```sh
|
||
git clone <repository-url> archipelago-world-tester
|
||
cd archipelago-world-tester
|
||
```
|
||
|
||
Using `uv`:
|
||
|
||
```sh
|
||
uv sync
|
||
```
|
||
|
||
Or using `pip`:
|
||
|
||
```sh
|
||
python3 -m venv .venv
|
||
source .venv/bin/activate
|
||
pip install -e .
|
||
```
|
||
|
||
### Configuration
|
||
|
||
Write a starter config and edit the paths in it:
|
||
|
||
```bash
|
||
apworld-tester init
|
||
```
|
||
|
||
That writes `~/.config/apworld-tester/config.yaml` (or
|
||
`$XDG_CONFIG_HOME/apworld-tester/config.yaml`) and prints the path.
|
||
Set `general.output_directory` - everything a run generates lives there,
|
||
including the Archipelago checkout and the downloaded apworlds - and
|
||
`general.roms_directory` for the worlds that need a base ROM.
|
||
|
||
The config is looked for in this order, first hit wins:
|
||
|
||
1. `$APWORLD_TESTER_CONFIG`
|
||
2. `~/.config/apworld-tester/config.yaml`
|
||
3. `config.yaml` beside a source checkout
|
||
|
||
`apworld-tester config-path` prints which one is in use, or lists
|
||
every location it tried.
|
||
|
||
Create `.env` with your GitHub token:
|
||
|
||
```text
|
||
GITHUB_TOKEN=ghp_...
|
||
```
|
||
|
||
## Test worlds
|
||
|
||
Use `TestRun` to test one or more worlds:
|
||
|
||
```python
|
||
from apworld_tester import TestRun
|
||
|
||
TestRun("Baba Is You").run()
|
||
```
|
||
|
||
Multiple worlds:
|
||
|
||
```python
|
||
TestRun(["Baba Is You", "Anodyne"]).run()
|
||
```
|
||
|
||
To test all worlds that have already been downloaded:
|
||
|
||
```python
|
||
TestRun(cached=True).run()
|
||
```
|
||
|
||
The first run clones Archipelago and builds the Docker image, which can take several minutes.
|
||
|
||
## Test all worlds
|
||
|
||
`UpdateRun` updates Archipelago, refreshes the community worlds spreadsheet, downloads changed worlds, and tests everything:
|
||
|
||
```python
|
||
from apworld_tester import UpdateRun
|
||
|
||
UpdateRun().run()
|
||
```
|
||
|
||
## Test a local `.apworld`
|
||
|
||
For a world you are developing, put the `.apworld` in its own directory:
|
||
|
||
```text
|
||
~/my-apworlds/
|
||
└── My Game/
|
||
└── my_game.apworld
|
||
```
|
||
|
||
Then run:
|
||
|
||
```python
|
||
from apworld_tester import TestRun
|
||
|
||
TestRun(
|
||
"My Game",
|
||
root_directory="/home/you/my-apworlds",
|
||
).run()
|
||
```
|
||
|