Soul Reaver 2.">
Soul Reaver 2 Gex Engine Notes
For my research in creating version 4.0 of my ModelEx program, I've done a lot of investigation into Soul Reaver 2's file format and after seeing a how popular my SR1 trainer has become, I've been inspired to develop the Soul Reaver2 trainer to the same level of functionality. As a part of this, I've had to further my knowledge of the game's engine as well.
With the 10 year anniversary of TLW coming up, I thought it would be a great opportunity to contribute some of my findings. The following is a few brief notes and discoveries I've made about the structure of the Gex engine and its LOK related successors.
Soul Reaver's Messaging System
Objects in Soul Reaver are known as Instances. This can be anything from physical objects and animated characters to intangible things like event triggers and particle effects.
There are some actions that can be done by all types of Instance and some that can only be done by specific types, but they must all be requested by sending messages. Instances can also be in many different states, which must also be requested using messages.
A basic message can be sent using a function called INSTANCE_Post, which accepts parameters including the ID of the Instance (eg. Frank the Sluagh), the ID of the state/action (eg. Walk to position) and the data needed to perform the action or go into the state (eg. The position to go to). I haven't been able to verify this, but I suspect the first two bytes of the message ID specify which type of Instance the message is for. There could also be a specified range of IDs that each type of Instance
Actions or states that only apply to more specific types of Instance use a variation of INSTANCE_Post that's specific to that type. For example, you could use SoulReaverPost to send an imbue message to Soul Reaver and the parameter would be the ID for the element to imbue it with.
You can also send messages to multiple entities at once, using a function called INSTANCE_Broadcast. This would be used in Soul Reaver for example to send a damage message to all entities in range of a glyph spell. There's also an INSTANCE_BroadcastAll. I'm not sure what the difference is, but I'm guessing INSTANCE_Broadcast has a range, and INSTANCE_BroadcastAll effects everything.
Another function called INSTANCE_Query is used to find out information about an instance. This accepts a parameter with the same action/state IDs as INSTANCE_Post does, except instead of requesting that the Instance enters the state or performs the action, it returns data about it. The data is often the same data as was provided in INSTANCE_Post.