Skin functions

Today I decided to make my first contribution ever to the open source community.
I added some lines to NiOverride.psc.

Can't wait for my pull request to be accepted.

I used to be a pro fighter, so I thought I was well acquainted with pain, but nothing could ever prepare me for dealing with this.

What are these used for?

If you followed the last article and played around with Node Override Layers, right now you should be able to use layers for:

But if you added a skin[2] TextureSet to your Actor, then it has got a milky white skin.

To get this:

NiOverride.AddNodeOverrideTextureSet(ref, true, "Body [Ovl0]", 6, -1, Skin, true)

Sure, you know how you can set the skin color using:

NiOverride.AddNodeOverrideInt(ref, isFemale, "Body [Ovl0]", 7, -1, 0x20EE10, true)
But how in blazes do I get my character skin color???

That will not do.

Skin functions to the rescue!

Last time we said layers that don't have a texture set assigned, remain invisible.
That's because layers start completely empty. And that includes the skin color.

The skin color of an Actor doesn't belong to any of the Node Override Layers because those layers are a separate entity from the Actor.
Remember I told you these are exactly as Photoshop layers? Well, when you create a new Photoshop layer it starts completely empty[3].

Anyway, want to know were the skin color is?
Why, it's in the skin.

Always remember

An Actor skin is the part of the model that contains info by default.

For practical purposes, you can think about the skin as the lowermost layer and the only one that has any kind of information by default.

... and if you want to retrieve any of that info, you need to use skin functions.
Particularly, the ones called GetSkinPropertyMeh.

What's the skin anyway?

Skin is the skin (as in "flesh") of an Actor.

If you open a model in Outfit Studio, the skin is precisely the meaty part of the 3D model (which ultimately ends up becoming an Armor).

It doesn't matter if you are a man or a woman, you all are a bro to me :' )

Bruh...

... ahem... I mean, what you see in that picture above is the armor and the flesh parts.
All NiOverride.SkinSomeShit functions will work on the skin, but not on the armor (shown as a wireframe in the pic above).

Before I confessed my love for you (no homo), what I wanted to say is that skin functions work on both men and women.
And you will see their effects as long as the currently equipped Armor has some skin to show.

... which for women armors will be "always".

So now you have a better toolbox of options.
Now you can work on either node or skin overrides.

*Wink*, *wink*

Notice how skin functions don't ask you to provide them a node?
That's because they don't work on nodes, but the flesh.

Just for a pointless but illustrative excercise, let's fix the very first thing we saw in this article.

int skinColor = NiOverride.GetSkinOverrideInt(ref, true, false, 0x4, 7, -1)
NiOverride.AddNodeOverrideTextureSet(ref, true, "Body [Ovl0]", 6, -1, Skin, true)
NiOverride.AddNodeOverrideInt(ref, true, "Body [Ovl0]", 7, -1, skinColor, true)

"OH, WHAT THE FUCK??? WHERE THE HELL DID YOU GET THAT 0x4", I hear you groaning.

Yes! That was (... yet another) one of those stupid and arcane values no one ever tells you where to get them from[4], but I'll do it because I'm nice, unlike other dudes.

Those values are taken from the Armor Slot Masks.

I'll put the ones you care about here, in case Bethesda pulls "a Bethesda" and moves the wiki to Instagram or some dumb shit like that:

int Property kSlotMask30 = 0x00000001 AutoReadOnly ; HEAD
int Property kSlotMask31 = 0x00000002 AutoReadOnly ; Hair
int Property kSlotMask32 = 0x00000004 AutoReadOnly ; BODY
int Property kSlotMask33 = 0x00000008 AutoReadOnly ; Hands
int Property kSlotMask34 = 0x00000010 AutoReadOnly ; Forearms
int Property kSlotMask35 = 0x00000020 AutoReadOnly ; Amulet
int Property kSlotMask36 = 0x00000040 AutoReadOnly ; Ring
int Property kSlotMask37 = 0x00000080 AutoReadOnly ; Feet
int Property kSlotMask38 = 0x00000100 AutoReadOnly ; Calves
int Property kSlotMask39 = 0x00000200 AutoReadOnly ; SHIELD
int Property kSlotMask40 = 0x00000400 AutoReadOnly ; TAIL
int Property kSlotMask41 = 0x00000800 AutoReadOnly ; LongHair

You can test and play with all of them, but the ones you really care about for skin functions are:

Skin super funny bonanza

Let's try something funny.
Strip completely naked, then proceed to do the same to your player character.

We'll apply a function for changing the diffuse skin texture by using a skin override.
I'll use an hypothetical texture path, but you should use one that actually exists:

string path = "textures\\actor\\character\\woman\\silky_soft_skin.dds"
Actor player = Game.GetPlayer()
NiOverride.AddSkinOverrideString(player, true, false, 0x4, 9, 0, path, true)
TADA! Who ordered pizza?

You can also try to set the normal map using 1 instead of 0 for the index.

Now you know how to properly and consistently make your character to get "The Pizza Hands Syndrome" 👌.
Don't worry, I'll show you how to solve that in a later article[5].

Wrapping up

And that's it for now.
Now you know how to change an Actor skin, but not their faces and *insert tape rewind sound here* say... WHAT???

Warning

Yes, you can't use skin overrides on the head.

Really.
Try to use 0x1 for the skin slot mask. It won't work.

I suppose this happens because the head is technically and literally never part of any body Armor.

I'll show you how to get access to the head in the next article, in which I will talk about...NODES.


  1. I trust you've played around with keys 2 and 3, yes? ↩︎

  2. As in "flesh". ↩︎

  3. I know you can create already filled layers. Don't be so pedantic. ↩︎

  4. One that took me moths to find all the info I needed, and it was only because I casually stumbled upon it. ↩︎

  5. It took me almost two years to solve it.
    Now you know why I say NiOverride difficulty level is above Legendary. ↩︎