Python

Installation

Merlon is available as a package on PyPI.

Important

Merlon requires Python 3.7 or newer.

You can install it with pip:

$ pip install merlon

Usage

Once installed, you can import the library in your Python code:

import merlon

print("Merlon version:", merlon.version())
print("Current package:", merlon.package.Package.current())

API Reference

merlon.version()

Returns the current version of Merlon as a string.

class merlon.package.Package

A package in the form of a directory.

copyright_notice()

Returns a copyright notice for this package by reading the package’s LICENSE file.

static current()

Gets the current package, if any, by looking for merlon.toml in the current directory and its parents.

export_distributable(options)

Exports the package as a distributable .merlon file.

id

The package ID.

manifest()

Returns the manifest of the package by parsing the merlon.toml file.

path

The package path.

readme()

Returns the text content of the README.md file in the package.

to_initialised(initialise_options)

Initialises this package if needed, and returns an InitialisedPackage.

uuid_equals(other)

Compares two packages by ID.

class merlon.package.manifest.Manifest

Package manifest data.

metadata

Package metadata.

class merlon.package.manifest.Metadata

Metadata about a package. Corresponds to the [package] section in merlon.toml.

authors

The package authors.

description

The package one-line description.

id

The package ID.

is_valid()

Returns whether the package metadata is valid.

name

The package name.

validate()

Validate package metadata, returning a list of errors

version

The package version.

class merlon.package.distribute.ApplyOptions

Options for [Distributable::apply].

baserom

The base ROM path.

build_rom_options

Options to build the ROM with.

class merlon.package.distribute.Distributable

A package in the form of a distributable file.

apply(options)

Applies the distributable to a base ROM, and returns the output ROM.

manifest(baserom)

Opens the distributable into a temporary directory and reads the package manifest.

open_to_dir(options)

Opens the distributable into a directory.

path()

Returns the path to the distributable.

class merlon.package.distribute.ExportOptions

Options for [Package::export_distributable].

baserom

The base ROM to use as the encryption key.

If not specified and the package is initialised, papermario/ver/us/baserom.z64 will be used.

output

The output path to write the distributable to.

If not specified, the default is NAME VERSION.merlon, where NAME is the name of the package and VERSION is the package version as specified in merlon.toml.

class merlon.package.distribute.OpenOptions

Options for [Distributable::open_to_dir].

baserom

The base ROM path.

output

The output directory to write the package source code to. Must be empty or not exist.

If not specified, the package name in kebab-case will be used.

class merlon.package.init.AddDependencyOptions

Options for [InitialisedPackage::add_dependency].

path

Path to the package to add as a dependency.

class merlon.package.init.BuildRomOptions

Options for [InitialisedPackage::build_rom].

clean

Whether to clean the build directory and build from scratch.

Will also re-split assets.

output

Path to output ROM to.

skip_configure

Whether to skip configuring (useful if you’ve already configured).

class merlon.package.init.InitialiseOptions

Options for [InitialisedPackage::initialise].

baserom

Path to an unmodified US-release Paper Mario (N64) ROM.

rev

Git revision of decomp to use.

If not provided, the latest commit on main is used.

class merlon.package.init.InitialisedPackage

An initialised package. Initialised packages are ready to be built.

add_dependency(options)

Adds a dependency by copying it into the dependencies directory and registering it. If the dependency already exists, it will be updated. Specifically, it will be copied into .merlon/dependencies/<package_id>.

baserom_path()

The path to base ROM.

build_rom(options)

Builds the ROM and returns the path to the output ROM.

static from_initialised(package)

If the given package is initialised, returns it as an [InitialisedPackage].

static initialise(package, options)

Initialises a package. Errors if it is already initialised. This will clone the papermario repository, and create the .merlon directory.

is_git_dirty()

Returns true if the decomp repository has uncommitted changes.

static is_initialised(package)

Checks whether a package is initialised.

package

The package that this InitialisedPackage was created from.

package_id()

The package ID.

registry()

The registry of packages. Includes dependencies of the package.

set_registry(registry)

Updates the registry.

setup_git_branches()

Update the decomp repository so that all dependencies and patches are applied. Also updates the patches directory if needed.

This will recreate the dependency tree in the subrepo, where each dependency has a branch. Additionally, a branch will be created for this package if it doesn’t exist, and the branch will be off of the branches that this package directly depends on. Each branch will have the respective package patches applied to it.

subrepo_path()

The path to the papermario repository used to build this package.

update_patches_dir()

Writes the patches required to take the repo from the nearest dependency to this package’s branch into the patches dir.

class merlon.package.registry.Registry

A package registry. This is an arena of packages. Allows for querying packages by name, uuid, etc., and dependency queries.

add_direct_dependency(id, dependency_id)

Adds a direct dependency to a package. Both the package and the dependency must be registered.

all_dependencies()

Returns the set of all dependencies across all packages in the registry.

calc_dependency_patch_order(root)

Calculates the patch order in order to build a given root package.

check_version_compatibility()

Returns an error if packages exist with incompatible versions. For example, if package A depends on package B ^1.0.0, but package B is registered as 2.0.0, its an error.

delete_orphans(root)

Unregisters and deletes the directories for all orphaned packages.

get_dependencies(id)

Iterates over all dependencies of a package, including both direct and transitive dependencies.

get_direct_dependencies(id)

Iterates over the direct dependency packages of a package.

get_orphans(root)

Returns packages that don’t appear in the dependency tree for the given root package.

has(id)

Returns true if the registry contains a package with the given ID.

has_dependency(id, dependency_id)

Returns true if a package has a dependency - transitive or direct - on another package.

register(package)

Add a package to the registry. Returns an error if the package is already in the registry. Returns the package’s ID so it can be used to refer to the package.

take(id)

Remove a package from the registry. Returns an error if the package is not in the registry.

topological_ordering()

Returns a topological ordering of the packages in the registry. That is, a list of packages such that for every dependency, the dependency appears before the dependent.

merlon.emulator.run_rom(rom)

Runs the given ROM in an emulator.

class merlon.rom.Rom

An N64 ROM file on disk.

path

Returns the path to the ROM file.

read_bytes()

Reads the ROM file into a [Vec] of bytes.

sha1_string()

Calculates the SHA1 hash of the ROM.