Oblivion

NorthernUI's been out for nearly three years now, and I guess I just want to write down some reflections on its development -- challenges I ran into, things I could've and should've done better, and the like. I don't want to use the term "post-mortem" because I don't want to permanently write off ever returning to maintain NorthernUI, but I suppose it'll be that general kind of write-up.


Scope and feature creep

This is absolutely the biggest and worst issue with NorthernUI. We're not dealing with Oblivion Reloaded levels of creep here, in any sense of the term, but NorthernUI does too many things at once and absolutely should've been multiple mods.

Having the gamepad support exist in the same DLL as everything else is definitely my biggest regret and the main source of feature creep. The only reason I implemented gamepad support at all was because Xpadder/AntiMicro wasn't satisfactory for navigating the game's menus; the only way to smoothly handle switching between gameplay and menus is to actually have built-in gamepad support. Unfortunately, I was unfamiliar with the Windows APIs for working with DLLs; I taught myself C++ and x86 assembly by making SKSE plug-ins, and SKSE, unlike OBSE, offers a simple mechanism for sending messages between plug-ins, so I never needed to learn the Windows APIs. (Essentially, when it comes to C++, I learned a lot of the hardest and most niche stuff first, and a lot of the basics last.) I didn't know how to pass messages between OBSE plug-ins, so to my thinking, anything that needed to access gamepad state needed to be part of the same DLL that was adding gamepad support in the first place. This is how features like enhanced movement and camera controls ended up in what was supposed to just be a UI reskin.

For anyone who's wondering, the right approach would've been to make the gamepad support a fully separate OBSE DLL, and have it "export" functions to be called by other DLLs. Then, any interested OBSE DLL could use GetModuleHandle both to check if the gamepad DLL is loaded and to gain access to its exported functions via GetProcAddress. With a system like that in place, features like the enhanced movement and camera behavior could have been placed in yet another DLL, keeping things neatly separated.

(Oh, speaking of which: do you find Oblivion's third-person camera uncomfortable and disorienting? Do you hate how strafing tries to turn the camera to the side to "peek" in the direction you're moving, such that your movement desynchs from the camera? Sick of the wild swings the camera takes every time you step over a curb? Set NorthernUI's "Camera Inertia" option to "Disabled" for a less vertigo-inducing experience. I literally forgot that I implemented that and only rediscovered it today, and holy heck does it make this game more tolerable! I'm so grateful that the camera inertia was gone by Skyrim. I'm still going to leave the inertia on (but with fixes) as the default setting, because Oblivion is Oblivion and should be Oblivion by default.)

If it had occurred to me to rely on this kind of DLL communication, I could also have allowed NorthernUI to provide an API for its options menu: I could've defined "option handler" classes with virtual member functions, and allowed NorthernUI to receive pointers to instances of these. Other DLLs could've then defined their own subclasses which override these functions, to specify the option's widget type (checkbox, slider, etc.), supply a value, react to the value being changed, and so on. This idea could also be taken further to allow other DLLs to insert nested menu structures. If I had separated my enhanced movement and camera patches into their own DLL, they could've used this framework; it could also be useful to the handful of other actively maintained DLL mods out there. (I did at one point consider the logistics of allowing scripts to add menu items to the options menu, but I couldn't think of a good API design for them.)


Control schemes

NorthernUI includes multiple pre-defined control schemes, and allows you to define your own as well. I don't think I did a good job of presenting the feature, but I think I did a decent enough job of implementing the feature. It was inspired by the approach to controls taken by games like Halo, where you have a wide variety of control schemes that emphasize different actions and abilities, like the iconic Bumper Jumper which is intended to let you jump and melee without having to take your thumbs off of the aim thumbstick. I wanted to offer some good pre-defined control schemes, but also let you create your own. IIRC Borderlands 2, by contrast, offers a few predefined control schemes and lets you make just one custom scheme, which is more limited but perhaps more intuitive than what I've done.

Looking back, it would've been nice if I could've actually had a graphic of an Xbox controller, with labels tied to each of the buttons to literally let you see the different layouts. As it stands, though, I think the look of the customization menu is on par with the rest of Oblivion's menus.

One thing that I'm pretty proud of is the one-handed control schemes. These were pretty much directly and entirely inspired by halfcoordinated's speedrun of NieR:Automata at Games Done Quick. I tried to design each control scheme to ensure that the most critical gameplay functions were quick and easy to access, though I'm not nearly skilled enough at games to try them out myself. I can barely manage with two hands.


Compatibility challenges

One thing that I didn't see coming at all was the number of compatibility issues that would come up when making a UI reskin. It turns out that an absolute ton of scripted mods rely on access to the UI to influence game state and features, and the script functions that these mods rely on are spectacularly brittle. Both OBSE and MenuQue's UI commands require that UI elements be accessed by a fully-qualified path. This means that if I change how elements are nested, or if I change the name of any element in a nested hierarchy, then those commands immediately stop working.

A few of these mods' authors included code to automatically detect DarNified UI and use different element paths for it. I recall one author actually embedding the element paths into a secondary file as variables, such that they could in theory add new paths very easily. Most of these mods' authors don't seem to have planned ahead for new UI overhauls at all, however... and they've been long-gone for years. Several of the mods in question use closed permissions, so providing specific patches for them wasn't necessarily an option (plus Oblivion embeds its scripts directly into ESP files, so any patches would've burned load order slots).

I also don't play Oblivion regularly, and never did. I got the game on sale years ago, and decided to play it casually while dealing with a real-life situation that got in the way of working on Skyrim projects. That turned into me disliking Oblivion's UI strongly enough to want to adapt it to something more familiar, which turned into... all this. My experience as a player involved grabbing the most popular graphics mods and one or two stability fixes and then diving in. The kinds of mods that use scripts to tamper with the UI are exactly the kinds of mods that I, as an ultra-casual player (and now pretty much not a player at all), would never have found on my own, so I was completely blindsided by the compatibility struggles.

What I ended up having to do in several cases was modify the UI to provide invisible elements with the fully-qualified paths that these mods expected, and then have the UI copy data to and/or from these dummy elements; this in turn required reading the mod's scripts closely to figure out what it needed. (This was fairly difficult for me just because I'm not used to Oblivion's scripting language, and my experiences with it have seldom been pleasant: it's clunky to edit, clunky to compile, often compiles incorrectly...) In other cases, it was easiest and cleanest to just take the entire mod concept and implement it in NorthernUI as a feature.


No vectors, rasters only, Final Destination

Skyrim's UI uses vector graphics by way of Scaleform, a framework that essentially allows you to run Adobe Flash inside of a video game. (About half of you reading this are going to say, "Wow. Bethesda would do something that jank." It's not just them.) This makes UI modding very inaccessible, because you need a particular version of a particular toolset intended for business customers and priced for business customers -- and that's without even getting into the fact that Scaleform was discontinued a couple years ago. There is one obvious benefit, though: you get all the benefits of using Adobe Flash, namely vector graphics that can be displayed with perfectly smooth linework at any scale, and also a variant on JavaScript if you're into that sort of thing.

By contrast, Oblivion's UI is defined using XML and DDS texture files. The game takes that XML and renders the elements inside in 3D, as a series of dynamically-constructed quads with textures mapped to them. This means that all UI graphics, including fonts, are game textures, and it's why the UI is affected by Oblivion's different graphics settings -- including the FOV option which, if changed, will completely destroy all the careful alignments Bethesda used to get the UI to show up properly. I mean, hell, the file format for Oblivion's fonts literally defines each glyph in terms of size, alignment, and texture UV coordinates. This kind of thing has a number of consequences for NorthernUI -- some of which were very unexpected.

Probably the strangest issue I ran into is that if any texture smoothing is applied to the game's mouse cursor (which happens by default), then every UI texture except for the cursor will end up absolutely mutilated. Imagine scaling a graphic down by half, scaling it back up with nearest-neighbor, and then blurring the hell out of it. You don't really notice it with Oblivion's vanilla UI because the skeuomorphic design that Bethesda went with isn't really affected by it so much, but when you have a style that revolves around clean, crisp lines, things get very bad very quickly. I ended up having to hack part of the engine to specifically exclude the cursor from any texture smoothing, so it renders with jagged lines but everything else looks fine.

Apart from that is just design issues. Raster graphics don't scale cleanly, and because Oblivion adapts its UI to your aspect ratio, it's always going to be scaled at least a little bit. The font format doesn't lend itself to scaling very well either; in theory, you could create an ultra-high-definition font texture and then set the glyphs up to define small quads, allowing a small-print font to render crisply and cleanly even at very high resolutions. In practice, something strange seems to happen to the UVs, so the font texture doesn't get cut properly and the letters get mangled.

If there was one thing I really wish I could've done, it's add some sort of support for vector graphics to the engine. If we could render SVGs and perhaps a real font format, then it would've become a lot easier to produce a high-quality UI at any resolution, and it would've been possible to offer a wider variety of options for things like UI scaling and (in particular) font size, the latter of which would've been great as an accessibility option. NorthernUI as-is probably looks fine to you, but I can't help but notice little inconsistencies like how the compass linework (at its default size) is noticeably thicker than the linework for the health/magicka/stamina meters, because scaling the compass down enough to match would likely have blurred the linework all to hell at most resolutions.

At one point, while I was struggling to figure out that texture smoothing issue, I got so desperate that I actually 3D modeled a single graphic from Skyrim in Blender -- specifically, the "up" endcap for scrollbars. Oblivion lets you embed NIFs directly into the UI (this is used to power anything that uses complex animations, including the lockpicking and persuasion mini-games), so I tried to use that as a cheap way to do "vector graphics." But remember what I said before: the UI uses the same render settings as the game world. (The UI also strips most shader settings off of the NIFs it loads, but it was easy to stop that with a patch.) My scrollbar endcap would look perfectly smooth if you ran the entire game with strong anti-aliasing, but IIRC Oblivion uses MSAA so that could have a heavy performance impact. Without anti-aliasing, the endcap was jagged and totally unusable. What a shame.



The 3D endcap as shown in NifSkope, with the grey portion selected and its polygon edges visible.
Mostly this was the 3D equivalent of a traceover, but IIRC as a shortcut I sliced a disc in half for the rounded base.


Now, all that said, I'm very proud of my work on the raster graphics. I extracted the original SVGs from Skyrim's UI for use as a visual reference, but Bethesda doesn't allow mod authors to port official assets between games, so all of NorthernUI's graphics were hand-pixeled from scratch using GIMP. The original graphics at launch were very low-quality; at some point well into development, I did a redraw of almost everything, and I couldn't be prouder of the results. The first drafts were just aiming to look sort of like Skyrim, but there were a lot of nuances to the linework that I picked up on the second time around. I'm not writing this to brag or toot my own horn; it's more that I feel fortunate to have managed to have done some good graphics work, y'know? It had been a long time since I'd done this kind of pixel art, and programming has been much more my forte, so I didn't think I still had it in me.



The original box corner graphic on the left, at 200% zoom, and the current box corner graphic on the right, at normal zoom.
Note the quirks in the linework on the right, mimicked from the original vector art in Skyrim.




The original compass graphic on the left, at 300% zoom, and the current compass graphic on the right, at normal zoom.
Note how the newer graphic is more on-model, both in terms of proportions and angles, and in terms of where the knotwork overlaps itself.


Redoing the assets in a higher resolution was probably one of the best decisions I could've made for the mod; more pixels means more room, literally, to work in, which helps for getting angles right and for capturing the smaller details. It helped that I didn't need to be absolutely spot-on. If you look closely at the newer compass endcap, you can probably see some rough edges and low-quality anti-aliasing; because Oblivion always scales the UI at least a little bit, "perfect" anti-aliasing often looks worse in-game, and edges that are a little too rough or sharp will be smudged just enough to smooth them out. This means that I was freed from focusing on a pixel-perfect mimicry of Skyrim's vector graphics; it was enough to be 90% on-model.


Hotkeys

A lot of people have asked for hotkey support on Xbox controllers, and the answer to that has gradually shifted from "hopefully soon" to "maybe later" to "probably not," if I may be entirely honest. I've been neck-deep in some projects for Skyrim (as of this writing I'm working on an entire alternate Creation Kit, built from scratch) and I worry that if I tear myself away from those for too long, I'll never come back to them. I have looked into Oblivion's hotkey system from time to time, but it's been... odd. Perhaps now I've improved enough to grasp it a little more fully, but like I said -- other projects. From what I've seen in the comments section, you all have found workarounds on your own to make up for this gap in functionality, at least.

I can, at least, put an explanation of what I know in a place that should be easy to find.

The weird thing about hotkeys is that Bethesda doesn't store one single item (or spell) per key. Under the hood, they store a list of items (or spells) per key, but they seem to take care to make sure that that list only holds one item. There are also about half a dozen totally unidentified variables in the engine that are associated with the hotkey system, some of which seem to be timers. My main concern is that I don't want to try to implement hotkey access on controllers when I'm not entirely sure how it works even for the keyboard and mouse. I need to know why Bethesda used a list, and I need to know what those variables are, and I just haven't had the time to dig deeply enough to find out.


Well, that's about all that comes to mind for now.

Hopefully this was an entertaining enough read. I know a few people like getting a peek behind the curtain, and I also think that it's good to just write this kind of stuff down after a while, so that maybe it can be learned from instead of forgotten.

I never expected NorthernUI to get quite the amount of attention it's gotten. As a content creator I'm "native" to Skyrim, so when I published NorthernUI, I figured Oblivion was a dead game and I didn't expect to break triple-digit endorsements. Y'all proved me wrong real quick: those of you who've stuck around with The Elder Scrolls IV are pretty darn devoted to the game. I try not to reply to comments unless they're support requests or similar, because I guess I'm kind of weird about praise; if fully half of my comment section was just me thanking people for complimenting me, it'd feel immodest. However, I do read every comment I get, and it's been real striking to see people who are still in love with Oblivion after all this time tell me that this mod has made it that much easier for them to revisit an old classic. The game's not really my scene, personally, but when people tell me that I've helped to keep the magic alive for them, it's something that's hard to even process. I'm glad that even with all its flaws, NorthernUI has been able to help keep a classic game going -- and modernize it a bit, for those of you who want that.

Article information

Added on

Edited on

Written by

DavidJCobb

3 comments

  1. syscrusher
    syscrusher
    • premium
    • 39 kudos
    Thanks for the mod and for this very interesting read.

    I led the team developing Rathunas (a large quest/town/home mod available on the Nexus) and can very much relate to your comments.

    In our case, though, most of our scope creep was intentional. I started alone, wanting to make an extremely immersive player home, purely in the Construction Set. I tried all sorts of weird kitbash hacks of Bethesda's meshes to build a unique home, but I wasn't happy at all with the results, so I started learning Blender 2.49b. By this time my wife (IRL) had gotten in to the game and was collaborating with me on the artistic aspects.

    When we put out word to our theatrical and reenactor friends looking for NPC voice actors to bring our little village to life, there were far more responses than we had expected. Since we were both excited about the collaboration so far, we made a conscious choice to "go big." My solo immersive house mod turned into a 5-year project with a team of 35 voice actors, 2 professional composers, two writers, three QA testers -- and still just one programmer. {ahem}

    The challenges in the game engine that you discuss differ from the ones I encountered, but they're relatable! Rendering and memory constraints were front-and-center, and unpredictable pathfinding/AI systems brought endless frustration. The other major challenge was persistent vs. non-persistent object state, and one-time initialization vs. per-startup initialization. Oblivion does not handle that well, at all. Finally, as you've noted so often, compatibility with other mods and load order permutations (numerically, approaching O(n!) complexity) is a QA nightmare.

    Anyway, thanks again for the article. It was really interesting to read about another developer's project experience. I hope you have as good an outcome from your modding as we did: Rathunas was released in 2015, and since 2019 I have been doing 3D programming and design as my day job (in mostly non-game applications, but using the same tools). My wife anc co-collaborator has recently entered the 3D artistic part of my employer's team. Three decades as a couple, now also professional teammates.

    For quite some time, I have considered the idea of a Rathunas developer retrospective. I think you may have given me the inspiration to actually do that.
  2. Wintceas
    Wintceas
    • supporter
    • 16 kudos
    Northern UI besides having two beautiful interfaces is one of the most useful mods I' ve ever used. It was, and still is, the single reason I return to play Oblivion. Thank you very much!
  3. MoonALM
    MoonALM
    • member
    • 3 kudos
    Hey man, I remember reading your posts when you were making progress on this mod prior to 1.0 release, and I've been struck by how vast the challenges were while reading this post. Personally, it feels a lot like there shouldn't be a need to go through so much effort to get this to work... But here we are and if there was a need for false duplicates of UI elements for compatibility, no matter how mad that is (for a non-competent-in-the-same-area like me) that's what it took. And I've got to say, I agree with the people that said this mod brought new life to an old game in a way I didn't think a UI mod could. Thank you for this, I sincerely believe a well applied mod like this can replace 5 or 10 other stacked mods and make the experience waaay more enjoyable. It also feeds the imagination, although, now that you've laid out the challenges that this poses, I feel a bit daunted... for instance, once, I had the idea of adding some of the drawings/graphics from the different classes as graphics for each object on the right side of the menu, a bit like Fallout 3 does with the Pip-Boy icons... or re-skin the theme to keep it in the same layout but give it a different style, and I think you've managed to give Oblivion an UI that is no longer stuck within it's own graphics. And if you ever decide to come back to this project after you're done with the other things you've been wanting to do, I'd be happy to read along for the ride once more.