Nitro Engine Advanced (NEA) is a 3D game engine for the Nintendo DS, forked from Nitro Engine. It provides a large set of functions designed to simplify the process of making a 3D game. It isn't standalone — it needs libnds to work.
You can use Nitro Engine Advanced with BlocksDS.
Features:
- Support for static models, converted from OBJ files with
obj2dl. - Support for multi-material static models using the DLMM format, where each submesh can have its own texture and material properties.
- Support for animated models with skeletal animation (MD5 format),
converted with
md5_to_dsma. Supports animation blending for smooth transitions. Multi-material animated models are also supported. - Animated material system: keyframe-driven material animation with 13
track types (alpha, lights, culling, vertex color, diffuse/ambient,
specular/emission, material swap, polygon ID, texture scroll X/Y, texture
rotate, texture scale X/Y). Exported from Blender via F-Curves, loaded at
runtime as
.neaanimmatbinaries. Supports STEP and LINEAR interpolation. - Scene system: binary
.neasceneformat with node hierarchy (mesh, camera, trigger, empty), asset/material reference tables, parent-children transforms, tag queries, and trigger zones with enter/exit/tick callbacks.NEA_SceneLoadFAT()automatically loads meshes and GRF textures from NitroFS, creating and binding materials to mesh nodes. - Two-pass rendering to double the polygon budget by splitting the screen into two halves, each rendered in a separate hardware frame (effective 30 FPS). Three modes available: FIFO, framebuffer, and HBL DMA.
- Depth buffer mode selection: switch between Z-buffering (linear, default) and W-buffering (reciprocal, better depth precision for perspective).
- Texture matrix manipulation: translate, rotate, and scale textures at
runtime on materials using
NEA_TEXGEN_TEXCOORD. Materials withNEA_TEXGEN_OFF(default) are unaffected. - Support for all texture formats (even compressed textures, thanks to ptexconv).
- Dual 3D (render 3D to both screens, but at 30 FPS instead of 60 FPS).
- Functions to render 2D images accelerated by 3D hardware.
- Text system based on libDSF, which is based on BMFont.
- Basic GUI elements like buttons and scrollbars.
- Physics engine with multiple collision shapes (AABB, sphere, capsule, triangle mesh), collision responses (bounce, stop, slide, sensor), mass-based impulse, collision groups with bitmask filtering, and collision callbacks.
- Triangle mesh collision (ColMesh): generate collision meshes from OBJ files
with
obj2dl --collision. Supports sphere-vs-mesh, AABB-vs-mesh, and capsule-vs-mesh detection with 64-bit precision arithmetic. - Per-bone collision for animated models: attach collision primitives (sphere, capsule, AABB) to skeleton bones. Shapes follow the animation in real time for accurate hit detection on animated characters.
- Sound system (optional, powered by Maxmod):
spatial 3D sound with distance attenuation and stereo panning, background music
with volume/tempo/pitch control, non-spatial SFX, and WAV streaming. Spatial
sources can be attached to models so audio follows objects in the scene. Enabled
by building with
NEA_MAXMOD=1— when disabled, the module compiles to nothing and has no dependencies. - Rigid body physics (experimental): ARM7-accelerated OBB rigid body
simulation with angular dynamics, impulse-based collision response, Coulomb
friction, and object sleeping. The ARM9 sends commands via FIFO and receives
position/rotation updates each frame. Supports dynamic bodies (OBB shape),
static colliders (axis-aligned rectangles for walls/floors/ceilings), and
integration with NEA's collision system (ColMesh, Sphere, Capsule) via contact
injection. Requires using one of the provided ARM7 binaries
(
arm7_nea.elforarm7_nea_maxmod.elf). - Hardware 2D pipeline (
NEAHw2D): use the NDS 2D hardware alongside the 3D engine. Supports tiled backgrounds (4bpp/8bpp), bitmap backgrounds (8bpp indexed and 16bpp direct color), and hardware OBJ sprites with animation frames, flip, priority, palette slots, and affine transformations. VRAM banks assigned to 2D are automatically excluded from 3D texture allocation. IncludesNEA_Hw2DTextRender()for rendering libDSF rich text onto 16bpp bitmap backgrounds. OAM updates are integrated intoNEA_WaitForVBL()via theNEA_UPDATE_HW2Dflag. See the examples underexamples/hw2d/for tiled backgrounds, bitmap backgrounds, sprites, and text rendering on bitmap BGs. - Configurable texture palette VRAM:
NEA_SetTexPaletteBank()lets you choose which VRAM banks (E, F, G) back 3D texture palettes, freeing bank E for 2D backgrounds when needed. - Asynchronous asset loading: load files in the background using BlocksDS
cooperative threads, so the main loop keeps running — audio keeps streaming
and the scene keeps rendering — while a file is read from the filesystem.
This avoids the audio gaps and frame stutter caused by blocking loads. A
worker thread reads the file in chunks, then a finalize step (such as a
texture VRAM upload) runs during the vertical blank.
NEA_FATLoadDataAsync()reads any file, with async variants for textures (NEA_MaterialTexLoadFATAsync(),NEA_MaterialTex4x4LoadFATAsync(),NEA_MaterialTexLoadGRFAsync()) and models (NEA_ModelLoadStaticMeshFATAsync(),NEA_ModelLoadDSMFATAsync(),NEA_ModelLoadMultiMeshFATAsync()). Loads are advanced with theNEA_UPDATE_ASSETSflag ofNEA_WaitForVBL()or by callingNEA_AsyncProcess()directly. See theexamples/loading/async_loadingexample. Note: for the loading to truly overlap on DS hardware, the filesystem driver must run on the ARM7 (DSi SD and cartridge NitroFS already do; on a DS flashcard calldldiSetMode(DLDI_MODE_ARM7)).
For features not covered by NEA (e.g. advanced 2D tilemaps, scrolling engines), you can also use libnds directly, or a library like NFlib. There is an example of how to integrate Nitro Engine Advanced and NFlib in the same project here.
Clone this repository and run:
make -f Makefile.blocksds install -j`nproc`This builds the library in both debug and release modes and installs it.
To enable sound support (Maxmod integration), add
NEA_MAXMOD=1:make -f Makefile.blocksds install NEA_MAXMOD=1 -j`nproc`Your project must also link
-lmm9, add-DNEA_MAXMODto its defines, and usearm7_maxmod.elfas the ARM7 binary. See the examples underexamples/sound/for reference Makefiles.If you want to check that everything is working as expected, open one of the folders of the examples and run:
make
That should build an
.ndsfile that you can run on an emulator or real hardware.
Note: The build system of the examples in this repository is make. The makefiles aren't very flexible, and they don't support converting 3D models, or saving graphics or models to the filesystem (you can only inject them as data to the ARM9, which isn't acceptable for big games).
You can also try ArchitectDS. This build system written in Python supports converting every format that Nitro Engine Advanced supports, and it lets you save everything in NitroFS so that your game can grow as much as you want.
Note that some features of the 3D hardware aren't emulated by most emulators, so you may need to use an actual NDS to test some things. melonDS seems to emulate all features correctly. DeSmuME doesn't emulate the polygon/vertices count registers, so the touch test feature of Nitro Engine Advanced doesn't work.
Normally you should link your programs with -lNEA, which is the release
version. If you want to use the debug features, link with -lNEA_debug and
add -DNEA_DEBUG to the CFLAGS and CPPFLAGS in your Makefile. Make
sure to clean and rebuild your project after doing the changes mentioned in this
step. Check the error_handling example to see how to use the debug mode.
Nitro Engine Advanced includes the following conversion tools under tools/:
- obj2dl: Converts Wavefront OBJ files into NDS display lists (
.bin). Supports--texture,--scale, and--collision(generates a.col.bintriangle mesh for the physics engine). - md5_to_dsma: Converts MD5 mesh and animation files into NDS-compatible
formats. Supports
--multi-materialfor DLMM output with per-submesh materials, and--collision <md5collimesh>to generate per-bone collision data (.boncol) from a collision mesh exported by the Blender addon. - img2ds: Converts images to NDS textures and palettes (deprecated, except for DEPTHBMP conversion).
- neascene_export: Converts JSON scene descriptions to binary
.neascenefiles for the scene system.
The blender_addon/ directory contains io_scene_md5.py, a comprehensive
addon for Blender 5.0 and above. It provides:
- MD5 mesh/animation import and export
- Animated material editor (Material Properties panel): keyframe NDS material
properties (alpha, colors, material swap, texture scroll/rotate/scale) using
Blender's F-Curve system. Animated properties are previewed in the viewport
during playback. Export to
.neaanimmatbinary with one click. - Scene node editor (Object Properties panel): configure nodes for the scene system with tags, trigger zones, and hierarchy.
- Per-bone collision editor for animated models.
- Integrated conversion tool execution (obj2dl, md5_to_dsma, ptexconv).
Animated model pipeline:
Model and rig your character in Blender with an armature.
Assign materials — each material slot with a unique shader image becomes a separate mesh block in the MD5 export. Multi-material models are fully supported.
Animate using Blender's action system (the addon supports Blender 5.0's action slots and bone collections).
Export via File > Export > MD5 Mesh/Anim (.md5mesh/.md5anim).
Convert the exported MD5 files with
md5_to_dsma:python3 tools/md5_to_dsma/md5_to_dsma.py \ --mesh model.md5mesh \ --anim walk.md5anim \ --output data/model \ --multi-materialLoad in your game code:
// For single-material animated models: NEA_ModelLoadDSMA(model, mesh_bin, anim_bin); // For multi-material animated models (DLMM): NEA_ModelLoadMultiMesh(model, dlmm_bin); NEA_ModelSetSubMeshMaterialByName(model, "skin", skin_material); NEA_ModelSetSubMeshMaterialByName(model, "armor", armor_material);
- Open Blender 5.0+.
- Go to Edit > Preferences > Add-ons > Install from Disk.
- Select
blender_addon/io_scene_md5.py. - Enable the addon in the list.
Screenshots of some of the examples included with Nitro Engine Advanced:
| Animated model | Box tower physics |
![]() |
![]() |
| Hardware fog | Specular material |
![]() |
![]() |
| Text | Shadow volume |
![]() |
![]() |
| Screen effects | 2D sprites |
![]() |
This fork is hosted on GitHub.
The original Nitro Engine is hosted on Codeberg.
The code of this repository is under the MIT license. The examples are under the CC0-1.0 license.
The full text of the licenses can be found under the licenses folder.
- BlocksDS: https://blocksds.skylyrac.net/
- SkyLyrac: Original Nitro Engine author
- devkitPro: https://devkitpro.org/
- DLDI: https://www.chishm.com/DLDI/
- DeSmuME: http://desmume.org/
- melonDS: https://melonds.kuribo64.net/
- no$gba: https://problemkaputt.de/gba.htm
- gbatek: https://problemkaputt.de/gbatek.htm
- gbadev forums: https://forum.gbadev.org/






