Page 1 of 1
Ensure to be loaded last

Posted:
Thu Jun 18, 2015 02:42
by SegFault22
I'm working on a mod where it would be a great advantage to "force" the mod to be loaded last. I am working on an algorithm to list the mods which add items, the items which they add, and to add compatibility with the materials api/system (while respecting those mods' naming conventions, when applicable). For mods which add materials that are also added by other mods, all of the items (which are basically the same thing, but are added by separate mods) get "unified" and are treated as the same thing in recipes - the items from the mods would still be defined as separate items (so they would still stack differently), but they would be interchangeable in recipes.
If any mods which add their own materials are loaded after this mod, their items would not be detected, and compatibility with other mods' similar items would not be available. I don't want to have to name the mod with special characters that put it at the end of the list, so is there some way (other than abusing the currently existing dependencies system) to force the mod to be loaded last?
Re: Ensure to be loaded last

Posted:
Thu Jun 18, 2015 04:03
by BrandonReese
Will it not work to use minetest.after to run your function x seconds after everything has loaded?
Re: Ensure to be loaded last

Posted:
Thu Jun 18, 2015 06:39
by HeroOfTheWinds
Considering that such a mod must have some sort of formspec or chat dialogue, it would not need to preload the other mods. It can merely compile the list when requested. And to do so, it would be very easy to reference the registered_* tables to find those items. (perhaps even tweak them?)
Since your mod causes craft items to be interchangeable if they are duplicates, this function would run whenever someone tries to craft an applicable object. Hence, it is after all mods are loaded.
Re: Ensure to be loaded last

Posted:
Thu Jun 18, 2015 06:52
by rubenwardy
If you're adding groups to items, it needs to be done at load time as node def are sent to the client, and crafting is client side predicted. I'm not absolutely sure, confirmation on this would be needed.
My food mod handles multiple dependecies in a similar way. Although, it soft depends and adds groups to a known list of items, rather than detecting from the item name.
How about going through registered_items, then overriding register_item to catch any mods loaded after your one?
Re: Ensure to be loaded last

Posted:
Thu Jun 18, 2015 07:13
by SegFault22
I would prefer not to use minetest.after for that, because any function (especially one registering items) which is executed after the timer has expired would not be usable by (or visible to) the function which makes the compatibility work. It also would leave the system idle for some time during loading, while it waits for the timer to expire. Unless there is some way to make minetest.after strictly adhere to executing the function only after all of the other mods in the mods folder have loaded, I will (unfortunately) have to get users to include every mod (which they want compatibility enabled for) in the depends.txt list of the mod.
It might be possible to include entries in the depends.txt list, followed by the question-mark-sign, for each known mod which adds considerable resource/material items, but that method offers no detection of mods which are not already known to add materials.
I will use minetest.after() for some similar issues, but not in the mod-loading/item-registering level
edit1: I intend to make registered crafting-grid recipes use groups instead of specific items, that way the items in the specified group can be used, regardless of what mod they are from. Also, since it is not possible to register more items after the mods are all loaded and the game (server) is initialized, the mod must load after the other mods (which add materials) have all been loaded, so that items (such as plates made from metals, nuggets for all metals, dust piles for all metals, and such) can be registered for the materials added by other mods, which are not included in my mod.
Re: Ensure to be loaded last

Posted:
Thu Jun 18, 2015 07:37
by rubenwardy
minetest.after never runs during the load stage, always during game ticks.
My suggestion would work, you can register other items in your overridden register_item.
Please note, I think register_node calls register_item, so no need to override the former.
Re: Ensure to be loaded last

Posted:
Fri Jun 19, 2015 00:41
by SegFault22
If minetest.after never runs during the load phase, the code registering items made from the materials (added by other mods) would be called after the server starts tick-ing. If I remember correctly, items can only be registered during the load phase. If there is some way to register items after the game (server) is initialized, there would have to be some way to prevent already existing items from turning into unknowns, after the game is initialized but before the items are registered. If there is some way around those problems, it would be possible to use minetest.after() for the purpose.
Re: Ensure to be loaded last

Posted:
Fri Jun 19, 2015 07:47
by rubenwardy
minetest.after is not a solution to this problem if you need to register craft recipes or items.
Why would this not work?
Your phone or window isn't wide enough to display the code box. If it's a phone, try rotating it to landscape mode.
- Code: Select all
minetest.register_craft({
output = "mymod:item",
recipe = {
{"group:ore"}
}
})
for name, data in pairs(minetest.registered_items) do
if name:find("ore") >= 0 then
local g = {}
if data.groups then
for k, v in pairs(data.groups) do
g[k] = v
end
end
g.ore = 1
minetest.override_item(name, {groups = g})
end
end
local old_reg = minetest.register_item
function minetest.register_item(name, date)
if name:find("ore") >= 0 then
if data.groups then
local g = {}
for k, v in pairs(data.groups) do
g[k] = v
end
g.ore = 1
data.groups = g
else
data.groups = {ore = 1}
end
end
old_reg(name, data)
end
Re: Ensure to be loaded last

Posted:
Sat Jun 20, 2015 00:45
by SegFault22
A lot of that code will work for a lot of the things I'm making the mod to do. However, the code that reads the registered items list must only execute after other mods have registered their materials, because the items (ingots, lumps, nuggets, piles of dust or grains, crystals, etc.) have to be registered before they can be read from the list and interpreted by the list-reading function as materials, for which to add items/recipes and change item definitions to include groups (which would be used as reference in crafting or other processing recipes, such that different items made of an identical material can be used interchangeably). If there is no way (by the current api) to force a mod to load last, I can get around the problem by adding all known mods which add materials to the optional dependencies (so that the mod is loaded after those mods only if they are present) - however, if a user using the mod also uses a mod which adds materials, but such mod is not indexed in the list as adding materials, they will have to add the optional dependency (and possibly report it so that the mod id can be added to the optional dependencies).
Thank you for the sample of code, some of it is structured in a way that I haven't used yet - I see where it could be used to make the existing code for the mod more efficient, and introduces more options for making the rest of the code