Cheeseball c34df03233 add character_anim | 1 year ago | |
---|---|---|
.. | ||
build | 1 year ago | |
minetest | 1 year ago | |
persistence | 1 year ago | |
web | 1 year ago | |
.gitignore | 1 year ago | |
License.txt | 1 year ago | |
Readme.md | 1 year ago | |
b3d.lua | 1 year ago | |
b3d_specification.txt | 1 year ago | |
binary.lua | 1 year ago | |
bluon.lua | 1 year ago | |
file.lua | 1 year ago | |
func.lua | 1 year ago | |
hashheap.lua | 1 year ago | |
hashlist.lua | 1 year ago | |
heap.lua | 1 year ago | |
init.lua | 1 year ago | |
json.lua | 1 year ago | |
kdtree.lua | 1 year ago | |
logo.svg | 1 year ago | |
luon.lua | 1 year ago | |
math.lua | 1 year ago | |
minetest.lua | 1 year ago | |
mod.conf | 1 year ago | |
persistence.lua | 1 year ago | |
quaternion.lua | 1 year ago | |
ranked_set.lua | 1 year ago | |
schema.lua | 1 year ago | |
screenshot.png | 1 year ago | |
table.lua | 1 year ago | |
text.lua | 1 year ago | |
trie.lua | 1 year ago | |
vector.lua | 1 year ago | |
web.lua | 1 year ago |
modlib
)Multipurpose Minetest Modding Library
No dependencies. Licensed under the MIT License. Written by Lars Mueller aka LMD or appguru(eu). Notable contributions by luk3yx in the form of suggestions, bug reports and fixes.
The tests are located in a different repo, modlib_test
, as they are quite heavy due to testing the PNG reader using PngSuite. Reading the tests for examples of API usage is recommended.
Mostly self-documenting code. Mod namespace is modlib
, containing all variables & functions.
A data log file based on Lua statements. Experimental. High performance. Example from test.lua
:
local logfile = persistence.lua_log_file.new(mod.get_resource"logfile.test.lua", {})
logfile:init()
logfile.root = {}
logfile:rewrite()
logfile:set_root({a = 1}, {b = 2, c = 3})
logfile:close()
logfile:init()
assert(table.equals(logfile.root, {[{a = 1}] = {b = 2, c = 3}}))
Both strings and tables are stored in a reference table. Unused strings won't be garbage collected as Lua doesn't allow marking them as weak references.
This means that setting lots of temporary strings will waste memory until you call :rewrite()
on the log file. An alternative is to set the third parameter, reference_strings
, to false
(default value is true
):
persistence.lua_log_file.new(mod.get_resource"logfile.test.lua", {}, false)
This will prevent strings from being referenced, possibly bloating file size, but saving memory.
Uses a SQLite3 database to persistently store a Lua table. Experimental. Obtaining it is a bit trickier, as it requires access to the lsqlite3
library, which may be passed:
local modlib_sqlite3 = persistence.sqlite3(require"lsqlite3")
(assuming require
is that of an insecure environment if Minetest is used)
Alternatively, if you are not running Minetest, mod security is disabled, you have (temporarily) provided require
globally, or added modlib
to secure.trusted_mods
, you can simply do the following:
local modlib_sqlite3 = persistence.sqlite3()
Modlib will then simply call require"lsqlite3"
for you.
Then, you can proceed to create a new database:
local database = persistence.modlib_sqlite3.new(mod.get_resource"database.test.sqlite3", {})
-- Create or load
database:init()
-- Use it
database:set_root("key", {nested = true})
database:close()
It uses a similar API to Lua log files:
new(filename, root)
- without reference_strings
however (strings aren't referenced currently)init
set
set_root
rewrite
close
The advantage over Lua log files is that the SQlite3 database keeps disk usage minimal. Unused tables are dropped from the database immediately through reference counting. The downside of this is that this, combined with the overhead of using SQLite3, of course takes time, making updates on the SQLite3 database slower than Lua log file updates (which just append to an append-only file).
As simple and fast reference counting doesn't handle cycles, an additional collectgarbage
stop-the-world method performing a full garbage collection on the database is provided which is called during init
.
The method defragment_ids
should not have to be used in practice (if it has to be, it happens automatically) and should be used solely for debugging purposes (neater IDs).
Binary Lua object notation. Experimental. Handling of subnormal numbers (very small floats) may be broken.
new(def)
def = {
aux_is_valid = function(object)
return is_valid
end,
aux_len = function(object)
return length_in_bytes
end,
-- read type byte, stream providing :read(count), map of references -> id
aux_read = function(type, stream, references)
... = stream:read(...)
return object
end,
-- object to be written, stream providing :write(text), list of references
aux_write = function(object, stream, references)
stream:write(...)
end
}
:is_valid(object)
Returns whether the given object can be represented by the instance as boolean.
:len(object)
Returns the expected length of the object if serialized by the current instance in bytes.
:write(object, stream)
Writes the object to a stream supporting :write(text)
. Throws an error if invalid.
:read(stream)
Reads a single bluon object from a stream supporting :read(count)
. Throws an error if invalid bluon.
Checking whether the stream has been fully consumed by doing assert(not stream:read(1))
is left up to the user.
nil
: nothing (""
)false
: 0true
: 1U8
, U16
, U32
, U64
, -U8
, -U16
, -U32
, -U64
F32
, F64
""
T8
, T16
, T32
, T64
L0
, L8
, L16
, L32
, L64
times M0
, M8
, M16
, M32
, M64
R8
, R16
, R32
, R64
local object = ...
-- Write to file
local file = io.open(..., "wb")
modlib.bluon:write(object, file)
file:close()
-- Write to text
local rope = modlib.table.rope{}
modlib.bluon:write(object, rope)
text = rope:to_text()
-- Read from text
local inputstream = modlib.text.inputstream"\1"
assert(modlib.bluon:read(object, rope) == true)
-- Serializes all userdata to a constant string:
local custom_bluon = bluon.new{
aux_is_valid = function(object)
return type(object) == "userdata"
end,
aux_len = function(object)
return 1 + ("userdata"):len())
end,
aux_read = function(type, stream, references)
assert(type == 100, "unsupported type")
assert(stream:read(("userdata"):len()) == "userdata")
return userdata()
end,
-- object to be written, stream providing :write(text), list of references
aux_write = function(object, stream, references)
assert(type(object) == "userdata")
stream:write"\100userdata"
end
}
-- Write to text
local rope = modlib.table.rope{}
custom_bluon:write(userdata(), rope)
assert(rope:to_text() == "\100userdata")
Place a file schema.lua
in your mod, returning a schema table.
minetest.conf
Suppose you have the following schema:
return {
type = "table",
entries = {
[42] = {
type = "boolean",
description = "The Answer"
default = true
}
}
}
And a user sets the following config:
mod.42 = false
It won't work, as the resulting table will be {["42"] = false}
instead of {[42] = false}
. In order to make this work, you have to convert the keys yourself:
return {
type = "table",
keys = {
-- this will convert all keys to numbers
type = "number"
},
entries = {
[42] = {
type = "boolean",
description = "The Answer"
default = true
}
}
}
This is best left explicit. First, you shouldn't be using numbered field keys if you want decent minetest.conf
support, and second, modlib
's schema module could only guess in this case, attempting conversion to number / boolean. What if both number and string field were set as possible entries? Should the string field be deleted? And so on.
<worldpath>/config/<modname>.<extension>
, the following extensions are supported and loaded (in the given order), with loaded configurations overriding properties of previous ones:
minetest.conf
and override configuration values<modfolder>/conf.lua
config/<modname>.<format>
<modfolder>/conf.<format>
minetest.conf
lua
field = value
worksluon
conf
json
variables(stacklevel)
Dumps local variables, upvalues and the function environment of the function at the given stacklevel (default 1
).
stack(stacklevel)
Dumps function info & variables for all functions in stack, starting with stacklevel (default 1
).
minetest
schematic
A schematic format with support for metadata and baked light data. Experimental.
Rolling releases (corresponding to releases on ContentDB) are made when either:
The following release notes are not exhaustive. Refer to the commit log for an exhaustive changelog.
rolling-98
binary.(read|write)_(float|single|double)
(and thus also bluon
number serialization)
write_float
now doesn't provide an "auto" mode anymore, use modlib.math.fround(x) == x
instead to determine whether x
fits in a floatdebug
module in favor of the dbg
modrolling-97
rolling-96
mod.configuration()
returns the conf, schema
nowbinary
: int & float writingrolling-9x
Many many fixes
rolling-8x
Fixes, minor additions (such as a hashheap
)
rolling-74
minetest
module. Note:
table.shuffle
was fixed (previously had an off-by-one error); small tables are now shuffled correctlyminetest
module was fixed (note that this crash was not included in the rolling-73
release)minetest
module:after
playerdata
, connected_players
& set_privs
utilitiesget_mod_info
& get_mod_load_order
, media
path gettingquaternion.from_euler_rotation
text.trim_spacing
json
modulemodlib.minetest.get_color_int
rolling-73
rolling-71
colorspec:from_string
colorspec:to_string
works nowluon
: Configurable serialization to and from Lua with circular and string reference supportminetest.luon
even supports ItemStack
and AreaStore
vector.rotate3
table.deep_foreach_any
func
:func.iterate
func.aggregate
rolling-70
rolling-69
rolling-68
rolling-67
kdtree
, trie
, ranked_set
, vector
, schema
rolling-66
modlib.persistence.lua_log_file
rolling-62
modlib.func.curry_tail
b3d:get_animated_bone_properties
to return a list according to hierarchyrolling-61
quaternion.to_euler_rotation
rolling-60
vector.interpolate
rolling-59
rolling-58
rolling-57
minetest.safe_file_write
for file.write
rolling-56
math.fround
_ = modlib.<module>
to avoid lag spikes at run time