Well, I expected circular dependencies to be checked inside CModHandler::resolveDependencies because there it’s both fast and simple. When for ( mods in input ) resolves no mods, then we have a cycle. But you don’t have to do it this way.
The important thing is that CModHandler::hasCircularDependency seems to have no recursion termination conditions. Making it a proper DFS won’t hurt.
I think some stuff could be improved in factions.json + I found out recently about some “workarounds” to have HOtA creatures and/or heroes without a town.
I think that a more elegant solution should be in-place. Here a draft!!! of what I am thinking of: (.json file contents osted below should be self explanatory). Some notes though: “town” is a mod, heroes is a mod (heroclasses + heroes), creatures is a mod, dwellings is a mod. <faction/castle> is also a mod that needs to be present any time you use any of the above mods.
And then rename faction in cove-town to “cove-creatures:cove”. In this case there is no need for those “workarounds”
This will look even better with minimods idea. In this case cove faction can be present in new base mod named “cove” while all 3 current mods are considered to be submods/minimods.
I still like my approach better :). Factions should have info about creatures, not the other way around.
Technically both ideas are the same, you just seem to want a factions file in every mod (creatures/heroes/dwelings/town) while I want a “main mod” that has ~ the same contents.
So in my approach you have a mod for factions (like above) and in that mod you specify what that faction consists of.
In most cases mod formats directly represent our internal structures.
So in this case creatures have “faction” field while factions don’t have any connections to creatures. In fact there is no way to get what creatures belong to faction without iterating over all creatures checking “faction” field.
Your proposition has downsides:
there is no easy way to remove or add creature to/from faction.
undefined behavior if creature is present in multiple factions (not supported by engine and unlikely to change). Same problem with keeping both current and your system.
more code to write. Current solution is just 1:1 mapping to our data structures.
? You go to faction.json and you remove that creature’s name. But here a more common scenario. Lets say you want to replace monk with sharpshooter. In my proposal you need to go to above factions.json, replace “monk” with “sharpshooter” and “monastery” with “wherever sharpshooters live”. That’s it! 2 strings replaced in 1! file and you replaced a unit in your faction. (Ok maybe you want to take a look at ingham too).
that is current behavior too so it does not count :).
Here is more about saving some time now, or loosing more time later.
Pharantesis: We and others are talking about stuff that would bring the whole modding system to its knees (EG: duplicate creatures to different factions). While the modding structure should be as flexible as possible, it should be built/improved with realistic use-cases in mind. So I think the discussion should go towards how to best model the modding system for real user needs and not towards how to make the most flexible modding system ever :).
But what about doing this by another mod? This means that you need to replace entire “creatures” field, possibly making conflicts with other mods.
It won’t be possible to have 2 mods that add creatures to same faction running at once.
These two properties (“creature recruitable in town” and “creature belongs to town”) are completely separate. Creature may belong to town but won’t be recruitable (a lot of examples in H4) or vice versa.
How? Currently you can specify “faction” only once in creature config. Duplicating entries in json will be detected on startup and removed.
You may replace this by another mod but this would give you dependency on this mod. Meaning correct load order where field will be always replaced by new mod.
Creature can’t belong to multiple factions. Engine just does not supports this.
Why you would need this? You may recruit “foreign” creatures in towns, you may give them to heroes. It only controls creature background and some bits of mechanics like “Units from X factions” morale bonus.
And what’s most important - system must be easy to understand.
“Zen of Python” describes this quite well: python.org/dev/peps/pep-0020/
Especially these two:
There should be one-- and preferably only one --obvious way to do it.
Now is better than never. Although never is often better than right now.
I have not found (and have to recognize neither searched too hard) any interface modding discussions. Is there anythings laid out already. Does anyone have a rough idea how it will look like?
I was thinking of something simpler as first step. For example, lets take kingdom overview window. It has a size, position, and some graphic resources positioned relative to that. Only with this info there will be no spectacular mods, but at least it is a start. (H2 look and feel would be possible for example, or battle log coming from top of the screen and initiative bar below, or some initiative bar border decoration).
The problem with such approach is that it will create tons of glue code to connect interface configuration with UI - every string you introduce in json must be manually connected with appropriate UI element. See current implementation of main menu.
Point #1 should remove need for most of trivial code we have in GUI right now.
Another issue is part of UI which was written long time ago - here you proposition won’t work anyway until point #3 is fixed. Example - map selection/load game set of dialogs.
If somebody (from VCMI team or not) will fix these issues UI modding will become a viable option but until then - it’s better leave everything as it.
Something like Coherent UI ( coherent-labs.com/ ) for GUI modding would be perfect. $99 would be affordable but I cannot find if they allow open source titles.
Tow dragon, not sure if replacing UI at this point is a good idea - current one is almost fully functional and I’m not sure if we can find something suitable for H3 UI (“everything is an image” is not a popular UI concept).
Interesting that all SDL-based games I know use custom UI instead of some library.
I think that the only “low level” change our UI needs is more generic event handling - currently only several classes like button have something like this.
Creating set of function pointers (aka Qt slots) in CIntObject should fix this and will remove need of custom classes just for different popup message.
@Ivan
Actually I thought about using Coherent UI on top of current UI, with possible gradual replacement. Making a home-made UI solution moddable will be a great pain. That solution is based on HTML 5 and (AFAIK) should be compatible with just-a-lot-of-images approach.
Current UI is more or less complete if you only compare it to OH3 (without WoG). It still lacks a lot of things modders could want, e.g. layouts, general drag and drop, proper window system, scriptable event handling and more GUI primitives to begin with. And it’s being rewritten to OpenGL anyway.
There is actually no good way out of this situation: maintaining old solution will gradually add complexity (and complex bugs) to it or leave modders with unfulfilled wishes. Employing an existing GUI library is a lot of work with no visible outcome. Either way we lose.
Not sure if Coherent UI can be used in open-source projects - GPL limits commercial usage quite a lot. Including Coherent source code into VCMI means that it should use license similar to GPL. So anyone can just take our version of Coherent instead of buying one.
Maybe something like this: sourceforge.net/projects/gigi/
Used by freeorion. And at least from player point of view it looks quite good.
How will partial changes to a file get handled? Maybe it was discussed before (maybe even by me ) but i forgot it/cannot find it.
EG: I make a mod that does minor modifications to HotA mod. HotA mod is under heavy development. If I just edit my changes in a copy of HotA files and “override” them with my mod I will have to do that every single time.
It will help if partial overrides would be supported eventually.
EG: Whole original creature file from HotA is “merged” with my file (that has nothing inside but a new entry under “abilities”)
That’s in-place already, but not on per-file basis.
Example for your balance mod:
"core:phoenix" :
{
"growth" : 1
}
This will take creature “phoenix” from mod “core” ( = H3 data) and will replace “growth” value with 1. File with this code should be placed into “creatures” section of your mod.json just like any other creatures.
To disable ability you can set it to null:
"abilities":
{
"abilityName" : null
}
This is also a reason why abilities format was changed from Json array to Json object - it is not clear how json vectors should be replaced in such situations
To add ability - just add it into this section with unique name (unique for this creature only)
Note that to change another mod, including WoG, name of mod must be placed in dependencies section of mod.json. Exception is mod “core” which represents data from H3 + VCMI files