I'd say there's a way to build a modern asset pipeline for the OG Xbox where you can leverage USD (well supported in all modern DCC), and then build tooling/viewers around it to process/split/export everything out to DirectX 8 .x in a much more manageable way. Makes artist collaboration a lot easier (modern tools with guardrails inplace), and can measure and keep metrics on everything (every KB counts with 64MB RAM).
All these old versions of Maya, 3ds Max and Visual Studio are just a total liability now. Licences for them can't be activated, and even if they can, it's a lot of backflips to get Autodesk to help. 3dsMax/Maya 8 and earlier barely work on Windows 10/11 now (Vista changed a lot for desktop apps) and even Visual Studio 2005 needed to be patched to support Vista!
Unfortunately nxdk does not have (any) great docs and it is much lower level than what you'd (probably) get with the official SDK - you basically have to write your own GPU driver for example (though i think nowadays there is a partial implementation of OpenGL that has enough functionality to port a modern-ish Quake engine).
I made a simple engine[0] some time ago for OG xbox using nxdk and i basically had to figure out what registers do what using old versions of Nouveau from when it had GeForce3 support - and whenever that wasn't enough, i was just trying random stuff :-P. And unfortunately xemu (currently the most complete OG xbox emulator) is not very accurate when it comes to failures, so very often you get stuff that work on it not actually working on the real hardware.
On the other hand, in case anyone cares, nxdk is basically the only "legal" way to make stuff for OG xbox and various communities (like on Discord) do not allow posting binaries/ISOs made with the original XDK. And from a more practical perspective, at least personally i prefer to use a Unix/Linux-based development environment :-P.
(unfortunately i'm also having some weird issue with my engine in that i get weird flickering on the real hardware that i do not get on the emulator that seem to be based on wrong values ending up to the renderer - but only with optimizations enabled and only on the xbox hardware - if i compile the engine for Linux, be it 32bit or 64bit, it works fine and no matter which tool i tried - valgrind, sanitizers, etc - and good old "pouring through the code" i cannot find what the issue is -- which makes me think it a compiler bug as nxdk relies on Clang and i'm not sure the Clang devs test Pentium 3 much - and unfortunately, unlike GCC, you can't enable only individual optimizations, you can only use the -O<n> optimization levels, so i can't even figure out what exactly breaks things that could have been a hint in case it is something in my code)
[0] http://runtimeterror.com/pages/iv/images/8a37dc59c6f6adbbb98...
Though i'd stick with Blender 2.79b for such projects because Blender 2.8 (i think) switched to a PBR pipeline that looks "wrong" when targeting non-PBR renderers (in theory you can recreate the original shading using material nodes or whatever they're called, but setting up materials in modern Blender is already more involved than Blender 2.79b without taking nodes into account). Most of the tools you'd need for making game assets (mesh editing and UV editing primarily) haven't changed much anyway to the point where you can follow most Blender mesh editing tutorials with it :-P. I'm in a few retro gamedev Discord channels and apparently i'm not the only one using 2.79b because of the changes in 2.8+.
[0] https://extensions.blender.org/add-ons/io-directx-x/?utm_sou...

Note: this post has nothing to do with me being an employee under the Xbox umbrealla. i did not get any fund, support, hardware, assisstant, documentations from Xbox as a company or anyone under the Xbox. It was entirly a game developer’s passion sub-project as part of a larger passion project (game engine from scratch) that was initated years ago before i even join the Xbox family! The hardware used was bought from eBay long time ago.
There is no doubt that the original XBOX is not only one of my all time favorite gaming consoles, but also one of my top all time favorite development hardware/environments! When i started converting my Mirage engine from exclusive PC enigne based on Vulkan mainly to a much wider engine that has a good layering that could allow me easily supporting any platform and any rendering API, it was not an easy task to be fair! As my initial thought was not to just support current modern hardware such as Xbox One and PS4 or even the new genreation that will release soon (Xbox Series & PS5), but my mind was else where! i had in mind quite a few older consoles/handhelds that i would like to support out of the box, and to not spoil my list of platfomrs, let’s just assume i had only Xbox OG in mind back then (of course was not the only one!).
Going that far back in technology as a modern target hardware was quite the task i needed, the type of thing that i like that most. Porting my engine to a new Nintendo or Sony device is not a big deal nowadays as long as i got granted the access, just follow the SDK, and you won’t hit any wall…probably..even if you hit walls, just go to the dev forums, and will find pretty much a handful amount of folks hit that wall already and discussing solutions for it..Easy! But supporting a dead hardware, that has no support, and only obsolete SDKs & documentation and the elephant in the room, obsolete requirements, toolchain and tools that is not matching any modern software creation process or even friendly with most recent OS versions (Linux or Win 10/11). That was the challenge.
At that time i had my engine that was built in few years for Vulkan only, Win/Linux only and running on C++17 (and later moved to C++20), using most recent 3.x cmake version at that time (3.4-ish or something), and of course running on Visual Studio 19! Now we need that to be C++98 or C++03 at most, count on the most ancient version of cmake possible (1.4.x if i’m not mistaken, which is not great btw), and to run on Visual Studio 2003 and of course support some set of different file formats. I’ll leave the rest to your imagination, but successfully got rid of any features that are between C++17 and C++98, and that meant re-writing lots of functions from scratch, readapted the entire engine API, disable some features and/or adding new exclusive ones for older hardware, and because Visual Studio have to make life harder, the MSVC can’t compile C++ code pre C++14, so had to work on my projects generation in generating projects for GCC to at least test compilation on VSCode on a Windows 11 environment to make sure that my code compiles, before i put it in the time machine and take it to the old boy XP computer to re-compile and run it.
With CMak’s presets, at least i can now generate & compile most of targetd C++ versiosn and APIs side by side on my main Windows PC before moving any to an ancient OS version to build and test against the hardware.
Note, that screenshot showing Win64 only presets
Yes i know!!
Now you may be thinking, oh, how come he did not know about the nxdk or other homebrew solutions?!
i konw about nxdk and all other opensource nice projects out there (for Xbox, N64, Dreamcast,…etc.), and they’re really great resources!! it just happens that i like 2 things too much when it comes to console or writing for specific hardware and it have always been the case.
First challenge was running my demo scene, the sponza! All the formats available for Sponza was very friendly for a today workflow, but not for a 2000-2005 development environment. The size of the file itself was larger than the entire memory installed in the original Xbox! Sponza OBJ out of the box was around 23.29MB that was for some reason when converted directly to the Xbox fomat, it resulted in a 82.3MB file! In order to make it kinda acceptable (and of course downgraded the poly count, which would’ve been visually okay if Sponza ran back then), i had to take the available FBX, convert it to OBJ (as a pure text format, OBJ is super portable not only in space, but in time), as the lowest FBX version i was able to convert to in Blender/Maya on Windows 11 was FBX2011 whcih still won’t work on my XP 2000-2005 environment if i tried to import in Maya (Blender did not have a FBX importer yet back then, and 3dsMax all what i knows and and all what it sees was *.3ds only, Maya & Blender were the best).
So converting to OBJ made perfect sense. Then taking that OBJ to an Maya 6.5 (in addition to exporter, geometry tools were greater than any other 3d software back then) and optimized it as much as possible, then converted it to another OBJ file.
That later OBJ file was opened in Blender 2.3, as Blender was the only software that could convert geometry to the DirectX (DirectX8)’s *.x file format. Finally opened that .x file and modify it manaully to cleanup any “null” values, as those will break in the next step, and there were no way to do that cleanup within any of the exporting steps, but i can live with that as long as i was able to spot the issue.
Here is an example of the “null” thing mentioned earlier as part of .x file.
The “convx” thing in my red-text notes is the cmd tool used to convert the file (if name is not explaining itself :D). This is possibly an issue with Blender’s converter, as the materials list in the blender file did not inlcude more than 2 materials!
Finally taking the final .x file, and convert it to a binary compressed .xbg (xbox geometry) file through one of the SDK tools (only possible if all the presiouvs steps did not produce a large or corrupt file). Also surprisingly, this tool still holding up & can run on Windows 11 under DirexctX 12!
And all files together (origianl Sponze converted VS the simpilified one), you can see the sizes..
and you can look at the bottom to the .zip version donwloaded from github (~109.9MB with textures, wihtout texture about 23.29MB).
One thing to keep in mind, we could’ve reduced that amount of software & format jumps, only if 3dsMax 6.0 of that time was friendly! Xbox OG toolset had the support of converting directly from .3ds to .x right away with a 3ds dedicated commandline tools, but the issue with discreet’s 3dsMax at that time that it won’t accept FBX and the OBJ loads broken all the time, this is why i mentioned earlier that “3dsMax all what i knows and all what it sees was *.3ds only”.
Only now, the original Xbox branch of the loading code can work if directed to the right file format (from a .fbx to load on the modern systems, to a .xbg to load on the original Xbox).
Now not everything in a game is just environments or static meshes. But there has to some form of skeletal meshes if not for characters, then for animals or some other moving objects! i want to put something that moved on my samples, but what mesh i can use?
It happened that few weeks ago that i noticed the Unreal Engine 6 branch on github went public for everyone, so i decided to sync that branch and compile the engine locally to have a look at all the new feature or half features.
One thing i observed was probably the Quinn mesh looked different, i think Epic did the same for the jump from UE4.x to UE5.x with the Mannequin, and that sparked in my head, why not backporting that Quinn character from the Unreal 6.0 default starter project to the OG Xbox?! We can now launch engine on the device, load files, and render them. We also have a set of tools and workflow to use, so let’s port that Quinn to 25 years ago!
At this time i wanted to update the texturing as so far rendering on Xbox was only involving mehses, i do have base for texture loading and sampling, but the issue with Sponza that it was not built with optimization in mind, it has so many textures, som duplicates, sizes are large and not ready at all for such production. So i wanted to load the textures for the character i want to render, and Quinn (again) seemed a good candidate, it has only 2 textures, so i won’t be wasting too much time in preparing those textures. Preparation is not only in resizing and converting formats, but it is more beyond that.
On Xbox in order to load textures, the best approach is to write a redefination file (*.rdf), that file inlcude all textures you want, with identifiers/names and their directoris, dimensions, mips, formats,…etc. and then that file will go through one of the commandline tools, in order to compress all of them to a large block with offsets in a file called the “resources” or the .xpr file (alongside a .h includes all the offsets), that later you just load that resources xpr single file, and use the offsets from the auto-generated header in the C++ code to read the offset for each texture by the name you gave it in the redefination file. It may not sound unqiue or new technique, and may sound very familiar to you, but back then that was kinda innovative idea!
The other part was the animations part, in order to deliver humanoid or “soft” deforming animations on Xbox, there were usuallyt wo approaches all through vertex shaders of course:
I’ll leave you guess which appraoch i took!\
But all in all regardless which technique choosen, it would requires a vertex shader to be wrttine in assembly in the *.vsh format (to be compiled with commandline tools into a much lite binary *.xvu format).
Final touches for an app, for icons and other texture media, there is a nice tool comes with the SDK called “Bundler” and it is used to generate files for more console friendly (and compressed enough) format. For example, to put an icon to the project, the Visual Studio build tools expects an icon given with the .xpr format. This one can be converted from *.bmp through the bunder, and then assigned as “Title Image” (as of image/texture) to the Xbox Image (as Iso/Snapshot image)—names are confusing i know!.
Last thing, i noticed while digging for solutions to some of the problems i met during my engine proting and during preparing these examples to run, these chms in my data. Thought about putthing them all in one screenshot for memory..Interesting how things have changed over the years,..It was quite a ride with the Xbox development..
-m