Replacing structs when merging Json


#1

Currently when merging json data from a mod with the corresponding core json, the only way to completely replace a struct (ignoring all old values) is to individually set every property that you’re not overwriting to null (correct me if I’m wrong here). This can be painful as you need to know all (often arbitrary for bonuses) property names set before.

One way to address this would be to add special treatment for property names that match a particular format to replace instead of merge with the original property (e.g. “bonuses=” to replace property “bonuses”).

Example: original json

{
	"struct1" : { "a" : 1, "b" : 2 },
	"struct2" : { "a" : 1, "b" : 2 }
}

merged with new json

{
	"struct1" : { "a" : 2 },
	"struct2=" : { "a" : 2 }
}

becomes

{
	"struct1" : { "a" : 2, "b" : 2 },
	"struct2" : { "a" : 2 }
}

Thoughts?


#2

I don’t think adding = is explicit enough. Would be better if mods could specify separately how exactly they want their data to be treated: override completely, merged, etc. I get it’s might be less flexible, but it’s could be better in long run as well.


#3

What advantages do you see with that approach? You’ll typically want to be able to merge some things but override others, so flexibility is a big concern here. E.g. when modding secondary skill bonuses, I’ll want to merge some skills where I just tweak numbers, and override others which I rework completely.


#4

I mainly concerned about two things:

  • First of all it’s some modders doing the wrong thing and override more stuff than needed. If overriding require reading a bit of documentation it’s will be used less often and only when needed.
  • Second is that it’s should be easy enough to detect conflicts with some automation scripts and without VCMI itself.

If you sure this wouldn’t be a problem then it’s fine to use “easy” overrides. Though some better syntax needed instead of just “=”.


#5
  • Mistakes by modders: I don’t think that making things complex is a good way approach for avoiding mistakes. We can add some recommendations on when to use this feature on the wiki, with a warning against overuse.
  • I’m not sure exactly what checking for conflicts involves - if it goes beyond a simple check for overlap in identifiers (which may lead to false positives), the script will have to work out what is merged or overwritten either way. I don’t see why parsing data annotations would be harder than whatever alternative we might use.

Any suggestions for a better syntax?


#6

Since we already using prefixes like core: we can as well use suffix like ::override.
Though someone else could suggest better option.


#7

I think it is better to use # or $ for override marker delimiter to be consistent with json schema.


#8

Recommended solution for heavy modifying is delete old object and create new one.

{
	"struct1" : null,
	"struct2" : null,
	"struct3" :  { "a" : 2 },
	"struct4" :  { "a" : 2 }
}

#9

In this case you are changing the key, so this is only works for situations where the key is meaningless. Plus setting something to null is not precisely the same as deleting it, and there are currently places where null values are triggering bugs (i.e. where the parser doesn’t handle null values).


#10

It works even if key has meaning (f.e. if you completely rewriting creature configuration it become another creature and should have unique key and all links to old one should be reviewed and updated)