Overriding and merging config files in mods. (DEPRECATED)

Discussion in 'Starbound Modding' started by bartwe, Dec 16, 2013.

Thread Status:
Not open for further replies.
  1. Leosky

    Leosky Void-Bound Voyager

    no, i want to delete the item having there "property1" where "value1" : "a" :)

    from :

    Code:
    {
        "itemBundle" : {
            "item" : {
                "proprety1" : [
                    { "value1": "a" },
                    { "value2" : "z" }
                ],
                "proprety2" : [
                    { "value1": "e" },
                    { "value2" : "r" }
                ],
                "proprety3" : [
                    { "value1": "t" },
                    { "value2" : "y" }
                ],
                "proprety4" : [
                    { "value1": "u" },
                    { "value2" : "i" }
                ]
            },
            "item" : {
                "proprety1" : [
                    { "value1": "o" },
                    { "value2" : "p" }
                ],
                "proprety2" : [
                    { "value1": "p" },
                    { "value2" : "q" }
                ],
                "proprety3" : [
                    { "value1": "s" },
                    { "value2" : "d" }
                ],
                "proprety4" : [
                    { "value1": "f" },
                    { "value2" : "g" }
                ]
            },
            "item" : {
                "proprety1" : [
                    { "value1": "h" },
                    { "value2" : "j" }
                ],
                "proprety2" : [
                    { "value1": "k" },
                    { "value2" : "l" }
                ],
                "proprety3" : [
                    { "value1": "m" },
                    { "value2" : "w" }
                ],
                "proprety4" : [
                    { "value1": "x" },
                    { "value2" : "c" }
                ]
            }
        }
    }
    to

    Code:
    {
        "itemBundle" : {
            "item" : {
                "proprety1" : [
                    { "value1": "o" },
                    { "value2" : "p" }
                ],
                "proprety2" : [
                    { "value1": "p" },
                    { "value2" : "q" }
                ],
                "proprety3" : [
                    { "value1": "s" },
                    { "value2" : "d" }
                ],
                "proprety4" : [
                    { "value1": "f" },
                    { "value2" : "g" }
                ]
            },
            "item" : {
                "proprety1" : [
                    { "value1": "h" },
                    { "value2" : "j" }
                ],
                "proprety2" : [
                    { "value1": "k" },
                    { "value2" : "l" }
                ],
                "proprety3" : [
                    { "value1": "m" },
                    { "value2" : "w" }
                ],
                "proprety4" : [
                    { "value1": "x" },
                    { "value2" : "c" }
                ]
            }
        }
    }
    But yes, that another trouble.
     
  2. Campaigner

    Campaigner Giant Laser Beams

    I'm rather dumb with this, I feel. I can't understand it at all, yet I feel like it's something simple that my head just isn't wrapping around.

    How would I go about just adding items, not changing values and such? Say I want to just add a crafting station and an item that requires said station; how would that work?
     
  3. Leosky

    Leosky Void-Bound Voyager

    For the moment follow the recommended player.config copy way.

    When the patch will be release, simply add like that :

    Code:
    {
      "defaultBlueprints" : {
        "tier1" : [
          { "item" : "new_item1" },
          { "item" : "new_item2" }
        ],
        "tier2" : [
          { "item" : "new_item3" }
        ]
      }
    }
     
    Last edited: Dec 18, 2013
  4. Campaigner

    Campaigner Giant Laser Beams

    Oh, ok. I didn't think it was that simple, but I guess it is.

    For instance, if I wanted 111_crafting to be the crafting station and 111_item to be the item made at the station, I'd use the following:

    Code:
    {
      "defaultBlueprints" : {
        "tier1" : [
          { "item" : "111_crafting" },
          { "item" : "111_item" },
        ]
      }
    }
    And that's it? Just make a blank player.config with the above, and with each extra { "item" : "111_item" } being the same as if I messed with the player.config?
     
  5. Leosky

    Leosky Void-Bound Voyager

    Yep,

    just delete the ',' after the { "item" : "111_item" }. I made a syntax error (bhooo).

    Code:
    {
      "defaultBlueprints" : {
        "tier1" : [
          { "item" : "111_crafting" },
          { "item" : "111_item" }
        ]
      }
    }
     
  6. FormalRiceFarmr

    FormalRiceFarmr Big Damn Hero

    is this currently active? I'm trying to use it to mod values of an existing item in the game, with no luck
     
  7. Xuhybrid

    Xuhybrid Scruffy Nerf-Herder

    This is coming in the next patch. For now the files are overwritten by default.
     
  8. Whitlinger Doodle Do

    Whitlinger Doodle Do Pangalactic Porcupine

    I'd like to see the dwarf fortress datafile format, which is the best.
     
  9. gibbed

    gibbed Orbital Explorer

    This is a joke right? That format is an unholy abomination.
     
    The | Suit likes this.
  10. CrownFox

    CrownFox Subatomic Cosmonaut

    I'm not sure I'm 100% a fan of this idea.

    While the idea is great in part, it still brings up a host of new problems.

    What if I want to remove something from Tier 1, and add something new to Tier 1?
    I can't do this. With the way the _merge entry is structured, you can only do one or the other.

    So, say I wanted to replace the default pickaxes with the drills that you can get later.

    Removing the pickaxes from Tier 1 is easy, but what about adding the drills to Tier 1?

    The only way to do such a thing would be to completely overwrite Tier 1, but then we're back to step one, because now the compatibility with other mods is potentially broken. If any mods load before my mod, their changes are removed because the entirety of the Tier 1 list is now overwritten.
     
    Med likes this.
  11. simplex

    simplex Astral Cartographer

    Isn't that just unnecessary syntax bloat, with limited functionality?

    Why can't we just define hooks in a Lua script to receive a JSON object when it's loaded as a Lua table, modifying it as we wish by changing/adding/removing fields dynamically?

    There are many libraries for Lua <-> JSON conversion: lua-json, lua-cjson, dkjson... And they are quite fast. In my PC, turning all the Starbound assets into a Lua map (mapping filenames to tables representing the object defined in it) takes roughly 0.3 seconds using lua-json, which is a pure Lua implementation (lua-cjson is faster, but it doesn't ignore Javascript comments).


    I was thinking of something like this:
    Code:
    AddAssetHook("recipes/refinery/voxel1k.recipe", function(obj)
        assert( obj.input[1].item == "voxel1k" and obj.output.item == "money" )
        obj.output.count = 800*obj.input[1].count
    end)
    
    Being able to receive the list of all assets as Lua tables to dynamically select which ones to alter would be a big bonus as well.
     
    Last edited: Dec 19, 2013
  12. Xuhybrid

    Xuhybrid Scruffy Nerf-Herder

    You want to talk about unnecessary syntax bloat, then you post that code as an example lol. Good way to fluff your point when the alternative is;
    Code:
    "__merge" : []
     
    FormalRiceFarmr likes this.
  13. simplex

    simplex Astral Cartographer

    I took a simple example for readability. Whether one approach or other has a lesser byte count for the most trivial cases is irrelevant. Yet I showed one advantage of using dynamic modifications over static ones: I was able to parameterize the money output of refining a 1k voxel on the number of voxels taken as input. So it'd be compatible even with a mod that decided to change the input count for voxels (to, say, make refining them faster). In my example this scenario would be somewhat farfetched, but still, it highlights that it is not equivalent to your "__merge: []".

    I fail to see how there's any syntax bloat there. If anything, it's much more readable, since it relies on the semantics of a formally defined programming language, Lua, instead of adding domain-specific keywords to a purely declarative language like JSON just to simulate programming logic in a very restricted sense.

    If your concern is that forcing modders to use a real programming language would raise the entry barrier for SB modding, there's no reason why both systems couldn't coexist. Though I feel the __merge could be dropped if that were the case, since it would be made vastly obsolete by the dynamic approach.
     
  14. Xuhybrid

    Xuhybrid Scruffy Nerf-Herder

    Don't get me wrong, i don't disagree. I think that complex merges would be better defined in a separate file. However, the ease of declaring a single variable to specify the most commonly used action, adding a blueprint, is quite useful. When it comes to deleting or overwriting though, we should have access to a Lua hook. I hope this proposed system isn't just a temporary botch job, because it's annoying having to update mods for no reason.
     
  15. simplex

    simplex Astral Cartographer

    I agree with you. While I dislike the idea of adding domain-specific keywords to a language in general, when there are few of them, targeted at the most common use cases, they are handy. Not a replacement for a fully generic Lua hook, as you put it, but handy.

    I'm just glad I'm using a layer of abstraction to create mod files "dynamically", so migrating to alternate systems will not require changing the mod code itself. (but, well, as I mentioned in another thread, I have no intention of writing non-trivial mods for SB until a proper Lua API is developed, so my experience is really not a measure for anything)

    The is the code for the actual mod on which I based that snippet from before.
    Code:
    local BANK_PENALTY = 0.2
    
    
    
    local sbutils = require 'sbutils'
    local utils = sbutils.utils
    
    
    local recipes = sbutils.assets.recipe
    
    for _, recipe in pairs(recipes) do
    	if
    		#recipe.input == 1
    		and recipe.output.item == "money"
    		and utils.FindValue("refinery", ipairs(recipe.groups))
    	then
    		local input = recipe.input[1]
    		local voxel_weight = input.item:match("^voxel(%d+)k$")
    		if voxel_weight then
    			voxel_weight = tonumber(voxel_weight)*input.count
    			recipe.output.count = 1000*voxel_weight*(1 - BANK_PENALTY)
    		end
    	end
    end
    
    
    sbutils.dumpChanges()
    
    Gladly, all I'll have to do is update the definition of sbutils.dumpChanges() (which generates the JSON files based on the changes made to the assets, which are tracked through some metatable magic). Though I'd much rather have written that within a modding API instead of having to write a "mod generator"...
     
  16. Leosky

    Leosky Void-Bound Voyager

    I don't totally agree, merging / overriding / deleting entries in static files is necessary without lua scripts. Simply for readability of other modders, when you write a mod to be compatible with another mod with the same context, it will be awful to interpret what recipes this mod is changing, especially with large mods (has you said, you gave a simple example, but you're still using regex in it), and while lots of modders aren't so familiar with lua, i don't thinks it's a good idea to start modding by learning lua and regex to make so elementary changes.

    I'm not fan of __merge. It should be the default action, __override and __ delete should make the work for other examples.
     
  17. Westeller

    Westeller Space Penguin Leader

    I for one think this will be an excellent addition to mod formatting. Allowing us to make changes to files without replacing the file entirely will drastically improve mod installation and compatibility. Many, many mods all edit the same common files and require hand-editing to make them compatible. That's about as far from user-friendly as mods can be. This functionality will change that. Multiple mods will be able to change the same files without unnecessarily conflicting. I'm sure you guys can think of a thousand other things you'd like to see happen, but, this early in Beta, I'm extremely glad that we're getting this much support for modding.
     
  18. simplex

    simplex Astral Cartographer

    The actual example I gave to the API proposal does not use regex, what does is my "by the way this is how I'm doing things now as a workaround". And I certainly didn't need to use regexes there, I could've taken several alternate, more "elementary" approaches.

    I think it's nice for there to be a purely declarative alternative to Lua scripting (at least in basic scenarios) to make it easier for people to start modding, as long as it's not overdone. Shielding modders from programming shouldn't be a top concern, and of all programming languages Lua is a very simple one. Advanced Lua is somewhat complex (mostly due to metatables and Lua's slant towards functional programming), but basic Lua is as basic as it gets. Learning a little bit of it as one mods can't be a bad thing...
     
    Leosky likes this.
  19. Leosky

    Leosky Void-Bound Voyager

    yeah im ok with that :>. Trying to make everything modable in json could bloat it's definition.
     
    simplex likes this.
  20. Med

    Med Phantasmal Quasar

    Here's how you need to handle it:

    You have a bunch of mods, most of them add recipes to Tier1, some - maybe only one of them - wants to delete recipes (pickaxes for example).

    So, mods that overwrite go first in your load order, an important concept now that we have overwrite capabilities.

    The "Drills Instead of Picks" mod would then provide two mod folders:
    - 0_DrillsInsteadofPicks: loads early and overwrites the default Tier1 recipes with a shorter list that is missing a few recipes. Presumably loads first because the number "0" is first alphabetically.
    - DrillsInsteadofPicks: loads whenever and adds drill recipes to Tier1.

    The only downside here is that if you have more than one mod that wants to delete recipes from the same tier, you need to manually merge them into a single file and mod, which isn't hard, and leaves us with very few instances where manual editing is still needed.:D
     
Thread Status:
Not open for further replies.

Share This Page