What is really cool about this, is that if the Mod Name passed to the minetest.register_*() Function in the item/node/tool/whatever id, is gotten from a global Variable "modname", and another Mod (depending on the first Mod) sets the Value of the same global Variable to its own Mod Name, the item/whatever is registered with the Mod Name of the second Mod! Here's some Code to define exactly (pretty much) how this is done, in the most simple Implementation:
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
-- First Mod
modname = "test"
test = {}
function test.create_item(number)
minetest.register_craftitem(modname..":testitem_"..number, {
description = "Test Item",
inventory_image = modname.."_testitem.png",
})
end
do
test.create_item(1)
end
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
-- Second Mod
modname = "testext"
do
test.create_item(2)
end
Note that the second Mod depends on the first Mod, in order for this to work.
When the first Mod runs, it first sets its "modid" global Variable to "test" and creates its global Mod Stuff Table. Then, it creates a Function "test.create_item()" wrapping the minetest.register_craftitem() Function, taking a single Variable "number" which is concatenated to the end of the id String. Finally, it invokes the Function it just created, passing the Number "1" as the Parameter, which registers an Item with the id "test:testitem_1".
When the second Mod runs, it sets the "modid" global Variable to "testext" (means "test extended"), and calls the Function "test.create_item()" passing the Number "2" as the Parameter. This registers an Item with the id "testext:testitem_2".
This means that anyone can create a Mod which does some really cool magic Tricks with the register Functions, by wrapping said Functions inside other Functions, which use their Parameters to calculate the Parameters passed to the wrapped register Functions - this is useful to control many registry Entries from one Variable (change the digging Times, total Uses, Level or whatever Parameters of several Tools, by a single Variable which is used to calculate said Parameters).
This also means that another Mod calling the wrapping Functions from the first Mod, if configured properly, will have all of its registered Stuff given its Mod Name, instead of the first Mod which created those Functions.
However, you cannot call those wrapping Functions from another Mod, and have them register Stuff with the Mod Name of the first Mod - if you try this, you get the wonderful "does not follow naming conventions" error and the game-world doesn't load.
The reason this works, is due to how Mods are loaded. I'm not totally sure, but it goes somewhat like this: The first Mod gets the Name of its init.lua File set as the valid "internal" Mod Name, which must be written as the Mod Name within all Item/Tool/whatever ids which are registered while that Mod is loading. When that Mod finishes loading, and Minetest moves on to loading the Mod which depends on it and uses its Functions, the valid "internal" Mod Name is set to the Name of its init.lua file (of course), and this applies to all registry Entries (except id-less Stuff such as crafting Recipes and whatnot), even those which are performed by Functions that were created by other Mods which have already loaded.
Before I realized this, I thought there could be a Problem, as I thought that all of the ids of Stuff registered by my Mod's wrapping Functions must include the Mod Name of the mod which created those Functions, since they are part of Files within the Folder of that Mod, which are loaded by the Mod's init.lua File. This would be extremely bad, since it would require that all Textures for registered Items be put into the same Textures Folder, belonging to the first Mod which creates the wrapping Functions - if another Mod tries to supply its own Textures for any Stuff registered via the first Mod's Functions, they will not be used, and the Stuff would get those beautiful randomly-generated placeholder Textures instead.
I was thinking that I would have to totally redesign my Mod, with it becoming something very complicated in order to register Stuff with the right Mod Name - but now I know that it is very simple and straightforward, and the work I have to do to make my Mod work properly is much less that what it would be if the System didn't work this way. Now that I think about it, it should have been obvious that it would work this way - but I was not sure because the Functions were created within that first Mod, and I thought the Mod Name "context" would be preserved somehow.
However, after trying this simple test, I have found that is not what happens, and I don't have to worry about this problem. I just have to create a global Variable "modname" or something like that, which is used by all of the wrapping Functions that need to compute the id for different Stuff, and put some information in the Mod's API "Manual" to tell Developers that they must set this global Variable to the proper Name of their Mod, in order for their Stuff to be registered properly.
I will not have to totally redesign my Mod, and it will be released sometime soon, after I finish some other simple Stuff - such as Ore Nodes for Types of Stone which have a different top/bottom Texture (slate or gneiss Ores - imagine that it becomes a little bit more difficult to find Ores in Gneiss, because the "banded vein" Textures only appear along the Foliations or "Layers" at the sides, and not on the Top which is a single flat Foliation/Layer), Tools, crafting Recipes (integrated with the Crafter mod, to allow creating different processing Types than the standard ones), Ore Generation with many available Patterns (most of the built-in ones except for "vein", and maybe a few custom ones), maybe work on the Groups System some more so that it is easier to assign Dig Groups and Dig Group Times, make very many pretty Textures for all of the default Stuff (Stuff which is added by my Mod by default, not Stuff which is added by the mod Default), then make a couple of simple Mods as Examples of how to use it to do cool Stuff, and finally release it to everyone.