mt-mods / technic

Technic mod for Minetest
18 stars 25 forks source link

Add ExchangeClone support. #335

Closed ThePython10110 closed 10 months ago

ThePython10110 commented 1 year ago

My mod ExchangeClone calculates an energy value for every item based on crafting recipes. I thought it would be a good idea for it to be able to use Technic's crafting methods, but I discovered that the way Technic waits until everything was loaded before populating technic.recipes made that difficult. This is an incredibly simple addition that calls a function every time a recipe is registered.

I have tested with and without ExchangeClone enabled. I doubt it could possibly mess anything up.

In case you're wondering, zzzz_exchangeclone_crafthook is named the way it is because Minetest loads mods in reverse alphabetical order.

The function this calls can be found here in the dev branch.

OgelGames commented 1 year ago

Technic waits until everything was loaded before populating technic.recipes

This is also a problem for #328, so it would be preferable to find a way to fix the cause than add more glue code.

Switching to use minetest.register_on_mods_loaded would be enough to fix it for your use case.

ThePython10110 commented 1 year ago

Switching to use minetest.register_on_mods_loaded would be enough to fix it for your use case.

I tried that first. My guess is that minetest.after doesn't run until after all minetest.register_on_mods_loaded functions (although it is just a guess).

Edit: I just checked, and that is how it works.

Using this code:

minetest.after(0.1, function(...) minetest.log("After") end)
minetest.register_on_mods_loaded(function(...) minetest.log("Loaded") end)

"Loaded" appears before "After" every time, as far as I can tell (I tried it a few times, sometimes closing Minetest in between, in case that mattered).

OgelGames commented 1 year ago

Yes, the minetest.register_on_mods_loaded functions are run before minetest.after, in the same order that they were registered.

From the documentation:

minetest.register_on_mods_loaded(function()) Called after mods have finished loading and before the media is cached or the aliases handled.

minetest.after starts after the world loads.

Now that I look at it, minetest.register_on_mods_loaded might not work, because we need the aliases to be handled.

BuckarooBanzay commented 1 year ago

but I discovered that the way Technic waits until everything was loaded before populating technic.recipes made that difficult.

one possibility to solve this would be to intercecpt all technic.register_recipe() calls at the load-time of your mod and at the same time check what is already registered, afaik the mesecons mod does something similar, for example:

-- store old ref
local old_register_recipe = technic.register_recipe
-- overwrite with interceptor
function technic.register_recipe(typename, data)
 -- your hook
 your_custom_code()
 -- old function
 return old_register_recipe(typename, data)
end

if everyone would implement it that way it should be compatible to each other (except if the parameter count changes)

but yeah: it is just more glue, not a proper solution :shrug:

ThePython10110 commented 1 year ago

The thing about that is... I'd have to override the function AFTER it gets defined but BEFORE everything else in the technic mod runs. That's why I did it the way I did it.

OgelGames commented 1 year ago

I'm going to have a go at fixing it, and also try to implement group support while I'm at it.

programmerjake commented 1 year ago

why not just expose a list of registered recipes that's filled when technic.register_recipe is called? this allows mods to just read the list instead of having to somehow hook the function before it's called.

ThePython10110 commented 11 months ago

It would be nice if this could be resolved before I publish the next ExchangeClone release.

S-S-X commented 11 months ago

It would be nice if this could be resolved before I publish the next ExchangeClone release.

There's currently 2 failures for required check, currently it is not possible to merge this:

    technic/machines/register/recipes.lua:99:121: line is too long (129 > 120)
    technic/machines/register/recipes.lua:104:3: accessing undefined variable exchangeclone

First is simple: line too long, make it shorter or break into multiple lines.

Undefined variable should be fixed by adding exchangeclone here (to read_globals): https://github.com/mt-mods/technic/blob/f1b99282e889e9a483c76af95ee3370b6d2b2d04/.luacheckrc#L22-L32

ThePython10110 commented 11 months ago

I fixed those things (and updated the mod name to the correct one, zzzz_exchangeclone_init, although I forgot to update the comment... whatever)