Configuration Reference
Porytiles works out of the box with no configuration at all. Every value described here has a sensible default, and the basic fieldmap configuration values are read from your decomp project’s source files, so you can theoretically compile new tilesets without a single line of YAML.
Configuration allows you to change advanced settings like:
lock tiles or palettes so you can edit vanilla tilesets without breaking dependent tilesets,
pick a different palette-packing algorithm,
silence a class of annoying warnings,
point Porytiles at non-standard asset directories.
This page is an exhaustive reference. If you just want a simple introduction, the Quick Start doc has a shorter overview.
How configuration is resolved
Porytiles builds each tileset’s configuration from eight sources. For every individual key, it walks the list below from top to bottom and uses the first source that provides a value. Resolution is per-key, not per-file: a command-line option can override one key while the rest still come from your YAML or the built-in defaults.
Priority |
Source |
Where the value comes from |
|---|---|---|
1 (highest) |
Command-line option |
A |
2 |
Per-tileset local YAML |
|
3 |
Per-tileset YAML |
|
4 |
Project local YAML |
|
5 |
Project YAML |
|
6 |
Fieldmap header |
The |
7 |
Metatiles header |
Inferred from |
8 (lowest) |
Built-in default |
The default baked into Porytiles |
Two critical consequences worth reiterating:
Per-tileset beats project-wide, and local beats committed. A key set in a tileset’s
config.yamloverrides the same key in the project-wideconfig.yaml, and eitherconfig.local.yamloverrides its committed sibling at the same scope.The
fieldmap.*values come from your project for free. Sources 6 and 7 read your decomp project’s own headers, so the tile, metatile, and palette limits already match your build. You only set them by hand when your project diverges from those headers.
Where configuration YAML files live
All configuration YAML files live under the porytiles/ management directory at your project root:
porytiles/
├── config.yaml # project-wide, committed
├── config.local.yaml # project-wide, machine-local (gitignore-friendly)
└── tilesets/
└── gTileset_Example/
├── config.yaml # per-tileset, committed
└── config.local.yaml # per-tileset, machine-local
Every one of these files is optional. Create only the ones you need.
The config.local.yaml files are meant for overrides you don’t want to commit:
a temporary path tweak, or a noisier diagnostic filter while you debug, etc.
Add config.local.yaml to your .gitignore and your committed config.yaml stays clean for the rest of the team.
File format
Each file is YAML, organized under a few top-level keys that mirror the value reference below:
fieldmap, tileset, diagnostics, and the standalone verify_checksums.
Nest keys to match the dotted paths in this document, so tileset.tiles.edit_mode becomes:
tileset:
tiles:
edit_mode: patch
Caution
Porytiles validates every key in your YAML against the set of known configuration paths.
An unrecognized key is a hard error (unknown-config-key),
so a typo like tileset.tile.edit_mode stops the compile instead of being ignored.
Overriding values on the command line
Nearly every value can be set with a command-line option, which is handy for one-off compiles where you don’t want to touch any YAML. The command-line is the highest-priority source, so for that one run it overrides every file and the built-in default:
porytiles compile-tileset gTileset_Example --tiles-edit-mode optimize --packing-strategy best-fusion
The flag names are listed alongside each value in the reference below, and porytiles compile-tileset --help prints the authoritative set.
A few conventions:
Boolean values also get a
--no-form to turn them off, for example--no-verify-checksumsor--no-pal-hints-enabled.List values (such as
--primary-pairing-partnersor--diagnostic-warnings-exclude) accept multiple arguments.Three values are YAML-only. Palette hints, packing strategy parameters, and per-animation overrides are too structured to express as a flag, so they can only be set in a config file. They’re marked YAML-only in the reference.
Tip
Option names don’t always match the YAML path one-to-one.
A few are abbreviated (tileset.palettes.edit_mode is --pals-edit-mode,
fieldmap.metatile_attribute_size is --metatile-attr-size).
When in doubt, trust the reference tables below or --help rather than guessing from the path.
You can also set up shell completion to make it even easier, see Installation.
Inspecting the resolved configuration
Because values come from up to eight places, “what is this key actually set to, and why?” is a real question.
dump-tileset-config provides the answer for a specific tileset:
porytiles dump-tileset-config gTileset_Example
For each key it prints the resolved value, the exact source it came from, and the full provider chain:
Number Of Tiles In Primary
--------------------------
'Number Of Tiles In Primary' is '512' due to configuration:
NUM_TILES_IN_PRIMARY = 512
Source: ./include/fieldmap.h:8
7:
➞ 8: #define NUM_TILES_IN_PRIMARY 512
9: #define NUM_METATILES_IN_PRIMARY 512
Provider Chain:
○ CliOptionProvider (not provided)
○ YamlFileProvider (not provided)
✓ HeaderDefineProvider = 512
○ MetatilesHeaderProvider (not provided)
○ DefaultProvider = 512
Read the Provider Chain from top to bottom:
✓ marks the source that won,
○ marks a source that either had nothing to offer for this key
or had a value that wasn’t selected.
You can see in the above example
that some providers did not provide a value for the key at all,
while others provided a value but were superseded by a provider with higher priority.
For a value that fell through to its default, the source reads default value and only DefaultProvider is checked.
This is the fastest way to debug a surprising result: dump the config, find the key, and the chain shows you which file (or flag) to change.
Important
The chain collapses all four YAML files into a single YamlFileProvider row,
but the Source line above it always names the exact file and line a value came from,
so you can tell project YAML from per-tileset YAML at a glance.
Configuration value reference
The rest of this page lists every configuration value, grouped by its top-level YAML key. For each value you get its YAML path, its CLI flag (or YAML-only), the default, and what it does. Each group links to the guide that explains the underlying subsystem in depth.
fieldmap — hardware layout
These describe your tile, metatile, and palette budget.
Porytiles reads the first eight from include/fieldmap.h and the last from src/data/tilesets/metatiles.h automatically,
so in a normal decomp project you never set them by hand.
Override them only when you explicitly want a particular run’s values to differ from those headers.
YAML key |
CLI flag |
Default |
Description |
|---|---|---|---|
|
|
|
Tiles reserved for the primary tileset. |
|
|
|
Total tile capacity (primary plus secondary). |
|
|
|
Metatiles reserved for the primary tileset. |
|
|
|
Total metatile capacity. |
|
|
|
Hardware palettes reserved for the primary tileset. |
|
|
|
Total hardware palettes available. |
|
|
|
The |
|
|
|
|
|
|
|
Bytes per metatile attribute: |
tileset.paths — asset directories
Where each tileset’s source and binary assets live, relative to the project root.
src holds the editable porytiles_src/ assets; bin holds the generated porytiles_bin/ files that Porymap reads.
YAML key |
CLI flag |
Default |
Description |
|---|---|---|---|
|
|
|
Source directory for primary tilesets. |
|
|
|
Binary directory for primary tilesets. |
|
|
|
Source directory for secondary tilesets. |
|
|
|
Binary directory for secondary tilesets. |
tileset — transparency
YAML key |
CLI flag |
Default |
Description |
|---|---|---|---|
|
|
|
The RGB color treated as transparent during compilation. Must be fully opaque. |
Pixels in this color (or with an alpha of 0) become transparent in the compiled tileset. The mental model for source layers is covered in the Quick Start.
tileset.tiles — the tiles.png artifact
YAML key |
CLI flag |
Default |
Description |
|---|---|---|---|
|
|
|
How much |
|
|
|
The color mode used when writing |
|
|
|
Whether the packer accounts for tile-sharing shape groups. |
|
|
|
The palette-slot alignment strategy for tile sharing. |
edit_mode controls how freely a compile may rewrite the tiles artifact:
locked— the artifact can’t change; the compiler must reuse what’s already in the base tileset.patch— the compiler may fill open (transparent) slots but won’t disturb existing tiles.optimize(default) — the artifact is cleared and packed from scratch (the original Porytiles behavior).
palette_mode:
true-color(default) — write an 8-bit indexed PNG that carries the real palette colors, handy for visually debugging tile layout. Porymap 5.2.0 and later fully supports this format, as doesgbagfx(it only checks the bottom four bits when buildingtiles.4bpp).greyscale— map indices to greyscale, matching the vanilla game tileset convention
sharing.packing and sharing.alignment tune tile-sharing deduplication:
sharing.packing:off(default),biased(a soft penalty steers shape-group siblings toward different palettes), oroptimal(planned).sharing.alignment:off(default),greedy(best-effort slot alignment via indirect link resolution), oroptimal(planned).
The full mechanism is explained in Tile Sharing.
tileset.palettes — palette packing
YAML key |
CLI flag |
Default |
Description |
|---|---|---|---|
|
|
|
How much the palette files may change during a compile. |
|
|
|
The palette-packing algorithm. |
|
YAML-only |
(preset) |
Per-strategy tuning parameters. |
|
|
|
Whether palette hints are fed to the packer. |
|
YAML-only |
(none) |
Named color groups the packer should keep together. |
edit_mode takes the same locked / patch / optimize values as tiles.edit_mode above, applied to the palette files.
packing.strategy selects the algorithm:
backtracking(default) — DFS/BFS backtracking search; handles the widest range of inputs.best-fusion— fast greedy weighted-cost packing, no retries; may fail on hard inputs.overload-and-remove— greedy with multi-start retries to escape local optima.
packing.strategy_params tunes the selected strategy.
Only the block matching the active strategy is read; best-fusion takes no parameters.
When omitted, each strategy uses a built-in preset:
tileset:
palettes:
packing:
strategy: backtracking
strategy_params:
backtracking:
search_algorithm: bfs # dfs or bfs
node_cutoff: 5000 # max nodes to explore before giving up
best_branches: 3 # keep the top-N branches at each level
smart_prune: true # enable heuristic pruning
overload_and_remove:
max_attempts: 100 # number of multi-start retries
seed: 42 # RNG seed, for reproducibility
shuffle_strategy: noisy-ffd # single-ffd, noisy-ffd, or random
packing.hints tells the packer that certain colors should land in the same hardware palette.
Each hint is a named group of RGB colors; the packer injects them as synthetic tiles to bias color grouping.
This is useful when you know certain colors co-occur within a tile and want to guarantee they share a palette:
tileset:
palettes:
packing:
hints_enabled: true
hints:
- name: foliage
colors:
- [12, 190, 20]
- [40, 210, 10]
The packing algorithms and when to tune them are covered in Palette Packing.
tileset.animations — animation handling
YAML key |
CLI flag |
Default |
Description |
|---|---|---|---|
|
|
|
How animation frames link to metatile entries. |
|
|
|
Whether Porytiles wires generated animation code into |
|
|
|
Match secondary tiles against a primary’s animation key frames. |
|
|
|
Which palette to use for animation tiles when decompiling. |
|
|
|
How to handle duplicate key-frame tiles when decompiling. |
|
|
|
How to handle subtiles referenced with multiple palettes when decompiling. |
|
YAML-only |
(none) |
Per-animation settings, keyed by animation name. |
frame_linking: automatic (default, uses key.png), manual (uses explicit overrides in anim.json), or hybrid (planned).
The three *_resolution_strategy values only matter when decompiling animations:
palette_resolution_strategy:scan-local-metatiles(default),palette-00throughpalette-15(use that index directly),internal-png-palette, orscan-all-tilesets(planned).key_frame_resolution_strategy:error(default),warning, ormangle(de-duplicate identical key-frame tiles).multi_palette_subtile_resolution_strategy:error(default),warning(continue using the lowest palette index), orsplit(planned).
per_animation_overrides lets a single animation depart from the global settings above.
Each key is an animation name; animations not listed fall back to the global values:
tileset:
animations:
per_animation_overrides:
flower:
frame_linking: automatic
key_frame_resolution_strategy: mangle
multi_palette_subtile_resolution_strategy: warning
palette_resolution_strategy: palette-00
# One entry per subtile; "_" falls back to the strategy above
per_tile_palette_resolution_strategies: [ _, scan-local-metatiles, _, _ ]
The animation pipeline is documented in Animations.
tileset.primary_pairing — pairing a secondary with its primary
When you compile a secondary tileset, Porytiles needs the compiled primary to produce correct global tile indices and palette references.
YAML key |
CLI flag |
Default |
Description |
|---|---|---|---|
|
|
|
How the partner primary is resolved. |
|
|
(none) |
Partner primary tileset names, used in |
mode: automatic (default, scans layout metadata to find the partner primary*)*, manual (use the names in partners), or off (compile as a standalone secondary).
partners is only consulted when mode is manual.
Primary pairing is introduced in Creating Your First Tileset.
diagnostics — warning and remark filters
Filter Porytiles’ warnings and remarks by tag.
Each value is a list of regex patterns matched against diagnostic tags.
Within a category, include is applied after exclude, so you can silence everything and then re-enable a few specific tags.
YAML key |
CLI flag |
Default |
Description |
|---|---|---|---|
|
|
(none) |
Regex patterns for warning tags to suppress. |
|
|
(none) |
Regex patterns for warning tags to keep (applied after exclude). |
|
|
(none) |
Regex patterns for remark tags to suppress. |
|
|
(none) |
Regex patterns for remark tags to keep (applied after exclude). |
diagnostics:
warnings:
exclude: [ ".*" ] # silence every warning...
include: # ...then re-enable just these two
- layer-mode-warning
- tile-color-count-warning
remarks:
exclude: [ ".*" ] # silence all remarks
The catalog of diagnostic tags and what each one means is in Understanding Diagnostics.
Top-level keys
YAML key |
CLI flag |
Default |
Description |
|---|---|---|---|
|
|
|
Verify artifact checksums during compilation. |
Validation rules
Some values are checked individually, and a few are checked against each other. A violation stops the compile with an explanatory error:
Every
fieldmap.*count must be greater than zero.fieldmap.num_tiles_in_primary≤fieldmap.num_tiles_total.fieldmap.num_metatiles_in_primary≤fieldmap.num_metatiles_total.fieldmap.num_pals_in_primary≤fieldmap.num_pals_total.fieldmap.num_tiles_per_metatilemust be8or12.fieldmap.metatile_attribute_sizemust be2or4.tileset.extrinsic_transparencymust be fully opaque (alpha255).tileset.tiles.sharing.packingrequirestileset.palettes.packing.strategyto bebacktracking.
Not yet implemented
The annotated example file previews two keys that aren’t wired up yet:
tileset.import_transparency— transparency handling for import.tileset.palettes.match_candidate_top_n— how many near-miss palettes to show when alockedpalette compile fails to find a match.
A handful of enum values are also reserved for future work and listed above as (planned):
tile-sharing optimal (both packing and alignment),
frame_linking hybrid,
palette_resolution_strategy scan-all-tilesets,
and multi_palette_subtile_resolution_strategy split.
Warning
These keys exist only in the annotated example, which is a documentation template Porytiles never loads.
Don’t copy them into a real config.yaml yet:
because they aren’t recognized configuration paths, the validator rejects them as unknown-config-key
and the compile fails. Use the example as a reading reference, not a starter file.
A worked example
A minimal project-wide config that locks palettes and lets tile compiles patch open slots:
# porytiles/config.yaml — applies to every tileset in the project
tileset:
extrinsic_transparency: [255, 0, 255]
palettes:
edit_mode: locked
tiles:
edit_mode: patch
To change just one value for a single tileset, add a per-tileset file and leave the rest to fall back to the project config:
# porytiles/tilesets/gTileset_Example/config.yaml
tileset:
tiles:
edit_mode: optimize # this one tileset re-packs from scratch
For a single file that exercises every key with inline comments, see the fully annotated example in the source repository, and remember the not-yet-implemented caveat above.
See also
Quick Start — the short tour of the configuration system.
CLI Command Reference — the complete command and flag listing.
Palette Packing, Tile Sharing, Animations, Understanding Diagnostics — the subsystems behind the values above.
porytiles dump-tileset-config <name>— confirm what’s actually in effect for a tileset.