Sometimes gamedev
Obsesses over projects
Not great at doing either
Current focus is Psychonauts


Psychonauts reverse engineering/modding blog
jillcrungus.com/projects/psychonauts/blog/
Mastodon, slightly less seldom used
mastodon.gamedev.place/@jill

I recently tried my hand at a little bit of Mario 64 hacking using the decomp and it was interesting. I'm too lazy to boot anything to show the test map I made but it was definitely fun to learn.

The process is a bit strange - a Blender plugin called Fast64 lets you set up the level in Blender and then export everything to C to build it into the decomp which is certainly a workflow.

But seeing Mario running around in my little test level made me sort of... melancholic. It's strange but it's kind of been a dream ever since I committed to the modding aspect of my Psychonauts projects just to be able to see Raz running around in a similar test map. Just being able to see a fully custom map working in game would be such a special moment. And yet, despite all the progress that's been made, despite so many of the pieces being in place, it still feels so far.

So trying my hand at this stuff with Mario 64 really got me thinking.


It's a tough task. Making a level editor is no easy feat so I don't think a fully custom tool for it has ever been on the table. I'm not a tool developer - that's why all of my projects have either been toolless or had extremely primitive, crappy tools just for testing and demonstrating the library. I've always banked on the off chance that someone else might notice the library and use it to integrate and do the heavy lifting while they wrote an actual tool.1

But there's another option - writing a plugin for some existing software instead. This is a much more viable option. You can use other software that can already do all the hard stuff of rendering in 3D and providing editing tools. This is how Fast64 works. This is how the original game worked.

Psychonauts, like many other games of the time (Simpsons Hit and Run, TimeSplitters,) made the decision to use an external tool as their entire level editor. In all 3 cases their editor of choice was Maya with integration provided via Maya editor plugins. This makes total sense, it was already at the point of game levels being built more like 3D models than with stuff like CSG so integrating level editing tools directly into 3D modelling software was natural.

With all this in mind, I saw 3 options in my eyes. Note of course that all of these I was considering even before I knew Fast64 existed:

Blender

This is the most obvious answer. It's 3D modelling software and would basically fill the same role as Maya did during the game's actual development except it's FOSS and far more accessible. Since it's full on modelling software it could handle both custom level creation and regular custom model creation. While it seems like a no-brainer there's actually a few reasons Blender could be a bad choice. For one, it's got the wrong coordinate system2 which adds some extra work. Second, it uses Python which means that if I was to go with this option I wouldn't be able to leverage any of the existing work in PsychoPortal directly which would really suck (more on this later). These two things were a big deal for me, so I regarded Blender as very much being a "so close yet so far" situation.

Unity

My second choice and the one I'd started my initial attempts on. I'm super familiar with Unity and it's all C# which means immediate PsychoPortal integration. I'd actually started a few prototypes on this on this and gotten basic entity info and level geo importing into Unity but not enough to do any exporting. Unity has its own issues though. For one, its hierarchy-based nature doesn't really fit Psychonauts, which is heavily scene based3. This isn't a big deal though. It's also still got the wrong coordinate system2 - it's left-handed where Psychonauts is right-handed. The biggest disadvantage is that Unity is not modelling software. This means that for building levels your options are a bit more limited to either using an addon for it or building your geo in an external tool to import into Unity. Not ideal, and making regular custom models is practically off the table (or at least, would be super inconvenient).

Godot

Godot was an option that at a glance seems like "Unity but better". Despite that I was very on the fence about it because I didn't really like the engine for a while. I have been warming up to it recently though and for a bit I thought this was the ideal option. Just like Unity it has C# support for direct PsychoPortal integration but unlike Unity it not only has the exact same coordinate system as Psychonauts but it's also scene based so it's also got the architecture in place! HOWEVER, it still has the issue that it's not designed for actual model editing itself. On top of that, if I'm being honest, the documentation for writing Godot addons is not very good. It's incredibly difficult to figure out how to do a lot of stuff without combing through the API reference for the relevant classes and hoping you find functions to do what you want and it's hard to find this info through searching for what you want to do. Compared to Blender and Unity it's a lot harder just to get started and learn how to whip up some functionality with Godot.

Conclusion

Even after I thought I'd settled on an option I frequently had doubts because like all things in life there isn't a perfect choice. My familiarity with Unity made it a VERY appealing option but it's definitely not designed for this kind of thing. Godot's a great choice in theory as it has the same benefits as Unity while resolving a couple of the issues but struggles with the documentation made working with it problematic. The fact that trying to export normal standalone models with either of these would be suboptimal is also a problem because it'd take much extra work to support it proper, and given that normal models and levels are actually both the same format it'd be really unfortunate to support one and not the other.

I discussed this quite a bit with @bekoha. At one point I considered using Blender, but with an intermediate conversion step. You'd use an external tool (Oatmeal) that uses PsychoPortal to convert to/from another format that could support Psychonauts-specific metadata (DAE?) and then you could import/export that same format in Blender using a helper addon to view and edit said metadata. I made a couple attempts at this but I recall something always getting in the way when it came to dealing with the intermediate formats. This is also not the greatest workflow. At one point I also considered having a custom intermediate format which, on reflection, is completely fucking insane because at that point reimplementing all of PsychoPortal in Python would probably actually be less work.

One thing was clear though - Blender was probably the best option in the long run. I even learned that Blender also had its own scene system which doesn't exactly act as a good equivalent to how Psychonauts and Godot do it but it is good enough to keep things better organised.

I was actually fully prepared to just start reimplementing all of PsychoPortal in Python until @bekoha also sent a link to SonicAdventureBlenderIO for reference since I'd never written a Blender addon and they figured they'd send stuff my way that seemed useful. It was at this point that I noticed the "dotnet" folders in SABIO's hierarchy sticking out like a sore thumb. SABIO did the exact thing I wanted to do all along - it facilitated import and export into and out of Blender while allowing a .NET module to do a lot of heavy lifting. It uses Python.NET to achieve this.

I'd known about Python.NET's existence, I think, but I suppose I'd never figured out how it could be easily integrated into Blender and so I'd given up and regarded it as a dead end. Here it was though, a perfect example of exactly what to do.

So that's where things are right now. The plan's to write a Blender addon leveraging PsychoPortal to do the hard work of reading and writing the formats. I'm still trying to figure out the actual design of the thing in my head, and through this it also means I'll be needing to actually learn how to write a Blender addon AT ALL, so that's fun. This is gonna be a real pain in some places. Even once mesh and entity info is importing/exporting there also comes the issue of generating lightmaps and visibility data and navmeshes. I have no idea how to handle any of those things. Those are all things that'd probably have been marginally easier in the actual game engines. I should have plenty of time to think about it though. Perhaps I can ask how they handled these in the original Maya workflow.

Yet another project on my plate but it's one that I've wanted to happen for a long time. We'll see what happens with it.


  1. However, the closest thing to this happening has only ever been RayCarrot's Psychonauts fork of Ray1Map which uses PsychoPortal but barely counts because RayCarrot ended up practically writing all of PsychoPortal for me prior.

  2. On coordinate systems: an environment's coordinate system essentially dictates which axis (X, Y, Z) is up and which way the other 2 axes go. You can find a helpful chart showing a visual reference as well as which engines go where made by Freya Holmer here (direct image for the Twitter adverse). Psychonauts being integrated with Maya means it shares Maya's coordinate system. From this chart you can see that Godot matches Psychonauts (Maya), Blender has the wrong up axis and Unity is the wrong handedness.

  3. All "models" in Psychonauts are actually scenes stored in files called PLB files. Everything from entire levels down to simple figments is a scene file that can contain triggers, entities, etc.


You must log in to comment.