Skip to content

Using Havok reflection data and public information

Léo Lam edited this page Jan 7, 2022 · 2 revisions

Havok is a large middleware suite that provides a physics engine and other useful utilities such as pathfinding and cloth simulation for video games.

BotW uses Havok Physics, Havok AI (for pathfinding -- called NavMesh in the KingSystem codebase) and Havok Cloth. (There is evidence [1] that Nintendo planned to use Havok Script at one point, but BotW ultimately went with Nintendo's in-house EventFlow engine, possibly because of Havok Script being discontinued.)

Reverse engineering code that interacts with Havok is a non-trivial task because of the massive amount of Havok code and classes and the complete absence of symbols. Fortunately, Havok comes with built-in reflection data and there are publicly/freely available headers for an older version of Havok (2014) that we can cross reference to figure out what we are looking at.

Reflection data

Havok packfiles are serialised and deserialised using reflection data that contains information about class hierarchies and layouts for any Havok object that might end up being written to disk.

This means that reflection data can be used to translate class offsets into member names, to figure out enum values, etc. The type information is often incomplete because the reflection class model does not allow for multiple inheritance and non-serialised pointers often lack detailed type information but this is still a good starting point.

Switch 1.5.0: https://raw.githubusercontent.com/leoetlino/botw-re-notes/master/tools/havok_reflection_info.json

Once you know what class or member you are looking at, you can cross reference the freely available headers to fill in the missing type information and context.

Type registry

Havok class constructors and/or their vtables are sometimes referenced from a giant list of built-in Havok types (called the type registry). This can be useful for figuring out class names.

Implementing stubs

Havok is out of the scope of this decompilation project, but obviously BotW code that uses inlined Havok utilities and interacts with Havok functions still needs to be decompiled.

Referencing the headers is permitted, but you should not copy entire files or chunks of code (non-trivial implementation code -- porting class/method/enum/... declarations is okay) from the headers when implementing stubs. To repeat:

DO NOT COPY ENTIRE FILES FROM THE PUBLIC HEADERS EVEN THOUGH THEY ARE FREELY AND PUBLICLY AVAILABLE.

Only declare/define what is actually needed for BotW.


[1] See the "hks" (Havok script?) and "lua" resource factories.