Over the last few months I’ve been gradually shifting my development over to 4coder (from Sublimetext and VS Code, which are actually both pretty great) so I created Papyrus syntax highlighting and a build script. I’m sharing this stuff on GitHub, and you can read more about it on its own blog page.

Time to update my tools, get SKSE64 working, and learn about this Vortex thing.

You guys need a bath.

Share:

Some users made a suggestion that instead of awarding penalties for getting hungry and tired, I should instead award benefits for staying full and rested. I think that actually fits in better with the vanilla sleep system, so I’ve decided to add it to my mods. I am including flags to turn this feature on and off, so once (if?) JsonUtil becomes available in the future, users will be able to easily toggle benefits, penalties and animations however they like.

Super Simple Needs will include a Well Fed bonus that adds 50 to Health for 4 hours after eating. Since you stay full for approximately half as long as you stay rested, the bonus lasts half as long as the vanilla Well Rested Bonus. The Rested/Well Rested/Lover’s Comfort benefits are entirely untouched.

Super Simple Bathing will include a Clean bonus that adds 5 to Speechcraft for 16 hours after bathing. Since you stay clean for approximately twice as long as you stay rested, the bonus lasts twice as long as the vanilla Well Rested bonus. Some users also complained that Troll Fat was too hard to get at lower levels, so I’m including an added recipe that uses potatoes instead. I’ve been told potato soap is a thing, but I’m not a soap expert. If you don’t like it don’t craft it, or remove the recipe with xEdit.

I am in the process of committing these changes to GitHub. After I play with them for a few days I will start the tedious process of updating Nexus and Bethesda.net.

Share:

Super Simple Lock Bash is out. You can get it on Nexus or Bethesda.net for PC and XB1. You can find links to it here.

I created this a long time ago for the original Skyrim to use with my barbarian character and it was the first mod I started porting over to SSE. Unfortunately, I found that I relied on SKSE to get references to the lock that was being bashed and to get the base damage of the weapon being used to bash the lock. It took a while, but I managed to change that detection over to a Quest Alias. I replaced the base damage in the calculation with the weapon material of the bashing weapon to roughly equate to what it used to be.

This is the last of my existing mods that I wanted to port over the SSE. I’ll start looking at Bathing in Skyrim 2 now, but I there is a very high chance that I won’t make much progress until after SKSE64 is released.

These mods, while great, add a lot of features and restrictions that cause me to spend time managing things I don’t want to manage. They often force me to do “realistic” things that I find cumbersome. There is a lot of demand for these mods, so I understand completely why they exist. On top of that they are some of the best made mods out there. They just don’t really fit in with my style of play.

So, I made my own basic needs mod. I am not trying to compete with these mods; I just wanted a much simpler system for myself so that when I play I am hassled if I don’t take a break to eat and sleep every so often.

Share:

My first real Skyrim Special Edition mod is now released. I created a stripped down version of Bathing in Skyrim. I left out water detection to prevent conflicts with water mods. Once SKSE64 is released I will investigate recreating my water patcher to reintegrate the need to be standing in water.

Super Simple Bathing is released on Nexus and Bethesda.net for both PC and XB1. I don’t currently have an XB1 to test, so its kind of a risk. I guess I’ll learn a lesson from this pretty quickly, good or bad.

Next I plan to release a basic needs mods very similar to Super Simple Bathing called (creatively) Super Simple Needs that will handle hunger and tiredness. I have it complete and tested, but creating all these screenshots, titles, descriptions, etc. for the mod pages takes a lot of time.

Something I thought was strange was that if I want a mod to support multiple platforms I actually must upload the mod multiple times (once for each platform) and they are treated as totally unrelated mods. Even more strangely, there doesn’t seem to be a way for users to tell what platform a given mod supports at a glance; you have to actually navigate all the way into the mod page to find out what platform it’s for.

I see that some mod authors have started to help users out by prefixing mod names with the platform, like as [PS4] or [XB1]. Some have gone further and include a platform stripe as part of the box art image for the game tile.

I couldn’t find where people were getting these images from, so I made some myself. They are 65×260 which is 1/4 of the horizontal space used by the box art tile. Feel free to use them if you want. I also made some 65×65 icons.

It isn’t a huge deal, I just don’t really like it; so I wrote a program to cover up the strings in the compiled files. I call it AnonPex and you can find more information about it on this page: http://www.mzin.moe/?page_id=170

It doesn’t do anything fancy. No code is compiled/decompiled. It just reads the binary and changes the two strings. The string lengths are preserved, so the output should be identical to the compiled Papyrus except that all of the characters in the Windows account name and PC name fields will be question marks.

Share:

I’m super hyped about getting Skyrim Special Edition, so I wanted to make a post about it!

My ambition is to port Bathing in Skyrim 2, Poser Hotkeys, and some of my unreleased mods to the new Special Edition for everyone to use. If possible, I would love to make versions for consoles as well.

I’d like to release mods on both Skyrim Nexus and Bethesda.net.

Since it is likely that I’ll need to strip out some functionality to get these working on consoles, I will probably release two separate versions with two different feature sets.

Unfortunately, I have to wait until next week for the new Creation Kit. Today I started to look at my scripts to identify SKSE dependencies which need to be addressed. There are more than I thought there would be…

I expect to port some of my unreleased mods ahead of Bathing in Skyrim since they are much smaller in scope with less complex dependencies. This will also give me a chance to catch any new gotchas with the new system.

Here’s to another 1800 hours of Skyrim!

Share:

Over the winter holiday I ran into a problem that resulted in the creation of a new mod and a new tool for Skyrim. The mod is called Poser Hotkeys and the tool that generates the data for the mod is PoserDataGen.

Recently, I’ve been spending most of my time in Skyrim setting up cool scenes for screenshots. I have several poser mods installed and I was finding it tedious to find a cool pose, apply it to an actor, position the actors and then find a good camera angle. I use several tools for this, but none of them seemed to play together nicely.

I have heard of some tool that allows you to assign hotkeys to iterate through poses in the MCM. That sounded great but I could never find a reliable download source, so I just created my own mod for it. You can get my mod and the data tool for the mod on the Nexus. The source code repositories are also available here and here.

If you want to know how to use them in your game, check out the Read Me or Nexus description. The rest of this post is a breakdown of what these things do, how and why.

Adding animations to Skyrim is made possible through a tool called Fores New Idles in Skyrim, or FNIS for short. If you are interested, Fore has some technical documentation available on the FNIS Nexus page.

When an artist adds animations to Skyrim, they need to supply FNIS with a text file containing a list of the animation files along with a name for each animation or pose. These names provide a means to play the animation through SendAnimationEvent in Papyrus.

Poser Hotkeys is essentially a means to organize animation events and call SendAnimationEvent when a user presses a button. In order to send the correct animation event, Poser Hotkeys has to know the event name to send. This is where PoserDataGen comes in.

PoserDataGen is a .NET tool that scans your Skyrim animations folder for FNIS definitions. These definitions are then placed into data files that Poser Hotkeys can read at run time. Being data driven allows the mod to work with any poser combination that exists on a user’s setup without the need to recompile scripts or make changes in the CreationKit.

Originally, I threw the data into XML and used FISS to read it at run time. This worked reasonably well, but there were some problems. The first is that FISS seems to be unable to handle reading a string from an empty XML attribute. For example, reading from the element “name” below:

C++

1

2

<name></name>

<moreStuff>some stuff</moreStuff>

I would expect this to return an empty string, but instead FISS sends through the XML starting with the end of the “name” element. In this example, the string returned by FISS for element “name” would be:

C++

1

2

</name>

<moreStuff>some stuff</moreStuff>

This is a problem for me, since there are times I am expecting elements to be empty. A second problem I was having was that I couldn’t scan a folder for XML files. This meant that I had to either create a hard coded list of XML to look for (thus limiting the poser support) or cram all of the definitions into a single, known XML file.

I opted to cram everything into a single XML file, which then created other problems: I could only handle 128 poser packs since that is the array length limit of Papyrus, whenever a user installed or removed a poser the entire XML file had to be recreated with PoserDataGen from scratch (invalidating their favorites), and the file had to be loaded by the user in MCM before the mod could be aware of data.

Beyond all that, another problem was that I was introducing an additional dependency for the user.

Since I already require PapyrusUtil for functions related to NPC packages (to stop them in place while they play an animation) I took a look at the Json library that comes with it. It turns out that JsonUtil works very well, so I changed PoserDataGen to spit out .json data files that JsonUtil can read at run time. This lets me update and save parts of the loaded .json files on the fly during run time and save things, like the currently selected pose, directly in the pose’s data file. There is also a function to get an array of all .json files in a specific directory, which lets me scan for poser data files without having to know which ones to look for ahead of time.

How it works now is that PoserDataGen loads all of the FNIS animation lists and organizes the pose data by poser and by “poser pack.” I define a poser to be an FNIS list file and a “poser pack” to be animation definitions that share a similar prefix. For example, Halo’s Poser S comes with two FNIS files which results in two poser data files. Each FNIS file has several groups of animations starting with a similar prefix. For example, all poses that are part of Halo’s Poser Module 11 start with “H11P” resulting in a “poser pack” called H11P in the data file.

I allow a user to specify their Skyrim directory in the accompanying config file. If it’s not there, I try to find it in the registry. Failing that, I try a hard-coded default path that Steam uses when it installs the game. Here is the C# for it:

Once I find a valid animations folder, I save the Skyrim directory in the config so I don’t need to keep asking for it every time you open the app:

C#

1

2

3

4

// save valid directory

this.textBoxSkyrimDirectory.Text=skyrimDirectory;

Settings.Default.SkyrimDirectory=skyrimDirectory;

Settings.Default.Save();

A neat feature I added is the option to validate that animation files actually exist for each animation event before adding them to the data file. If I simply trust the FNIS file, Poser Hotkeys could send animation events to an actor that do not have a matching animation file, resulting in the actor simply doing nothing. Since the SendAnimationEvent function has no return value, Poser Hotkeys does not know if sending the event succeeded or failed. Users would be left without any information as to why they pressed a button to start a pose and nothing happened, which is obviously a bad experience for the user.

I added this because my copy of Pinup Poser includes many animation events for animation files that are absent, resulting in lots of data records that did nothing when executed. With this option turned on, PoserDataGen skips the missing animations, making them invisible to the user.

When parsing the FNIS files, I only worry about a single FNIS list file in each directory. I may change this to handle multiple files in the future, but I have never come across a poser that had more than one in a single folder, and I think FNIS enforces that only one list file can be in a given directory anyway.

I then go line by line to find the animation events. FNIS allows the author to define some options in between the animation event and the animation file path, so I need to check and skip the unneeded data if present. I need the animation file path to verify the file actually exists, assuming the user has selected the option:

All of this data is written out to .json in a structure matching what is expected by JsonUtil. The structure is unintuitive to me, though I have to assume it’s needed for the utility to function. Since Papyrus has no concept of objects, it is difficult to serialize related data in a meaningful way. JsonUtil seems to prefer to nest elements according their data type. For example, all strings are nested under an element called “string” and all integer lists under “intList.”

Something peculiar I found while using JsonUtil was that it refused to read data from keys that started with a capital letter. When JsonUtil creates data, it seems to always start with a lower case letter. Since I am not using JsonUtil to create the data files I didn’t know about this and I had a hard time discovering why I could not read from an element with the key “Name” while I could read and write other data to the file perfectly fine. Changing the key to “name” solved the problem.

As far as the Papyrus goes, the bulk of it is MCM magic to handle key assignments, drop down lists and user experience. Perhaps the most important parts are the functions that start and stop posing, so I’ll post them here.

The akTarget argument passed in is determined by looking at the player’s cross-hair reference. If there is an NPC in the cross-hair the NPC is the target, otherwise the player is the target.

For NPCs, I take an empty AI package I made called “PackageStop” and apply it with ActorUtil to freeze them in place. I also set “IsNPC” to false, which stops them from head-tracking the player

For both the player and NPCs, I set “bHumanoidFootIKDisable” to true, which turns off the inverse-kinematics used to position the legs/feet of actors on uneven terrain.

These settings result in a pose that should be as close to the artist’s intent as possible. You shouldn’t see posed NPCs engaging in combat or breaking their backs trying to face you while talking. They also should keep their feet flat on the ground, preventing weird leg positions that could result from the inverse-kinematics.

Clearing a pose from an actor is done essentially the same way, but in reverse: restoring the old AI package and turning on head tracking and inverse-kinematics:

Papyrus

1

2

3

4

5

6

7

8

9

10

11

12

FunctionPoseStop(ObjectReference akTarget)

IfakTarget==Player

PlayerIsPosing=False

Else

ActorUtil.RemovePackageOverride(akTarget asActor,PackageStop)

(akTarget asActor).EvaluatePackage()

akTarget.SetAnimationVariableInt("IsNPC",1); enable head tracking

EndIf

akTarget.SetAnimationVariableBool("bHumanoidFootIKDisable",False)

Debug.SendAnimationEvent(akTarget,"IdleForceDefaultState")

EndFunction

Sending the “IdleForceDefaultState” animation event at the end clears the current pose from the actor, returning them to their normal idle state.

The core functionality of this mod was spun up over a weekend, but polishing it to make it user friendly took nearly two weeks. I hope I made these tools intuitive and robust, but I’m sure users will quickly show me the holes when I release it this week.

Share:

For some background – something that has been a problem with many of the basic-needs mods for Skyrim is that the CreationKit does not expose a reliable way to detect if an Actor is standing in water.

Early on, someone discovered that there is something in the CreationKit that lets you mark the water as “dangerous water” along with a float that represents the amount of damage per second received while standing in it (which can be set to 0). This is helpful since Papyrus and the CreationKit have an exposed method named IsInDangerousWater that will detect an Actor in dangerous water even if they just dip their toe into it. This is how mods like Realistic Needs and Diseases detects water.

A problem comes up, though, if a mod makes additional edits to WaterTypes. Like all Forms, the changes made last will win any conflict. That means if you load a mod like Realistic Water Two (that makes changes to water) after Realistic Needs and Diseases, the “dangerous water” flag will be set to false and water detection breaks. If you load them in reverse order, water detection works but the water will look like vanilla water.

To fix this problem, people started making “patches” that are ESP files existing solely to set the “dangerous water” flag to true in a way that merges the change with the changes from the water mod. This is how Bathing in Skyrim detected water until 1.10.

This method is fine, but it requires mod authors to write patches for every DLC and water mod combination that users want to use. It’s not complicated but it is tedious. It also requires users to activate several ESPs in their load order for a single mod. Since people have recently been hitting the 255 ESP cap, this presents a problem.

A few months ago, two of the three biggest water mods decided to bundle their mods with other mods and change the ESP names. This made all of my patches worthless. I did not want to re-patch all the water mods/DLC again, so I looked for alternatives.

In a recent release of SKSE, there is a new exposed method of getting the height of the water level in a cell. This is how iNeed started detecting water recently. The idea is that if you know the water level of an area and test it against the player’s position you can tell if they are standing below the water level and therefore standing in water. Theoretically, this solves all the problems with patching and lets people use any water mod/DLC combinations they want.

I tried implementing this method of water detection with Bathing in Skyrim 1.05 but I ran into problems and switched back to patching. My main issue was that I could not reliably detect water in areas that had stepped water levels – for instance, the stairway up to Dragonsreach in Whiterun. The water level reported in the cells was the same even though the water was placed at different heights, breaking the detection in those areas. So the trade off is that I could do less work and support more water mods, but some areas would just be off-limits. I decided not to go this route since I believe it’s a worse overall experience for the user.

More recently I became interested in writing my own SKSE plugins. I was originally playing around with camera controls and thought I might try to find some automatic SKSE way of setting the water to “dangerous water.” I managed to do just that, allowing Bathing in Skyrim 1.10 to take advantage of the new method.

In mzinWaterUtil.dll I expose two Papyrus methods for water:

C++

1

2

BoolFunctionIsDangerousWater(Form WaterForm)GlobalNative

FunctionSetDangerousWater(Form WaterForm,BoolDangerous)GlobalNative

The first tells you if the “dangerous water” flag is checked or not on a given Form. The second will set the flag to true or false based on the Dangerous parameter.

I found that the unknown value “unk075” represents the “is dangerous” flag by dumping all of the data out of a WaterType and comparing a “patched” version vs a vanilla version. I found that unk075 changes from 0 (false) to 1 (true) when patched. unk075 is a UInt8 and I’m not sure if any other flags might get stored there (with bit-sets or whatever) so instead of just hard setting it to 0 or 1, I decided to use bit-wise operations with this bit-mask:

C++

1

staticconstUInt8 DangerousWaterFlagMask=0x01;

This might be total overkill, but it should produce the same results as water patching when checking the “dangerous water” box in maybe a safer way then setting the UInt8 directly as 0 or 1. I’m also checking that the passed Form is a WaterType before doing any operations since Papyrus has no exposed WaterType Form, making it unenforceable as a type in the Papyrus script itself.

So now there is a way to mark the dangerous water flag dynamically in Papyrus, but it needs to know the Form IDs to do it. So, I created a FormList in the CreationKit and placed all the vanilla Skyrim WaterType Forms inside which gets processed by a script at startup.

This is what the Papyrus code looks like to mark the water:

C++

1

2

3

4

5

6

7

8

9

IntIndex=WaterList.GetSize()

BoolDangerous=WaterRestrictionEnabled.GetValue()AsBool

WhileIndex

Index-=1

Form WaterForm=WaterList.GetAt(Index)

IfWaterForm!=None

mzinWaterUtil.SetDangerousWater(WaterForm,Dangerous)

EndIf

EndWhile

Pretty simple – it just iterates through the FormList and uses SKSE to set the flag.

For Dragonborn and Dawnguard I just wrote down the Form IDs to add them to the list dynamically. This happens just before processing the FormList:

C++

1

2

3

4

5

6

7

8

9

IfGame.GetModByName("Dragonborn.esm")!=255

AddWaterToList(Game.GetFormFromFile(0x0173B6,"Dragonborn.esm"))

AddWaterToList(Game.GetFormFromFile(0x01DFF1,"Dragonborn.esm"))

AddWaterToList(Game.GetFormFromFile(0x028644,"Dragonborn.esm"))

AddWaterToList(Game.GetFormFromFile(0x02ADEC,"Dragonborn.esm"))

AddWaterToList(Game.GetFormFromFile(0x03731A,"Dragonborn.esm"))

AddWaterToList(Game.GetFormFromFile(0x03805D,"Dragonborn.esm"))

Debug.Notification("Bathing in Skyrim - Dragonborn Support Added")

EndIf

Game.GetModByName() is awesome since it lets me know if someone has a mod loaded or not. If it returns 255 then the mod is not loaded and I won’t try to add the WaterTypes to the FormList. Since DLC and user-made mods are treated the same, I have a similar block for Falskaar and I can add new ones whenever new user-made mods add new WaterTypes. Mod authors could also write their own methods for this since it’s all in Papyrus.

The changes to the Forms do not stick through a save, so they must be reapplied every time a user loads the game. To do this, in the main Bathing in Skyrim Quest I added a ReferenceAlias for the Player and call this:

C++

1

2

3

EventOnPlayerLoadGame()

BatheQuest.UpdateDangerousWater()

EndEvent

Which calls the Quest to check for DLC and process the FormList of WaterTypes.

I’ve been trying to get this same behavior contained within the mzinWaterUtil DLL entirely so that once the game loads it will just automatically patch all the water without the need for Papyrus, but so far I’ve been unsuccessful. Hopefully it’s something I can add in the future so players can just drop the DLL in a folder and magically get patched water for Bathing in Skyrim, Realistic Needs and Diseases, etc without the need for a single water patch ESP regardless of water mods or DLC installed, but so far no luck.