Page 1 of 1

What's the Right Way to derive new things?

Posted: Sun May 05, 2019 12:14 pm
by mrudat
I'm putting together a mod that derives new things from existing things.

I started deriving things from new things in data, data-updates and data-final-fixes.

On the one hand, I should run my code in data, so that other mods that derive things can see the new things as soon as possible.

Unfortunately, this conflicts with mods that edit existing prototypes if they do not run before my mod does, as my mod currently only derives new things from a given prototype once, and does not check if the prototype has changed since the last time.

So, I skipped running my derivation function in data, so that I would pick up edits to the vanilla prototypes.

Now another mod I'm using derives things from other things and only runs in data-updates, and derives new things from the things my mod creates quite happily.

Unfortunately yet another mod edits vanilla items in data-updates (which is probably where it should), but it sorts after the mod I'm creating, so I do not pick the new values up in data-updates.

To fix this, I added an optional dependency on that mod. This caused the derived items my mod creates to include the changes added to the vanilla item by this mod.

This however now causes my mod to run after that mod, and also after the mod that used to derive things from my mod.

The current order of operations:
  • Robot World - edits logistics chests in data.
  • bullet-trails - Adds bullet trails to turrets - in data-updates.
  • Loaded Turrets - Creates an item that combines turret + ammo into a single item in data-updates.
  • Big_Things - My mod that builds bigger things from other things - currently runs in data updates and data-final-fixes.
I get big turrets with bullet trails, but I don't get any turrets filled with ammo.


What I'm beginning to think is that what I need to have is a framework that allows me to register a callback for when a new thing is added, or the definition of an existing thing I've seen before is changed, collect new/updated things from my mod, then pass them around again.

Something similar to the control phase, where you don't actually do anything in the top level script, just register callbacks, and the framework calls your callbacks at the appropriate times.

From what I understand of things, it should be entirely feasible to implement something like that in a library and have it shared by any mod that cares to use it.

As a programming exercise, it might be fun to try implementing something like that.

Re: What's the Right Way to derive new things?

Posted: Tue May 07, 2019 11:59 pm
by Deadlock989
Welcome to the dependency arms race.

These are all problems I ran into with my stacking beltboxes mod, trying to please everyone by supporting a bunch of different mods that implement things differently, and why in the end I gave up trying to make it work with everything and instead wrote a kind of "mini API" to let other modders sort it out for themselves. I ran into one popular mod which makes a ton of edits to vanilla items in data-final-fixes, and when I pointed out that this more-or-less forced me to add their mod as a dependency and that if everyone did it then the dependency list would run to the moon and back, I got told that was just how it was and I could like it or lump it. I don't support that mod in anything I've written since. Personally I don't think anyone should ever be editing vanilla data after data-updates.lua and they should only create their brand new things in data.lua. But it doesn't matter what I think because people will do whatever they feel like.

You can't do callbacks as such but you can provide public functions that other mods can use. Since fairly recently, you can now require() files from other mods as well, which is great because order suddenly matters less than it did. So you can have a file full of local functions which do the groundwork and then returns a public function, sort of like an interface, nicely wrapped up in the return value.

But it doesn't help you with other people's code.

Re: What's the Right Way to derive new things?

Posted: Wed May 08, 2019 9:19 am
by eradicator
Deadlock989 wrote: Tue May 07, 2019 11:59 pm [...] if everyone did it then the dependency list would run to the moon and back [...]
That's what hidden "(!)" dependencies are for. When the only reason the dependency exists is load-order fixing, and there isn't actually any special cross-mod features that users would care about.
Deadlock989 wrote: Tue May 07, 2019 11:59 pm Personally I don't think anyone should ever be editing vanilla data after data-updates.lua and they should only create their brand new things in data.lua. But it doesn't matter what I think because people will do whatever they feel like.
I don't have that much experience with data stage, but i doubt it's that easy. If too many mods want to modify each other then at some point you run into a dependency loop and have to go to the next stage to resolve it. That said it feels like far too many inexperienced modders (and modding tutorials) tell people to do all their changes in final-fixes, and updates is barely used by anyone.

@OP:
I have to agree with @Deadlock that it's probably best to expose some global functions (or a file to require) that other mods can use to properly get things done, and to communicate with the mod authors that you're trying to integrate with. And regarding the "framework" idea, please consider that you're not the only one who needs data.raw to work as expected ;).