Skyrim

Since there's few information out there on editing Skyrim's Havok Behavior files, I would like to keep a record of my discoveries and important information thus far. 
 

Getting Started

 

1. Tools to read the files. Many awesome modders have made programs that can help you to edit and read.
  • hkxcmd: necessary to convert .hkx files to .xml and visa-versa.
  • convert-xml-hkx-kf: A UI for hkxcmd, makes it easier.
  • Skyrim Behavior Organizer: Somehwat detailed, used to look at values and flags
  • CondenseBehavior: barebones, used to quickly reference or find a section of the behavior files, where a modifier is used, etc.
  • An .xml editor. I use "XML Copy Editor", some prefer "Notepad++".

2. How to get new behaviors into the CK. I do not want to alter the original behavior files because it's linked to NPC AI, especially for dragons. I had no idea how to add behaviors until at long last, a google search yielded the answer.
 
EASY WAY: Copy existing behavior files into a new actor folder
CONS: Must duplicate animations resulting in a larger mod; behavior files will conflict with vanilla files affecting NPCS too.
 
First, you have to make a new directory: data/meshes/actors/CUSTOMRACE
Then you extract animations and behaviors from an actor "Skyrim - Animations.bsa" and copy them into the CUSTOMRACE folder, and also extract the corresponding skeleton.nif from "- Meshes.bsa".

In the CK, you can change the paths to skeleton and behavior for a custom race for BOTH GENDERS. On the top of the window are options for changing male and female parameters. For the longest time this stumped me because I only changed the male behavior path and forgot the female one.
Finally, you make a new actor of your custom race and reload the .esp file. You can now go to Gameplay > Animations and fill in those animation events for your custom race.
 
 
BEST WAY: Custom-named, separate behavior files
CONS: No knowledge of how to implement completely: Actor actions not working, aka pressing movement buttons will not register to the game. Unfortunately, until movement is figured out, if choosing this path you must send animation events through scripts or an external plugin! There is a file that may be the final link, SpeedDataSIngleText.txt, but it is unreadable to the human eye...
Spoiler:  
Show

Example of my process using dragon behavior as the host files!
  •  
  • Renamed "dragonproject.hkx" to "PDdragonproject.hkx"
  • In "PDdragonproject.hkx," changed filepath 'Characters\DragonTEST.hkx' to  'Characters\PDDragonTEST.hkx'
  • Renamed "dragonTEST.hkx" to "PDdragonTEST.hkx"
  • In "PDdragonTEST.hkx," changed <hkparam name="name"> from 'DragonTEST' to 'PDDragonTEST" and <hkparam name="behaviorFilename"> from 'Behaviors\DragonBehavior.hkx' to 'Behaviors\PDDragonBehavior.hkx'
  • Renamed "dragonbehavior.hkx" to "PDdragonbehavior.hkx"
  • In "PDdragonbehavior.hkx," changed <class="hkbBehaviorGraph" name> from 'DragonBehavior.hkb' to 'PDDragonBehavior.hkb' (.hkb is the same thing as .hkx)
  • In animationdatasinglefile.txt, increased filecount from 429 to 430 and at the bottom of the path list, added 'PDDragonProject.txt' at the bottom of the list. This file contains all the behavior .txt files, so I deemed it necessary.
  • Added the PDdragonbehavior data to the bottom of the adsf file (I just copied dragonproject data and changed filenames to PD)
  • In animationsetdatasinglefile.txt, increased filecount from 49 to 50 and added 'PDDragonProjectData\PDDragonProject.txt' to the list of paths
  • Copied the dragon CRC data, then added it to bottom of asdsf file. (more info later on Pre-cache)
  • In meshes\animationsetdata, created folder 'PDdragonprojectdata'
  • Within the folder, copied 'dragonprojectdata' files and renamed 'dragonproject.txt' to 'PDdragonproject.txt'
  • In 'fullcharacter.txt,' made sure the contents were the same as the CRC data added to animationsetdatasinglefile.txt
  • In CK, linked both genders of the custom Race to PDDragonproject.hkx
  • Reload .esp and checked animation manager
  • Right clicked an existing filepath > "Add Sibling," and found 'PDdragonbehavior.hkx' in the 'Behaviors' folder.

Rationale: #7-8: animationdatasinglefile.txt stores all the behavior files used in game. Without linking your behavior here, the CK will spit out a "Cannot find behavior root" error.
 
#9-13: animationsetdatasinglefile.txt stores data for animation pre-cache, otherwise the game takes too long to read animation files and the character occasionally T-poses. Very unsightly. Each component of asdsf is separated into a text file found in animationsetdata directory, which contains a folder for each actor's behavior project and the associated text files. The information in both locations is exactly the same.
 
It's possible steps 12-14 are useless because the important file is animationsetdatasinglefile, but there's merit to separating the components so you can find the relevant data. asdsf is a HUGE file, after all.
 
Finally, names must be congruent! dragonproject.txt::dragonproject.hkx, etc. Bethesda uses project names for all the external stuff like the text files!
 


 
3. Pre-Cache
According to nexus user Fore, the game uses a precache to cope with the high stress loads of animation blending, etc. It reads from the animationsetdatasinglefile.txt found within the Meshes folder. As a note, if one mod alters the asdsf file, any other mods, including FNIS, are incompatible. Making a patch is easy but tedious: copy the info from one mod into another. Since FNIS makes the biggest changes to this file, any smaller mods should be copied into the FNIS generated asdsf.
 
Getting CRC32 value of your animation filepath:
Spoiler:  
Show

 

...
THe whole file consists of blocks that start with the number of entries it contains, followed by these entries. Now these entries can be just 1-liners (like this very first block), or of nested blocks. But with a little inspiration that can also be done.
 
Now you see the second block starts at line 51 (line 1 + 1 line with count ("49") + 49 * 1 line = 51). These 3 lines ("1"/"FullBody.txt"/"V3") are the typical start of a project ("ChickenProject").
 
Now looking into the dragon project it looks extremely simple compared to character. It starts at line 62838 with the 1/FullCharacter.txt/V3, followed by a few anim events together with the corresponding clipgenerator names. Then there starts the block of 192 animations. Interestingly the dragon only has 179 animations, but some of them seem to be doubles. Each file entry consists of 3 lines:
3692944883  'crc32 for meshes\actors\dragon\animations
3191128947  'e.g crc32 for ground_bite, the first dragon animation, lowercase, without ".hkx"
7891816  'crc for hkx
 
Now I would assume that it is completely sufficient to add dragon custom animations to pre-cache by simply adding triples with the same scheme at the end of the list. There are plenty of online crc converters. Just make sure they provide the same result when fed with the "meshes\actors\dragon\animations".
...

CRC calculator: http://www.zorc.breitbandkatze.de/crc.html
 
CRC Order: 32
CRC Poly: 4C11DB7
Initial value: 000000
Final value: 000000
 
Check "Direct," "reverse data bytes" and "reverse CRC result before final XOR"
 
In data sequence, you can put the string of the animation name and path. Use lowercase! The string "hkx" does not create the same checksum as the # found in animationsetdatasinglefile. Inputting "hkx" (without quotes) into the calculator returns 9E13D1FA (hex) = 2652099066 (dec). But the file lists 7891816 in the lines that are assumed to be "hkx." A curiosity indeed.

 
Nitty Gritties of the Behavior Graph

 
1. Hardcoded events. The major problem with playable dragons was that the flying animations caused CTDs unless the player was AI driven, but then it's kind of pointless. Takeoff and landing animations were impossible UNLESS you edit the behavior file. I tried changing a lot of animation modifiers and even replaced the walking animation with the flying animation to confirm it wasn't the actual animation causing problems. The animations were fine, but when I checked player.getisflying with console commands, turns out the engine thought I was flying even with a completely different behavior file. I thought, "What if I replaced all the names of the animation events related to flying?" Walaah, no more CTDs. My character was also considered "not flying."

While I haven't tested, I'm guessing the events "moveStart" "shoutStart" "sneakStart" "sprintEnd" etc. are universal to all actors and if added in the behavior file, the game, in addition to playing the animations, will recognize and execute the action. Otherwise, it just plays animations.

Some events include:
idleChairSitting: makes the actor sit (sitting state 3). Actor can sit in midair; if you call reset event without the appropriate exit event, the actor will be stuck on the same z position.
idleChairGetup: exits sitting state (sitting state 0)
FlightCruising/Hovering/Perching: Only applicable to dragons. Calls engine code that makes player CTD or the camera go wack. I renamed/removed these event calls entirely to make dragons playable.
2_KillActor: kills actor who shares this behavior graph. For example, the human to dragon killmoves, where the dragon dies, this event is called in the dragon behavior graph.
weaponSwing: right hand weapon swing
weaponLeftSwing: left hand weapon swing
hit: hit registers
 
etc...

2. Hardcoded variables.
Some variables are also hardcoded. You can add them in a behavior file and they'll work automatically. Examples:

AimPitchCurrent: used for NPC's to aim their spells and when the player aims their bow; can be applied to other combat states like shown in Zartar's Character Behaviors Enhanced. 
iState: For dragons. 0 = default/ground, 1 = flying, 2 = hovering, 3 = perching (can check with Behavior Organizer tool). Setting this variable directly affects the Movement Type of the actor. Thus, default, flying and hovering can be changed in the CK's Movement Types.
 
3. Definitions. Let's see, I'm not an expert but here's what I can gather.

Clip generator: links the animation files to the proper states and special effects.

Event: A cause. Events trigger certain states, like drawing out a weapon changes the state of the character to a combat stance.

Transition: Cause and effect. In a transition object, you can link events and states together. A "jump" event would bring the actor to a "jumping" state. There are still many flags whose effects are unknown.
  • wildcard transition: a state machine defines which event will cause transition FROM ANYWHERE in the graph to one of its states, or to a state in one of its children state machines. (credits to fore)

State: A condition that the actor is in, like sneaking state, combat state, walking, running, sprinting. You can have states within a state (nested state). Say there's a default state, the actor is simply standing around. Within that state, you can have a combat state, a running state, a jumping state, etc. Within the combat state, you can have 1h weapon state, 2h weapon state, spells. Within the jumping state, there's jumping forward, backwards, sideways, sprint-jumping. Pretty much every animation has its own state. 

Modifier: a special trait of this state. I believe it applies to all nested states too. (hkb = native to Havok Behavior. BS = Bethesda Softworks custom changes) Here are some examples of many:

hkbEvaluateExpressionModifier: Change variable values.
BSIsActiveModifier: I think it makes a boolean variable true as long as the graph is within this state.
hkbModifierGenerator: When you want to have more than one modifier, you use this which links to a list of modifiers.
hkbModifierList: Where you define at least one modifier.
hkbEventDrivenModifier: activates and/or deactivates another modifier with certain events.
hkbTwistModifier: alter rotation of bones on three axis, in the positive direction (1) or negative (-1).
BSTimerModifier: Sends an event after a specified amount of time. Useful for things like altering the falling animation after falling for a while, and/or to give a different landing animation after falling for x seconds.
BSLookAtModifier: Related to headtracking; probably needs a lot of tweaking to get it right for players, if at all.
BSDirectAtModifier: manipulate certain bones to follow the camera/LOS with variables AimPitchCurrent and AimHeadingCurrent (vanilla game does this for bows and NPC magic only)

4. Attack Data
I have limited info on this. It's questionable, but I believe it is possible to add new attacks to a race. Under the 'Attack Data' tab, there is a button "Update Events." Clicking it will update the window if new attack events are added to the behavior graph. "Display Event Data" is self explanatory, but it will show you if data is missing from an attack. The attack events are hardcoded, but there are many events. Theoretically you could add new attacks. For example, attackStart_Attack1 is a viable event, used for creature races but unused in NPCs.
 
Curiously, the dragon attack clips do not send the "hit, weaponswing, etc." events that clips in the humanoid graphs send. However, these events are defined in animationdatasinglefile.txt. The attack animations themselves do not contain any attack events, so it is safe to assume the game reads attack data through the behavior graph and/or adsf. I would not recommend editing adsf, so I assume behavior graph changes. But i have not actually implemented new attacks as there are more pressing issues.

Article information

Added on

Edited on

Written by

Ceruulean

3 comments

  1. BoayGamingYT
    BoayGamingYT
    • supporter
    • 17 kudos
    Failed...no one can crack this yet.
    However...my custom weapon is working...with its behavior files
    I'm still figure it out how to create custom races...still...no clues.
     
    Perhaps, linking custom behavior in nif files may work.
    This may require Custom race to work.

    I'll try that later.
  2. Ceruulean
    Ceruulean
    • member
    • 41 kudos
    I can finally get custom named behaviors to stop giving me "cannot find root" error in the CK...
    but there's still a problem:
    Spoiler:  
    Show

    nxfobwX.jpg
     
    What I've done to get this screenshot: (PD is my custom file moniker):
    • Renamed "dragonproject.hkx" to "PDdragonproject.hkx"
    • In "PDdragonproject.hkx," changed filepath 'Characters\DragonTEST.hkx' to  'Characters\PDDragonTEST.hkx'
    • Renamed "dragonTEST.hkx" to "PDdragonTEST.hkx"
    • In "PDdragonTEST.hkx," changed <hkparam name="name"> from 'DragonTEST' to 'PDDragonTEST" and <hkparam name="behaviorFilename"> from 'Behaviors\DragonBehavior.hkx' to 'Behaviors\PDDragonBehavior.hkx'
    • Renamed "dragonbehavior.hkx" to "PDdragonbehavior.hkx"
    • In "PDdragonbehavior.hkx," changed <class="hkbBehaviorGraph" name> from 'DragonBehavior.hkb' to 'PDDragonBehavior.hkb'
    • In animationdatasinglefile.txt, increased filecount from 429 to 430 and at the bottom of the path list, added 'PDDragonProject.txt' at the bottom of the list. This file contains all the behavior .txt files, so I deemed it necessary.
    • Added the PDdragonbehavior data to the bottom of the adsf file (I just copied dragonproject data and changed filenames to PD)
    • In animationsetdatasinglefile.txt, increased filecount from 49 to 50 and added 'PDDragonProjectData\PDDragonProject.txt' to the list of paths
    • Copied the dragon CRC data, then added it to bottom of asdsf file.
    • In meshes\animationsetdata, created folder 'PDdragonprojectdata'
    • Within the folder, copied 'dragonprojectdata' files and renamed 'dragonproject.txt' to 'PDdragonproject.txt'
    • In 'fullcharacter.txt,' made sure the contents were the same as the CRC data added to animationsetdatasinglefile.txt
    • In CK, linked both genders of the custom Race to PDDragonbehavior.hkx
    • Reload .esp and check animation manager
    I thought the problem is .hkb format, but in a google search, someone says it's the same as .hkx.  And in this thread (http://forums.nexusmods.com/index.php?/topic/624251-progress-in-behavior-filesalmost-done/), someone has properly named behavior filepaths in the manager, without the random 3. I've come so close, and yet so far. I swear, it must be possible to add custom-named behaviors!
     


     
    EDIT: Ok, it's possible to add a new behavior file! Right click on a filepath, choose "Insert Sibling," find the .hkx file in the Behaviors folder and now you can add Action children. However.... if it's a custom behavior file, ActorActions don't register. Funny though, I can send animevents via console. The actor also plays the idle animation, the default state. Then there's more to the puzzle... it may be related to SpeedDataSingleFile.txt. With all these developments, I have updated the first post.