3 Guide Custom Carts
bryanthaboi edited this page 2026-10-20 17:01:40 -04:00

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 under its base game. Any of the eleven games can be a base: Red, Blue, Yellow, Gold, Silver, Crystal, FireRed, LeafGreen, Ruby, Sapphire or Emerald. 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.

Player workflow

  1. Get the .g1rcart file for the cart version you want to play, and import its base game's ROM first.
  2. On that game's card in the launcher, select Custom Carts, then Import .g1rcart and choose the file. On Switch and PS4 copy it into imports/carts/ and select Scan again instead.
  3. Select Use cart on its row, then press the cart to play. Its saves are kept in the cart's own scope.
  4. If the cart reports a missing pin, select Install required mods and retry after installation completes. If a pin cannot be downloaded, the cart page explains the Break the seal option and marks the save as modified; use that only when you understand the consequence.

The launcher's cart page is the player-facing source of truth. A pin is a specific mod release recorded by the cart. A seal controls whether the player can change the cart's pinned set. A sealed custom cart is the approved bundle for link play; enabling loose mods beside it is a different state.

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. Import .g1rcart in the Custom Carts window opens the platform file picker instead. A cart is listed only under the game named by its base.

From the launcher's MODS tab, Save as cart freezes the mods enabled for one game into a new cart.

Fields

Field Meaning
id, title, version, author identity; title is what the launcher draws
summary, repo optional one-line blurb and owner/name source repo
base the game it plays as: any version id (red to emerald)
engine optional engine version range the cart needs
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
label the label PNG path in the cart repo; the packed file embeds it as labelArt

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.

Check and recover

After Import .g1rcart, the cart should appear in its base game's Custom Carts window with its title and label, and playing it should open that cart's save scope. If a pin is missing, use Install required mods and retry; preserve the seal and record the exact missing pin if installation still fails.