Difference between revisions of "Guide: Optional dependencies"

From Minetest Developer Wiki
Jump to navigation Jump to search
m
(rename Minetest to Luanti)
 
(3 intermediate revisions by 3 users not shown)
Line 1: Line 1:
 +
{{LuaTips}}
 
== Introduction ==
 
== Introduction ==
Managing and declaring dependencies are a core part of modding for Minetest. However, sometimes it is more desireable to write mod code which is only ''optionally'' dependent on another mod, not mandatorily, epspecially if only a small part of the actual code is actually dependent on the other mod. One example are crafting recipes; often, they are not that important, since the core part of a mod, namely, the registered items, can still function without them.
+
Managing and declaring dependencies are a core part of modding for Luanti. However, sometimes it is more desireable to write mod code which is only ''optionally'' dependent on another mod, not mandatorily, epspecially if only a small part of the actual code is actually dependent on the other mod. One example are crafting recipes; often, they are not that important, since the core part of a mod, namely, the registered items, can still function without them.
  
 
This short guide describes how to convert any mandatory dependency to an optional one and briefly discusses this technique.
 
This short guide describes how to convert any mandatory dependency to an optional one and briefly discusses this technique.
Line 9: Line 10:
 
One way to make a dependency optional is to insert the code which causes the mandatory dependency into a simple <code>if</code> block and optionally insert fallback code into the <code>branch</code>
 
One way to make a dependency optional is to insert the code which causes the mandatory dependency into a simple <code>if</code> block and optionally insert fallback code into the <code>branch</code>
  
With [[minetest.get_modpath]] is can be checked whether a mod is present, it will return nil if the mod is not present.
+
With <code>core.get_modpath</code> it can be checked whether a mod is present and loaded, as it will return nil if not.
<source>
+
 
if(minetest.get_modpath("example")) ~= nil then
+
<pre>
 +
if core.get_modpath("example") then
 
--[[ Insert code which depends on the example mod here ]]
 
--[[ Insert code which depends on the example mod here ]]
 
else
 
else
Line 17: Line 19:
 
    If you intend no fallback, you can leave this section empty. ]]
 
    If you intend no fallback, you can leave this section empty. ]]
 
end
 
end
</source>
+
</pre>
  
Additionally, the file [[depends.txt]] needs to be adjusted accordingly; it must contain the line “<code>example?</code>” instead of “<code>example</code>.
+
In addition, you need to add the depending mod into your mod's optional dependencies list in <code>mod.conf</code>.
  
 
=== Examples ===
 
=== Examples ===
 
The following example code has a mandatory dependency on the default mod, because the crafting recipe requires items from the default mod:
 
The following example code has a mandatory dependency on the default mod, because the crafting recipe requires items from the default mod:
<source>
+
 
minetest.register_craft({
+
<pre>
 +
core.register_craft({
 
output = "example:awesome_item",
 
output = "example:awesome_item",
 
recipe = {
 
recipe = {
Line 31: Line 34:
 
}
 
}
 
})
 
})
</source>
+
</pre>
  
 
By putting above code into the template, we get the following code, which is now ''optionally'' dependent on the default mod.
 
By putting above code into the template, we get the following code, which is now ''optionally'' dependent on the default mod.
<source>
+
 
if(minetest.get_modpath("default")) ~= nil then
+
<pre>
minetest.register_craft({
+
if core.get_modpath("default") then
 +
core.register_craft({
 
output = "example:awesome_item",
 
output = "example:awesome_item",
 
recipe = {
 
recipe = {
Line 44: Line 48:
 
})
 
})
 
end
 
end
</source>
+
</pre>
  
 
Note that the <code>else</code> has been left out because we don't intend to use any fallback option here.
 
Note that the <code>else</code> has been left out because we don't intend to use any fallback option here.
Line 52: Line 56:
  
 
In theory, all dependencies can be made optional using this technique. But sometimes, it more practical to keep a mandatory dependency, especially if large portions of code are dependent on another mod and writing a fallback option would be unreasonable.
 
In theory, all dependencies can be made optional using this technique. But sometimes, it more practical to keep a mandatory dependency, especially if large portions of code are dependent on another mod and writing a fallback option would be unreasonable.
 
If your almost your entire mod code is dependent on another code, writing a fallback option would likely be highly redundant, so you should keep the dependency optional.
 
[[Category:Rules and Guidelines]]
 

Latest revision as of 17:14, 28 October 2024

Mbox information.png This page contains community-written advice, tips, tricks or recommendations about modding. Your mileage may vary.

Introduction

Managing and declaring dependencies are a core part of modding for Luanti. However, sometimes it is more desireable to write mod code which is only optionally dependent on another mod, not mandatorily, epspecially if only a small part of the actual code is actually dependent on the other mod. One example are crafting recipes; often, they are not that important, since the core part of a mod, namely, the registered items, can still function without them.

This short guide describes how to convert any mandatory dependency to an optional one and briefly discusses this technique.

The “standard” technique

One way to make a dependency optional is to insert the code which causes the mandatory dependency into a simple if block and optionally insert fallback code into the branch

With core.get_modpath it can be checked whether a mod is present and loaded, as it will return nil if not.

if core.get_modpath("example") then
	--[[ Insert code which depends on the example mod here ]]
else
	--[[ Optionally insert fallback code here when the mod is not available.
	     If you intend no fallback, you can leave this section empty. ]]
end

In addition, you need to add the depending mod into your mod's optional dependencies list in mod.conf.

Examples

The following example code has a mandatory dependency on the default mod, because the crafting recipe requires items from the default mod:

core.register_craft({
	output = "example:awesome_item",
	recipe = {
		{ "default:wood", "default:stone", "default:mese" },
		{ "", "default:wood", "" },
	}
})

By putting above code into the template, we get the following code, which is now optionally dependent on the default mod.

if core.get_modpath("default") then
	core.register_craft({
		output = "example:awesome_item",
		recipe = {
			{ "default:wood", "default:stone", "default:mese" },
			{ "", "default:wood", "" },
		}
	})
end

Note that the else has been left out because we don't intend to use any fallback option here.

Discussion

This technique is useful when you have small and simple chunks of code causing a mandatory dependency. This technique is especially useful for crafting recipes, as they are often not that neccessary; other mods may be more interested in the registered items and may even register their own crafting recipes.

In theory, all dependencies can be made optional using this technique. But sometimes, it more practical to keep a mandatory dependency, especially if large portions of code are dependent on another mod and writing a fallback option would be unreasonable.