OpenXcom Forum

Modding => OpenXcom Extended => OXCE Support => Topic started by: zee_ra on March 26, 2023, 11:18:57 pm

Title: Modding collections (lists, maps).
Post by: zee_ra on March 26, 2023, 11:18:57 pm
I would like to create two mods that add ammunition to a weapon in a vanilla game, along with some other items specific to each mod.

A question is, how could this be accomplished with current configuration interpretation semantics.

Currently, there exists a definition

  - type: STR_SMALL_LAUNCHER
    compatibleAmmo:
      - STR_STUN_BOMB
      - STR_ELERIUM_BOMB
      - STR_EMP_BOMB

which corresponds to configuration

{ { type : "STR_SMALL_LAUNCHER" ,
      compatibleAmmo: [ "STR_STUN_BOMB" , "STR_ELERIUM_BOMB" , "STR_EMP_BOMB" ]
   },
   # ...
}


I would like to provide additional definitions, along the lines of

  - type: STR_SMALL_LAUNCHER
    compatibleAmmo:
      - insert: STR_MEGA_BOMB
      - insert: STR_GIGA_BOMB

in one mod and also

  - type: STR_SMALL_LAUNCHER
    compatibleAmmo:
      - insert: STR_GIANT_BOMB
      - insert: STR_ULTRA_BOMB

in another mod in order to yield the following configuration:

{ { type : "STR_SMALL_LAUNCHER" ,
      compatibleAmmo: [ "STR_STUN_BOMB" , "STR_ELERIUM_BOMB" , "STR_EMP_BOMB",
      "STR_MEGA_BOMB", "STR_GIGA_BOMB", "STR_GIANT_BOMB", "STR_ULTRA_BOMB" ] },
   # ...
}


What is the best way to accomplish that?

Title: Re: Modding collections (lists, maps).
Post by: Yankes on March 27, 2023, 01:28:18 am
I assume you target OXCE, then you can:


For some properties yes, add `!info` after node name to get feedback in logs for game what options are avaiable. If none is show its mean this is "dumb" node and do not support special operations.

quoting: https://www.ufopaedia.org/index.php/Ruleset_Reference_Nightly_(OpenXcom)
Code: [Select]
#base mod:
 items:
   - type: STR_WEAPON
     compatibleAmmo: !info     #this tag does not change anything, but when used it will show (in the log file) if the list supports this functionality or not
       - STR_AMMO_1
       - STR_AMMO_2
 
 #sub-mod
 items:
   - type: STR_WEAPON
     compatibleAmmo: !add      #now `STR_WEAPON` will have ammo list equal to `[STR_AMMO_1, STR_AMMO_2, STR_AMMO_3]`
       - STR_AMMO_3
 
 #another sub-mod
 items:
   - type: STR_WEAPON
     compatibleAmmo: !remove   #now `STR_WEAPON` will have ammo list equal to `[STR_AMMO_1, STR_AMMO_3]`
       - STR_AMMO_2

another thing is do not use `type:` when you override some other mod items, use `override:` that check if item exist and do not interpret your typo as new item.
you can use too `update:` that allow missing item with given name, and then it skip given additions.

This `override:` and `update:` recent addition to OXCE, best if you add in mod metadata what version of OXCE you created mod with.
Title: Re: Modding collections (lists, maps).
Post by: zee_ra on March 27, 2023, 02:20:39 am
@Yankes, Thank you.  I'll experiment in the next few days with these tags.

So far, this seems like a good approach with the config design: the tags are a nice side channel to the main data stream.  I have been trying to figure out the approaches based on patching, and some YAML-specific patching libraries, but the inherent issue seems to be a problem of versioning.

More discussion is available at the https://openxcom.org/forum/index.php/topic,11192.msg154202.html#msg154202.
Title: Re: Modding collections (lists, maps).
Post by: zee_ra on March 27, 2023, 02:46:31 am

another thing is do not use `type:` when you override some other mod items, use `override:` that check if item exist and do not interpret your typo as new item.
you can use too `update:` that allow missing item with given name, and then it skip given additions.

This `override:` and `update:` recent addition to OXCE, best if you add in mod metadata what version of OXCE you created mod with.

Concerning the versioning, what metadata item should be used?  Would the following be appropriate?
requiredExtendedVersion: "7.8"

I wonder, how should I approach the following scenario.  Two sub-mods add weapons that need to share sub-munitions that are common to all three mods.
Code: [Select]
#base mod:
 items:
   - type: STR_MINI_CANNON
     compatibleAmmo:
       - STR_MINI_BOMB
 
 #sub-mod-1
 items:
   - override: STR_MINI_CANNON
     compatibleAmmo: !add
       - STR_MAXI_BOMB
   - type: STR_MINI_ASSAULT_CANNON
     compatibleAmmo:
       - STR_MINI_BOMB
       - STR_MAXI_BOMB
 
 # sub-mod-2
 items:
   - type: STR_MAXI_CANNON
# how to approach these definitions?
# I would like to use STR_MINI_BOMB and STR_MAXI_BOMB here if sub-mod-1 is loaded
# If sub-mod-1 is *not* loaded, I would like to use STR_MINI_BOMB here
# Would it be more preferable to simply require sub-mod-1 to be always loade
# by including it as a dependency?

Title: Re: Modding collections (lists, maps).
Post by: Yankes on March 27, 2023, 04:08:15 am
It need `7.8.14` as it was added after `7.8.0`was published.

If I understand correctly, you want support 3 cases:
Code: [Select]
#only one mod A
items:
   - type: STR_A
     compatibleAmmo:
       - STR_A_AMMO

Code: [Select]
#only one mod B
items:
   - type: STR_B
     compatibleAmmo:
       - STR_B_AMMO
and
Code: [Select]
#both A and B
items:
   - type: STR_A
     compatibleAmmo:
       - STR_A_AMMO
       - STR_B_AMMO
   - type: STR_B
     compatibleAmmo:
       - STR_A_AMMO
       - STR_B_AMMO

Then no, this is not possible, any options avaialbe can only check if given item exist before game try update it.
If both mods need be independent of each other then you need third mod that link both and it set up all cross references.

Title: Re: Modding collections (lists, maps).
Post by: zee_ra on March 27, 2023, 05:43:48 am
It need `7.8.14` as it was added after `7.8.0`was published.

If I understand correctly, you want support 3 cases:
Code: [Select]
#only one mod A
items:
   - type: STR_A
     compatibleAmmo:
       - STR_A_AMMO

Code: [Select]
#only one mod B
items:
   - type: STR_B
     compatibleAmmo:
       - STR_B_AMMO
and
Code: [Select]
#both A and B
items:
   - type: STR_A
     compatibleAmmo:
       - STR_A_AMMO
       - STR_B_AMMO
   - type: STR_B
     compatibleAmmo:
       - STR_A_AMMO
       - STR_B_AMMO

Then no, this is not possible, any options avaialbe can only check if given item exist before game try update it.
If both mods need be independent of each other then you need third mod that link both and it set up all cross references.

Thank you for sharing this.

From the modder perspective, the addition of an extra mod is not an unacceptable solution.  I wonder, if there exists a way to specify a dependency on other non-master mods, and in particular the dependency on versions.  Ideally, there should be a dependency clause along the lines of ">=0.2".  Pretty much like rpm / deb packages.
Title: Re: Modding collections (lists, maps).
Post by: zee_ra on March 27, 2023, 05:45:30 am
I assume you target OXCE, then you can:


For some properties yes, add `!info` after node name to get feedback in logs for game what options are avaiable. If none is show its mean this is "dumb" node and do not support special operations.

quoting: https://www.ufopaedia.org/index.php/Ruleset_Reference_Nightly_(OpenXcom)
Code: [Select]
#base mod:
 items:
   - type: STR_WEAPON
     compatibleAmmo: !info     #this tag does not change anything, but when used it will show (in the log file) if the list supports this functionality or not
       - STR_AMMO_1
       - STR_AMMO_2
 
 #sub-mod
 items:
   - type: STR_WEAPON
     compatibleAmmo: !add      #now `STR_WEAPON` will have ammo list equal to `[STR_AMMO_1, STR_AMMO_2, STR_AMMO_3]`
       - STR_AMMO_3
 
 #another sub-mod
 items:
   - type: STR_WEAPON
     compatibleAmmo: !remove   #now `STR_WEAPON` will have ammo list equal to `[STR_AMMO_1, STR_AMMO_3]`
       - STR_AMMO_2

another thing is do not use `type:` when you override some other mod items, use `override:` that check if item exist and do not interpret your typo as new item.
you can use too `update:` that allow missing item with given name, and then it skip given additions.

This `override:` and `update:` recent addition to OXCE, best if you add in mod metadata what version of OXCE you created mod with.

I noticed that the wiki mentions an ability to inherit definitions.  I wonder, how does listOrder get generated when inheritance occurs?  Also, is it possible to somehow automate the generation of this value in mods?  It's not a huge issue, but could be a nuisance maintenance-wise.
Title: Re: Modding collections (lists, maps).
Post by: Yankes on March 27, 2023, 04:26:19 pm
Thank you for sharing this.

From the modder perspective, the addition of an extra mod is not an unacceptable solution.  I wonder, if there exists a way to specify a dependency on other non-master mods, and in particular the dependency on versions.  Ideally, there should be a dependency clause along the lines of ">=0.2".  Pretty much like rpm / deb packages.

`overrdie:` in some way could work in that aspect, as you could "probe" if other mod was already loaded.
In theory we could add mechanism like this, it will be complex as will need handle lot of corner cases. Only problem is that only couple of small mods (that I aware of) could benefit from it, for now grain/cost ratio is too small to consider adding feature like this.

Beside `requiredMasterModVersion` is not yet used much at this time, adding more features like this would be waste of time if nobody will use it.

I noticed that the wiki mentions an ability to inherit definitions.  I wonder, how does listOrder get generated when inheritance occurs?  Also, is it possible to somehow automate the generation of this value in mods?  It's not a huge issue, but could be a nuisance maintenance-wise.

This is not "inherit" its more like "sharing" because it work only in one file and work more like copy-paste on yaml level that object in memory.
And `listOrder` in OXCE is only updated when new rule is created, aka `new:` or old `type:` if given name did not exists before, in OXC or older OXCE it was incremented each time you use `type:` even if do not use it.
Title: Re: Modding collections (lists, maps).
Post by: Meridian on March 28, 2023, 09:50:28 am
I noticed that the wiki mentions an ability to inherit definitions.

It's not inheritance, it's an automated copy-paste.

I will update the ruleset reference this weekend to be more precise.
Title: Re: Modding collections (lists, maps).
Post by: zee_ra on March 28, 2023, 12:24:13 pm
It's not inheritance, it's an automated copy-paste.

I will update the ruleset reference this weekend to be more precise.

I would appreciate that.  Thank you.

I would like to inquire, if it is possible to remove nodes in the definitions.  Say,

Code: [Select]
- type: STR_MEGA_BOMB
  refNode: *STR_STUN_BOMB
  # now, I need to remove recoveryPoints from the STR_STUN_BOMB definition,
  # so that it doesn't appear anywhere in STR_MEGA_BOMB
  # the following seems hackish
  recoveryPoints: 0
  # could I instead use something along the lines of
  # recoveryPoints !remove
  # that is not a to-spec YAML, though ...

Title: Re: Modding collections (lists, maps).
Post by: Yankes on March 28, 2023, 12:34:27 pm
You need set new value, there no other way and probably will not be as it would require rewrite all rule loading to handle every property.

Best way to avoid it is simply have in `STR_STUN_BOMB` only things that do not change, and you do not need overwrite after.
Title: Re: Modding collections (lists, maps).
Post by: zee_ra on March 28, 2023, 09:35:36 pm
You need set new value, there no other way and probably will not be as it would require rewrite all rule loading to handle every property.

Best way to avoid it is simply have in `STR_STUN_BOMB` only things that do not change, and you do not need overwrite after.

Well, what I would like to accomplish is to inherit from an existing definition, which has an extraneous property.  For example, if I inherit from a STR_LARGE_ROCKET, there's a parameter costBuy.  This parameter does not make sense in an item that is produced and is never being bought.  For instance, in a mod I may desire to make a gas rocket.  The rocket would largely share the traits of a large rocket, but woudld have a different damage mode, different graphics, and could only be manufactured at a workshop.  When a master mod maker encounters this issue, he has an option of simply exhaustively specifying all parameters for a new type.  As a sub-mod maker, I would like to avoid doing so, since I conceptually want to only alter an existing definition.

Now, I understand that items come with a pre-defined set of parameters.  How does costBuy get semantically handled?  I asssume, it has a default value which is interpreted appropriately.  An issue is what is a canonical default value for each type of argument node.  From a general scripting standpoint, a good approach is to assign a form of null value to a field to indicate that it needs to contain either a default or other empty placeholder.

Please note that assigning a null value is conceptually different than removing a node, but for all practical purposes it yields the same semantic effect from the perspective of modding.

What would happen if I assign a null value to costBuy?  to recoveryPoints?
Title: Re: Modding collections (lists, maps).
Post by: zee_ra on March 28, 2023, 09:48:27 pm
It's not inheritance, it's an automated copy-paste.

I will update the ruleset reference this weekend to be more precise.

What do you think about making a page on wiki to go over the common mod making problems and their solutions?  I am currently making a small mod to XCF that adjusts some weapons and armors, and vehicles.  Ideally, it should make these adjustments tunable as game options.  No scripting would is being involved.  I think, it covers almost all of the basic extension questions : altering graphics, altering config, and not making the project into an unmaintainable mess.  That is, it is a case of a small mod that alters some parameters, and does not need subsequent maintenance as the master evolves.

I could contribute my perspective as a mod maker.  Someone should be able to provide narrative responses to sections I'll put forth.
Title: Re: Modding collections (lists, maps).
Post by: Yankes on March 28, 2023, 10:28:44 pm
Well, what I would like to accomplish is to inherit from an existing definition, which has an extraneous property.  For example, if I inherit from a STR_LARGE_ROCKET, there's a parameter costBuy.  This parameter does not make sense in an item that is produced and is never being bought.  For instance, in a mod I may desire to make a gas rocket.  The rocket would largely share the traits of a large rocket, but woudld have a different damage mode, different graphics, and could only be manufactured at a workshop.  When a master mod maker encounters this issue, he has an option of simply exhaustively specifying all parameters for a new type.  As a sub-mod maker, I would like to avoid doing so, since I conceptually want to only alter an existing definition.

Copy-paste all properties of base mod file to your mod and alter it in your heart content. This is only solution that will last long time. If you did any "inherit" of object do you not control in any way, it will break if base mod change it in incompatible way.

Now, I understand that items come with a pre-defined set of parameters.  How does costBuy get semantically handled?  I asssume, it has a default value which is interpreted appropriately.  An issue is what is a canonical default value for each type of argument node.  From a general scripting standpoint, a good approach is to assign a form of null value to a field to indicate that it needs to contain either a default or other empty placeholder.

You could suggest it 10 years ago when SupSuper start writing OXC, now most how its is handled is set in stone and I or any other developer do not plan to alter it in any major way as it would break any most of mods in wild.

Sematic is simple, you keep current value (by not mentioning property in any way) or setting it by new value. For default values, look in ufopedia page.


Please note that assigning a null value is conceptually different than removing a node, but for all practical purposes it yields the same semantic effect from the perspective of modding.

What would happen if I assign a null value to costBuy?  to recoveryPoints?
probably it will get ignored by yaml-cpp as it can't convert text `null` to number.
Title: Re: Modding collections (lists, maps).
Post by: zee_ra on March 28, 2023, 11:01:25 pm
Copy-paste all properties of base mod file to your mod and alter it in your heart content. This is only solution that will last long time. If you did any "inherit" of object do you not control in any way, it will break if base mod change it in incompatible way.

The problem is that the inheritance of properties would be lost in this case.

You could suggest it 10 years ago when SupSuper start writing OXC, now most how its is handled is set in stone and I or any other developer do not plan to alter it in any major way as it would break any most of mods in wild.

Sematic is simple, you keep current value (by not mentioning property in any way) or setting it by new value. For default values, look in ufopedia page.

probably it will get ignored by yaml-cpp as it can't convert text `null` to number.

Are there sets of canonical defaults that would yield the desired outcome (in my case, being effectively a no-op).

Also, how had the null values been used in the existing mods that contradicts their semantics as no-op values?

I could e.g. set recoveryPoints to 0 to achieve this end consistently.

Now, regarding the costBuy the issue is more along the lines of what value could yield me a desired interpretation.  If the value must be numerical, then perhaps a negative number could have a desired significance.  Or a zero?  Ideally of course, the value should be a more complex variant type, but numerical conventions are workable.

probably it will get ignored by yaml-cpp as it can't convert text `null` to number.

Do any of the conversion stages populate the entire set of all arguments available for an object?  If so, there must be defaults defined for all arguments, and most of them should include a no-op value case (i.e. a value whose effect is to have no effect).

A conversion stage should be able to convert null to a no-op default, unless there's some established semantical conversion regarding nulls that would contradict such interpretation.
Title: Re: Modding collections (lists, maps).
Post by: Yankes on March 28, 2023, 11:22:50 pm
Can you remind me what is point of this discussion? If you want some details or quirks of some properties in rulest read wiki.
Even if we describe some mathematical model how it work, you will find multiple exceptions and inconsistencies that will make every thing pointless.

Simple rule is:
If you want edit some property, you do:
Code: [Select]
propertyX: Y
where `Y` is value describe in ufopedia wiki as valid value, any thing else is Undefined Behavior (yes, same UB like in C++).
Title: Re: Modding collections (lists, maps).
Post by: zee_ra on March 28, 2023, 11:38:18 pm
Can you remind me what is point of this discussion? If you want some details or quirks of some properties in rulest read wiki.
Even if we describe some mathematical model how it work, you will find multiple exceptions and inconsistencies that will make every thing pointless.

Simple rule is:
If you want edit some property, you do:
Code: [Select]
propertyX: Y
where `Y` is value describe in ufopedia wiki as valid value, any thing else is Undefined Behavior (yes, same UB like in C++).

The point of this discussion is editing existing configuration structures.

I think, the Ruleset Reference doesn't mention the interpretations of all desired properties.

Now, when considering undefined behaviour, what this means in practice, is that there exists a default value for many of the parameters that need to be considered (and they're there in the first place to be considered somewhere), if only that value lies in the code.

A practical solution for the current situation would be to describe what explicit defaults would work for at least a relevant (determined by modding experience) subset of parameters.
Title: Re: Modding collections (lists, maps).
Post by: zee_ra on March 28, 2023, 11:40:41 pm
The point of this discussion is editing existing configuration structures.

I think, the Ruleset Reference doesn't mention the interpretations of all desired properties.

Now, when considering undefined behaviour, what this means in practice, is that there exists a default value for many of the parameters that need to be considered (and they're there in the first place to be considered somewhere), if only that value lies in the code.

A practical solution for the current situation would be to describe what explicit defaults would work for at least a relevant (determined by modding experience) subset of parameters.

I could eventually list all parameters that need further documentation of this nature.

For the time being, I would like to inquire how to make costBuy into a no-op.  The one unclear point to me is what would be the behaviour if costBuy = 0 and requiresBuy is populated?  I assume, whence the requiresBuy is not populated and costBuy = 0, the behaviour would be that the item is un-purchaseable, and must be acquired as either a trophy or by means of being manufactured.

Should a separate thread in modding subform (which would you suggest?) be started?
Title: Re: Modding collections (lists, maps).
Post by: Yankes on March 29, 2023, 12:40:16 am
I could eventually list all parameters that need further documentation of this nature.

For the time being, I would like to inquire how to make costBuy into a no-op.  The one unclear point to me is what would be the behaviour if costBuy = 0 and requiresBuy is populated?  I assume, whence the requiresBuy is not populated and costBuy = 0, the behaviour would be that the item is un-purchaseable, and must be acquired as either a trophy or by means of being manufactured.

Should a separate thread in modding subform (which would you suggest?) be started?

I think that your current mental model of ruleset OXC is so different to how OXC work that become unmatchable for me to anything in OXC.
What could even mean "no-op"? Especially in case of `costBuy`, this is simple numerical value, noting more, nothing less. If value is zero then item will not be available to buy. If you add some `requiresBuy` then it only can add to "not available", this mean both condition need be meet to have given item available to buy.
Title: Re: Modding collections (lists, maps).
Post by: zee_ra on March 29, 2023, 09:45:03 am
I think that your current mental model of ruleset OXC is so different to how OXC work that become unmatchable for me to anything in OXC.
What could even mean "no-op"? Especially in case of `costBuy`, this is simple numerical value, noting more, nothing less. If value is zero then item will not be available to buy. If you add some `requiresBuy` then it only can add to "not available", this mean both condition need be meet to have given item available to buy.

I see.  This matches my understanding.  It's a classical config file approach, and it seems that most values always exist, with well-defined defaults in case they're absent in the configuration.

The "no-op" means essentially a zero value, where zero is whatever makes sense in the context.  The "no-op" means that a value does not convey any properties to the object upon which it is applied.  If I moved by zero meters, then I did not move at all.  I assume, the analogy is rather obvious.

Title: Re: Modding collections (lists, maps).
Post by: zee_ra on March 31, 2023, 12:44:19 pm
It's not inheritance, it's an automated copy-paste.

I will update the ruleset reference this weekend to be more precise.

It seems that I still need to import an anchor into my mode's namespace in order to enable the propagation of values.

Could you please have a look at the technique suggested below and ascertain its validity.

Code: [Select]
# In order to reference the large rocket definition in my mod,
# I actually need to create an anchor that refers to a parent
# definition
items:
  - &STR_LARGE_ROCKET
    override: STR_LARGE_ROCKET
# nothing is done to this definition
# the override there is merely as a means of importing the definition
# [...]
#
# Now I could take advantage of the definition through refNode.
  - &STR_GAS_ROCKET
    type: STR_GAS_ROCKET
    refNode: *STR_LARGE_ROCKET
# I could define whatever fields need to be defined.
# All the values that were populated in the parent mod large rocket definition
# would be pre-populated in this definition already.
# [...]
#

I also wonder, whether it makes a difference whether I use update: or override in the example above.
Title: Re: Modding collections (lists, maps).
Post by: Meridian on March 31, 2023, 12:51:50 pm
It seems that I still need to import an anchor into my mode's namespace in order to enable the propagation of values.

yes

Could you please have a look at the technique suggested below and ascertain its validity.

it's invalid

I also wonder, whether it makes a difference whether I use update: or override in the example above.

since the example is invalid, this question is also invalid

but purely technically, it makes a technical difference, we don't have any reason to add 2 keywords doing exactly the same thing :)
Title: Re: Modding collections (lists, maps).
Post by: zee_ra on March 31, 2023, 01:10:53 pm

it's invalid

since the example is invalid, this question is also invalid

but purely technically, it makes a technical difference, we don't have any reason to add 2 keywords doing exactly the same thing :)

Could you please suggest a solution to my original task of reusing definition from the parent mod?  Would the stub code above be sufficient for illustration?
Title: Re: Modding collections (lists, maps).
Post by: Meridian on March 31, 2023, 01:42:42 pm
Currently, there is no solution.

OXCE does not support inheritance.
Most we can do is various forms of smart copypaste, within the scope of one single rul file.

You can change the definition from a parent mod.
You cannot reuse a definition from a parent mod to define something new.
Title: Re: Modding collections (lists, maps).
Post by: zee_ra on March 31, 2023, 01:49:56 pm
Currently, there is no solution.

OXCE does not support inheritance.
Most we can do is various forms of smart copypaste, within the scope of one single rul file.

You can change the definition from a parent mod.
You cannot reuse a definition from a parent mod to define something new.

I basically need to copy data from the parent mod.  The binding time is at the instantiation of the data.  Clearly, the copying semantics is satisfactory.

I hope the use of terminology that is homonymous with that adopted by c++ does not convey the wrong idea.

You mentioned smart copying.  How could this be achieved?
Title: Re: Modding collections (lists, maps).
Post by: zee_ra on March 31, 2023, 01:52:37 pm
Currently, there is no solution.

OXCE does not support inheritance.
Most we can do is various forms of smart copypaste, within the scope of one single rul file.

You can change the definition from a parent mod.
You cannot reuse a definition from a parent mod to define something new.

Could I create a copy of the item already available in a mod?

Why is my original technique invalid?  What happens when those definitions are applied?
Title: Re: Modding collections (lists, maps).
Post by: Yankes on March 31, 2023, 02:18:29 pm
because two separate things, yaml file and rules in engine, data can only flow from yaml file to engine not in opposite way.
OXCE only support "coping" in yaml file as some nodes are duplicated in multiple places.
This duplication do not alow in any way to duplicate any thing that is in engine as this is different layer.
Title: Re: Modding collections (lists, maps).
Post by: zee_ra on March 31, 2023, 06:05:14 pm
because two separate things, yaml file and rules in engine, data can only flow from yaml file to engine not in opposite way.
OXCE only support "coping" in yaml file as some nodes are duplicated in multiple places.
This duplication do not alow in any way to duplicate any thing that is in engine as this is different layer.

Well, let's for the sake of discussion assume that a solution at the YAML level is not being considered.  In YAML, it's possible to parse multiple data buffers and to merge them.  The tooling for that is not a part of a YAML specifications.

If we treat the config as just data, then we in the end have a set of definitions that are processed in the second step.  The merging occurs in that step, whence definitions from sub-mods are applied.  At this step, all config data is already parsed, and we have available to us a set of unmerged configuration definitions.  The definitions then need to be applied in descending order to the main configuration.  The definitions thus may refer to whatever was previously defined.  The way this reference is achieved is not through the YAML constructs, but through the reference (e.g. a field, without any special meaning in YAML, called "inheritFrom", which contains an id of the parent definition).

---

Please allow me to note that the specific problem that I'm trying to solve is a very practical one, and it is about extending master mods, and actually any other mods, in a way that eliminates the bulk of the maintenance burden.  I'm working out a solution within the current implementation constraints.

Anywhere a copy-pasting at the level of writing mod files is involved, we get a source of bugs and maintenance burdens.
Title: Re: Modding collections (lists, maps).
Post by: Yankes on March 31, 2023, 08:07:36 pm
Well, let's for the sake of discussion assume that a solution at the YAML level is not being considered.  In YAML, it's possible to parse multiple data buffers and to merge them.  The tooling for that is not a part of a YAML specifications.

If we treat the config as just data, then we in the end have a set of definitions that are processed in the second step.  The merging occurs in that step, whence definitions from sub-mods are applied.  At this step, all config data is already parsed, and we have available to us a set of unmerged configuration definitions.  The definitions then need to be applied in descending order to the main configuration.  The definitions thus may refer to whatever was previously defined.  The way this reference is achieved is not through the YAML constructs, but through the reference (e.g. a field, without any special meaning in YAML, called "inheritFrom", which contains an id of the parent definition).

Do we discuss OXCE or some theoretical data processing? I here to answer question for former not latter.
If you want simplified model how OXCE work I can provide it:
We start with yaml file:
Code: [Select]
fooA: "X"
fooB: "Z"
fooC: 123
And you have struct in code:
Code: [Select]
strict Data
{
   std::string fooA;
   std::string fooB;
   int fooC;
};
Then loading is function that is called for each loaded yaml file:
Code: [Select]
void load(Data& d, const YamlFile& f)
{
    if (f["fooA"]) d.fooA = f["fooA"].as<std::string>();
    if (f["fooB"]) d.fooB = f["fooB"].as<std::string>();
    if (f["fooC"]) d.fooC = f["fooC"].as<int>();
}

And there is nearly noting aside from that. With this you can understand most of OXC or OXCE loading of rulesets.


Please allow me to note that the specific problem that I'm trying to solve is a very practical one, and it is about extending master mods, and actually any other mods, in a way that eliminates the bulk of the maintenance burden.  I'm working out a solution within the current implementation constraints.

Anywhere a copy-pasting at the level of writing mod files is involved, we get a source of bugs and maintenance burdens.
Again, if you want have copy of some item from master mod you need manually copy it yourself. I do not plan add any functionality that would allow copy existing rule objects under different name.
Title: Re: Modding collections (lists, maps).
Post by: zee_ra on April 01, 2023, 01:17:10 am
Do we discuss OXCE or some theoretical data processing? I here to answer question for former not latter.
If you want simplified model how OXCE work I can provide it:
We start with yaml file:
Code: [Select]
fooA: "X"
fooB: "Z"
fooC: 123
And you have struct in code:
Code: [Select]
strict Data
{
   std::string fooA;
   std::string fooB;
   int fooC;
};
Then loading is function that is called for each loaded yaml file:
Code: [Select]
void load(Data& d, const YamlFile& f)
{
    if (f["fooA"]) d.fooA = f["fooA"].as<std::string>();
    if (f["fooB"]) d.fooB = f["fooB"].as<std::string>();
    if (f["fooC"]) d.fooC = f["fooC"].as<int>();
}

And there is nearly noting aside from that. With this you can understand most of OXC or OXCE loading of rulesets.
Again, if you want have copy of some item from master mod you need manually copy it yourself. I do not plan add any functionality that would allow copy existing rule objects under different name.

So, the algorithm is as follows:

1. Read config at current point.
2. Apply config data directly to a global object.
3. Advance cursor in (1).  If cursor points to the end, terminate.


Is that what is happening in the OXCE?
Title: Re: Modding collections (lists, maps).
Post by: Yankes on April 01, 2023, 01:35:22 am
If you totally simplify it, yes.