diff --git a/mods/CORE/mcl_init/API.md b/mods/CORE/mcl_init/API.md
new file mode 100644
index 000000000..e30ea0793
--- /dev/null
+++ b/mods/CORE/mcl_init/API.md
@@ -0,0 +1,62 @@
+# mcl_init
+
+Initialization of VoxeLibre, in particular some shared variables and utility functions exposed via `mcl_vars`.
+
+## `get_node_name`
+
+This is an interim API while we still support Luanti versions that do not expose `core.get_node_raw`.
+We would like to use that function because it generates fewer Lua tables, and hence causes less garbage collection,
+yielding better performance. The current `get_node_name` API is a middle-ground that covers many use cases
+of that API, while having little overhead over the old `core.get_node`, nor the new `core.get_node_raw` API then.
+
+- `mcl_vars.get_node_name(pos)` returns the node *name*, param1 and param2 at position `pos`.
+
+- `mcl_vars.get_node_name_raw(x, y, z)` returns the node *name*, param1 and param2 at position (x,y,z).
+
+- `mcl_vars.get_node_raw(x, y, z)` returns the *content ID*, param1 and param2 at position (x,y,z).
+
+Which version to use:
+
+1. if you are working with content ids (integers), use `get_node_raw`.
+2. if you work with node names, and vectors, use `get_node_name`.
+3. if you work with node names and integer coordinate loops, use `get_node_name_raw`.
+4. if you need dense access on a larger volume, use a Lua Voxel Manipulator.
+
+Overhead:
+
+On current Luanti, without trusted mods, all functions use `get_node`, and the performance will be similar to
+using `get_node`.
+
+When `core.get_node_raw` becomes a public API, or when the trusted mod hack is enabled, the first two perform similar
+to using `core.get_node_raw` followed by an content ID to node name lookup (which is supposedly a simple array access).
+While the function `get_node_raw` becomes an alias for `core.get_node_raw`.
+
+
+## Optimized LuaJIT parameters
+
+As of 2024, the default LuaJIT parameters are not well tuned, *depending on the version you use*.
+
+According to <https://luajit.org/running.html>, standard LuaJIT uses:
+
+| maxtrace   |  1000 | Max. number of traces in the cache                  |
+| maxrecord  |  4000 | Max. number of recorded IR instructions             |
+| maxirconst |   500 | Max. number of IR constants of a trace              |
+| minstitch  |     0 | Min. # of IR ins for a stitched trace.              |
+| maxmcode   |   512 | Max. total size of all machine code areas in KBytes |
+
+However, the openresty branch uses more sane defaults for a long time <https://github.com/openresty/luajit2/blob/v2.1-agentzh/src/lj_jit.h#L117>:
+
+| maxtrace   |  8000 | Max. number of traces in the cache                  |
+| maxrecord  | 16000 | Max. number of recorded IR instructions             |
+| maxirconst |   500 | Max. number of IR constants of a trace              |
+| minstitch  |     3 | Min. # of IR ins for a stitched trace.              |
+| maxmcode   | 40960 | Max. total size of all machine code areas in KBytes |
+
+Mineclonia contributor "halon" investigated this, and
+increasing these values appears to be beneficial for improving the performance of Luanti,
+although users of openresty (e.g., on Debian GNU/Linux) may not notice a difference.
+
+TODO: every few years, the situation should be re-assessed. For example, Luanti upstream might set improved values.
+Unfortunately, it does not appear that we can query the values, only set them.
+
+
diff --git a/mods/CORE/mcl_init/get_node_name.lua b/mods/CORE/mcl_init/get_node_name.lua
new file mode 100644
index 000000000..352daff27
--- /dev/null
+++ b/mods/CORE/mcl_init/get_node_name.lua
@@ -0,0 +1,66 @@
+-- NOTE: As of Luanti 5.9 and 5.10, the function `core.get_node_raw` is NOT exposed.
+-- However, via `secure.trusted_mods=vl_trusted` it is possible to expose and use it.
+-- If <https://github.com/minetest/minetest/issues/15317> is merged, it may become public API.
+-- For more details, see the vl_trusted module.
+-- We do not call into vl_trusted directly, but it set `core.get_node_raw` if loaded first.
+-- Load order hence is important, and this mod should depend on vl_trusted.
+
+local core_get_node = core.get_node
+local core_get_node_raw = core.get_node_raw
+local core_get_name_from_content_id = core.get_name_from_content_id
+local core_get_content_id = core.get_content_id
+
+--- Get the node name, param and param2 using `core.get_node_raw` if available, fall back to regular get_node otherwise.
+---
+--- @param pos vector: position
+--- @return (string, number, number): node name, param1 and param2
+function mcl_vars.get_node_name(pos) -- Fallback version
+	local node = core_get_node(pos)
+	return node.name, node.param1, node.param2
+end
+-- optimized version
+if core_get_node_raw then 
+	mcl_vars.get_node_name = function(pos)
+		local content, param1, param2, pos_ok = core_get_node_raw(pos.x, pos.y, pos.z)
+		if not pos_ok then return "ignore", 0, 0 end
+		return core_get_name_from_content_id(content), param1, param2
+	end
+end
+
+--- Get the node name, param and param2 using `core.get_node_raw` if available fall back to regular get_node otherwise.
+--- Note: up to Luanti 5.10 at least, this will create a new vector. If you already have a vector, prefer `get_node_name`.
+---
+--- @param x number: coordinate
+--- @param y number: coordinate
+--- @param z number: coordinate
+--- @return (string, number, number): node name, param1, param2
+function mcl_vars.get_node_name_raw(x, y, z) -- Fallback version
+	local node = core_get_node({x=x,y=y,z=z}) -- raw table, not need for vector
+	return node.name, node.param1, node.param2
+end
+-- optimized version
+if core_get_node_raw then
+	mcl_vars.get_node_name_raw = function(x, y, z)
+		local content, param1, param2, pos_ok = core_get_node_raw(x, y, z)
+		if not pos_ok then return "ignore", 0, 0 end
+		return core_get_name_from_content_id(content), param1, param2
+	end
+end
+
+--- Get the node name, param and param2 using `core.get_node_raw` if available, fall back to regular get_node otherwise.
+--- Note: up to Luanti 5.10 at least, this involves an unnecessary roundtrip via the node name.
+--- If you use the node name anyway, prefer `get_node_name_raw` or `get_node_name`.
+---
+--- @param x number: coordinate
+--- @param y number: coordinate
+--- @param z number: coordinate
+--- @return (number, number, number, boolean): node content id, param1, param2, pos_ok
+function mcl_vars.get_node_raw(x, y, z) -- Fallback
+	local node = core_get_node({x=x,y=y,z=z}) -- raw table, not need for vector
+	return core_get_content_id(node.name), node.param1, node.param2, node.name ~= "ignore"
+end
+-- optimized version
+if core_get_node_raw then
+	mcl_vars.get_node_raw = core_get_node_raw
+end
+
diff --git a/mods/CORE/mcl_init/init.lua b/mods/CORE/mcl_init/init.lua
index aae6b090e..b87ac2639 100644
--- a/mods/CORE/mcl_init/init.lua
+++ b/mods/CORE/mcl_init/init.lua
@@ -1,5 +1,6 @@
 -- Some global variables (don't overwrite them!)
 mcl_vars = {}
+local modpath = core.get_modpath(core.get_current_modname())
 
 minetest.log("action", "World seed = " .. minetest.get_mapgen_setting("seed"))
 
@@ -22,7 +23,7 @@ if not map_version then
 	core.set_mapgen_setting("vl_world_version", map_version, true)
 end
 mcl_vars.map_version = map_version -- make available
-core.log("action", "Voxelibre mapgen version = "..map_version)
+core.log("action", "VoxeLibre mapgen version = "..map_version)
 
 mcl_vars.redstone_tick = 0.1
 
@@ -216,6 +217,7 @@ minetest.craftitemdef_default.stack_max = 64
 -- Set random seed for all other mods (Remember to make sure no other mod calls this function)
 math.randomseed(os.time())
 
+---DEPRECATED. If you need to ensure the area is emerged, use LVM.
 ---"Trivial" (actually NOT) function to just read the node and some stuff to not just return "ignore", like mt 5.4 does.
 ---@param pos Vector Position, if it's wrong, `{name="error"}` node will return.
 ---@param force? boolean Optional (default: `false`), Do the maximum to still read the node within us_timeout.
@@ -252,3 +254,6 @@ function mcl_vars.get_node(pos, force, us_timeout)
 	-- it still can return "ignore", LOL, even if force = true, but only after time out
 end
 
+dofile(modpath.."/tune_jit.lua")
+dofile(modpath.."/get_node_name.lua")
+
diff --git a/mods/CORE/mcl_init/mod.conf b/mods/CORE/mcl_init/mod.conf
index 4ce7b394d..355eb6048 100644
--- a/mods/CORE/mcl_init/mod.conf
+++ b/mods/CORE/mcl_init/mod.conf
@@ -1,3 +1,4 @@
 name = mcl_init
 author = Wuzzy
 description = Initialization mod of VoxeLibre.  Defines some common shared variables and sets up initial default settings which have to be set at the beginning.
+optional_depends = vl_trusted
diff --git a/mods/CORE/mcl_init/tune_jit.lua b/mods/CORE/mcl_init/tune_jit.lua
new file mode 100644
index 000000000..1809ca3ba
--- /dev/null
+++ b/mods/CORE/mcl_init/tune_jit.lua
@@ -0,0 +1,23 @@
+--- This code is largely based on the work by halon for mineclonia, but encapsulated differently
+local luajit_present = core.global_exists("jit")
+
+-- Increased limits for the JIT, as of 2024
+-- TODO: re-assess this every year or so, as either upstream Luanti may
+-- eventually increase these limits itself, or the luajit libraries increase
+-- their parameters - e.g., the openresty version already has increase limits
+-- because apparently we can not query the JIT parameters
+if luajit_present then
+	local status, opt = jit.status()
+	if not status then
+		core.log("warning", "[mcl_init] LuaJIT appears to be available, but turned off. This will result in degraded performance.")
+	end
+	jit.opt.start(
+		"maxtrace=24000",
+		"maxrecord=32000",
+		"minstitch=3",
+		"maxmcode=163840"
+	)
+	core.log("action", "[mcl_init] increased LuaJIT parameters. LuaJIT version: "..jit.version.." with flags "..tostring(opt))
+else
+	core.log("warning", "[mcl_init] LuaJIT not detected - it is strongly recommended to build luanti with LuaJIT for performance reasons!")
+end
diff --git a/mods/CORE/vl_trusted/API.md b/mods/CORE/vl_trusted/API.md
new file mode 100644
index 000000000..58a8b5f00
--- /dev/null
+++ b/mods/CORE/vl_trusted/API.md
@@ -0,0 +1,22 @@
+# vl_trusted
+
+This module does not provide a public API.
+
+The optimized function calls are only available via existing APIs.
+
+We currently implement one feature that require trusted access:
+
+## Access to `core.get_node_raw`
+
+The `core.get_node_raw` function has been added to Luanti in version 5.9.0, but as of 5.10 is not a public API,
+although we have asked for this to be made public: <https://github.com/minetest/minetest/issues/15317>
+
+This function is beneficial as it does not create a table for the return, which reduces the amount of garbage collection necessary,
+in particular as LuaJIT's allocation sinking does not appear to eliminate these, unfortunately.
+
+For compatibility, we expose this with slightly different semantics, which are a tradeoff between using the new API when available
+(or exposed via this trusted module), and having to be able to fall back to the regular `core.get_node` call.
+
+TODO: when the minimum version of Luanti has a public version of the API, these wrappers should likely be removed and the unmodified
+`core.get_node_raw` should be used where possible.
+
diff --git a/mods/CORE/vl_trusted/init.lua b/mods/CORE/vl_trusted/init.lua
new file mode 100644
index 000000000..e8fd95dbd
--- /dev/null
+++ b/mods/CORE/vl_trusted/init.lua
@@ -0,0 +1,30 @@
+--- Make `core.get_node_raw` public. It's safe to use and stable.
+--
+-- This code is based on the work by halon for mineclonia, but encapsulated differently
+-- Check if `core.get_node_raw` is public by now.
+if not core.get_node_raw then
+	-- try to un-hide the function
+	local ie = core.request_insecure_environment()
+	if not ie then
+		core.log("action", "[vl_trusted] cannot unhide get_node_raw, please add vl_trusted to secure.trusted_mods to improve performance (optional).")
+	elseif not ie.debug or not ie.debug.getupvalue then
+		core.log("warning", "[vl_trusted] debug.getupvalue is not available, unhiding does not work. Version: "..dump(core.get_version(),""))
+	else
+		for i=1,5 do -- will not be five levels deep
+			local name, upvalue = ie.debug.getupvalue(core.get_node, i)
+			if not name then break end
+			if name == "get_node_raw" then
+				core.get_node_raw = upvalue
+				break
+			end
+		end
+		if core.get_node_raw then
+			core.log("action", "[vl_trusted] get_node_raw unhiding successful.")
+		else
+			core.log("warning", "[vl_trusted] get_node_raw unhiding NOT successful. Version: "..dump(core.get_version(),""))
+		end
+	end
+else
+	core.log("verbose", "[vl_trusted] get_node_raw available without workaround.")
+end
+
diff --git a/mods/CORE/vl_trusted/mod.conf b/mods/CORE/vl_trusted/mod.conf
new file mode 100644
index 000000000..50f4ddb83
--- /dev/null
+++ b/mods/CORE/vl_trusted/mod.conf
@@ -0,0 +1,3 @@
+name = vl_trusted
+author = kno10
+description = Optional - access to some protected Luanti functionality for increased performance