Heroes of Might and Magic Community
visiting hero! Register | Today's Posts | Games | Search! | FAQ/Rules | AvatarList | MemberList | Profile


Age of Heroes Headlines:  
5 Oct 2016: Heroes VII development comes to an end.. - read more
6 Aug 2016: Troubled Heroes VII Expansion Release - read more
26 Apr 2016: Heroes VII XPack - Trial by Fire - Coming out in June! - read more
17 Apr 2016: Global Alternative Creatures MOD for H7 after 1.8 Patch! - read more
7 Mar 2016: Romero launches a Piano Sonata Album Kickstarter! - read more
19 Feb 2016: Heroes 5.5 RC6, Heroes VII patch 1.7 are out! - read more
13 Jan 2016: Horn of the Abyss 1.4 Available for Download! - read more
17 Dec 2015: Heroes 5.5 update, 1.6 out for H7 - read more
23 Nov 2015: H7 1.4 & 1.5 patches Released - read more
31 Oct 2015: First H7 patches are out, End of DoC development - read more
5 Oct 2016: Heroes VII development comes to an end.. - read more
[X] Remove Ads
LOGIN:     Username:     Password:         [ Register ]
HOMM1: info forum | HOMM2: info forum | HOMM3: info mods forum | HOMM4: info CTG forum | HOMM5: info mods forum | MMH6: wiki forum | MMH7: wiki forum
Heroes Community > Heroes 3.5 - WoG and Beyond > Thread: Heroes 3 Hacking Reference Guide (started by BTB in February 2020)
Heroes 3 Hacking Reference Guide This thread is 43 pages long: 1 2 3 4 5 ... 10 20 30 ... 39 40 41 42 43 · «PREV
BigPig
BigPig

Tavern Dweller
posted March 02, 2026 09:31 PM

Hi! Thank you for the suggestions.

It has not escaped me that you, @AlexSpl are a prominent proponent of plugins as a tool of modding and I am not opposed to using them in principle. But, as I get the impression might also be the case with some others around here, the main joy of modding for me is not the results but learning to achieve them. I am exploring different methods step by step and for now I am looking to see how far txt and hex editing can get me. An added motivation here for me is the fact that I see these two methods used in modding of some other games I play and will likely look to adjust next.

Seeing as you appear to be very knowledgeable about plugins, maybe you would like to write up a short intro guide and post it here on the forum. A general description of the process along with a very basic example or two of a simple plugin written from scratch? You frequently link to sources in russian and that is likely an added access barrier for at least some aspiring/modders, I know it is for me. A "H3 plugins 101" guide in english (maybe you know of an existing one somewhere?) could be very helpful.

Another thing is, I have seen some comments about plugins and HD mod compatibility, what's the situation there exactly?

 View Profile
Phoenix4ever
Phoenix4ever


Legendary Hero
Heroes is love, Heroes is life
posted March 02, 2026 11:35 PM
Edited by Phoenix4ever at 23:38, 02 Mar 2026.

Hi BigPig

Do you play HotA or just regular old H3 Complete? Cause plug-ins does'nt work with HotA. That is why I sadly can't use plug-ins, but you can, if you only play H3 complete.
HotA does fix some of your issues though, along with adding 3 new factions, new artifacts, skills, map objects, bug fixes and more...
I think HotA is awesome, but sadly a bit closed and hard to mod.

By the way, shout out to Alex and BTB, who both have been extremely helpful and kind to a complete noob modder like me.
I am able to do a lot of things now though, but mostly hexediting and txt editing.

 View Profile
BigPig
BigPig

Tavern Dweller
posted March 03, 2026 12:04 AM

I play the gog complete edition (SoD) with HD mod and pretty much exclusively single player. My main aim is to tone down the OP stuff and buff the useless stuff to the point it doesnt feel like a punishment by means of adjusting values and very minor changes.

 View Profile
AlexSpl
AlexSpl


Responsible
Supreme Hero
posted March 03, 2026 12:13 AM
Edited by AlexSpl at 00:25, 03 Mar 2026.

Quote:
A "H3 plugins 101" guide in english (maybe you know of an existing one somewhere?) could be very helpful.


A quick step-by-step guide for beginner modders

C++ Plugins

0. Install Microsoft Visual Studio. The free version of Microsoft Visual Studio 2008 Express Edition is available here: https://go.microsoft.com/fwlink/?LinkId=104679 (895 MB). During installation, select Microsoft Visual C++ 2008 Express Edition.

1. Download the patcher_x86.hpp header file (you'll need to copy it to the folder with dllmain.cpp, see below):

patcher_x86.zip
(11.6 KiB) Downloaded 1781 times

2. Create a new project: File -> New -> Project... (Ctrl + Shift + N), select the Visual C++/Win32/Win32 Project template, give it a meaningful name, remember the full path to your project, and click OK.
3. The Win32 Application Wizard will open. Click "Next >".
4. Select the application type: "DLL Library" and click "Finish".
5. The "Solution Explorer" window will appear on the left side of the screen. Double-click dllmain.cpp and change the code to the following:

// Uncomment the line below if you have Microsoft Visual Studio 2017 or later
// #include "pch.h"

// Uncomment the line below if you have an older version of Microsoft Visual Studio
// #include "stdafx.h"

// The following line is needed for the sprintf() function
// You can delete it if you don't use it in your plugin
#include <stdio.h>

// Specify the relative path to the patcher library here
#include "patcher_x86.hpp"

Patcher* _P;
PatcherInstance* _PI;

int __stdcall TestLoHook(LoHook* h, HookContext* c)
{
   char TextBuffer[256];

   DWORD GameMgr = *(DWORD*)0x699538;
   short Day = *(short*)(GameMgr + 0x1F63E);
   short Week = *(short*)(GameMgr + 0x1F640);
   short Month = *(short*)(GameMgr + 0x1F642);

   sprintf(TextBuffer, "Hello, World!\n\nDays passed: %d", Day + 7 * Week + 28 * Month - 36);
   CALL_12(void, __fastcall, 0x4F6C00, TextBuffer, 1, -1, -1, -1, 0, -1, 0, -1, 0, -1, 0);

   return EXEC_DEFAULT;
}

BOOL APIENTRY DllMain(HMODULE hModule, DWORD ul_reason_for_call, LPVOID lpReserved)
{
   static bool plugin_On = false;

   if (DLL_PROCESS_ATTACH == ul_reason_for_call)
   {
       if (!plugin_On)
       {
           plugin_On = true;
           P = GetPatcher();
           _PI = _P->CreateInstance((char*)"HD.Plugin.TestPlugin");
           _PI->WriteLoHook(0x4C80F4, TestLoHook);
       }
}

return TRUE;
}


6. Save the solution (Ctrl + S).
7. Select the "Release" solution configuration (simply select "Release" from the list at the top of the window next to the "Start Debugging (F5)" icon or press Alt + F7. In the left part of the window, select "Configuration Properties," click the "Configuration Manager..." button, and select "Active Solution Configuration: Release" at the top. Close and OK). Now press F7 (Build -> Build Solution).

8. Go to the project folder, open the folder with your project name -> Release, and copy the dll from there directly to the _HD3_\Data\Packs\{Your Plugin Name} folder.
9. Launch HD Launcher, add the plugin (Plugins window, click the "Add" button), and click "Play."

A. Congratulations! You've just created your first plugin for the HD mod.

P.S. Now all you have to do is figure out what changes the plugin makes and how to make them yourself, and you'll be a fully-fledged modder.

Delphi Plugins

0. Download PatchAPI:

PatchApi.zip
(10.11 KiB) Downloaded 1370 times

1. Create a DLL (File -> New -> Other..., Dynamic-link Library) with the following code (the code is provided as an example):

library MyFirstDelphiPlugin;

uses System.SysUtils, Windows, PatchApi;

var _P: TPatcher;
   _PI: TPatcherInstance;

function TestHook(h: TLoHook; c: PHookContext): Integer; stdcall;
var TextBuffer: string[200];
   GameMgr: PDWORD;
   Day, Week, Month: Word;
begin
 GameMgr := Ptr($699538);
 Day := Word(Ptr(GameMgr^ + $1F63E)^);
 Week := Word(Ptr(GameMgr^ + $1F640)^);
 Month := Word(Ptr(GameMgr^ + $1F642)^);

 TextBuffer := ShortString('Hello, World!'#13#10'Days passed: ' +
   IntToStr(Day + 7 * Week + 28 * Month - 36));

 Call(FASTCALL_, $4F6C00, [TextBuffer, 1, -1, -1, -1, 0, -1, 0, -1, 0, -1, 0]);
 Result := EXEC_DEFAULT;
end;

procedure DLLMain(Reason: Integer);
begin
 if DLL_PROCESS_ATTACH = Reason then
 begin
   _P := GetPatcher;
   _PI := _P.CreateInstance('HD.Plugin.DelphiTest');
   _PI.WriteLoHook($4C80F4, @TestHook);
 end;
end;

begin
 DLLProc := @DLLMain;
 DLLMain(DLL_PROCESS_ATTACH);
end.


* * *
As you build your first plugin, you will feel the thing works, and will have something to start from. Looking into the code of existing plugins will teach you more than you can imagine now, provided you are not grinning now like a pro But yes, it will give you motivation to continue and eventually you will write something bigger than the New Spells plugin

 View Profile
BigPig
BigPig

Tavern Dweller
posted March 03, 2026 12:30 AM

This looks.. non-trivial.. but doable at some point in the future!

 View Profile
AlexSpl
AlexSpl


Responsible
Supreme Hero
posted March 03, 2026 01:18 AM
Edited by AlexSpl at 01:28, 03 Mar 2026.

Why modding the original game does still stay actual thing? I checked the VCMI project and was in awe what miracles folks did. With VCMI you can do whatever you want, but I name two problems why it is not so popular. First, for the team capable of recreating the original game from scratch it's a shame not to reverse and to document original AI algorithms. I want to be sure that I play the same game against the same AI. Second, lack of the original content which feels proper and feels at the same level as the original content does. HotA team does just it. They modify the existing core and they add new awesome content, and it lightning fast earns credability.

 View Profile
BigPig
BigPig

Tavern Dweller
posted March 03, 2026 02:42 PM
Edited by BigPig at 15:29, 03 Mar 2026.

AlexSpl said:
Why modding the original game does still stay actual thing?

Well, for me it is because thats the game I am used to and have been playing all these years. Hota takes enough liberty with changing game mechanics to feel like a different game to me, it does look fun though and I understand the appeal. Other mods.. I honestly never even heard about until the past few months.

So what I set out to do is basically take the game I know and have this nostalgia for and fix the obvious problems (useless and OP skills, necromancy, fireball etc) and balance it to the point where I dont feel compelled to always hire the same 3 heroes whenever I see them in the tavern, to check the spells in lvl 3 mage guild when i build it, to not just go straight for vampire lords every time I play necro etc. I like the game "as it is", I just want to play it in more ways without the feeling of gross suboptimality.

That said, now that I have started actually doing it I am becoming a little bit more flexible to the idea of minor qualitative/mechanics changes, I still dont want more content but I am looking at ways to make the game feel even more like what I want it to be. And I am having a ton of fun figuring it out!
AlexSpl said:
Quote:
4. Change priorities for AI skill selection (including Wisdom/School skills).

This can be achieved by 'playing' with AI SSkills weighting functions. Full calculations - step by step - described in FizMiG.

I googled fizmig and the only english version I could find was more descriptive than technical and didnt help me much.. Do you know where these functions might be found? I remember seeing some discussion about this in one of the two threads but I dont think it lead to any conclusions I could use here..


 View Profile
AlexSpl
AlexSpl


Responsible
Supreme Hero
posted March 03, 2026 02:48 PM
Edited by AlexSpl at 14:49, 03 Mar 2026.

Just a few plugins you probably haven't tried -

FairCancelSpells

"Dispel and Cure spells only remove the last spell/effect cast. If the last spell/effect cannot be removed (for example, the last effect is Poison for Dispel or a buff for Cure), the closest spell/effect that can be removed is removed."

It may look simple, but good luck to do the same in hex.

ForgetSecSkill

"Secondary skills can be deleted directly from the hero window. Left-clicking on a skill and pressing the Cancel button will cancel that skill or skill tier."

Works like a legal cheat for those who think that unlearning a skill is an option. I must agree, the price you pay is a whole level-up usually, so why not?

NewFirstAidTent

"Significantly improves the First Aid Tent. Without the "First Aid" secondary skill, the tent restores 50 health to a random friendly unit. At the Basic level of the "First Aid" secondary skill, the tent heals all friendly units, restoring 100 health each; at the Advanced level, it heals all friendly units and combat vehicles except itself, restoring 200 health; at the Expert level, it restores 300 health to all friendly units and combat vehicles. Additionally, the tent's stats have been adjusted: it now costs 1500 gold, has 10 defense, and 300 health."

Tested by online players. They say it's fun.

XXL mod (SOD)

Play huge random maps like in HotA.

 View Profile
BigPig
BigPig

Tavern Dweller
posted March 03, 2026 03:26 PM
Edited by BigPig at 15:33, 03 Mar 2026.

AlexSpl said:
Just a few plugins you probably haven't tried -
A safe bet seeing as I havent tried any at all.
Quote:
"Dispel and Cure spells
I am actually ok with the way cure and dispel work for the time being.
Quote:
"Secondary skills can be deleted
Not something I am looking for.
Quote:
"Significantly improves the First Aid Tent.
I actually just upped my First Aid skill to restore up to 100/200/300 hp and doubled the tent's hp and honestly it doesnt feel useless anymore and the specialists heal lvl 7 creatures quite consistently into the late game.
Quote:
XXL mod (SOD)
Now This. This I will definitely want to replicate at some point in the future!

But plugins aside (as I mentioned, I will have a look at learning how to make them in a bit) I feel like at least some of the questions on my list must be relatively simple hex edits?
BigPig said:
2. Remove or modify the special rule for Wisdom and School of magic skills on level up (offered every 3 lvls for magic, every 6 for might heroes).

3. a) Fix the Necromancy bug that makes AI only raise 1 skeleton per battle.
b) Also the arrow tower archery bug if it is still active  
d) ALSO, the arrow tower targetting bug.

4. Change priorities for AI skill selection (including Wisdom/School skills).

5. Edit diplomacy unit join formula bonus values.

7. Allow AI to cast land mine and quicksand, as I understand fire wall and force field are unlikely to be cast in any sensible way?

10. Change the values of the hero number caps in difficulty settings.
These all feel like they should be a matter of finding the right bit of code and just changing a value or two..?

 View Profile
phoenix4ever
phoenix4ever


Legendary Hero
Heroes is love, Heroes is life
posted March 03, 2026 03:35 PM

AlexSpl said:

ForgetSecSkill

"Secondary skills can be deleted directly from the hero window. Left-clicking on a skill and pressing the Cancel button will cancel that skill or skill tier."

Works like a legal cheat for those who think that unlearning a skill is an option. I must agree, the price you pay is a whole level-up usually, so why not?


Damn, I wish that worked with HotA.

 View Profile
AlexSpl
AlexSpl


Responsible
Supreme Hero
posted March 03, 2026 03:44 PM
Edited by AlexSpl at 16:06, 03 Mar 2026.

Quote:
These all feel like they should be a matter of finding the right bit of code and just changing a value or two..?

Right. And you can do it right now within an hour or two with some expertise. I'd wish I could be helpful, but I wrote a whole collection of plugins already, so writing them further doesn't feel rewarding. But again, the above problems can be solved by a beginner.

As for other plugins, sometimes you spent an hour or two, and people call your plugin great, and sometimes you spent a week or two, and nobody uses it, so I left writing for a while I already wrote my biggest plugin, and it was unique at the time (I know about predecessors, but they all failed to add new spells in a way I added, I mean - for everyone who learn C++). I, myself, too, play Heroes So, for me it's a waste of time to write plugins for people, which could be spent on the game itself. If you make something with your hands you probably get a reward. So, you write plugins, create mods, etc. only for yourself, until it feels fun. I think my position is clear, yet I have a call to share my humble knowledge

Quote:
4. Change priorities for AI skill selection (including Wisdom/School skills).

5. Edit diplomacy unit join formula bonus values.

Google these hard, but even AI won't help you. The 4th problem was lit by me and I know exactly how AI makes its choices. Diplomacy? I think I was amongst the first pioneers who discovered how it works. OK, there was Xarfax, but he wasn't so precise as I was. Check my program for Heroes 1-3, there is a thing I called Adventure Oracle, and it tells 100% if the group joins. So altering the original mechanics for someone who know how it works is not a problem.

 View Profile
AlexSpl
AlexSpl


Responsible
Supreme Hero
posted March 03, 2026 04:32 PM

This is how Diplomacy works -

void __thiscall advManager:oWanderingMonsterResult(
       advManager *this,
       NewmapCell *cell,
       hero *current_hero,
       type_point point,
       bool32 human_player)
{
   TCreatureType objectIndex; // ecx
   signed int setup; // eax
   int v8; // ebx
   int v9; // esi
   char *v10; // eax
   const char *v11; // eax
   hero *v12; // edi
   TCreatureType like_modifier; // eax
   __int64 v14; // rax
   int *p_current_hero; // ecx
   int v16; // ecx
   int v17; // eax
   type_point v18; // ebx
   NewmapCell *v19; // esi
   int v20; // [esp+Ch] [ebp-Ch] BYREF
   TCreatureType creature; // [esp+10h] [ebp-8h]
   advManager *v22; // [esp+14h] [ebp-4h]

   objectIndex = cell->objectIndex;
   setup = cell->setup;
   v22 = this;
   creature = objectIndex;
   v8 = setup & 0xFFF;
   v9 = setup << 15 >> 27;
   if ( setup < 0 )
   {
       v10 = (char *)this->map->CustomMonsterList.first + 48 * (unsigned __int8)((unsigned int)setup >> 19);
       if ( (_BYTE)human_player )
       {
           if ( *((_DWORD *)v10 + 2) )
           {
               v11 = (const char *)*((_DWORD *)v10 + 1);
               if ( !v11 )
                   v11 = kEmptyString;
               NormalDialog(v11, 1, -1, -1, -1, 0, -1, 0, -1, 0, -1, 0);
           }
       }
   }
   v12 = current_hero;
   *(float *)&current_hero = COERCE_FLOAT(AI_approximate_strength(current_hero));
   *(float *)&v20 = (float)(int)current_hero;
   *(float *)&current_hero = (float)(v8 * akCreatureTypeTraits[creature].AI_value);
   *(float *)&current_hero = *(float *)&v20 / *(float *)&current_hero;
   like_modifier = advManager::get_like_modifier(v12, creature);
   LOWORD(v8) = v12->SSLevel[4];
   creature = like_modifier;
   if ( *(float *)&current_hero < 7.0 )
   {
       if ( *(float *)&current_hero < 1.0 )
       {
           if ( *(float *)&current_hero <= 0.5 )
           {
               LOWORD(v14) = -2;
               if ( *(float *)&current_hero <= 0.333 )
                   LOWORD(v14) = -3;
           }
           else
           {
               LOWORD(v14) = -1;
           }
       }
       else
       {
           v14 = (__int64)(*(float *)&current_hero + *(float *)&current_hero - 2.0);
       }
   }
   else
   {
       LOWORD(v14) = 11;
   }
   if ( !gpGame->sSetup.difficulty && (_BYTE)human_player )
   {
       current_hero = (hero *)3;
       v20 = (__int16)v8 + 1;
       p_current_hero = (int *)&current_hero;
       if ( v20 <= 3 )
           p_current_hero = &v20;
       v8 = *p_current_hero;
   }
   v16 = (__int16)v8;
   v17 = (__int16)v8 + (__int16)creature + (__int16)v14;
   if ( v9 > v17 )
   {
       advManager::monsters_fight(v22, v12, cell, point, human_player);
       return;
   }
   v18 = point;
   LOBYTE(current_hero) = v9 == v17;
   if ( v9 <= (__int16)creature + v16 + 1 )
   {
       v19 = cell;
       if ( advManager::monsters_join(v22, v12, cell, point, (bool)current_hero, human_player) )
       {
           if ( !VictoryConditionStruct::CheckForDefeatedMonsterWin(&gpGame->sMapHeader.victory_condition, v12, v18) )
               return;
           goto LABEL_25;
       }
       goto LABEL_31;
   }
   if ( v9 > (__int16)creature + 2 * v16 + 1
     || !advManager::monsters_sell_out(v22, v12, cell, point, (bool)current_hero, human_player) )
   {
       v19 = cell;
LABEL_31:
       if ( (_BYTE)current_hero || (v19->setup & 0x20000) != 0 )
           advManager::monsters_fight(v22, v12, v19, v18, human_player);
       else
           advManager::monsters_flee(v22, v12, v19, v18, human_player);
       return;
   }
   if ( VictoryConditionStruct::CheckForDefeatedMonsterWin(&gpGame->sMapHeader.victory_condition, v12, v18) )
LABEL_25:
       CheckEndGame(0);
}


It's 4A73B0, so HiHook it and have a control over it.

 View Profile
BigPig
BigPig

Tavern Dweller
posted March 03, 2026 05:30 PM
Edited by BigPig at 17:37, 03 Mar 2026.

AlexSpl said:
This is how Diplomacy works -
LOWORD(v8) = v12->SSLevel[4];
So the diplomacy bonus in the formula is literally the level of the skill? And v16 is the value i am looking to tone down. But..
Quote:
if ( v9 <= (__int16)creature + v16 + 1 )
(...)
if ( v9 > (__int16)creature + 2 * v16 + 1

How come these two tests have opposite signs?
Quote:
It's 4A73B0, so HiHook it and have a control over it.
As soon as i figure out what that means!

Edit:

OR, I could just get rid of the doubling of the bonus in the second test, in which case the test to join for gold becomes just a reroll of the first test? This could be nerf enough maybe? AND it does sound like a hex edit, doesnt it?

 View Profile
Jump To: « Prev Thread . . . Next Thread » This thread is 43 pages long: 1 2 3 4 5 ... 10 20 30 ... 39 40 41 42 43 · «PREV
Post New Poll   Post New Topic   Post New Reply

Page compiled in 0.1140 seconds