|
Thread: Help with reverse engineering the game | |
|
bulya
Adventuring Hero
|
posted December 11, 2020 04:28 PM |
|
|
Help with reverse engineering the game
I already mentioned here that I work on a mod for H4 some time ago.
The purpose of the mod is mainly the PvP experience, by means of how balanced things are, making games more diverse, etc. Regarding balance, the equi team made it way more balanced then the vanilla version, but yet being inactive for 15 years there are still flaws with the balance they left us, which require a lot of map making to balance things out, which sometimes make the game even less diverse due to blocking certain artifacts or spells (which require blocking some spell books as well).
I already implemented some balance changes to the equi mod, which are tested in some PvP games at the moment. I'm also one of the testers, but fortunately we have more then 2 or 3 testers for that, so I have time to mod as well. Some changes are questionable but some are just necessary. And may be I will release an actual mod soon, which will allow keeping the equi mod, but also launching my mod so that you can pick which game you wold like to play.
My other direction is adding features which will make ease some of the stuff we have to mess around with when playing PvP. First goal for now is implementing a battle log. That requires reverse engineering, and I'm already doing that on my own. But I'm no expert at this, and learning most of it on the fly while doing so (having like half a day per week).
I already have an address of a procedure called on practically every combat action, and I can distinguish what kind of an action is it by the values in the registers and the values they point at. For example I can distinguish a move action from a defend action, and I think I found thew way to distinguish an attack action, and most importantly I can definitely point out morale actions. For the first step, a morale log which will point all the creatures and heroes that have morale on them for the ongoing combat round, will already be great. Here is the address of the procedure:
56B310
Near by by there is also a procedure that runs on each morale action (and seemingly nothing but morale actions), but I didn't manage to extract that much information based on the registry values I get there.
For the sake of this feature my following task is getting what the morale was triggered on (what creature / hero, belonging to what player). This is probably about finding the structure of the creature / heroes objects (probably inherit from the same class anyway), though I'm just starting with it and may be some people already have the answers that I work quite hard on finding (being lucky with some things, but wasting time on many others as well).
So if somebody already have this info it would be great if you can share it with me. Any clues I should fish for there can also be way more then helpful. And any help with actually reverse engineering the game, or reverse engineering tips are way more then welcome.
I'm doing that for a few weeks now, with not that much background in reverse engineering, which gives me hope I can dig it to a point I can implement at least partially the features we'd like to add to the game. So any help for a starter is welcome.
|
|
Baronus
Legendary Hero
|
posted December 11, 2020 05:10 PM |
|
|
Thats the best site.
Here you have best thread for modders:
null
But not only you must search subforum.
|
|
bulya
Adventuring Hero
|
posted December 11, 2020 06:00 PM |
|
|
Thank you.
I already checked this thread, which was sort of a starting point about a month ago. The addresses there did help, and even though for now I didn't include the changes to the creature abilities or spells which I could have from that thread, I didn't do so yet as those are very experimental changes when it comes to balance.
The changes that I did include in the version that is tested may seem minor to the PvE player, but are actually major to the PvP player. I do hope I can make Catapults (though I have less hope for those) viable as well as Gnashars (I have more hope for those) by changing or simply removing some of their abilities and playing with their stats. (something I already did with the Champions, for example)
The real challenge for now is the log, as I can play with the creature stats, as well as the artifacts and spells almost to any point I want. I'd like to change a few hardcoded mechanics, which equie did manage to put their hands on, but that is not my highest priority for now.
I do keep in mind the info in that thread there, as it might be helpful not just for modding but the log as well.
Thank you, as anything which can lead me to some info might be useful.
|
|
Phylante
Tavern Dweller
|
posted December 12, 2020 11:35 AM |
|
|
Note that offset are for version 2.2 of the game.
Yes, creatures and heroes do have a common inheritance hierarchy,
Here is the inheritance for both C++ classes, which shows flawlessly their common base classes.
**************************************************************
t_hero::RTTI_Base_Class_Array
009aa118 00 a1 9a RTTIBase
00 50 2d
9a 00 38
009aa118 00 a1 9a 00 RTTIBase t_hero::RTTI_Base_Clas [0] =
009aa11c 50 2d 9a 00 RTTIBase t_stack_with_backpack: [1] =
009aa120 38 2d 9a 00 RTTIBase t_creature_stack::RTTI [2] =
009aa124 90 b8 98 00 RTTIBase t_counted_object::RTTI [3] =
009aa128 20 2d 9a 00 RTTIBase t_abstract_creature::R [4] =
009aa12c 08 2d 9a 00 RTTIBase t_has_defense::RTTI_Ba [5] =
And creatures :
**************************************************************
t_creature::RTTI_Base_Class_Array
009a2c90 78 2c 9a RTTIBase
00 50 2d
9a 00 38
009a2c90 78 2c 9a 00 RTTIBase t_creature::RTTI_Base_ [0] =
009a2c94 50 2d 9a 00 RTTIBase t_stack_with_backpack: [1] =
009a2c98 38 2d 9a 00 RTTIBase t_creature_stack::RTTI [2] =
009a2c9c 90 b8 98 00 RTTIBase t_counted_object::RTTI [3] =
009a2ca0 20 2d 9a 00 RTTIBase t_abstract_creature::R [4] =
009a2ca4 08 2d 9a 00 RTTIBase t_has_defense::RTTI_Ba [5] =
I don't know for now which class holds morale information.
Regarding the log. I don't know what is your way of implementing the battle log, but there may already be one in the game.
Let me explain this (a decompiler is a must):
-Run the command 'strings' on the binary and grep for "ai_log.txt", for example `strings -t x heroes4.exe | grep "ai_log"` (standard linux commands, check what it does if on windows)
This will give you where this string lies in the binary.
-Check for references in the code to this string, you will find one single function.
004792f1 68 20 e0 a3 00 PUSH s_ai_log.txt_00a3e020 = "ai_log.txt"
004792f6 e8 fb 83 46 00 CALL FUN_008e16f6 FILE * FUN_008e16f6(LPCSTR param)
This function is responsible for opening the file before logging some actions.
-Check a little above this call, you'll notice a condition wether we should log or not.
004792db 3a c3 CMP AL,BL
004792dd 74 48 JZ LAB_00479327 > Jump Continue the game without opening the file / logging data.
Problem here is that the value coming into the check ALWAYS make us step over the logging, because IMHO, this is a release build, and the developers built it with something like `#define LOG_AI 0;`
What I did is just patch the test, for us to always step in the function, and log. I'm not really precise here, because I don't fully recall, and would take me some time which I haven't writing this answer, but feel free to ask for more information if needed.
It results in the creation of a log_ai.txt file in your heroes4 directory, containg stuff like
```
<blue>
< ( 46, 36, 0) - #0 (MPs: 2256)>
( 46, 35, 0) - V:376.17
( 45, 35, 0) - V:376.17
( 44, 36, 0) - V:400.00
( 51, 41, 0) - V:16875.00
( 52, 41, 0) - V:1530.72
( 42, 48, 0) - V:250.00
( 38, 47, 0) - V:0.00
( 37, 47, 0) - V:78.18
( 37, 48, 0) - V:78.18
Picked: (51,41,0) - MC:750 V:2454.10 DV:0.00 MDV:0.00
Path: [(51,41,0) MC:750 AMC:750 MR:1506 DV:0.00 MDV:0.00)] [(50,40,0) MC:600 AMC:600 MR:1656 DV:0.00 MDV:0.00)] [(49,39,0) MC:450 AMC:450 MR:1806 DV:1.00 MDV:0.00)] [(48,38,0) MC:300 AMC:300 MR:1956 DV:1.00 MDV:0.00)] [(47,37,0) MC:150 AMC:150 MR:2106 DV:0.00 MDV:0.00)]
Triming path: 4
MPs Remaining : 2106 DV: 0.00 (47,37,0) Sleeping: 0
< ( 47, 37, 0) - #1 (MPs: 2106)>
( 46, 35, 0) - V:376.17
( 45, 35, 0) - V:376.17
( 44, 36, 0) - V:400.00
( 51, 41, 0) - V:16875.00
( 52, 41, 0) - V:1530.72
( 42, 48, 0) - V:250.00
( 38, 47, 0) - V:0.00
( 37, 47, 0) - V:78.18
( 37, 48, 0) - V:78.18
```
which is ... the ai_log .
So now, to answer your question> I don't know.
But what you could do is check if there are other logging functions, and I may have activated it only in one place, and maybe it should log some things onto the battle. (did not tried IIRC).
You can for example grep for strings containing `%s` and `%i`, that are well known formaters passed to the printf family of functions, or streams in C++.
One subset of what you can find :
642d74 %i-%i
642d7f (%i)
643218 %i
6469a8 %s (%i)
64a078 resource_%i_text
64a08c resource_%i
64a258 row %i
64b380 ability_%i
64cefc %i_of_%i
64cf08 1_of_%i
64d90c target_shadow.%i
651e49 %i/%i %s
651e52 %i/%i %s
I am 90% sure that some of these strings are used in some logging functions, already built into the game, and that just have been deactivated for the release build.
Let me know if you can find some more.
|
|
bulya
Adventuring Hero
|
posted December 12, 2020 01:36 PM |
|
|
Thanks.
Yes, I do work with a debugger, and well familiar with linux, so your info is very helpful.
I already advanced a bit, and reverse engineering the stuff I can catch which creature got morale at the beginning of a combat turn. Though the structure of the objects are definitely important, as for now I only know where is the creature index (type of creature) and stack size. And nothing when it comes to heroes. So this info can help.
In case the game can prepare me a log by itself, then it becomes way easier, even if it means I will have to parse it and figure out what all means.
I will definitely check the way you suggested it as well. For now I'm just finding the procedures which are called when morale is triggered and finding the creature objects by the pointers those receive as their parameters. But I still have a long way this way, as I'm doing it for like a month (which is like 4-6 days, as I only have one day per week for that).
|
|
|
|