Patch-style edits:The point of a patch-style edit (or a patch, or an edit) is to describe only the changes made to a base object, if tokens are added/removed/changed(converted) or if the whole object is removed.
When applying a patch, the base object must first be read by whatever installs the mods, so some sort of order is implied. Patches should also be able to negate one another. For example: we have Mod A, Mod B and Mod C.
- Mod A includes the base version of the object (let's call it TOAD)
- Mod B includes a patch to remove some tokens in TOAD, but also other patches/additions
- Mod C is meant to revert the changes Mod B made to TOAD, by including a patch which re-adds the removed tokens
Here, it is important that the base Mod A is first, and the patches in B and C must be applied in order, otherwise C will add the tokens only for B to remove them along with the original tokens. Solving this order for every set of mods is difficult, I think this is a case where the task is best offloaded onto the player. The mods in the right list are ordered, and the player is able to change the order, guided by instructions in the mod descriptions, and the dependencies (as these imply which mods are before).
Whether this order should be top-down or bottom-up, with the base mods on the top or bottom of the list, is arbitrary. There is intuition and examples in other games for both.
But before that, here's aside on how to solve duplication errors, have "later" objects (in the installation order) overwrite "earlier" ones. This can be a useful tool, redefining an object from scratch when the corresponding patch would be too substantial, but mostly it solves duplication errors. Even when misused, the worst case scenario is that objects that should not be overwritten are, and parts of mods are left out like with the current file conflicts.
For the patches to work, I suggest EDIT "objects", to exist alongside the normal objects in a mod's raws.
EDIT objects do not describe a new object, instead they describe a patch to apply on an already existing object.
EDIT objects should have the powers that the current
creature variations (though they shouldn't replace them) have, they should be able to add, remove, and convert tokens. This can be done with tokens like ADD_TAG, REMOVE_TAG, or CONVERT_TAG (the raws themselves call tokens "tag"), but it should be noted that ADD_TAG can as well be left out. If it is, then EDIT objects adding tokens will look mostly like the objects they edit, making it easy to copy-and-paste between them during the modding process.Not having this is currently an issue with the creature variations and CV_ADD_TAG.
An EDIT object might look something like this:
[EDIT:ENTITY:MOUNTAIN]
[PERMITTED_REACTION:MITHRIL_MAKING]
[PERMITTED_REACTION:MITHRIL_MAKING2]
It adds two PERMITTED_REACTION tokens to the end of ENTITY:MOUNTAIN, presumably allowing the dwarves to create mithril (the reactions and materials for this still have to be defined elsewhere).
In addition, EDIT objects should be able to remove objects altogether. This is probably best done by adding a token like REMOVE_OBJECT, which slates an object for removal, but doesn't remove it there and then in the installation process. This way mods can easily add back objects removed by earlier mods.
For example: Mod A removes an object (CREATURE:TOAD) using the following EDIT object:
[EDIT:CREATURE:TOAD]
[REMOVE_OBJECT]
which adds the REMOVE_OBJECT token to the end of CREATURE:TOAD. Then all Mod B has to do to add it back is using:
[EDIT:CREATURE:TOAD]
[REMOVE_TAG:REMOVE_OBJECT]
The alternative would be for B to include a full definition of CREATURE:TOAD, to add it back. This latter solution has the weakness of B having to keep up with the original definition of CREATURE:TOAD, should it be changed. Any edits of CREATURE:TOAD before A (say by Mod C) would also be ignored by this new definition.
However, creature variations (and COPY_TAGS_FROM) complicate EDIT objects. I will assume a familiarity with the former here, otherwise I refer to
their Wiki article. Say you want to be kind to slug men, and allow them to use APPLY_CREATURE_VARIATION:ANIMAL_PERSON instead of APPLY_CREATURE_VARIATION:ANIMAL_PERSON_LEGLESS. This sounds reasonable, how would we do it with an EDIT object?
[EDIT:CREATURE:SLUG_MAN]
[CONVERT_TAG]
[CT_MASTER:APPLY_CREATURE_VARIATION]
[CT_TARGET:ANIMAL_PERSON_LEGLESS]
[CT_REPLACEMENT:ANIMAL_PERSON]
Now, we are also upset that slug men get the SAVAGE token from CREATURE_VARIATION:ANIMAL_PERSON; we want our legged slug men to appear in all biomes. We only want that for slug men though, not other animal people. How would that look?
[EDIT:CREATURE:SLUG_MAN]
[REMOVE_TAG:SAVAGE]
Finally, we want to re-add the PREFSTRING which was removed by CREATURE_VARIATION:ANIMAL_PERSON.
[EDIT:CREATURE:SLUG_MAN]
[PREFSTRING:slimy trails]
Of course, these three can be written together, like
[EDIT:CREATURE:SLUG_MAN]
[CONVERT_TAG]
[CT_MASTER:APPLY_CREATURE_VARIATION]
[CT_TARGET:ANIMAL_PERSON_LEGLESS]
[CT_REPLACEMENT:ANIMAL_PERSON]
[REMOVE_TAG:SAVAGE]
[PREFSTRING:slimy trails]
These are reasonable, and can be achieved using manual edits, but here they won't work together; the first example can only be done if EDIT objects are applied
before APPLY_CREATURE_VARIATION (because creature variations are irreversible),
while the latter two require that they are applied
after it (SAVAGE must be removed after it is added, and the creature variation removes any instances of PREFSTRING when applied). I said this can be achieved using manual edits, but how?
The former is very simple, replace [APPLY_CREATURE_VARIATION:ANIMAL_PERSON_LEGLESS] with [APPLY_CREATURE_VARIATION:ANIMAL_PERSON].
To do the latter you use creature variations, you add the following to the slug man raws
after (below) [APPLY_CREATURE_VARIATION:ANIMAL_PERSON]:
[CV_REMOVE_TAG:SAVAGE]
[APPLY_CURRENT_CREATURE_VARIATION]
[PREFSTRING:slimy trails]
Note that we would also need to apply an EDIT before if it removed or added any APPLY_CREATURE_VARIATION. What this means is essentially that we need to add/remove/convert any instances of APPLY_CREATURE_VARIATION in a step before they are applied, and add/remove/convert normal tokens in a step after.
EDIT objects also need to be able to edit creature variations, e.g. in case you want to change all animal people, or giant animals, or [insert custom modded creature variation here]. This is of course also possible to do currently, manually.
With these use cases explained, I think it is possible to take multiple paths. The one followed in the thread leading up to writing this suggestion (and when writing the mockup) was treating the add/remove/convert tokens within EDIT objects like they were creature variation tokens, and applying them as such. I am unsure if that is the best path, it lead to certain complications and was conceptually confusing, so I won't go into details here. That said, it did lead to many insights about creature variations, that have been baked into the
"goals/suggestions of the third kind" below. The best path probably depends on the structure of the code as well, something we can't know.
Toady, if you choose to go this far with the mod structure rework, I believe any solution will be a good one
Goals/suggestions of the third kind:- Generalize creature variations to be useable by all raw objects. They are general enough that it feels strange they only exist for creatures. As an asset, that kind of very general templates is really useful, though it has been underutilized in the modding community. A proposed name is "object templates", skipping "variation" as that presumably had to do with the animal people and giant animals being variations on the base animal, and with that origin being so removed from the use it makes little sense to keep it.
A wish from those making a DF markup language (Mr_Crabman being one of them) is that if many kinds of objects (entities, creatures, tools, etc.) use the same kind of template, they should be distinguished somehow to clarify the context for the parser. - Make creature variations/object templates nestable. This is an old goal from when creature variations were first revealed. It is also a good idea, and could be done "while you're at it", though that is probably a dangerous mindset.
- Merge body detail plans with creature variations/object templates. Likewise, an old goal.
- Condense the syntax of X_CONVERT_TAG tokens. Why have
[CV_CONVERT_TAG]
[CVCT_MASTER:BODY]
[CVCT_TARGET:QUADRUPED]
[CVCT_REPLACEMENT:HUMANOID]
[CV_CONVERT_TAG]
[CVCT_MASTER:BODY]
[CVCT_TARGET:QUADRUPED_FRONT_GRASP]
[CVCT_REPLACEMENT:HUMANOID]
[CV_CONVERT_TAG]
[CVCT_MASTER:BODY]
[CVCT_TARGET:QUADRUPED_NECK]
[CVCT_REPLACEMENT:HUMANOID_NECK:3FINGERS]
[CV_CONVERT_TAG]
[CVCT_MASTER:BODY]
[CVCT_TARGET:QUADRUPED_HOOF]
[CVCT_REPLACEMENT:HUMANOID_HOOF:3FINGERS]
when it can be condensed into the following?
[CV_CONVERT_TAG:BODY]
[CVCT_TARGET:QUADRUPED]
[CVCT_REPLACEMENT:HUMANOID]
[CVCT_TARGET:QUADRUPED_FRONT_GRASP]
[CVCT_REPLACEMENT:HUMANOID]
[CVCT_TARGET:QUADRUPED_NECK]
[CVCT_REPLACEMENT:HUMANOID_NECK:3FINGERS]
[CVCT_TARGET:QUADRUPED_HOOF]
[CVCT_REPLACEMENT:HUMANOID_HOOF:3FINGERS]
This applies to whatever conversion tokens are used in the EDIT objects as well.
- Split CVCT_TARGET (and corresponding EDIT token) into CVCT_TARGET and CVCT_TARGET_STRING. The way CVCT_TARGET currently works by looking for strings is quite uncumbersome, as seen with the body conversions which have to be in a certain order so [CVCT_TARGET:QUADRUPED] won't affect [BODY:QUADRUPED_HOOF]. The suggestion is to let CVCT_TARGET look for whole token arguments, as separated by colons, and give the string-searching functionality (which is still needed for e.g. giant bushmasters) to CVCT_TARGET_STRING.
- Give all objects "classes" like the CREATURE_CLASS and SYNDROME_CLASS that already exist. Primarily for the mass-editing purposes described below, but also because these kinds of arbitrary tokens are good to build off of and use in the future. They give freedom, and modders love that.
- Allow EDIT objects to select not only one, but multiple objects at once, by following some criteria. Suggested criteria are specific tokens, object classes (see above) and of course object IDs. This is both so you can shorten some expressions, instead of having
[EDIT:ENTITY:MOUNTAIN]
[PERMITTED_REACTION:MITHRIL_MAKING]
[PERMITTED_REACTION:MITHRIL_MAKING2]
[EDIT:ENTITY:MOUNTAIN_DARK]
[PERMITTED_REACTION:MITHRIL_MAKING]
[PERMITTED_REACTION:MITHRIL_MAKING2]
[EDIT:ENTITY:MOUNTAIN_DEEP]
[PERMITTED_REACTION:MITHRIL_MAKING]
[PERMITTED_REACTION:MITHRIL_MAKING2]
to add the mithril reactions to the vanilla dwarven entity and their two modded cousins (made up on the spot as examples) it could be shortened to
[EDIT:ENTITY:MOUNTAIN]
[PLUS_SELECT:ENTITY:MOUNTAIN_DARK]
[PLUS_SELECT:ENTITY:MOUNTAIN_DEEP]
[PERMITTED_REACTION:MITHRIL_MAKING]
[PERMITTED_REACTION:MITHRIL_MAKING2]
or even to
[EDIT:ENTITY:SEL_BY_CLASS:DWARVEN]
[PERMITTED_REACTION:MITHRIL_MAKING]
[PERMITTED_REACTION:MITHRIL_MAKING2]
if we imagine all these dwarven civ to have a shared "DWARVEN" class. This class-based selection may also select other "DWARVEN" civs, even ones the person creating the mithril mod had no knowledge of (for instance because they were made after it). Another example would be
[EDIT:ENTITY:ALL]
[ALL_MAIN_POPS_CONTROLLABLE]
to make all entities available for adventurers to come from. This kind of mass-editing is thus a boon for the connectivity between mods, as long as the community can come up with some standard for classes. Though as I have already seen propositions for the limited creature classes, and other modding communities like the Minecraft one has been able, I have no doubts we would.
The examples given here are all inclusive (like a logic "or"), but it should also be able to be restrictive (like a logic "and"), e.g. only select the plants that are both giant mushrooms and found underground. Or a combination thereof.
This is also where the "technical function" of mod bundles lie. Take the mithril mod we've used as an example. It consists in part of the mithril raws themselves (which we haven't seen) and the reactions, and in part of the EDIT object giving the mithril reactions to all dwarven entities. We also assume it contains those dark dwarves and deep dwarves implied by the object names. Now imagine another mod, let's call it the orichalcum mod. Much like the mithril mod, the orichalcum mod adds a new material, and a few dwarven civs (forge dwarves and moss dwarves), and it too intends for the new metal to be usable for all dwarven civs, by using something like the SEL_BY_CLASS construction seen above.
How do you order these mods?
If you put the mithril mod before the orichalcum mod, then the dark and deep dwarves will get both mithril and orichalcum, but the forge and moss dwarves will only get the latter. If you reverse the situation and put the orichalcum mod the reverse will be true, with dark and deep dwarves only getting mithril but no orichalcum.
The solution is to split the mods into two parts each, one for the definitions and one for the EDIT-based assignments. The assignment parts. As you don't want separate downloads/subscriptions for these parts, and want them grouped together in the left list for readability, mod bundles are perfect for this.
(As a final note (for now, and obviously I want people to reply here, I just didn't know where to put this), Steam Workshop mods may be auto-updated, so if that feature is used then presumably the mods in the "all mods" folder are periodically overwritten with newer versions. This could be an issue if mods aren't stored somehow in conjunction with each save file, as changing the raws of existing saves doesn't always work well.)