-
Notifications
You must be signed in to change notification settings - Fork 2
Concepts Compatibility
Four separate compatibility questions, four separate answers: which mod API a mod speaks, which engine it needs, which other mods it can sit beside, and whether two linked games agree.
api in the manifest picks the contract. Absent means 1, which is what
every mod written before v2 says by omission. A v1 mod gets the whole v2
mod object — the surface only ever grew — and differs in strictness: a
value that violates a registry schema is a load error for api = 2 and an
attributed warning for api = 1, as is an unknown profile or
permission. Declaring api: 2 is how you ask for the errors.
api higher than the engine provides is refused outright. The engine's
number lives in src/core/Version.lua and moves only on a breaking change
to the mod surface.
game_version is a semver range against the engine release, checked
before the entry chunk runs — a mod that needs a newer engine is refused
with needs game version <range>, engine is <version> instead of loading
and breaking in the middle. Leave it out if you have no reason to pin.
dependencies, optional_dependencies and conflicts are enforced, and
each entry may carry a version range ("colorlib@^1.2"). Failure is
per-mod: whatever cannot be satisfied is refused with a reason the manager
shows, and everything else still loads. See the
manifest reference for resolution rules and the
range grammar.
Reaching another mod's code goes through mod.exports and mod.find:
return function(mod)
-- hard dependency: guaranteed loaded before this mod runs
local color = mod.find("colorlib").exports
-- optional dependency: declare it for the ordering, then branch
local radio = mod.find("radio")
if radio then radio.exports.addStation("NIGHT_FM") end
mod.exports = { hour = function() return 12 end }
endfind returns { id, version, exports }, or nil when the other mod is
absent, disabled or failed. Treat another mod's exports as a versioned
public API: range-check handle.version (src/mods/Semver.lua is a
supported require) before relying on its shape.
Two connected games compare a fingerprint: a digest over the
link-relevant merged surface — pokemon, moves, the type chart,
statuses, move_effects, link-relevant constants, and any registered
link_fields — plus the id and version of every mod that declares it
affects link (src/link/Fingerprint.lua). The handshake verdict
(src/link/Handshake.lua):
| Verdict | Meaning | Battle | Trade |
|---|---|---|---|
full |
identical link surfaces | yes | yes |
vanilla_peer |
old build on the far side, this side unmodified | yes | yes |
subset |
both v2, surfaces differ | no | negotiated strict-vanilla subset |
refused |
an old build we would corrupt, or an engine mismatch | no | no |
Manifest affects_link feeds this: it defaults to true for overhaul
and total_conversion profiles and false for content. A mod that
declares affects_link = false while writing into a link-relevant
registry gets an attributed warning at load. Never desync silently is the
rule; see Link Compatibility for keeping a
content mod link-safe.
The base game keeps three parity ledgers, and
docs/known-differences.md reads "None currently." — mods must not
invalidate that. A mod's divergences are the mod's, documented by the mod:
ship a DIFFERENCES.md enumerating what you change from vanilla
(mirroring docs/known-differences.md's format), and let the manifest
profile (content / overhaul / total_conversion) be the
machine-readable summary of how far you depart. The engine's promise stays
auditable precisely because disabling your mod restores vanilla exactly.
A name that is superseded keeps working for the life of the mod API major
and logs one attributed warning the first time a given mod touches it —
scripts and ui are the current examples, renamed to map_scripts and
screens, and the v1 audio registry is superseded by the granular audio
registries. Nothing a v1 mod does stops working inside API 2, and
pokemon.before_give fires forever.
Engine 1.0.0 · mod API 2 · repository · Discord
This project ships no ROM data. All game content is decoded on the player's machine from their own verified Pokemon Red ROM; mods ship recipes and original assets, never extracted content.
Start here
Concepts
Tutorials
- The ladder
- 01 Sprite and Text Tweak
- 02 Balance Patch
- 03 New Species
- 04 New Item and Ball
- 05 New Move
- 06 NPC and Dialogue
- 07 New Map
- 08 Quest
- 09 Custom Music
- 10 New Mechanic
- 11 Custom UI Screen
- 12 Mini Total Conversion
Reference
Guides
Playing