Exporting models

This guide walks through the full end-to-end process — from sourcing a model all the way to viewing your custom export running in the game.

Note: the exporter is a work in progress. It produces working models for Pokémon Colosseum and XD, but the output is occasionally buggy and in rare cases can crash the game. Round-trip fidelity is high for character/Pokémon models; some map and scene features aren't yet supported on the export side.

1. Blender setup

Before following this guide, make sure Blender and the addon are installed. The home page covers both steps:

Once that's done, return here and continue with step 2.

2. Getting a model

The exporter works with any Blender scene that has a single armature with meshes parented to it. There are three common ways to end up with one:

Option A — Edit an existing game model

The simplest path. Follow the importer guide to load a Pokémon Colosseum or XD model, then edit it directly in Blender (re-texture, re-pose, retopologise, whatever you like). All the metadata the exporter needs (animation slots, shiny params, body map) is already set on the armature, so you can skip most of the prep work later.

Outliner showing imported Pokemon model
An imported model in the Outliner — armature + meshes, ready to edit.

Option B — Import a model from another source

This can be other Pokémon games, other game series, or models from anywhere else. Many modern Pokémon titles (Sun/Moon onwards, Sword/Shield, Legends Arceus, Scarlet/Violet, etc.) have community-maintained rips available as .glb or .fbx files, and the same formats are used widely outside Pokémon too. Blender opens these natively — use File → Import → glTF 2.0 (.glb/.gltf) or File → Import → FBX (.fbx).

File Import glTF menu
Importing a .glb rip via File → Import → glTF 2.0.

Rips from other games arrive without any of the metadata the exporter expects. The preparation step below adds it automatically.

Stylized-face characters: GLB rips of modern Pokémon (and Splatoon, Fire Emblem, Xenoblade, etc.) often have small black discs floating in front of the eyes. These are "eye masks" — animation helpers that don't survive the export. You'll need to select the mesh, enter Edit Mode (Tab), press P to separate by loose parts, then delete the small disc-shaped meshes in front of each eye.

Option C — Build a model from scratch

Fully custom models work too. The constraints are the same as for any rip: you need an armature, meshes parented to it, materials with image textures, and a face count well under the game's limits. See Checking compatibility for the full feature list.

3. Setting up the scene

The exporter writes the entire Blender scene to the output file (with one narrow exception: hidden cameras are skipped). That means before you export, the scene needs to contain only the things you want in the game model. This step is about cleaning up.

Step 1 — Delete the default cube, light, and camera

When you opened Blender, it created a default scene with a Cube, a Light, and a Camera. If you're working with a freshly imported model, these may or may not still be around — either way, delete them.

In the Outliner (top-right panel), click on each unwanted object and press X in the viewport (or Delete on the keyboard) to remove it. Alternatively, right-click the object and choose Delete from the drop-down menu. Confirm the deletion if Blender asks.

Tip: you can change Blender's startup settings so that new projects no longer include the default cube, camera, and light. Set up an empty scene the way you'd like, then go to File → Defaults → Save Startup File.
Default cube selected, about to delete
Select the default Cube, Light, and Camera and delete them with X.

Step 2 — Confirm the scene structure

Import the model as described in section 2 and make any desired modifications.

What should remain is one Armature with the model's meshes parented to it. In the Outliner, the armature is the entry with a stick-figure icon; meshes appear nested underneath it (click the triangle to the left of the armature to expand).

Outliner with armature parent and mesh children
A correctly structured scene: one armature with all meshes as its children.
Note: depending on where you got the model from you'll probably not need to worry about parenting. If a mesh isn't parented to the armature, the exporter will ignore it. To parent a mesh: click the mesh in the viewport, hold Shift and click the armature (so the armature is the last selected, "active" object — usually highlighted brighter), then press Ctrl+P and pick Armature Deform.
Note: switch the viewport shading to Material Preview so the colours and textures are visible while you work with the model.

Step 3 — Make sure the model faces the right way

In Blender, your model should be standing upright (Z is up) and facing along the negative Y axis (toward the default camera position when looking from front). If the model is lying on its side or facing backwards, rotate the armature to fix it.

It's common for other software to use the Y axis as the up axis. If the model is lying on the ground, then it's most likely that a rotation of 90 degrees around the X axis will convert it to Blender's Z-up coordinates: select the armature, press R, X, type 90, and press Enter.

To rotate more generally: select the armature, press R, then optionally an axis key (X, Y, or Z), type the angle in degrees (e.g. 90), and press Enter.

Rotating the armature
Rotating with R → axis key → angle → Enter.
Model facing the correct direction
The model should be upright and facing forward (toward the viewer when looking from front view).
Note: the button circled in the image above can be used to hide or show a model's bones. The bones aren't visible in game so you don't need to worry about how they look. However, the armature may not be selectable (for things like rotation or selecting animations) if the bones are hidden.

Step 4 — Scale the model to match real-world dimensions

Blender measures things in metres. The plugin expects the model to be sized like the real thing — for Pokémon, that's the species' official height. A scale mismatch shows up in-game as a Pokémon that's tiny or enormous compared to the rest of the cast.

  1. Click the armature in the viewport.
  2. Press N to open the sidebar on the right of the viewport.
  3. Switch to the Item tab. The Dimensions section shows the model's current X / Y / Z size in metres.
N-panel showing Dimensions
The N-panel (N) shows the model's current dimensions.

Look up the Pokémon's official height (Bulbapedia is a good source). For most Pokémon, match the Z dimension (height) to the official metres value. For long serpentine Pokémon like Gyarados or Rayquaza, the official "height" is actually body length — use the Y dimension instead.

To scale: with the armature selected, press S, type the scale factor (e.g. 0.5 to halve all 3 dimensions at the same time), and press Enter.

Scaling the armature
Scaling the armature with S → type factor → Enter.
Note: zoom in or out after scaling to view the model properly again.
Note: depending on the model's pose (such as snake-like Pokémon being curled up), the height or length may not be a 1:1 conversion and some judgment may be required to determine the size to use. It can be helpful to import an existing Pokémon from the game side-by-side as a comparison — just remember to delete it before exporting.

4. Checking compatibility

The exporter understands a specific subset of Blender features. Anything outside that subset is either ignored or — for limits like polygon count — can cause the model to fail to load in-game. This section walks through what's supported, organised the way Blender itself groups things.

Note: if you don't understand what some of these mean, you can ignore this step and just try things out to see if it works.

Legend: ✓ Supported ⚠ Partial ✗ Not supported

Scene objects

What kinds of Blender objects the exporter pays attention to.

Object typeSupportNotes
Armature Each armature in the scene becomes one model in the output file.
Mesh (parented to armature) Has to be parented to an armature, otherwise it's ignored.
Mesh (not parented) Parent it to the armature first.
Camera (Perspective) Position, field of view, clip planes, and Track To target are exported.
Camera (Orthographic) Ortho scale is written into the field-of-view slot.
Camera (Panoramic) No GameCube equivalent.
Light (Sun) Color, direction, brightness.
Light (Point) Color, position.
Light (Spot) Color, position, target.
Light (Area) No GameCube equivalent.
Empty Empties are only meaningful internally (camera/light targets).
Curves / Text / Volumes Convert to mesh first (Object → Convert → Mesh).

Mesh data

The geometry, UVs, and color information attached to your meshes.

FeatureSupportNotes
Vertices & faces All faces are triangulated automatically on export.
Normals (auto) Per-vertex normals are exported.
Custom split normals Read from mesh loops.
UV maps Up to 8 UV layers per mesh (GameCube hardware limit).
Vertex colors Float-color attribute layers.
Multi-material meshes Auto-split per material slot on export.
Shape keys (morph targets) Not yet implemented.

Skinning

How meshes attach to bones for animation.

FeatureSupportNotes
Vertex groups (multi-bone) Standard skinned envelope. The prep script limits to 3 influences per vertex and quantises weights to 10% steps for GameCube efficiency.
Vertex groups (single bone) Rigid bind — all verts attached to one bone.
No vertex groups Mesh is bound to whichever bone it's parented to.
Armature modifier Required for skinning to work.

Materials

The Principled BSDF shader plus image textures cover almost everything the exporter can handle. Procedural textures and custom node groups are ignored — bake to image if you need them.

FeatureSupportNotes
Principled BSDF — Base Color Diffuse color.
Principled BSDF — Specular Tint Reverse-mapped to absolute specular color.
Principled BSDF — Alpha Every material is exported as opaque. See note below.
Image Texture node All GameCube texture formats supported.
Texture alpha channel Image alpha is encoded faithfully (for hard-edged cutouts like the ring around an iris), but the material itself is always opaque.
Procedural textures (Noise, Checker, etc.) Bake to image texture first.
Custom node groups Only specific nodes the exporter recognises are read.
About transparency: the exporter always writes materials as fully opaque, regardless of the Principled BSDF's Alpha slider or whether you've connected a texture alpha channel. Author your model assuming every material is solid. Soft fringes (feathery edges, wispy fabric) need to be hard-edged geometry instead.

Animations

FeatureSupportNotes
Bone actions (location / rotation / scale) Both Euler and Quaternion rotation modes are supported.
Material color & alpha actions Animated material properties.
Texture UV scroll / scale Animated texture offset and scale.
Camera animations Position, target, FOV, roll, clip planes.
NLA strips Actions referenced by NLA strips are exported.
Shape key actions Not yet implemented.
Drivers Bake to keyframes first.

Constraints

ConstraintSupportNotes
Inverse Kinematics (IK) Chain length and pole target.
Copy Location
Copy Rotation
Track To
Limit Rotation Min/max per axis.
Limit Location Min/max per axis.
Other constraints Ignored — no GameCube equivalent.

Hardware limits

Even when every feature you use is supported, the GameCube has hard runtime limits the model must stay under. The exporter rejects scenes that violate these (with a clear error message); the preparation script in the next step handles most of them automatically.

LimitValueNotes
Texture size≤ 512×512 px Larger textures are downscaled by the prep script.
Bone weights per vertex≤ 4 Prep script caps to 3 by default to leave headroom.
Polygon count~15,000 faces (rough) Higher counts may still work — the upper boundary isn't precisely measured.
File size~500 KB (target) Original Pokémon range from 65–430 KB. Bigger files may not load.
Animation timing offset0 Actions must start at frame 0.
Armature world transformIdentity All transforms applied (no scale, rotation, or translation on the armature object itself). The prep script handles this automatically.

5. Preparing the model

The preparation script handles the bulk of the prep work automatically and should be run in all cases. For models you imported through this addon, most of the prep work is already done — but the script should still be run. For models from anywhere else (GLB rips, custom models), it handles much more.

Pick the prep script that matches your output kind:

Step 1 — Open the Scripting workspace

At the top of Blender, click the Scripting tab in the workspace bar. The layout changes to show a text editor, an interactive console, and an info log.

Blender Scripting workspace
Click the Scripting tab at the top of Blender to switch workspaces.

Step 2 — Open the preparation script

In the text editor at the top of the workspace, click Open and browse to the prep script that matches your output — scripts/prepare_for_pkx_export.py for .pkx or scripts/prepare_for_dat_export.py for bare .dat — inside the plugin's installation folder.

To find the plugin's installation folder:

Open script in Blender text editor
Open the prep script (prepare_for_pkx_export.py or prepare_for_dat_export.py) from the plugin's scripts/ folder.

Step 3 — Run the script

With the script open, click the Run Script button (or press Alt+P with the cursor inside the script). Wait a few seconds — the info log at the bottom will show what it did.

Run Script button highlighted
The Run Script button — or press Alt+P.

What the script does

Note: if you're exporting to an overworld .dat model, skip to section 6. The remaining prep steps are only required for .pkx models.

Step 4 — Set the PKX metadata

Select the armature and open the Properties editor's Object Properties tab (orange square icon). Scroll down to the PKX Metadata panel.

PKX Metadata panel on armature
The PKX Metadata panel — set species ID, format (XD vs Colosseum), and animation slot assignments.

Key things to set:

Note: Leave Species ID at 0 unless you're exporting an edited version of a model that was originally imported from the game (in which case keep the species ID the importer set, so the model still identifies as the same Pokémon). For brand-new models built from scratch — or models imported from any other source (PBR, GLB / FBX rips, other tools) — leave it at 0. Nothing in the in-battle render path reads this field.

Step 5 — Set the body map

The body map is 16 named slots in the PKX header that the in-game waza-effect pipeline looks up to anchor particles, sound emitters, and overlay models on your Pokémon. Set these in the Body Map section of the PKX Metadata panel.

Body Map section of PKX Metadata
The Body Map — pick the bone for each slot.
How important is each slot? A corpus-wide survey of 1401 game-native .wzx move files shows the waza pipeline actively reads only a handful of these slots. The table below splits the slots into important (almost every move references them), occasional (a small number of moves), and rare (mostly authored but not read). Spend your time on the important ones.
SlotNameFrequencyUsed for
0OriginImportant The model's root attach point. Used by ~95% of all waza effects when they have no more specific target. Auto-filled with the first bone of the armature by the prep script.
1MouthImportant Where head-attached Model entries land — fire-breath models, status overlays (sleep Z's, confusion stars), ice crystals. Pick a mouth/jaw/head bone.
2ChestImportant The LensFlare anchor — every move with a chest-level light flash (Fire Punch, Flamethrower, Mega Punch/Kick, Solar Beam charge-up, Counter, etc.) attaches its glow here. Pick a mid-spine / chest / upper-torso bone.
3TailOccasional Distal tail attach for tail-themed moves. Pick the tip of the tail.
4–5Eye Left / Eye RightOccasional Eye bones from the Pokémon's perspective.
6–7Hand Left / Hand RightOccasional Hand attach points (Pokémon's perspective). For quadrupeds without hands, use the closest forelimb or paw bone.
8–11Additional 1–4Rare Rarely consumed by waza files. Leave on the default (origin) unless you have a specific reason.
12–13Foot Left / Foot RightOccasional Foot attach points (Pokémon's perspective). Falls back to leg bones if the rig has no explicit foot.
14CenterOccasional A secondary trunk anchor distinct from Chest — typically lower-spine / hips. Used by a small number of full-body overlay effects (Conversion's texture wrap).
15Additional 5Rare Like Additional 1–4 — leave on origin unless needed.

The most important slot to get right is the Head Bone field above the body map (a separate PKX header field used by the in-game camera for head-tracking) — and the body map's Mouth and Chest slots, since they anchor most of the visible move effects.

Note: some models come with names provided for each bone. If not, they'll likely just be numbered bones (Bone_000, Bone_001, …), and you'll need to select the bones individually in the viewport to find the bone at each required body part. Tip: in Pose Mode, enable Object Data Properties → Viewport Display → Names to overlay every bone name in the 3D view.

Step 6 — Assign actions to animation slots

Pokémon battle models have 17 animation slots. Each slot gets a Blender Action assigned to it.

SlotUsed for
IdleDefault stance — also the fallback for moves with no animation.
Physical AMost physical-damaging moves.
Special AMost special-damaging moves.
DamageHit reaction (taking damage).
FaintFainting / KO animation.
Physical B–E, Special B–C Variants triggered by specific moves (Magnitude, Triple Kick, Weather Ball, etc.). E.g. progressively more intense variants of the animation. You can set these to the same as the A variant.
Remaining slots Other animation slots — suggested to leave empty.

In the PKX Metadata panel, click the dropdown next to each slot and pick the matching Action.

Action assignment dropdown in PKX panel
Click the dropdown next to a slot and pick the matching Action.
Note: the timings for the animations can be left unset for now — they'll be automatically assigned in step 7.

Step 7 — Re-run the script

After assigning actions, run the script again. It auto-derives animation timing values from the action durations you assigned. The timings can be adjusted afterward if necessary, but in most cases the auto-assigned values should be fine.

6. Exporting the model

Once the scene is set up and prepared, the export itself is a single menu choice.

Step 1 — Open the export dialog

In Blender, open the File menu, hover over Export, and click Gamecube model (.dat).

File Export Gamecube model menu
File → Export → Gamecube model (.dat).

Step 2 — Pick output format and location

Type the filename and choose the extension based on what you want:

ExtensionUse for
.dat A bare model file with no header. Used for overworld props and NPCs. Includes every action in the scene, so delete unused actions first or the file will be huge.
.pkx A Pokémon or trainer battle model, with the header carrying animation slots, shiny colors, body map, and species ID. Requires the PKX metadata set in step 5 above.
.fsys Replace the model inside an existing .fsys archive. The fastest way to test in-game — see the next section. Double-click an existing .fsys in the export dialog to overwrite it.

Step 3 — Click Export

The export takes a few seconds. When it finishes, you'll have a usable model file at the path you chose. The next section covers getting it into the game.

Known limitations

7. Importing the model back into the game

You have a model file. Now you need to get it back into a playable copy of the game. The flow uses Dolphin's "boot from folder" feature — no ISO rebuild needed — together with the project's browser-based FSYS Tool for swapping the model into an existing archive.

Step 1 — Extract the game's filesystem (one-time setup)

Follow the importer's file system extraction guide to extract the game's contents to a folder. If you already did this for the importer walkthrough, you can reuse the same folder.

Step 2 — Find the .fsys you want to replace

Inside the extracted folder, navigate to the files/ subfolder. Find the pkx_*.fsys archive for the Pokémon or trainer you want to overwrite.

Step 3 — Back up the original

Before overwriting anything, copy the .fsys file to a safe place. If your export doesn't work in-game, you can restore the original by copying the backup back.

Step 4 — Choose your replacement method

Pick whichever fits your situation:

Method A — Direct .fsys export from Blender (simplest)

If the archive you're replacing has exactly one model entry inside it (true for every pkx_*.fsys), Blender can write the modified archive in one step.

  1. In Blender, run the export (step 6).
  2. In the file dialog, navigate to the folder containing the .fsys you want to replace.
  3. Double-click the existing file in the dialog — this picks it as the output target.
  4. Click Export.

The plugin overwrites the archive in place, replacing the original model entry with yours and preserving every other entry in the archive.

Method B — Use the FSYS Tool (extract / swap / repack)

For archives with more than one model entry, archives where you want to inspect or modify other files alongside the model, or when you just prefer working with loose files, use the project's FSYS Tool. It runs entirely in your browser — no installation, no upload, everything stays local.

  1. Export your model from Blender as .pkx (or .dat), not .fsys. Save it somewhere you can find it.
  2. Open the FSYS Tool in your browser.
  3. Switch to the Extract tab. Pick the .fsys archive you want to modify and click Extract archive. The tool downloads a .zip file — unpack it to get a folder containing every entry from the archive, plus a <name>-manifest.json describing the layout.
  4. Swap the model. Inside the unpacked folder, find the entry file corresponding to the model (typically the .pkx or .dat file). Delete it and replace it with your exported model, keeping the exact same filename. The manifest doesn't need to be edited — only the file content.
  5. Switch to the Repack tab. Drag the folder into the drop zone (or use the picker), set the output filename to match the original (e.g. pkx_065.fsys), and click Repack archive. A new .fsys downloads.
  6. Drop it into the game's files/ folder, overwriting the original (which you already backed up in step 3).

Step 5 — Boot the modified game from main.dol

In your file browser, open the extracted folder, go into sys/, and double-click main.dol. Dolphin launches the game using your modified files — without needing to rebuild the ISO.

Launching main.dol from sys folder
Double-click sys/main.dol to boot the modified game.

8. Troubleshooting

The model garbles in-game or has extra geometry radiating out from it

If the model loads in-game but renders as the correct body plus large flat planes, long thin triangles, or other geometry stretching off into space, the export is most likely pushing past one of the renderer's per-frame caps — too many surfaces (PObjects), too many bone-weight combinations, or too many matrices. XD's hardware has limits the importer and Blender don't enforce, so the file looks fine when re-imported but the game's draw loop chokes.

The prep script can produce a smaller, simpler model by collapsing similar bone weights together. The knobs that control how aggressive this is live as constants at the very top of scripts/prepare_for_pkx_export.py (and the same block at the top of prepare_for_dat_export.py):

To diagnose, watch the export log (Blender's system console). Lines like splitting mesh 'X' (137 envelopes) into 42 PObjects tell you where the budget is going. Game-native bodies sit at around 8–15 PObjects per material; anything well above that on an arbitrary model is likely to garble.

A reasonable first escalation when the defaults don't fly is:

MAX_WEIGHTS_PER_VERTEX = 2
WEIGHT_QUANTISATION_STEP = 0.25
REDISTRIBUTE_SUB_THRESHOLD_WEIGHTS = True

Save the script, re-run it on the scene, and re-export. The splitting mesh … counts should drop substantially. If the largest mesh is still emitting 25+ PObjects after the tightest knobs, the source mesh itself is too dense for the renderer — apply a Decimate modifier to bring the face count down (Pokémon-sized models typically sit in the 600–1,500 face range), then re-prep and re-export.

Other problems

If you hit a problem the docs don't cover, ask on the community Discord: discord.gg/xCPjjnv. Include screenshots of your scene (Outliner + Material Properties at minimum), the exact error message Blender showed, and the model file you tried to export.

← Back to home