Understanding NiOverride texture functions

NiOverride has been my most frustrating experience as a programmer so far[1].

I really love what it does and I think is kind of a miracle we even have it, but it's quite arcane for all the people that didn't create it (that's you and me[2]) and there's simply no documentation to be found[3].

Things that are trivial to implement (once you know what the fuck you are doing) take weeks of experimenting just because there's simply no reference on it.

By the holy beard of baby Jesus... I even tried to decypher the C++ code for skee64.dll so I could know what functions to use and why!
Next time I would rather learn poetry in Klingon; I'm quite sure it will be more intelligible than anything written in C++.

This is the first article in a series that I hope will help all programmers to avoid all the frustrations and wasted time I already had to deal with.

Since there's much to learn, this article will be just an overview for beginners.
In later articles I will talk about how to actually use these things.

Of course this info is incomplete because how the fuck am I supposed to experiment with it if most of the time I don't even know what parameters I'm supposed to feed the functions with?

... but now, thanks to these articles, at least there's some info on it.

One last warning: ⚠️ I gathered all my info on NiOverride for its Skyrim SE version ⚠️.
If you are a time traveler from 2010, please take into account these articles will be dealing with games we play in 2020, so some of this info may or may not apply to Skyrim LE[4].

What the hell are Node Override Layers?

Face, body, feet and hands can have what it's called Node Override Layers.

Those things are exactly the same as Photoshop layers, and whatever texture you put on one of those layers (nodes) may hide whatever is below.

Their numbers tell you what they will hide.
Body [Ovl5] (sixth body layer) may hide whatever you put on layers 0 through 4.

Layer numbering is zero-based

This means that, if you have 6 layers, their numbers go from 0 to 5 instead of 1 to 6.

It's an old C language-style tradition that somehow stuck through the ages, although I've always found it kind of counterintuitive (I learned how to properly program in Fortran 90, you see).

Have you seen how you can add tattoos on all those body parts using RaceMenu? That's thanks to Node Override Layers.

Each one of those layers is actually a Node Override Layer.

If your mod uses Node Override Layers you may actually override/hide whatever your mod users have on those layers, so handle them with care.

There are also special layers that have names like Face [SOvl1].
I don't know what they are supposed to do and when, but I know they are somehow related to spells.

You can know which nodes (layers) are available (in names and numbers) by opening data/SKSE/Plugins/skee64.ini.

I wish someone would have taught me this.

All functions dealing with these layers (override nodes) are called AddNodeOverrideMeh, GetNodeOverrideBla...

Armors and naked bodies

The first thing you need to know is that naked bodies are implemented as armors in the game.
Yeah, you read it right.

Go see all NakedWhatever records of type Armor and ArmorAddon in the CK.
You will learn quite a lot about some internal Skyrim mechanics.

That being said, some armors can show skin along with the armor per se.
Think about the Wench Clothes or the Forsworn Armor.

For those cases, NiOverride has functions that allow you to change textures of either the skin or the armor.
For example, you can change the brown fur for the Forsworn Armor while leaving the skin alone... or viceversa.

Notice how tattos on Node Override Layers are applied only to the skin, not the armor.

As far as I know, all Node Override Layers (see section above) work only on the skin.

Skin functions

All those functions called AddSkinWhatever, GetSkinShit, etc, are the ones that work on skins.

The skin is a bit different than the Node Override Layers in the sense that (for practical purposes) it's always the lowermost layer of all.

If you want a more precise explanation: unlike the override layers, the skin is always visible and it seems to be internally different than those layers.
My experience tells me the skin is somehow related to the nif file used for the body/armor[5], while the override layers are an addition made by skee64.dll[6] and are not part of vanilla Skyrim at all.

Beware, though.
For Skyrim SE at least, functions that change diffuse and normal textures on an Actor don't work quite well, but they work as expected when you change specular textures.
That's why there's such a thing as Wet Function Redux but not my own Sandow Plus Plus v4.0[7][8].

Summary: textures applied to bodies are also applied to hands, thus giving characters what I call "The Pizza Hands Syndrome".

When it comes to textures, I only have experience with the node override (layer) and skin functions, so I can only talk about those.

NiOverride has functions that deal with armor and even weapon textures, but I don't know how to use them.
Hopefully you will someday discover how to do that and then let us know?

Wrapping up

That's all for now.

For the next article I will talk about what in blazes are keys and indexes.

  1. After 20+ years of programming experience, that's really something. ↩︎

  2. I don't blame Expired for that, though.
    I suppose he never meant NiOverride to be used by others but himself. ↩︎

  3. In fact, this was the only "reference" I could ever find.
    Everything I know about NiOverride comes from it, trying to decypher other mods, and months (yeah, MONTHS) of tinkering with it. ↩︎

  4. To be fair, NiOverride has full functionality for LE, but not SE.
    So... if you are still using LE in 2020, maybe you are the one that should be mocking me. ↩︎

  5. In some article in some indeterminate future I will talk about the Skyrim function called SetSkin(). ↩︎

  6. NiOverride is only a Papyrus script that makes all functions declared in skee64.dll available to Papyrus.
    All the real work is done by that dll. ↩︎

  7. When I was learning about NiOverride by studying scripts made by others, I found out SlaveTats also had problems with normal maps and NiOverride. ↩︎

  8. Great news! After almost 2 years struggling with this shit, I finally solved this issue and I know the precise technical reason of why it happens.
    Since this is a more advanced topic, I'll leave it for a future article. ↩︎