Heroes of Might and Magic II Mod

The old Heroes games developed by New World Computing. Please specify which game you are referring to in your post.
User avatar
GreatEmerald
CH Staff
CH Staff
Posts: 3330
Joined: 24 Jul 2009
Location: Netherlands

Unread postby GreatEmerald » 06 Aug 2010, 21:35

Darmani wrote:I would very much like to ultimately be able to add new units and factions and the like. I'm not that optimistic, however.
Yea, I'm pretty sure they're hardcoded.

User avatar
Darmani
Blood Fury
Blood Fury
Posts: 479
Joined: 06 Jan 2006
Location: Cambridge, MA

Unread postby Darmani » 06 Aug 2010, 22:26

It's all just bytes, man.

Hardcoded isn't a problem. Unit stats are hardcoded, but we can modify them quite easily.

Adding stuff is harder. Say the information for spell costs and descriptions starts at address 0x10000. Say the information for units starts at address 0x9000. Now say we add another unit to the units table. Now the spell table gets pushed back a hundred bytes or so -- and every single piece of code which thinks the spell table starts at 0x10000 will break, and the game will crash when you walk into a town with a mage guild.

This is certainly possible to fix with the right tools. It's just a lot harder.

Also, there's probably a lot of code that looks like this:

Code: Select all

for(int i = 0; i < NUMBER_OF_UNITS; i++)
{
  ....do stuff....
}
The compiler will see "NUMBER_OF_UNITS" and replace it with a constant (65, I believe). So now we also have to go around and find all the instances of the constant "65" with the meaning "NUMBER_OF_UNITS" and replace it with "66." Of course, we have to be careful not to accidentally change other bytes that just coincidentally have the same value (like, IIRC, the Crusader's HP value).

And that's just the tip of the iceberg...


By the way, did I mention that the machine language generated by C compilers is among the easiest to reverse-engineer? We are lucky in that regard.

Modifying a couple bytes modifies a couple bytes. Adding a couple bytes moves every single byte after that. Modifying stuff is easier.

User avatar
UndeadHalfOrc
Titan
Titan
Posts: 1363
Joined: 13 Mar 2007

Unread postby UndeadHalfOrc » 07 Aug 2010, 00:05

Thanks for the recommendation, Darmani. Is this what your friend is talking about?
http://www.hex-rays.com/idapro/

I'm gonna give it a try eventually. If it's as good as it advertises itself, it should be a breeze to change the power of fireball, cold ray and fireblast (from 10, 10, 10, to 13, 13, 15 respectively)

blueskirt
Leprechaun
Leprechaun
Posts: 16
Joined: 02 Aug 2010

Unread postby blueskirt » 07 Aug 2010, 01:30

Nigh herculean task or not, it's good to hear I'm not the only one who'd like to see that old game get another add-on.

User avatar
GreatEmerald
CH Staff
CH Staff
Posts: 3330
Joined: 24 Jul 2009
Location: Netherlands

Unread postby GreatEmerald » 07 Aug 2010, 07:06

Darmani wrote:Also, there's probably a lot of code that looks like this:


The compiler will see "NUMBER_OF_UNITS" and replace it with a constant (65, I believe). So now we also have to go around and find all the instances of the constant "65" with the meaning "NUMBER_OF_UNITS" and replace it with "66." Of course, we have to be careful not to accidentally change other bytes that just coincidentally have the same value (like, IIRC, the Crusader's HP value).
Indeed, but if they are lazy, they won't even use NUMBER_OF_UNITS and just copy-paste 65, which doesn't help any.

dudejo
Leprechaun
Leprechaun
Posts: 45
Joined: 18 Jul 2010

Unread postby dudejo » 07 Aug 2010, 13:03

i had a quick look at the IDA program and it looks like it could help get it done.

among other things, it can execute the game in parallel.

edit : i just thought of something. what are the chances that the game loads the starting secondary skills...from the game map?

i'm wondering because it's one of the few starting attributes we can modify from the editor.

User avatar
UndeadHalfOrc
Titan
Titan
Posts: 1363
Joined: 13 Mar 2007

Unread postby UndeadHalfOrc » 07 Aug 2010, 15:11

Just checked the website again. Those sharks are charging a FORTUNE for their software. I'd try to find a pirated copy but I've never been a downloader and no nothing about any pirate sites.

I'll try the trial version shortly but I doubt it can get the job done.

User avatar
Darmani
Blood Fury
Blood Fury
Posts: 479
Joined: 06 Jan 2006
Location: Cambridge, MA

Unread postby Darmani » 07 Aug 2010, 16:11

If we both fail with free software, I may be willing to purchase it.

But.....woah, they also have a C decompiler! Last time I Googled for one (two and a half years ago, while reading this very thread), I just got a bunch of people saying it's impossible. And there's also a (severely limited) open-source one too, http://boomerang.sourceforge.net/index.php .

blueskirt
Leprechaun
Leprechaun
Posts: 16
Joined: 02 Aug 2010

Unread postby blueskirt » 07 Aug 2010, 19:01

I got one more wish for your mod: Changes the difficulty options.

When I play HoMM, I want the AI to be as smart as it can be, but I still want the fight to be fair: all player and AIs should start with the same amount of resources, about the same strength and AI should not be a cheating bastard.

If you manage to modify that game any way you want to, you should make the AI level independent of the difficulty level, like in HoMM1 where you could play with genius AIs on easy difficulty, or dumb AIs on impossible difficulty.

User avatar
UndeadHalfOrc
Titan
Titan
Posts: 1363
Joined: 13 Mar 2007

Unread postby UndeadHalfOrc » 07 Aug 2010, 20:23

Darmani, hold off buying it for now - one of my friends (a complete pirate if I've ever known one) found it and sent it to me. Hopefully it's the version we need.

I haven't tried it yet, it's 89 mbs. file name is "idapro55.exe".
I can transfer it to you by skype or windows messenger.

User avatar
Darmani
Blood Fury
Blood Fury
Posts: 479
Joined: 06 Jan 2006
Location: Cambridge, MA

Unread postby Darmani » 08 Aug 2010, 08:35

It's too early to think about anything more complicated than changing a number.

I return to St. Louis (and regain access to Windows) in 9 days. We'll talk then, UHH.

dudejo
Leprechaun
Leprechaun
Posts: 45
Joined: 18 Jul 2010

Unread postby dudejo » 08 Aug 2010, 16:05

that "trial" version is actually a full-feature freeware. it's just based on version 4.x instead of the current 5.x

i played with it some but i have the feeling there's a lot more to the program than i found so far.

User avatar
Darmani
Blood Fury
Blood Fury
Posts: 479
Joined: 06 Jan 2006
Location: Cambridge, MA

Unread postby Darmani » 18 Aug 2010, 22:27

Let the fun begin.

Image

(This is only a partial success. IDA is not is good about letting me modify the file as it is about letting me analyze it.)

User avatar
UndeadHalfOrc
Titan
Titan
Posts: 1363
Joined: 13 Mar 2007

Unread postby UndeadHalfOrc » 18 Aug 2010, 22:29

Awesomeness!

But is it good at giving you the offset to change in the EXE? You can then use any hex editor for the job.

BTW, Lightning bolt is fine as it is. Fireball, Cold Ring and Fireblast are the ones that need changing :D

User avatar
Darmani
Blood Fury
Blood Fury
Posts: 479
Joined: 06 Jan 2006
Location: Cambridge, MA

Unread postby Darmani » 18 Aug 2010, 22:45

(Get on MSN so we can talk in more detail.)

After compilation, it's not so easy. That's why I failed in my original plan to change it to 1337.

I found that the compiled lightning bolt code, after putting the spell power into the eax register, does this:

Code: Select all

lea eax, [eax+4*eax]
lea eax, [eax+4*eax]
The "load effective address" command used here is mainly used to compute the address of array elements, but it's faster than the multiplication operator, so optimizing compilers use it for multiplication by special values (like 5). I can only change the "4" in "4*eax" to 1,2, 4, or 8. Those two lines are 6 bytes, so, while I can write some assembly and insert the bytes into that spot, if I need more than 6 bytes, I'm going to have to change the entire file. IDA might be able to do that easily since it already analyzes all the memory references, but I haven't figured out how. Since I knew off the top of my head that the byte for the "do nothing" operation is the same as the ASCII for the "Z" character, I just overwrote those 6 bytes with ZZZZZZ, effectively making lightning bolt do 1*spellpower damage.

I now see why the WoG guys run H3 inside a special environment.

User avatar
UndeadHalfOrc
Titan
Titan
Posts: 1363
Joined: 13 Mar 2007

Unread postby UndeadHalfOrc » 18 Aug 2010, 23:31

Darmani wrote: so optimizing compilers use it for multiplication by special values (like 5).
That will make it a bitch then, since ALL damage spells in Heroes 2 currently use a multiple of 5 as damage multiplier...
Darmani wrote:I now see why the WoG guys run H3 inside a special environment.
Which environment it is? They didn't use IDA pro?

Darmani, I'm leaving my appartment for a week tomorrow morning so I won't be able to provide any IDA input but I probably will as soon as I get back. In the meantime I will most likely browse these forums and check out my PMs using my mom's computer, but nothing beyond that.

EDIT: I'll try to be on MSN this evening

dudejo
Leprechaun
Leprechaun
Posts: 45
Joined: 18 Jul 2010

Unread postby dudejo » 20 Aug 2010, 23:08

multiples of 5...

would it be too strong for the multiplier to be *15 instead of *13 like you originally wanted?

i guess it could be combined with a MP cost increase.

User avatar
UndeadHalfOrc
Titan
Titan
Posts: 1363
Joined: 13 Mar 2007

Unread postby UndeadHalfOrc » 21 Aug 2010, 19:40

I guess 15 would be better than nothing if 13 meant having to write additional assembly code at the end of the file...

spell points are already very easily modified

User avatar
Darmani
Blood Fury
Blood Fury
Posts: 479
Joined: 06 Jan 2006
Location: Cambridge, MA

Unread postby Darmani » 22 Aug 2010, 06:56

There are basically three ways I see of modding code:

One is to do make a function call for every insertion you want to make a call can be made to an arbitrary location in five bytes, so this is definitely doable. You'd have to also write scripts though to make sure all headers get updated appropriately. This would be fairly cumbersome and wouldn't scale -- it would be hard to do anything more complicated than changing some multipliers around. It would also involve violating many of the principles of function calls, meaning you'd likely have to do all work in assembly.

The second is to do what doom3D described on page 4: Run the EXE inside an emulator, and add hooks to perform special behavior at certain addresses. This is probably more maintainable than option one, and allows writing modifications in languages other than assembly, but is still of limited use.

IDA can output an assembly file based on the executable. It does a pretty good job of "unlinking" the code -- that is, it sees a constant like "0x05DF12", notices that this is the memory address of the string "Sawmill", and then creates a name for that location (like "aSawmill"), and replaces the hard-coded memory-address with "offset aSawmill". This enables you to insert code into the file, thereby changing the memory address, and have it be updated approriately upon reassembling.

Using this would be somewhat-ideal approach, as we'd be able to slowly replace functions written in assembly with functions written in C, and eventually decompile enough pieces to make major changes.

The big question is whether IDA does a good enough job with the unlinking to allow you to insert code, reassemble, and have it still work. I don't know, because of a smaller problem: IDA outputs the assembly in its own format, and some nontrivial editing is necessary to get in a form recognizable by an assembler. And its output is closest to that accepted by Borland's Turbo Assembler, which, of the four most commonly used assemblers, is the only one which isn't free.

I worked a little yesterday on trying to get that to work, and will hopefully work some more tomorrow. Unfortunately, tomorrow is the last day before classes start, after which my free time will quite likely drop to near-zero (71 units, eek!).

User avatar
Soronarr
Pixie
Pixie
Posts: 117
Joined: 25 Aug 2010
Location: Croatia

Unread postby Soronarr » 27 Aug 2010, 08:29

If there's anything I'd change in HOMM2...I'd probably invert Paladin/Crusader to Crusader/Paladin and make em stronger and less numerous. They are the weakest tier 6 unit.

Apart from that..I'd really have to think about it.


Return to “Heroes I-IV”

Who is online

Users browsing this forum: No registered users and 5 guests