Hello everyone.
I've been wanting to create a universal map generation tool for quite some time now, one that would allow for convenient and balanced gameplay with friends. I've tried creating my own templates for both the standard RMG and IRMG, but each has significant advantages and disadvantages. For example, IRMG:
- First, I don't like the zone generation algorithm. The fact is that in 90% of cases, the connection between zones is made using a portal, which is very inconvenient. When many zones are open, it's easy to get lost and confused. And when you break through from one zone to another, you have to break through twice. It's especially problematic that the second breakthrough isn't visible, and you can only find out who is on the other side of the portal when there's no way back.
- Second, the resource generation. It's a small thing, but in my opinion, it would be more interesting and balanced if resources were generated in small groups that would be guarded. Currently, they are generated one by one and without any guards. In principle, adding a guard to each group isn't a problem, but that would be overkill, considering their total number on the map.
- Third, the artifact generation. Currently, the logic for the template is that the chance of generating each individual artifact for a specific zone is set manually. This can lead to an imbalance. For example, for the starting zone of the 1st and 2nd players, if you choose 25 minor artifacts with a generation probability of ~0.08, assuming that each player will get 3 minor artifacts, it is quite possible that player 1 will generate 5 of these artifacts, while player 2 will only generate 1. I should note that I was able to fix this flaw, although in a rather clumsy way.
Now, if you look at the map generation algorithm of the standard RMG, you can see that the 1st and 2nd disadvantages of IRMG are resolved here. The location of zones on the map is usually such that the use of portals is minimized, and resources are often located in guarded groups.
However, RMG also has its disadvantages, the main one of which, in my opinion, is that you cannot specify the generation of a specific object on the map in most cases. For the template, the sum of the values of objects that belong to a certain group is specified. For example, if you specify a 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 would like to be able to specify the generation of a specific object in a specific zone. For example, I need an artifact shop. But if I set ShopPoints to 15, I might get a hill fort and an elementary in the zone.
Of course, you could say that all these disadvantages are minor. The same resource groups can be replaced with treasure chests, for example. But I disagree. Not all treasure chests are equally well-protected. For example, breaking through an ent grove for wood and a gargoyle lair for stone – seemingly equal resources – is not the same task.
Therefore, I decided to try modifying the generators. Modifying IRMG is obviously more difficult because you need to change the generation algorithms themselves. It's easier to write my own generator, but I definitely don't have enough experience for that. It's better to take the easier path.
Thus, 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 data.pak\GameMechanics\RefTables.xdb file. For example, if you remove all buildings from the group:
→ RACE_HEAVEN → NewShopBuildings
except, for example, Trading_post, then in the human zone, nothing but a trading post will be generated.
It turns out that the list of possible generations for each zone is known; now, you need to find where RMG stores the list of all used groups. I searched in Data.pak and found that, apparently, the list is stored in types.xml. Specifically, starting from line 46505, the category begins
RMGPresetwhich, in particular, contains such subcategories as:
490d4cdf
NewShopBuildings
19
00000000
00000000
There are a total of 26 subcategories. Each has a unique Type and ChunkID. The other attributes are the same. Further down the file, there is also a category that also contains data for the subcategory in the following form:
<__ClassTypeID>270082827
<__ServerPtr>490d4cdf
TYPE_TYPE_ARRAY
5903800f
NewShopBuildings
5a065235
-1
00000000
00000000
In which, for each of the "objects", only ServerPtr differs, which is equal to Type in the previous category. All other values, such as ClasssTypeID, EnclosingNamespace, and Type, are the same for all. I tried to add a new category to both of these places, changing only the name. Obviously, you need to somehow assign a unique ServerPtr and Type as well, but I don't know how yet. So far, I tried adding it with a repeating one, and, as expected, the game stopped launching.
I started reading the forums here, in particular that thread where people discussed adding new spells. It turned out that in addition to changes in types.xml, you also need to make changes to the .exe file using a hex editor. I haven't dealt with this before, so I just started studying hex editors, but I decided that it might be more profitable to start a separate topic here as well.
In general, fellow modders, and everyone interested. If the task seems not too difficult and worth the effort, then I would not refuse help. In any case, I will continue to dig, but people with experience will definitely figure it out faster. Besides, maybe what I found is not what is needed. In the near future, I would like to create several separate categories for templates, in which to place a mentor, an artifact shop, etc. One object per template, as is now implemented for the prison and cartographer. In my opinion, this will add a significant degree of flexibility to the generated maps. Also, in the future, I would like to move artifacts into separate categories – minor/major/relic, and now they are in one sum with resources, where they don't belong.
I apologize in advance for the abundance of tautology and, perhaps, sometimes unclear wording; I tried as best I could. That's all. Thank you all for your attention.
), but I wasn't able to bind them to the functionality (as in the code in your second example).