How to fix NPC models causing crashes
Original post on the Nexus Mods Forums.
If an NPC model works normally, but crashes when loading a play area, or in a cutscene, the problem always seems to be the body model. As far as I can tell, the game seems to use the body model for basic bone structure and important bone references.
WHY IT CRASHES
The game is looking for a bone to assign something, but that bone doesn't exist. So it crashes.
For example, if the game is looking for where to place the slinger parts, and that bone map byte is FF, then that model will crash the game when it tries to load the slinger part onto it. I imagine the NPC outfit causing cutscene crash is likely because there's a bone map reference for a cutscene camera that's missing from some NPC models. I've still yet to confirm this.
Anyway, if we can figure out which byte of the bonemap it's looking for slinger/camera/etc, we should be able to prevent crashing by redirecting to a bone that does exist.
Note that it's time consuming to compare bone maps between models, because the bone numbers for each model are different.
BONE DATA AND THE BONE MAP
Bone data always starts at 00000140 and ends just before the material names. There's a byte that says how long the bone section is, but it's pretty obvious just by looking at the data in hexadecimal.
Each bone index entry is 24 bytes. First byte seems to be the number of the entry, but not the same number as the bone name. Second byte is always 00. This helps in identifying the start of each bone index entry. The third byte is the parent bone. If you can't figure out the bone you want to edit, you should be able to narrow it down by what its parent bone is. I have no idea what the rest of the bytes are for.
After all of the bone index entries is the bone position data, in float. Each bone's float data is 64 bytes. Note that these positions/rotations seem to be relevant to the parent.
After that, is the bone map. This is where you need to fix the crashing. The bone map can start at the beginning or middle of a line. The bone map always looks like it has lots of FF bytes. It usually starts with bytes 00, 02, 03, 04 (corresponding to those bone names). The total size of the bone map can vary between models, but each byte of the bone map refers to a function of the game's animation, in the same order for every bone map.
Each byte refers to a bone by number. For example, FF is bone 255. You can use CrazyT's importer to see which bone is which number, in Blender.
What I like to do is copy paste the bone map into a fresh file, so that it's in order and easy to compare with other bone maps.
HOW TO FIX THE CRASHING
The bytes you need to fix are, from the start of the bone map, the 102nd to 106th bytes. It should be the 6th to 10th bytes on the 6th line. These bytes are the slinger "tray" bone, slinger pod bone, and the two bow portions (front, then back). I think that's the order.
If you compare bonemaps with other models, you'll notice crashing models have these bytes as value FF, but player models refer to the slinger bone names. You can set these values to the elbow bone, or wrist bone, and it'll fix the crashing. But it won't shoot from the slinger properly.
Example: In the NPCBS020 model file, at 000055F4 you can see the byte is 87, surrounded by FF bytes. 000055F5 is actually the slinger position. 000055F6 is the slinger firing position.
I figured this out by trial and error, by going through each 16 bytes of the bonemap to see which 16 bytes caused the game to crash. Replace each 16 bytes with a low number, like 01 or something. Parts of the model will distort, but low values shouldn't crash (because those bones should exist).
Once I figured out exactly what those bytes are for, I imported NPCBS020 body model into Blender, looked for the arm, elbow, wrist bone numbers. Then I changed 000055F5 and 000055F6 to those bones.
If you ever need to figure out other animation functions, you can use this trial and error method, and Blender bone look up method.
HOW TO "ADD" SLINGER BONES
It's currently not possible to add new bones, because it'll change offsets throughout the entire file. But it's possible to take existing bones and modify them into slinger bones. This is especially applicable in the case of some NPC outfits that have extra bones for parts you've probably removed, like the Handler's book and bookstrap.
Here are the steps to doing this: 1. You need to figure out where the bone index data for the bones you want to modify are. The most reliable way I've found is to search by parent. As I said earlier, the third byte of each bone index entry is always the parent.
If you're modifying a chain of bones, chances are they're in order, and you can see them referring to each other as parents, one after another. This should make it easy to identify those bones.
2. Load up a player model and find the slinger bone index data in it, using the same method. The 1st, 3rd and 4th slinger bones are parented to the elbow bone. The 2nd slinger bone is parented to the 1st slinger bone. This should help you narrow it down. Copy the data of these 4 bones to a new file (should be 24 bytes x4) for easier reference.
3. Back to your "modified" bones, you'll need to edit the parents to match how slinger bone hierarchy is set up. Find the elbow bone name of the model you're editing. For example, if it's 19, you need to convert that to Hexadecimal, which will become 13. You then need to change the 3rd byte of the 1st, 3rd and 4th of these bones' index data to this elbow bone (eg. 13). The 2nd bone needs to be changed to the 1st bone.
4. Using the data of the player model, copy paste the 4th to 24th byte data for each bone, over the modified bones. I don't know what this data does, but I did this and it worked. I don't know if it's important or not. Make sure the first 3 bytes are kept intact (as you just edited the parent).
5. Open up two instances of Blender. In one, have the modified model. In the other, have a player body model. If you modified the bone parents correctly, you should see some new bones connected to the elbow where they were not before.
6. What you need to do now, is open up the transforms window (hit N in Blender) and copy paste the start and end transform XYZ values from the player body model, to the modified slinger bones. If you do it right, the modified slinger bones should change position to look like the player model version. You may need to make some slight height adjustments, depending on the model.
If you did this correctly, you should now have a proper animated slinger.
If the slinger parts are all over the place, that means the bone positions are mangled, and you need to reposition them in Blender. Copy pasting the position/rotation from another model isn't guaranteed to work (it didn't for me).
If the game still crashes, that means you didn't edit the correct bone map bytes.
If parts of the body start stretching, it means you probably typed in the wrong bone numbers for the slinger bone map bytes.
If you find the physics of the model start acting weird, that's because CrazyT's importer/exporter recalculates bone orientation stuff and seems to sometimes cause issues with physics. You will need to recopy the bone position/rotation from the original model.