Good day to everyone.
In general, I've been wanting for quite a while now to make a universal tool for generating maps that would be convenient and balanced to play with friends. I tried creating my own templates, both for the standard RMG and for IRMG, but each of them has significant pros as well as cons. For example, IRMG:
- First of all, I don't like the zone generation algorithm. The thing is, in 90% of cases zones are connected via portals, which is very inconvenient. When many zones are open, it's easy to get lost and confused in them. And when you're breaking through from one zone to another — you have to break through twice. What's especially problematic is that the second breakthrough isn't visible, and you can only find out who's on the other side of the portal when there's no way back anymore.
- Secondly — resource generation. A minor thing, but in my opinion it would be more interesting and balanced if resources were generated in small guarded groups. Right now they generate one by one without guards. In principle, adding guards to each pile isn't a problem, but that would be overkill given their total number on the map.
- Thirdly — artifact generation. Currently the template logic is such that the chance of generating each individual artifact for a specific zone is set manually. This can lead to imbalance. For example, for the starting zone of players 1 and 2, if you pick 25 minor artifacts with a ~0.08 generation probability, expecting each player to get 3 minor artifacts — a situation may easily arise where player 1 gets 5 of these artifacts generated while player 2 gets only 1. I should note that I did manage to fix this flaw, albeit in a rather hacky way.
Now, if we look at the standard RMG map generation algorithm, we can see that flaws 1 and 2 of IRMG are solved here. Zone placement on the map is generally such that portal usage is minimized, and resources are often located in guarded piles.
Nevertheless, RMG also has its drawbacks, the main one being that you cannot specify the generation of a specific object on the map in most cases. The template specifies the sum of costs of objects belonging to a certain group. For example, if you set the total ShopPoints = 30 in the template, any combination of buildings from the NewShopBuildings list can be generated from it.
For example, Black Market + Hill Fort + Trading Post. However, I'd like to be able to specify the exact generation of a specific object in a specific zone. For instance, I need an Artifact Merchant. But if I set ShopPoints to 15, I might well end up with a Hill Fort and an Elemental Conflux in the zone instead.
Of course, one could say all these flaws are insignificant. Those resource piles could be replaced with treasure chests, for example. But here I disagree. Not all treasure chests are equally protected. For example, breaking through a grove of ents for wood versus a gargoyle storage for stone — seemingly equal resources — is not an equal task at all.
That's why I decided to try modifying the generators. Modifying IRMG is obviously harder because you need to change the generation algorithms themselves. At that point it's easier to write your own generator — and I definitely don't have enough experience for that. Better to get away with minimal effort.
So, I started digging into how the standard generator works. I found that for each specific zone, the buildings that can be generated in it are defined in the file data.pak\GameMechanics\RefTables.xdb. For example, if from the group:
→ RACE_HEAVEN → NewShopBuildings
you remove all buildings except, say, Trading_post, then nothing else will generate in the human zone for shop points besides the trading post. So it turns out we know where the list of possible generations for each zone is defined; now we need to find where RMG stores the list of all used groups. I searched around Data.pak and found that apparently the list is stored in types.xml. Specifically, starting from line 46505 begins the category
<TypeName>RMGPreset</TypeName>Which, among others, contains subcategories such as:
<Item>
<Type>490d4cdf</Type>
<Name>NewShopBuildings</Name>
<ChunkID>19</ChunkID>
<Description/>
<Constraints/>
<Attributes/>
<DefaultValue>
<Type>00000000</Type>
</DefaultValue>
<ComplexDefaultValue>
<Type>00000000</Type>
</ComplexDefaultValue>
</Item>A total of 26 subcategories. Each has a unique Type and ChunkID. The remaining attributes are identical. Further down the file there's also a category that contains those same subcategories in the following form:
<Item>
<__ClassTypeID>270082827</__ClassTypeID>
<__ServerPtr>490d4cdf</__ServerPtr>
<Type>TYPE_TYPE_ARRAY</Type>
<EnclosingNamespace>5903800f</EnclosingNamespace>
<BoundTo>NewShopBuildings</BoundTo>
<Field>
<Type>5a065235</Type>
<Name/>
<ChunkID>-1</ChunkID>
<Description/>
<Constraints/>
<Attributes/>
<DefaultValue>
<Type>00000000</Type>
</DefaultValue>
<ComplexDefaultValue>
<Type>00000000</Type>
</ComplexDefaultValue>
</Field>
</Item>Where for each of the "objects" only ServerPtr differs, which equals the Type from the previous category. All other values, such as ClasssTypeID, EnclosingNamespace, and Type, are the same for all. I tried adding a new category in both of these places, changing only the name. Obviously, I need to somehow assign a unique ServerPtr and Type as well, but I don't yet know how. For now I tried adding one with duplicate values — and, predictably, Heroes stopped launching.
I started reading forums here, particularly that thread where people discussed adding new spells — it turned out that besides changes to types.xml, you also need to make changes to the .exe via a hex editor. I hadn't dealt with that before; I just sat down to study hex editors, but decided it might be more profitable to also start a separate topic here.
Anyway, fellow modders, and everyone interested. If the task seems simple and worth attention — I wouldn't refuse help. Either way, I'll keep digging, but experienced people will surely figure it out faster. Besides, maybe what I found isn't what's needed at all. In the foreseeable future, I'd like to create several separate categories for templates, moving mentor, artifact merchant, etc. into them. One object per template, like prison and cartographer are already implemented. In my opinion, this alone would add a significant degree of flexibility to generated maps. Also in the future, I'd like to move artifacts into separate categories — minor/major/relic — since right now they share a single sum with resources, where they don't belong.
Apologies in advance for the abundance of tautology and possibly unclear explanations in places; I tried my best. That's how it goes. Thanks everyone for your attention.
), but I wasn't able to bind them to the functionality (as in the code in your second example).