-
Notifications
You must be signed in to change notification settings - Fork 2.2k
Description
Luanti version
(Flatpak release)
Luanti 5.14.0 (Linux)
Using LuaJIT 2.1.1756211046 (OpenResty)
Built by GCC 15.2
Running on Linux/6.12.57 x86_64
BUILD_TYPE=Release
RUN_IN_PLACE=0
USE_CURL=1
USE_GETTEXT=1
USE_SOUND=1
STATIC_SHAREDIR="/app/share/luanti"
STATIC_LOCALEDIR="/app/share/locale"
Operating system and version
Linux Mint Debian Edition 7 (based on Debian 13)
CPU model
Intel Core i7-5650U
GPU model
No response
Active renderer
No response
Summary
Naive calculations based on player position seem to suffer from rounding errors. I'd expect the following code to provide the node below the player:
pos = player:get_pos()
pos.y = pos.y - 1
n = core.get_node(pos)However, it does not work reliably when y < 0. While this can probably be worked around, it seems that several mods suffer from this problem and the behaviour is confusing, to say the least. I am not sure if it can be fixed in the engine, but I think there should be a canonical way to do such calculations, and I found nothing related to this in the docs.
Background and use case
I was investigating that several mods don't work properly on my server. TNT run and sumo minigames sometimes don't kill players or let TNT fall.
Upon investigation, I also found that other mods like worldedit are not consistent: The behaviour of which node is selected differs based on the y value. I recorded a demonstration in which I additionally demonstrate that the selected node is not even deterministic based on the node I stand on. If I fly, go down slightly, and disable fly, I can trigger that I'm apparently on a different level. See demonstration video:
we-node-glitch.webm
Steps to reproduce
I created a demonstration world and a simple mod that demonstrates the behaviour.
init.lua:
core.register_on_joinplayer(function(player, last_login) checkfn(player) end)
function checkfn(player)
pos = player:get_pos()
pos_get = pos
pos_get.y = pos_get.y - 1
node_name = core.get_node(pos_get).name
core.chat_send_all("y: " .. tostring(pos.y) .. ", below is: " .. node_name)
core.after(1, function() checkfn(player) end)
endmod and world are attached. I recorded another video (with audio comments):