As I glance through the code, it seems mostly consistent that offsets will be relative to the descriptive name of the struct they are contained in, or what's in their name.
For example, the "LifeComponentOffsets" struct contains offsets that will be relative to the object start of any "Life" component object in the game. The offset will get added to any "Life" component object's base address, but to understand where the "Life" component objects come from, you need to understand the basic ECS (
Entity component system - Wikipedia) the game uses. In short, objects have components dedicated to specific groups of data, so the "Life" component contains information on hp/mp/es related stuff.
Check out "Entity.cs" and the component related functions there, as it's a vital part of accessing information in the game. There's many possible components, and objects only contain the components they need, so a chest in the game will have a "Chest" component, but a NPC won't.
In this case, "IngameStateOffsets" contain offsets to "IngameState", which is part of another important game system, and that's the client's state system. There's main states such as PreGameState, LoginState, InGameState, SelectCharacterState, etc.. that contain various state specific information.
To find offsets, you calculate the difference of the address from the start of the InGameState object itself. In ExileAPI, you'd want to open up "GameStateContoller.cs" and check the state related stuff in the constructor to understand how it's finding the state system stuff. So the math, assuming your address actually lies in the InGameState, is simply
Code:
YourOffset = YourNewFoundAddress - InGameState.Address;
Then you can go and update IngameStateOffsets::UIHover in the struct and test to verify everything works or not. A hint is, if your found address is less than the start of InGameState.Address, or the resulting offset is too far away from other offsets in IngameStateOffsets (as in > 0x2000 atm), you can be sure you've got the wrong address.