[abandoned] [Mod] Mod Configuration & Settings Reader [modconf]

Post Reply
User avatar
AntumDeluge
Member
Posts: 213
Joined: Sun Aug 07, 2016 05:42
GitHub: AntumDeluge
IRC: AntumDeluge
Contact:

[abandoned] [Mod] Mod Configuration & Settings Reader [modconf]

by AntumDeluge » Post

Abandoned

Description:

A mod that reads settings from mod.conf.

NOTE: This mod is a work-in-progress but is functional. Currently, in order to use modconf.getModMetaData, key-value instances in mod.conf must be delimited by an equals symbol with one whitespace on both sides (e.g. " = "). In the future, trimming out whitespace will be done automatically.

Usage:

Global Functions:
  • modconf.getModMetaData
    • Adds fields from mod.conf to a table object.
    • Usage: modconf.getModMetaData(object)
    • Parameters:
      • object: (optional if saving returned value) The object table of which to append fields read from mod.conf file.
    • Returns: Table object containing fields read from mod.conf file.
    • Aliases:
      • core.get_mod_metadata
      • minetest.get_mod_metadata
  • modconf.getModDefaults
    • Reads default settings from local settingtypes.txt file.
    • Usage: modconf.getModDefaults(object)
    • Parameters:
      • object: (optional if saving returned value) The object table of which to append fields read from settingtypes.txt file.
    • Returns: Table object containing fields read from settingtypes.txt file.
    • Aliases:
      • core.get_mod_defaults
      • minetest.get_mod_defaults
Example usage:

depends.txt:

Code: Select all

modconf?
init.lua (using core object function provided by modconf):

Code: Select all

-- Main global object table
mymod = {}

-- Create settings object from core function
if minetest.global_exists('modconf') or minetest.get_modpath('modconf') then
	mymod.settings = minetest.get_mod_metadata()
end

mymod.name = mymod.settings:get('name')
mymod.version = mymod.settings:get('version')

minetest.log('action', 'Loading ' .. mymod.name .. ' version ' .. mymod.version)
init.lua (using modconf.getModMetaData):

Code: Select all

-- Main global object table
mymod = {}

-- Read fields into table from 'mod.conf'
if minetest.global_exists('modconf') then
    modconf.getModMetaData(mymod)
end

minetest.log('action', 'Loading ' .. mymod.name .. ' version ' .. mymod.version)
init.lua (reading settingtypes.txt file):

Code: Select all

-- Table object to read fields into
local defaults = {}

-- Read fields into table from 'settingtypes.txt'
if minetest.get_modpath('modconf') then
    modconf.getModDefaults(defaults)
end

-- Alternatively can be called thus:
local defaults = modconf.getModDefaults()
Lisensing:
Links:
Releases:
Last edited by AntumDeluge on Mon Jul 05, 2021 00:02, edited 13 times in total.

User avatar
rubenwardy
Moderator
Posts: 6978
Joined: Tue Jun 12, 2012 18:11
GitHub: rubenwardy
IRC: rubenwardy
In-game: rubenwardy
Location: Bristol, United Kingdom
Contact:

Re: [Mod] Mod Configuration Reader [0.1] [modconf]

by rubenwardy » Post

Minetest already has this using the Settings api. https://github.com/minetest/minetest/bl ... .txt#L3754

Code: Select all

local settings = Settings(minetest.get_modpath("mymod") .. "/mod.conf")
print(settings:get("name"))  -->  the name field in mod.conf

-- equiv to your mod
for key, value in pairs(settings:to_table()) do
    mymod[key] = value
end
print(mymod.name)  --> also the name field in mod.conf
Renewed Tab (my browser add-on) | Donate | Mods | Minetest Modding Book

Hello profile reader

User avatar
AntumDeluge
Member
Posts: 213
Joined: Sun Aug 07, 2016 05:42
GitHub: AntumDeluge
IRC: AntumDeluge
Contact:

Re: [Mod] Mod Configuration Reader [0.1] [modconf]

by AntumDeluge » Post

Nice! Thank you rubenwardy. And I see you have it documented in your modding book.

I still feel like this mod adds some functionality. It does automate locating the local mod.conf file. Would be nice were that added to the core as well. Something like:

Code: Select all

local settings = minetest.get_local_settings()
or:

Code: Select all

local settings = minetest.get_mod_settings()
It also adds all fields to a pre-created object. Though this, I suppose would potentially be more resource heavy as it could end up requiring more memory than only extracting the settings that you want.

For now, I want to keep this mod up, but modify it to use the minetest.settings object, as I think it is simpler than writing out:

Code: Select all

local settings = Settings(minetest.get_modpath(minetest.get_current_modname()) .. '/mod.conf')
Again, thank you for the modding book. It is very helpful. Do you use a doc generator, like LDoc or Doxygen for it?

User avatar
Linuxdirk
Member
Posts: 3219
Joined: Wed Sep 17, 2014 11:21
In-game: Linuxdirk
Location: Germany
Contact:

Re: [Mod] Mod Configuration Reader [0.1] [modconf]

by Linuxdirk » Post

What's the advantage of the relatively static and not update-reliable mod.conf (are users even supposed to modify this file?) over the flexible and update-safe settingtypes.txt?

User avatar
Beerholder
Member
Posts: 199
Joined: Wed Aug 03, 2016 20:23
GitHub: evrooije
In-game: Beerholder

Re: [Mod] Mod Configuration Reader [0.1] [modconf]

by Beerholder » Post

settingtypes.txt is just weird. It implies that it is a text document, like api.txt, containing the types of settings you can specify (at least, that was my first reaction when I first saw the file name).

settingstypes.txt should be changed to mod.conf, as mod.conf actually implies that it is a configuration file, that it is for the mod, in line with the naming convention for e.g. minetest.conf and many many other UX configuration file names. At the moment mod.conf is a useless file that only contains the mod name and I see plenty of mods that don't even bother supplying one (so ... what's the use ...)

As far as safety is concerned, all the engine does is this:

Code: Select all

Settings info;
info.readConfigFile((spec.path+DIR_DELIM+"mod.conf").c_str());
if (info.exists("name"))
    spec.name = info.get("name");
After this, info is not used anymore. So pretty safe, but this could of course change in the unlikely event the devs decide to add functionality or start doing all kinds of other things with the mod.conf file.

Pretty sure this has come up before ;-) In any case the issues with settingtypes.txt are cosmetic and otherwise it works fine with the advantage of supplying mod settings in the menu. This mod might steal the hearts of those whose code is running in a server only environment where the menu is not important, and want to better organize the configuration options inside the mod directories instead of the global config.

Choice is good, right? :-)

User avatar
Linuxdirk
Member
Posts: 3219
Joined: Wed Sep 17, 2014 11:21
In-game: Linuxdirk
Location: Germany
Contact:

Re: [Mod] Mod Configuration Reader [0.1] [modconf]

by Linuxdirk » Post

Beerholder wrote:settingtypes.txt is just weird. It implies that it is a text document, like api.txt, containing the types of settings you can specify (at least, that was my first reaction when I first saw the file name).
Like mod.conf implying to be a configuration file but being a simple key-value storage. Or modpack.txt being a file containing text but only being used as flag-file for indicating a modpack.
Beerholder wrote:In any case the issues with settingtypes.txt are cosmetic and otherwise it works fine with the advantage of supplying mod settings in the menu.
Plus: You don't need to establish an own configuration interface and you can safely update the mod without caring about modifications you made.
Beerholder wrote:This mod might steal the hearts of those whose code is running in a server only environment where the menu is not important, and want to better organize the configuration options inside the mod directories instead of the global config.
Sorry, but no. Just no. User configuration and program logic should never ever be mixed. Never. Ever.

User avatar
rubenwardy
Moderator
Posts: 6978
Joined: Tue Jun 12, 2012 18:11
GitHub: rubenwardy
IRC: rubenwardy
In-game: rubenwardy
Location: Bristol, United Kingdom
Contact:

Re: [Mod] Mod Configuration Reader [0.1] [modconf]

by rubenwardy » Post

Settingtypes is documentation and is not meant to be used for saving settings. It's used to add entries to the advanced settings menu.

Mod.conf is intended to be used for mod metadata not settings, for example name, author, forum topic

Mod config files shouldn't be changed imo, but instead should use the main settings system. Until we have world specific minetest.conf, it's worth adding a work around as well to add that.
Renewed Tab (my browser add-on) | Donate | Mods | Minetest Modding Book

Hello profile reader

User avatar
AntumDeluge
Member
Posts: 213
Joined: Sun Aug 07, 2016 05:42
GitHub: AntumDeluge
IRC: AntumDeluge
Contact:

Re: [Mod] Mod Configuration Reader [0.1] [modconf]

by AntumDeluge » Post

rubenwardy wrote:Settingtypes is documentation and is not meant to be used for saving settings. It's used to add entries to the advanced settings menu.
As I understand it, settingtypes.txt currently only works from the game root directory. Am I correct? I add a settingtypes.txt file to my mods to make it easy to copy the info over to the one located in game dir.
rubenwardy wrote:Mod config files shouldn't be changed imo, but instead should use the main settings system.
I agree, 100%.
Beerholder wrote:Choice is good, right? :-)
That's how I see things. And, free as in Beerholder. ;-)

User avatar
AntumDeluge
Member
Posts: 213
Joined: Sun Aug 07, 2016 05:42
GitHub: AntumDeluge
IRC: AntumDeluge
Contact:

Re: [Mod] Mod Configuration Reader [0.1] [modconf]

by AntumDeluge » Post

AntumDeluge wrote:Do you use a doc generator, like LDoc or Doxygen for it?
Sorry rubenwardy, I completely bypassed the introduction & missed this.

User avatar
Beerholder
Member
Posts: 199
Joined: Wed Aug 03, 2016 20:23
GitHub: evrooije
In-game: Beerholder

Re: [Mod] Mod Configuration Reader [0.1] [modconf]

by Beerholder » Post

Oh AntumDeluge you can rewrite the line key value parsing in api.lua line 43 with something like:

Code: Select all

local key, value = string.match(line, "(.*)[%s]*=[%s]*(.*)")
key = key:gsub("^%s*(.-)%s*$", "%1")
value = value:gsub("^%s*(.-)%s*$", "%1")
You can e.g. try this test case on https://www.lua.org/cgi-bin/demo:

Code: Select all

local key, value = string.match("     mykey     =     myvalue     ", "(.*)[%s]*=[%s]*(.*)")
key = key:gsub("^%s*(.-)%s*$", "%1")
value = value:gsub("^%s*(.-)%s*$", "%1")
print(key)
print(value)
key, value = string.match("mynumber=16", "(.*)[%s]*=[%s]*(.*)")
key = key:gsub("^%s*(.-)%s*$", "%1")
value = value:gsub("^%s*(.-)%s*$", "%1")
print(key)
print(value)
key, value = string.match("myvaluewithspaces= 99 bottles of beer on the wall", "(.*)[%s]*=[%s]*(.*)")
key = key:gsub("^%s*(.-)%s*$", "%1")
value = value:gsub("^%s*(.-)%s*$", "%1")
print(key)
print(value)
It looks terrible, I know (I hate those one pattern matching strings XD), but does the job of white space stripping and populating the variables correctly;-)

EDIT: Whelp ... My original failed on values with spaces ... Updated to something that works, guess I am not that good at one liners (FAIL!! ;-))>

User avatar
Linuxdirk
Member
Posts: 3219
Joined: Wed Sep 17, 2014 11:21
In-game: Linuxdirk
Location: Germany
Contact:

Re: [Mod] Mod Configuration Reader [0.1] [modconf]

by Linuxdirk » Post

rubenwardy wrote:Settingtypes is documentation and is not meant to be used for saving settings.
So you say, the settingtypes file where you configure settings that can be set by the user is not for settings? Makes total sense :D
AntumDeluge wrote:As I understand it, settingtypes.txt currently only works from the game root directory.
No, you can use it for games, modpacks, and mods in modpacks, too.
rubenwardy wrote:Mod config files shouldn't be changed imo, but instead should use the main settings system.
Like settingtypes.txt providing the options in a central location and changes will be stored in the "main settings system" (that is minetest.conf in the user-related directory).
Beerholder wrote:you can rewrite the line key value parsing in api.lua line 43 [...] It looks terrible, I know (I hate those one pattern matching strings XD), but does the job of white space stripping and populating the variables correctly;-)
Because local foobar = minetest.setting_get('foobar') or 'my default value' is too mainstream, huh? :D

User avatar
karamel
Member
Posts: 56
Joined: Wed Jul 19, 2017 21:51
Contact:

Re: [Mod] Mod Configuration Reader [0.1] [modconf]

by karamel » Post

There are a few things that may miss from settingtypes in the current version. Just for autopromotion you can look a little discussion about mod configuration here: viewtopic.php?f=47&t=18150

First I was planning to do something about mod configurations. I'm glad someone made it so there are discussions before maybe redoing it in the core once most of the issues are solved.

Default values

I haven't seen your mod defining default values. That would be quite usefull. Linuxdirk has already provided a little code snippet to automatically load settingtypes.txt in a mod viewtopic.php?p=285505#p285505 to get that default value.

The main issue I have now is that I have a duplication between settingtypes.txt and getting the values one by one (I was to lazy to update my code) and that lead to some bugs when they weren't matching. That is: the default value is shown in settingtypes.txt and my code used an other default value (it's a PEBKAC). That wouldn't have happened by reading the default value automatically.

But that's not enough. In my mods, the default values requires sometime an other mod from the optional dependencies (because if the mod is activated that would be what's expected, but if it's incompatible). So it may have to handle a default function to check a few cases. This only for not spreading that check and probably introduce human mistakes.

Instance dependent config

With your mod, a mod is configured by itself. What about a server running multiple games with that same mod activated but with a different configuration? Or just across multiple worlds. You can do it when the options are provided in minetest.conf simply by loading a different config for each running instance. Not perfect from end-user side because there's currently no way to switch from a minetest.conf to an other from the GUI, but it does the trick on server side.

Update

By putting settings in mod.conf, it will be erased at every mod update. When updating a mod on my server, I simply delete the mod and unzip the new version. If I updated from git this file would create merge conflicts.

But for some metadata that are not meant to be modified, that's great.

Settingtypes VS mod.conf

If I read correctly the debate is just about merging settingtypes.txt in mod.conf, right? Both files aren't meant to be edited.

And I may have misread the topic. This mod is about adding a new configuration that can be tweaked or just a access to a static mod.conf to define some constants? The name "configuration" is rather misleading, it may be configuration for the user (to edit usage) or configuration for the modder (to configure the mod for the engine).

User avatar
Linuxdirk
Member
Posts: 3219
Joined: Wed Sep 17, 2014 11:21
In-game: Linuxdirk
Location: Germany
Contact:

Re: [Mod] Mod Configuration Reader [0.1] [modconf]

by Linuxdirk » Post

karamel wrote:I haven't seen your mod defining default values. That would be quite usefull. Linuxdirk has already provided a little code snippet to automatically load settingtypes.txt in a mod viewtopic.php?p=285505#p285505 to get that default value.
Please always see that as workaround for missing functionality. minetest.get_setting('foobar') should either return the user-set foobar value from minetest.conf or the value defined in one of the parsed settingtypes.txt values. If there are only a few values to define local foobar = minetest.get_setting('foobar') or 'default value' would be the easier variant. You need to define the default value in settingtypes.txt and the code, but for just a few values this would be easier then implementing a parsing/wrapper function getting the values for you.
karamel wrote:By putting settings in mod.conf, it will be erased at every mod update.
Either this or you need to create your own local branch of the mod and merge the updates from upstream. No-one wants that just for configuration. Thus strictly separating user-settable values and default values and/or code is a MUST.

User avatar
AntumDeluge
Member
Posts: 213
Joined: Sun Aug 07, 2016 05:42
GitHub: AntumDeluge
IRC: AntumDeluge
Contact:

Re: [Mod] Mod Configuration Reader [0.1] [modconf]

by AntumDeluge » Post

Linuxdirk wrote:
AntumDeluge wrote:As I understand it, settingtypes.txt currently only works from the game root directory.
No, you can use it for games, modpacks, and mods in modpacks, too.
Sorry, I was thinking in terms of games only. Nested settingtypes.txt files within the mods folder of a game are not recognized by the client as I understand it.
karamel wrote:I haven't seen your mod defining default values. That would be quite usefull.
It's funny you should mention that. I was just thinking about it today after editing some settingtypes.txt files. Parsing the settingtypes.txt file for setting default values in the code seems like a good idea.
karamel wrote:And I may have misread the topic. This mod is about adding a new configuration that can be tweaked or just a access to a static mod.conf to define some constants? The name "configuration" is rather misleading, it may be configuration for the user (to edit usage) or configuration for the modder (to configure the mod for the engine).
You bring up a good point. The original intent of the mod was to only read static meta data from mod.conf. It wasn't intended to override settings from minetest.conf & the mod.conf file should not be used as a settings file. And you are right. The name configuration is misleading & perhaps the mod needs a rename. I assumed the name configuration from the suffix conf.


--- Edit ---

Also, I'm not sure if this was clear, but this mod does not override settings from minetest.conf. It uses separate functions for reading the local mod.conf. As rubenwardy said, the data contained in mod.conf should be static.

The modconf.readConfig function takes an object & adds fields to it retrieved from mod.conf. As I understand it, Lua has no keyword like C++'s const, so there is no way to make these fields immutable (please correct me if I am wrong).

The other function, minetest.get_mod_settings, is designed to work like the familiar minetest.settings object, but not as a replacement. I can see how this could lead to confusion.

User avatar
AntumDeluge
Member
Posts: 213
Joined: Sun Aug 07, 2016 05:42
GitHub: AntumDeluge
IRC: AntumDeluge
Contact:

Re: [Mod] Mod Configuration Reader [0.1] [modconf]

by AntumDeluge » Post

I personally like the functionality of the modconf.readConfig function for these instances. I would love to see something in the core that would do the same:

Code: Select all

local modconf = minetest.get_modconf()
I was actually planning on attempting this myself. But, we will see.

User avatar
Linuxdirk
Member
Posts: 3219
Joined: Wed Sep 17, 2014 11:21
In-game: Linuxdirk
Location: Germany
Contact:

Re: [Mod] Mod Configuration Reader [0.1] [modconf]

by Linuxdirk » Post

AntumDeluge wrote:Sorry, I was thinking in terms of games only. Nested settingtypes.txt files within the mods folder of a game are not recognized by the client as I understand it.
Can't check right now but in the advanced configuration there is a "Games" section. So you can at least use it for games. Didn't try for mods in games though. But I know for sure that it works for mods and modpacks and games in general.
AntumDeluge wrote:Parsing the settingtypes.txt file for setting default values in the code seems like a good idea.
And it's super easy. Just load the file and iterate over the lines and do this for each line within your iteration loop:

Code: Select all

if line:match('^([a-zA-Z])') then
    local name = line:gsub(' .+', '')
    local value = line:gsub('^[^ ]+ %b() %a+ ', '')
    if value == line then value = '' end
    -- do whatever you want with that now
end
Now you have name and value (or an empty string if the value was not set in settingtypes.txt) as local variables name and value.

User avatar
AntumDeluge
Member
Posts: 213
Joined: Sun Aug 07, 2016 05:42
GitHub: AntumDeluge
IRC: AntumDeluge
Contact:

Re: [Mod] Mod Configuration Reader [0.1] [modconf]

by AntumDeluge » Post

Thank you Linuxdirk, I just did something like this. But I will have a look over your suggestion later (it is probably better).

Added functions core.get_mod_defaults & minetest.get_mod_defaults:

modconf @ Git commit db40d6c

User avatar
Beerholder
Member
Posts: 199
Joined: Wed Aug 03, 2016 20:23
GitHub: evrooije
In-game: Beerholder

Re: [Mod] Mod Configuration Reader [0.1] [modconf]

by Beerholder » Post

AntumDeluge wrote: The modconf.readConfig function takes an object & adds fields to it retrieved from mod.conf. As I understand it, Lua has no keyword like C++'s const, so there is no way to make these fields immutable (please correct me if I am wrong).
So looking at the code, object is a table and you want the table to be immutable (no changes to values or adding/ deleting elements)... If so, you may want to create a function which wraps your table object with a proxy before returning it. Have a look at this snippet for example:

Code: Select all

local function immutable(object)
  local mt = {}
  function mt.__index(proxy,k)
    return object[k]
  end
  function mt.__newindex(proxy,k,v)
    print("object is constant")
  end
  local tc = setmetatable({}, mt)
  return tc
end

-- Test cases

local a = {}
a["key1"] = "Old Value" -- Direct change works
a["key2"] = "Some other value" -- Direct change works

local b = immutable(a) -- b is proxied and immutable

b["key1"] = "New Value" -- Change value, fails
print(b["key1"]) -- Still "Old Value"

b["key2"] = nil -- Delete element, fails
print(b["key2"]) -- Still "Some other value"

b["key3"] = "Extra value" -- Add element, fails
print(b["key3"]) -- nil
So where you do "return object" in readConfig, just do "return immutable(object)" and you can no longer make changes to the table. This is (sort of) how you can make (certain things) immutable in Lua.

Make sure you know what you want to do if someone tries to change it. You can print a warning or an error using minetest.log and be safe in the knowledge that the table had not changed, or you may want to "punish the perpetrator" by exiting (as something like changing your object is under no circumstances allowed to happen anyways).

User avatar
AntumDeluge
Member
Posts: 213
Joined: Sun Aug 07, 2016 05:42
GitHub: AntumDeluge
IRC: AntumDeluge
Contact:

Re: [Mod] Mod Configuration Reader [0.1] [modconf]

by AntumDeluge » Post

Linuxdirk wrote:Just load the file and iterate over the lines and do this for each line within your iteration loop:

Code: Select all

if line:match('^([a-zA-Z])') then
    local name = line:gsub(' .+', '')
    local value = line:gsub('^[^ ]+ %b() %a+ ', '')
    if value == line then value = '' end
    -- do whatever you want with that now
end
Now you have name and value (or an empty string if the value was not set in settingtypes.txt) as local variables name and value.
Thanks. I will try this out.

User avatar
AntumDeluge
Member
Posts: 213
Joined: Sun Aug 07, 2016 05:42
GitHub: AntumDeluge
IRC: AntumDeluge
Contact:

Re: [Mod] Mod Configuration Reader [0.1] [modconf]

by AntumDeluge » Post

Beerholder wrote:

Code: Select all

local function immutable(object)
  local mt = {}
  function mt.__index(proxy,k)
    return object[k]
  end
  function mt.__newindex(proxy,k,v)
    print("object is constant")
  end
  local tc = setmetatable({}, mt)
  return tc
end

-- Test cases

local a = {}
a["key1"] = "Old Value" -- Direct change works
a["key2"] = "Some other value" -- Direct change works

local b = immutable(a) -- b is proxied and immutable

b["key1"] = "New Value" -- Change value, fails
print(b["key1"]) -- Still "Old Value"

b["key2"] = nil -- Delete element, fails
print(b["key2"]) -- Still "Some other value"

b["key3"] = "Extra value" -- Add element, fails
print(b["key3"]) -- nil
Thank you Beerholder. If I decide to & make objects immutable, I will definitely try this.

User avatar
AntumDeluge
Member
Posts: 213
Joined: Sun Aug 07, 2016 05:42
GitHub: AntumDeluge
IRC: AntumDeluge
Contact:

Re: [Mod] Mod Configuration Reader [0.1] [modconf]

by AntumDeluge » Post

I have this section in my getModDefaults function (which I just realized is wrong):

Code: Select all

-- FIXME: How to convert to float (math.tofloat(string)?)
if k_type == 'int' then
	-- Convert integers
	value = tonumber(value)
elseif k_type == 'bool' then
	-- Convert booleans
	if value == 'true' then
		value = true
	else
		value = false
	end
end
Is there a reliable way to convert a string to boolean?

Code: Select all

if string.find(value, '.') then
    local float_list = {}
    for i, num in ipairs(string.split(value, '.')) do
        table.insert(float_list, tonumber(num))
    end
    
    if #float_list > 1 then
        value = float_list[1].float_list[2]
    end
end
Is Minetest configured for Lua to work with floating point numbers?

User avatar
rubenwardy
Moderator
Posts: 6978
Joined: Tue Jun 12, 2012 18:11
GitHub: rubenwardy
IRC: rubenwardy
In-game: rubenwardy
Location: Bristol, United Kingdom
Contact:

Re: [Mod] Mod Configuration & Settings Reader [0.1] [modconf

by rubenwardy » Post

minetest.is_yes(str)
Renewed Tab (my browser add-on) | Donate | Mods | Minetest Modding Book

Hello profile reader

User avatar
AntumDeluge
Member
Posts: 213
Joined: Sun Aug 07, 2016 05:42
GitHub: AntumDeluge
IRC: AntumDeluge
Contact:

Re: [Mod] Mod Configuration & Settings Reader [0.1] [modconf

by AntumDeluge » Post

rubenwardy wrote:minetest.is_yes(str)
Thank you rubenwardy. I will use that.


--- Edit ---

modconf @ Git commit 314c6d7

Post Reply

Who is online

Users browsing this forum: No registered users and 37 guests