Skip to content

Guide Custom Carts

bryanthaboi edited this page Aug 24, 2026 · 1 revision

Custom carts

A custom cart is a named, version-pinned set of mods that plays as its own game. It has its own title, shell colour, label art and save slots, and the launcher lists it beside the base games. Two people running the same cart run the same mods at the same versions.

A cart carries no game data. It pins mods that live in their authors' own repos, exactly as the mod index does, plus the presentation the launcher needs to draw the cartridge.

The file

One cart is one file, <id>.g1rcart (CartManifest.EXT, src/carts/CartManifest.lua). It is not an archive: CartManifest.encode writes a Lua table through SaveSerializer, so the file opens with

return {
  cart = {
    author = "...",

and carries a format/formatVersion header that CartManifest.decode checks before anything else. The label PNG is base64 inside that table, which is why a cart is far larger than its field list suggests -- the art has to travel with the cart, since a .g1rcart is the whole thing.

Carts live in the carts folder of the save directory (CartManifest.DIR). Drop one in by hand and the launcher adopts it: CartStore.list scans the folder for files no registry entry covers and heals the registry from them. On desktop, Import a cart on the Custom Carts list opens a file picker instead.

Fields

Field Meaning
id, title, version, author identity; title is what the launcher draws
base the game it plays as (red, blue, yellow, gold, silver, crystal)
shell cartridge colour, #rrggbb
finish optional: sparkle, holo, or sparkle+holo
speeds optional: the game-speed multipliers this cart permits
seal sealed, sealed+ or open
mods the pinned mods, 1 to 64
load_order the order they load in
labelArt the embedded label PNG

shell and finish only affect how the cartridge is drawn. speeds and seal change what the player can do.

Seals

The seal decides who owns the mod list once the cart is running. It is the cart's promise about what a run consists of.

Seal The mod set The switches
sealed fixed fixed: every pin runs exactly as pinned
sealed+ fixed the player may switch any pin on or off
open the player may add more the cart's pins load first

sealed is the competitive mode: a pin the cart ships switched off stays off, and nothing can be added. sealed+ exists for the cart that wants to ship a mod configured but dormant -- a Nuzlocke ruleset at the author's preferred settings, off until the player wants it. Loader.pinTogglable (src/mods/Loader.lua) is the one rule that decides this, and both the in-game mod manager and the launcher ask it rather than deciding for themselves.

Switching a pin under sealed+ does not break the seal. Breaking the seal is a separate, deliberate two-press action on the cart's own page, and it marks the save as modified.

A player's answer for a cart's mod is stored per cart, not in the game's own mod flags, so switching a cart's mod never changes what the base game runs.

Pinning a mod off

A pin may carry enabled: false. The mod is installed, ordered and given its frozen options, but does not run. Combine it with sealed+ so the player can switch it on and immediately get the author's settings rather than the mod's defaults.

An absent enabled means enabled, so every cart written before the field existed behaves exactly as it did.

Frozen options

Each pin may carry an options table of strings, numbers and booleans. Those values are captured when the cart is saved and are part of the cart hash, so a cart's mods arrive configured and cannot drift.

Speeds

speeds lists the multipliers the cart allows, taken from GameSpeed.LEVELS (src/core/GameSpeed.lua). A cart with "speeds": [1, 2] gives the player 1x and 2x and nothing else; a single entry pins the speed outright. The constraint is applied when the cart boots and lifted when it hands back to the launcher, so it never follows the player into another game.

Saves

A cart's saves are its own. activeScopeKey (src/core/SaveData.lua) routes slots to cart_<id> while a cart is active, so a cart never writes into the base game's slots.

Settings that describe a playthrough follow the cart too: text speed, battle animations, battle style, the ruleset and the three speed multipliers layer over the global values while the cart runs. Everything else -- audio, video mode, key bindings, touch controls, language -- stays global, because a rebound controller that vanished on every cart would be a bug rather than a feature.

When a pinned mod is missing

A sealed cart refuses to start rather than quietly running without a mod it pins. The cart's page then offers two things:

  • Install required mods, which resolves each missing or mismatched pin to its release, downloads it, checks the archive against the sha256 the cart recorded, and installs it. A mismatch refuses and installs nothing. This is the normal remedy, and it leaves the seal intact.
  • Break the seal, which plays the cart with the mods you have and marks the save as modified.

Reach for the first. Breaking the seal is for when a pin cannot be resolved at all -- a GameBanana pin the launcher cannot download, or a local pin that points at a copy on the machine that built the cart.

Publishing one

Author the cart with cartkit, which scaffolds the repo, resolves pin hashes, packs the .g1rcart and installs a release workflow. Then add an entry under carts/ in the mod index so the launcher can find it.

The index entry's repo and github name the cart's own repo, not the repo of any mod it pins. The index refresh job reads that repo's releases to track the cart's version; pointed at a pinned mod's repo it would record the mod's version as the cart's.

Clone this wiki locally