DSPRE (DS Pokémon ROM Editor Reloaded) is a tool for editing Nintendo DS Pokémon games (Generation IV). It allows you to modify maps, scripts, events, Pokémon data, trainers, and more.
For additional documentation, tutorials, and research on DS Pokémon ROM hacking, see the DS Pokémon Hacking Wiki.
- Supported Games
- Editors
- ROM Toolbox Patches
- Related Tools
- Installation
- Getting Started
- Enhancements Over Original DSPRE
- Development Guide
- Architecture Overview
- Creating New Editors
- Contributing
- External Resources
| Game | EN | ES/IT/FR/DE | JP | KR | Notes |
|---|---|---|---|---|---|
| Diamond | Full Support | Extensive Support | Partial Support | Minimal Support | |
| Pearl | Full Support | Extensive Support | Partial Support | Minimal Support | |
| Platinum | Full Support | Extensive Support | Partial Support | Minimal Support | |
| HeartGold | Full Support | Extensive Support | Partial Support | Minimal Support | |
| SoulSilver | Full Support | Extensive Support | Partial Support | Minimal Support | |
| hg-engine ROMs | Partial Support | N/A | N/A | N/A | Some editors disabled |
View and edit 3D map-related data including collisions, permissions, building placement, import and export of map models.
- OpenGL 3D visualization
- Mouse-based building placement and movement
- Collision editing with type painters
- Permissions editing with flood fill
- BGS (Background Sound) section editing
- BDHCAM import/export
- Map NSBMD and BIN import/export
- DAE, GLB, and NSBMD model export
- 512px map screenshot export (for PDSMS backgrounds)
Note: To create new maps from scratch, use Pokémon DS Map Studio (PDSMS).
Edit game scripts in binary or plaintext format.
- Syntax highlighting via ScintillaNET
- Dual-format support (binary
.binand plaintext.script) - External editing support with VS Code
- Script Navigator for quick navigation
- Search for any command
- Text Search and Replace
- Syntax error detection
- Level script clearing
- Number format selection (hex or decimal)
- Custom script command database support
VS Code Extension: Install the DSPRE Script Compatibility extension for syntax highlighting when editing scripts externally. This can be installed directly in VS Code by searching "DSPRE" in the Extensions: Marketplace.
Script Command Databases: The command databases are maintained at scrcmd-database. Contributions are welcome.
Edit map header properties.
- Copy and paste headers
- Import and export
- Add and remove headers (if relevant patch applied)
- Location search
- WorldMap Coordinates (HGSS)
- Weather effects with preview
- Internal names editing
- Battle Background and Following Pokémon properties
- Camera settings
- Music settings
Edit world map layout and connections.
- Custom color table support
- Matrix resizing
- Status bar coordinates
- Matrix names in selector
Place and configure NPCs, warps, triggers, and spawnables.
- Mouse-based event placement
- Warp navigation
- Event duplication
- Selective event import from other files
- Overworld sprite rendering
- 512px customisable map and event data screenshot export
Configure wild Pokémon encounters.
- Encounter slot editing
- Import and export
- Add and remove encounter files
- Broken encounter file repair
- Separate editors for DPPt and HGSS formats
Edit trainer data including party, AI, and items.
- Trainer Class editing
- Party composition (up to 6 Pokémon)
- Custom movesets
- AI flags
- Trainer and held items
- Party reordering
- DV Calculator (IV & Nature determination)
- Export to Showdown format
Note: For more advanced trainer editing features, see VSMaker2, which supports DSPRE unpacked ROMs.
Note: See Generation IV Trainer Move Selection AI Reference for details on AI flags.
Edit Pokémon base stats and attributes.
- Base stats (HP, Attack, Defense, Sp.Atk, Sp.Def, Speed)
- Types
- Abilities
- EV yield
- TM/HM compatibility
- Catch rate, base EXP, growth rate
- Gender ratio
- Egg groups
- CSV import/export
Edit level-up moves.
- Add, edit, and delete moves
- Auto-sorting by level
- Manual sorting of moves learned at the same level
- Entry count warning for 20+ moves (see maximum move threshold)
- Bulk Learnset Editor with:
- CSV import/export
- Copy learnset to other Pokémon
- Global move replacement
- Level adjustment
- Filter and search
Edit evolution methods and targets.
- All evolution methods supported
- Evolution parameters (level, item, move, etc.)
- Multiple evolution paths
Edit egg moves by species.
- Bulk replace and delete
- Search by Pokémon name
- CSV import/export
- Size limit tracking
Edit move properties.
- Type, Split, Power, Accuracy, PP
- Priority
- Side Effect Probability
- Attack Range/Target
- Battle Effect Sequence
- Move Flags
- Contest data
- Natural Gift, Fling, Pluck effects
- CSV import/export
For more information, see the DS Pokémon Hacking Wiki - Editing Moves.
Edit item data and effects.
- Icon and palette selection
- Price
- Hold effects
- Field and Battle pocket
- Field and Battle use functions
- Natural Gift, Fling, Pluck effects
- Party Use Parameters (status healing, HP/PP restoration, stat boosters, EV modifiers, friendship modifiers)
Edit TM/HM move assignments and item palettes.
Edit in-game trade Pokémon.
- Species (given and requested)
- IVs
- Held item
- PID
- OT ID and gender
- Contest stats
- Origin language
- Nickname and OT name
Edit Safari Zone encounters.
- All zone areas
- Grass, Surf, and Rod encounters
- Block placement requirements
- Import/export
Edit Headbutt tree encounters with 3D map visualization.
- Normal and Special tree groups
- Click-to-select trees on map
- Import/export
Edit fly destination tables.
- Game-over respawn locations
- Fly warp destinations
- Unlock conditions
Edit camera positions and angles.
View and manage 3D building models.
- Interior and exterior models
- NSBMD model viewing
- Building NSBMD import/export
- DAE building export
Add, edit and delete AreaData and texture packs.
- Add and remove map and building texture packs (NSBTX)
- Add, edit and remove AreaData files
- Import/export NSBTX and AreaData
- Palette matching
- Texture preview
Edit in-game text.
- Line reordering
- Row number display (decimal or hex)
- Search and Replace
- Chinese text support
- STRVAR helper with type reference
- Import/export
Edit various game tables.
- Conditional Music Table (HGSS)
- Pre-Battle Effects (VS. sequences and battle tracks)
View and manage overlays.
- Compression status
- Decompression operations
- RAM address mapping
Edit starting location and money.
- NARC Packer/Unpacker
- Batch Rename (list-based and content-based)
- Advanced Header Search
- NSBMD/NSBTX utilities
- DocTool (export data to CSV)
Apply patches to expand ROM capabilities:
| Patch | Description |
|---|---|
| Expand ARM9 Memory | Increase usable ARM9 memory |
| Dynamic Cameras | BDH camera positioning |
| Overlay1 Uncompressed | Keep Overlay1 uncompressed |
| Sentence Case Names | Convert Pokémon names to sentence case |
| Standardize Items | Standardize item numbers across games |
| Expand Matrix 0 | Larger world map matrices |
| Dynamic Headers | Extended header functionality |
| Disable Texture Animations | HGSS texture animation killswitch |
| Script Command Repointing | Custom script database support |
| Trainer Name Expansion | Extended trainer name length |
| Tool | Purpose |
|---|---|
| Pokémon DS Map Studio | Create new 3D maps from scratch |
| VSMaker2 | Advanced trainer editor (supports DSPRE unpacked ROMs) |
| VS Code Extension | Syntax highlighting for DSPRE scripts |
- Windows 7 or later
- .NET Framework 4.8
- Download the latest release from GitHub Releases
- Extract to a folder of your choice
- Run
DSPRE.exe
- Open DSPRE and click "Open ROM" or drag-drop a
.ndsfile - Wait for ROM extraction (first-time setup)
- Select an editor tab to begin editing
- Save your work frequently in each editor
- Click "Save ROM" to repack changes to a modified
.ndsfile - Test your ROM in an emulator
These improvements were made compared to the original DSPRE by Nomura:
- Faster load and save times
- Fixed Japanese DP ROM support
- Configurable toolbar layouts
- User preference persistence
- Automatic updates via Velopack
- Auto-updating script command databases
- Application logging with crash reporter
- Load extracted data from directory without ROM
- ARM9 mismatch warnings
- ALT key shortcuts
- Custom character map support
- Recent project quick-open
- Visual Studio 2019 or later
- .NET Framework 4.8 SDK
- Git
git clone https://github.com/DS-Pokemon-Rom-Editor/DSPRE.git
cd DSPRE
msbuild DSPRE.sln /p:Configuration=ReleaseDSPRE/
??? DS_Map/ # Main application (DSPRE.csproj)
? ??? Editors/ # All editor UserControls and Forms
? ??? ROMFiles/ # Data model classes
? ??? DSUtils/ # Low-level DS utilities
? ??? Resources/ # Databases and static resources
? ??? LibNDSFormats/# 3D model format handling
? ??? ...
??? Ekona/ # Image/sprite library (Ekona.csproj)
??? Images/ # Nintendo image format plugin (Images.csproj)
All ROM metadata is stored statically for global access:
string workDir = RomInfo.workDir;
GameFamilies family = RomInfo.gameFamily;
string scriptsPath = RomInfo.gameDirs[DirNames.scripts].unpackedDir;All ROM data structures inherit from RomFile:
public abstract class RomFile {
public abstract byte[] ToByteArray();
public bool SaveToFile(string path, bool showSuccessMessage = true);
protected bool SaveToFileDefaultDir(DirNames dir, int IDtoReplace, bool showSuccessMessage = true);
}Game data is stored in NARC archives that are unpacked for editing:
DSUtils.TryUnpackNarcs(new List<DirNames> {
DirNames.scripts,
DirNames.eventFiles
});
string path = Filesystem.GetScriptPath(fileID);Prevent event handler recursion:
private void SomeControl_ValueChanged(object sender, EventArgs e)
{
if (Helpers.HandlersDisabled) return;
Helpers.DisableHandlers();
try {
otherControl.Value = newValue;
} finally {
Helpers.EnableHandlers();
}
}Track unsaved changes. For Form-based editors:
private bool dirty = false;
private void SetDirty(bool status) {
dirty = status;
this.Text = formName + (dirty ? "*" : "");
}
private bool CheckDiscardChanges() {
if (!dirty) return true;
var result = MessageBox.Show("Unsaved changes. Discard?",
"Warning", MessageBoxButtons.YesNo);
return result == DialogResult.Yes;
}For UserControl-based editors (tab panels), implement IEditorWithUnsavedChanges:
public class MyEditor : UserControl, IEditorWithUnsavedChanges
{
private bool isDirty = false;
// IEditorWithUnsavedChanges implementation
public bool HasUnsavedChanges => isDirty;
public string UnsavedChangesMessage => $"My Editor (File {currentFileID})";
private void SetDirty()
{
if (!isDirty)
{
isDirty = true;
OpenEditorsRegistry.Register(this);
}
}
private void SetClean()
{
if (isDirty)
{
isDirty = false;
OpenEditorsRegistry.Unregister(this);
}
}
}using DSPRE.ROMFiles;
using System;
using System.Collections.Generic;
using System.Windows.Forms;
namespace DSPRE.Editors
{
public partial class MyNewEditor : Form
{
private MyDataFile currentFile;
private int currentId = 0;
private bool dirty = false;
private readonly string formName = "My New Editor";
private readonly string[] itemNames;
public MyNewEditor()
{
DSUtils.TryUnpackNarcs(new List<RomInfo.DirNames> {
RomInfo.DirNames.myDataFiles
});
itemNames = RomInfo.GetItemNames();
InitializeComponent();
Helpers.DisableHandlers();
fileIdNumeric.Maximum = GetFileCount() - 1;
itemComboBox.Items.AddRange(itemNames);
Helpers.EnableHandlers();
LoadFile(0);
}
private int GetFileCount()
{
return Directory.GetFiles(
RomInfo.gameDirs[RomInfo.DirNames.myDataFiles].unpackedDir
).Length;
}
private void LoadFile(int id)
{
Helpers.DisableHandlers();
currentId = id;
currentFile = new MyDataFile(id);
itemComboBox.SelectedIndex = currentFile.ItemId;
valueNumeric.Value = currentFile.Value;
SetDirty(false);
Helpers.EnableHandlers();
}
private void SetDirty(bool status)
{
dirty = status;
this.Text = formName + (dirty ? "*" : "");
}
private bool CheckDiscardChanges()
{
if (!dirty) return true;
var result = MessageBox.Show(
"Unsaved changes. Save before switching?",
"Unsaved Changes",
MessageBoxButtons.YesNoCancel
);
if (result == DialogResult.Yes)
{
SaveFile();
return true;
}
return result == DialogResult.No;
}
private void SaveFile()
{
currentFile.SaveToFileDefaultDir(currentId, showSuccessMessage: false);
SetDirty(false);
}
private void fileIdNumeric_ValueChanged(object sender, EventArgs e)
{
if (Helpers.HandlersDisabled) return;
if (CheckDiscardChanges())
{
LoadFile((int)fileIdNumeric.Value);
}
else
{
Helpers.DisableHandlers();
fileIdNumeric.Value = currentId;
Helpers.EnableHandlers();
}
}
private void itemComboBox_SelectedIndexChanged(object sender, EventArgs e)
{
if (Helpers.HandlersDisabled) return;
currentFile.ItemId = itemComboBox.SelectedIndex;
SetDirty(true);
}
private void valueNumeric_ValueChanged(object sender, EventArgs e)
{
if (Helpers.HandlersDisabled) return;
currentFile.Value = (int)valueNumeric.Value;
SetDirty(true);
}
private void saveButton_Click(object sender, EventArgs e)
{
SaveFile();
}
private void MyNewEditor_FormClosing(object sender, FormClosingEventArgs e)
{
if (!CheckDiscardChanges())
{
e.Cancel = true;
}
}
}
}using System.IO;
namespace DSPRE.ROMFiles
{
public class MyDataFile : RomFile
{
public int ID { get; }
public int ItemId { get; set; }
public int Value { get; set; }
public MyDataFile(int id)
{
ID = id;
string path = Filesystem.GetMyDataPath(id);
using (var reader = new BinaryReader(File.OpenRead(path)))
{
ItemId = reader.ReadUInt16();
Value = reader.ReadInt32();
}
}
public override byte[] ToByteArray()
{
using (var ms = new MemoryStream())
using (var writer = new BinaryWriter(ms))
{
writer.Write((ushort)ItemId);
writer.Write(Value);
return ms.ToArray();
}
}
public void SaveToFileDefaultDir(int id, bool showSuccessMessage = true)
{
SaveToFileDefaultDir(RomInfo.DirNames.myDataFiles, id, showSuccessMessage);
}
}
}In Filesystem.cs:
public static string myDataFiles =>
RomInfo.gameDirs[RomInfo.DirNames.myDataFiles].unpackedDir;
public static string GetMyDataPath(int id)
{
return GetPath(myDataFiles, id);
}
public static int GetMyDataCount()
{
return Directory.GetFiles(myDataFiles).Length;
}In Main Window.cs:
private void myEditorToolStripMenuItem_Click(object sender, EventArgs e)
{
DSUtils.TryUnpackNarcs(new List<DirNames> { DirNames.myDataFiles });
new MyNewEditor().Show();
}- Follow existing patterns - look at similar editors for reference
- Use Helpers -
Helpers.DisableHandlers(),Helpers.statusLabelMessage(), etc. - Log appropriately - use
AppLogger.Info(),AppLogger.Error(), etc. - Check game version - use
RomInfo.gameFamilyfor version-specific logic - Avoid useless comments - only comment "why", not "what"
- SetDirty() guards - When calling
SetDirty()in event handlers, ALWAYS check BOTHHelpers.HandlersDisabledAND the relevant selection index (e.g.,listBox.SelectedIndex < 0). Setup code can trigger handlers afterEnableHandlers(), causing false dirty state. - Reset() for UserControl editors - Editors that maintain state must implement a
Reset()method to clear all data when switching ROMs. Always wrap inDisableHandlers()/EnableHandlers().
- Fork the repository
- Create a feature branch:
git checkout -b feature/my-feature - Commit your changes with clear messages
- Ensure the solution builds without errors
- Create a Pull Request with a detailed description
The DS Pokémon Hacking Wiki is the primary documentation resource for DS Pokémon ROM hacking:
- DSPRE - This repository
- Script Command Database - Script command definitions (contributions welcome)
- VS Code Extension - Syntax highlighting for external script editing
This project is open source. See the repository for license details.
- Original DSPRE by Nomura
- All contributors to the DSPRE Reloaded project
- The DS Pokémon ROM hacking community



















