2
Guide Publishing
bryanthaboi edited this page 2026-07-31 10:15:53 -04:00
This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

Publishing a mod

The path from a working mods/<id>/ directory to something other people can install, and the rules that bind it.

The checklist

  1. Manifest hygiene. A real version (semver, so dependents can range-check you), a description the manager can show, an honest profile, game_version pinned only if you rely on something version-specific, affects_link stated when the profile default is wrong (Link Compatibility). Set github to owner/repo if you want launcher Update / Versions. Mark unfinished work experimental so it stays off until the player confirms enable (Manifest).

  2. README.md — what the mod does, how to install it, and the regenerate instructions for any transform-derived art.

  3. DIFFERENCES.md — what you change from vanilla, in the format of the engine's docs/known-differences.md. Your divergences are yours to document; the base game's ledger stays "None currently." (Compatibility).

  4. Validate and lint clean.

    python3 tools/modkit.py validate my_mod --strict
    python3 tools/modkit.py lint my_mod
    
  5. Pack (hand zip / .modpkg) or publish Releases from GitHub.

    python3 tools/modkit.py pack my_mod -o my_mod-1.0.0.modpkg
    

    pack re-runs both gates at strict level — any finding refuses the package — and zips the directory. Users unpack into their mods/ folder (Getting Started).

    For GitHub-hosted updates, put the mod in its own repo, set "github": "owner/repo" on the manifest, and add the release workflow:

    python3 tools/modkit.py set-github my_mod owner/repo   # if the field is missing
    python3 tools/modkit.py add-release-workflow my_mod
    

    Each push to main (or a manual workflow run) publishes a my_mod-<version>.zip GitHub Release with files at the archive root — the shape Import mod .zip, Update, and Versions install. Bump manifest.json's version, or put [release X.Y.Z] in the commit message, or pass a version on a manual run.

The content rule

A distributed mod contains no ROM-derived content: no extracted PNGs, no chip-audio banks, no ROM images, no IPS/BPS/UPS patches (lint rules MK301MK304). Derived art ships as an asset transform that regenerates it from the player's own cache (Art Pipeline). Because nothing you distribute contains Nintendo/Game Freak content, your mod is shareable as ordinary open-source Lua and PNGs — the same posture the engine itself claims.

Branding is your responsibility: name and present your mod as your own work, not as an official product.

Versioning etiquette

  • Bump patch for fixes, minor for compatible additions, major when you break your own save shape or exported API.
  • Ship a mod.migrations:add step whenever your modData shape changes (Save Model) — old saves are your users' progress.
  • Treat mod.exports as a public API: additive changes only within a major.
  • Declare conflicts (or the alias incompatible) when you know two mods cannot coexist; the declaring mod loses at load time, so state it in the mod that knows.

Play-testing the failure paths

Before shipping, test what your users will actually hit: enable alongside popular mods (merge-order surprises), disable mid-save (your content quarantines and reclaims cleanly), and load a save from your previous version (migrations fire). A mod that fails politely — attributed errors, no crashes, clean rollback — is one the manager can help users live with.