Skip to content

Commit

Permalink
Merge branch 'main' into use-nkey-actor-for-freestanding-items
Browse files Browse the repository at this point in the history
  • Loading branch information
mike8699 committed May 27, 2022
2 parents 4751f08 + d8fcf62 commit 8bce5d8
Show file tree
Hide file tree
Showing 111 changed files with 6,851 additions and 460 deletions.
422 changes: 422 additions & 0 deletions .github/workflows/build-test-release.yml

Large diffs are not rendered by default.

190 changes: 0 additions & 190 deletions .github/workflows/test.yml

This file was deleted.

4 changes: 3 additions & 1 deletion .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,6 @@ MANIFEST
# Usually these files are written by a python script from a template
# before PyInstaller builds the exe, so as to inject date/other infos into it.
*.manifest
*.spec

# Installer logs
pip-log.txt
Expand Down Expand Up @@ -133,3 +132,6 @@ data/
overlay/
*.bin
*.nds

# PyCharm
.idea/
33 changes: 33 additions & 0 deletions CONTRIBUTING.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
# Contributing to the randomizer

Note, this document is very much a work-in-progress.

## Code style/formatting guidelines

All code is linted and, in the case of Python, type-checked in CI on every commit. To run these checks locally, make sure you have `tox` installed:

`pip install tox`

and simply run `tox` in the root of the repository.

You can also auto-format your code with `tox -e format`. It won't fix every linting error, but it will fix most.

It's recommended that you run `tox -e format` and `tox` prior to opening a PR to avoid unexpected CI failures.


## Automated testing

Note, this section summarizes the testing philosophy of the randomizer and gives a brief overview of the testing infrastructure. For information on how to write or run these tests, see `tests/README.md`.

Several automated tests exist to verify the correctness and exercise various parts of the randomizer. They are written in Python using the `pytest`
testing framework and are located in the `tests/` directory.

There are two distinct classes of automated tests used to test the randomizer.

1) General unit/integration-style tests that test parts of the randomizer application code like the shuffler, patcher, and UI.

2) Tests that spin up a live instance of the DeSmuME emulator that actually runs a copy of the ROM that has been patched in some way by the randomizer, while issuing commands to it and making assertions about the state of RAM and/or CPU registers. These are mostly used to test the base ROM patches, since realistically the only way to test those is to apply them to a real ROM and run it to make sure it behaves as expected.

Generally, the former type of test is easy to write and very cheap in the sense that, when done right, they have a low maintenance burden while providing a high value in terms of catching bugs. It's usually a good idea to have at least one of these tests if adding a new feature to the randomizer.

The latter type of test tends to be the opposite, in that they are usually difficult to write and can introduce a significant maintenance burden. You're essentially giving an emulator a series of buttons and touch screen coordinates to hit and then making assertions about the state of the game's memory based on them, which doesn't translate into easily readable code. Tests of this kind should probably be kept to a minimum, and only written for crucial components of the randomizer that cannot be tested with the former, more conventional approach (such as the base ROM patches). In any case, it's best to discuss with the randomizer team before writing one.
43 changes: 43 additions & 0 deletions DEVELOPMENT.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
# Phantom Hourglass Randomizer Developer Documentation

This document provides a general overview of the parts of the randomizer, as well as a brief description of the file structure of the git repo.

Developers who wish to contribute to the randomizer should start here to get a high-level understanding of how the randomizer works, and then
proceed to `CONTRIBUTING.md` for a lower-level description for how to contribute code.

## Randomizer Architecture
There are 4 inter-operating components to the randomizer that work together to go from an unmodified, vanilla ROM to a logic-compliant randomized ROM.

### Base ROM patches
This refers to a collection of code changes and hooks that modify the behavior of the game, prior to any randomization even happening.
This is necessary to support aspects of the randomizer that aren't possible in the original game. For example, it is not possible to
have the sword sold in a shop in the original game; this is because the shop has a hardcoded list of items that it can hold. So, we
have a base patch that modifies the ROM's code to support this.
Another example is progressive swords; in the original game, there are two distinct sword items - the Oshus Sword and the Phantom Sword.
Randomizing these items in the vanilla ROM would mean the player can potentially find them in the wrong order. To fix this, most randomizers
implement progressive swords, where there is only a single sword item that always gives you the "next one up". This is yet another base patch.

These patches consist of, for the most part, code hooks written in either ARM assembly or C. In order to apply them to a ROM several steps must be taken
(TODO: outline these steps. For now, anyone interested can look at the Dockerfile), some of which require installing various development
dependencies. To avoid requiring users to install all of these just to run the randomizer, the base patches are pre-generated at compile-time and
bundled with the randomizer as BPS patches, which are in turn applied to users' ROMs by the patcher at run-time (see Patcher section for more info).

### UI
The user interface (UI) is the component of the randomizer that the user sees and interacts with directly, and is responsible for calling the other components of the randomizer.
It provides an interface that lets the user choose the settings they want for the randomizer and to provide their copy of the ROM; after the user provides these, the UI passes this information to the shuffler. It then takes the output of the shuffler and passes it to the patcher, which itself outputs the randomized ROM.
Note, "the UI" can potentially refer to _any_ user-facing interface to the randomizer; in the early stages of development, this will simply
be a CLI. Once the randomizer matures and is ready for general use, a GUI will be written to make it more convenient and user-friendly.

### Shuffler
The shuffler is the component of the randomizer that performs the high-level randomization of the game's items. As input, it takes logic files, aux data files,
and any settings relevant to randomization that the user specified and were passed by the UI. It parses the logic into a graph data structure and reads the aux data
files to determine what items are available to be shuffled. It then uses the logic and aux data together to randomly shuffle the items in the game such that it is still
completable, adhering to user settings where applicable. The final output of the shuffler is a new set of aux data with the items shuffled.

### Patcher
The patcher is the component of the randomizer that actually changes around the items in the game ROM. To put it simply, it takes in some set of aux data and outputs
a patched ROM with the items randomized as specified in the aux data. Generally, what will happen is the UI will call the shuffler and pass its output (the
randomized aux data) to the patcher.

## Structure of git repo
TODO
Loading

0 comments on commit 8bce5d8

Please sign in to comment.