Post your modding questions here
Re: Post your modding questions here
@Don @Ferk
Thanks for the info.
I've now solved the chest problem: after placing the schematic in my world, I lookup all chests in the building and replace them by default:chest again. And then fill them with items (to fill them I use a piece of code I found in another mod: the villages mod by Sokomine I think).
Thanks for the info.
I've now solved the chest problem: after placing the schematic in my world, I lookup all chests in the building and replace them by default:chest again. And then fill them with items (to fill them I use a piece of code I found in another mod: the villages mod by Sokomine I think).
Re: Post your modding questions here
That sounds like a cool mod.
The main problem with using ABMs to detect a player touching a node (other than being a lousy workaround for something that should be done in the engine) is that an ABM minimum interval is 1 second. So it's not very good for things that need a fast reaction since the player won't normally spend 1 second waiting in the node for the handler to kick in. But maybe for your usecase this would be fine. You might have to add an additional delay in case the player stepped the same instant the ABM activated, though.blocks which decay if you step on them
That's very similar to what my subgame does. Maybe you can have a look at it, perhaps it helps. But most of dungeon_rooms is very specific to my usecase.a castle which gets randomly (sort of) generated by combining several pre-built building-part schematics to build either a small or a medium castle
Re: Post your modding questions here
Wow... just looked at your mod. looks very impressive.Ferk wrote: That's very similar to what my subgame does. Maybe you can have a look at it, perhaps it helps. But most of dungeon_rooms is very specific to my usecase.
- stu
- Member
- Posts: 923
- Joined: Sat Feb 02, 2013 02:51
- GitHub: stujones11
- Location: United Kingdom
Re: Post your modding questions here
I doubt very much that stepping on/touching nodes will ever be handled by the engine, it would add way too much overhead, although I could be wrong there.Ferk wrote: The main problem with using ABMs to detect a player touching a node (other than being a lousy workaround for something that should be done in the engine) is that an ABM minimum interval is 1 second. So it's not very good for things that need a fast reaction since the player won't normally spend 1 second waiting in the node for the handler to kick in. But maybe for your usecase this would be fine. You might have to add an additional delay in case the player stepped the same instant the ABM activated, though
I suggest you take a look at how the mesecons pressure plates or player detectors work as those are reasonably responsive and iirc they do not rely on ABMs
- Napiophelios
- Member
- Posts: 1035
- Joined: Mon Jul 07, 2014 01:14
- GitHub: Napiophelios
- IRC: Nappi
- In-game: Nappi
Re: Post your modding questions here
Pyramids by BlockMen uses similar traps.Ferk wrote:That sounds like a cool mod.
The main problem with using ABMs to detect a player touching a node (other than being a lousy workaround for something that should be done in the engine) is that an ABM minimum interval is 1 second. So it's not very good for things that need a fast reaction since the player won't normally spend 1 second waiting in the node for the handler to kick in. But maybe for your usecase this would be fine. You might have to add an additional delay in case the player stepped the same instant the ABM activated, though.blocks which decay if you step on them
But Maze by Echo uses "close stones" that seem much faster to react to players position and spring the traps.
Code: Select all
local maze_closer = {} -- list of all closer stones
-- closer stone definition
minetest.register_node("maze:closer", {
tile_images = {"default_cobble.png"},
inventory_image = minetest.inventorycube("default_cobble.png"),
dug_item = '',
material = { diggability = "not"},
description = "Closestone",
})
-- detect player walk over closer stone (abm isn't fast enough)
minetest.register_globalstep(function(dtime)
local players = minetest.get_connected_players()
for i,player in ipairs(players) do
-- print(i.." "..player:get_player_name())
for i, pos in ipairs(maze_closer) do
local player_pos = player:getpos()
local dist = math.sqrt( ((pos.x - player_pos.x) * (pos.x - player_pos.x)) + ((pos.y - (player_pos.y - 0.5)) * (pos.y - (player_pos.y - 0.5))) + ((pos.z - player_pos.z) * (pos.z - player_pos.z)) )
if dist<3 then -- 2.2 would be enough, just make sure
local meta = minetest.env:get_meta(pos)
if dist<0.5 then
meta:set_string("trap", "triggered")
elseif dist > 1 then -- 0.71 would be enough, at least one node away
if meta:get_string("trap") == "triggered" then
meta:set_string("trap", "")
minetest.env:add_node(pos,{name="default:cobble"})
minetest.env:add_node({x = pos.x, y = pos.y + 1, z = pos.z},{name="default:cobble"})
minetest.env:add_node({x = pos.x, y = pos.y + 2, z = pos.z},{name="default:cobble"})
end
end
end
end
end
end)
-- create list of all closer stones (walk over detection now in globalstep, because abm isn't called often enough
minetest.register_abm(
{nodenames = {"maze:closer"},
interval = 1,
chance = 1,
action = function(pos, node, active_object_count, active_object_count_wider)
local found = false
for i, closer_pos in ipairs(maze_closer) do
if closer_pos.x == pos.x and closer_pos.y == pos.y and closer_pos.z == pos.z then
found = true
end
end
if not found then
table.insert(maze_closer, pos)
end
end,
})
Re: Post your modding questions here
It's faster because it uses globalstep. But that's also very hacky, and it doesn't look like he ever removes the node from the maze_closer table.. and you still have both an ABM and a globalstep handler running.
globalstep gets called every I think 0.05 seconds or something, if you don't keep track of the dtime (which it doesn't look like that code does) you are killing the CPU with that. Please correct me if I'm wrong.
If you don't have too many nodes to check it's probably more efficient to use timers, I guess timers get unloaded by the engine and handled more efficiently since the logic is all coded in C++. Note however that timers also won't get saved in mts schematics.
And all these approaches are workarounds, I still think it would be way better to have a handler on collision from the engine.
globalstep gets called every I think 0.05 seconds or something, if you don't keep track of the dtime (which it doesn't look like that code does) you are killing the CPU with that. Please correct me if I'm wrong.
If you don't have too many nodes to check it's probably more efficient to use timers, I guess timers get unloaded by the engine and handled more efficiently since the logic is all coded in C++. Note however that timers also won't get saved in mts schematics.
And all these approaches are workarounds, I still think it would be way better to have a handler on collision from the engine.
Re: Post your modding questions here
Doesn't the engine already handle that? I mean.. how does it know a player can't go forward if there's a wall in front? or how does it know you are touching fire and should get damaged? I guess the server checks for collisions.stu wrote:I doubt very much that stepping on/touching nodes will ever be handled by the engine, it would add way too much overhead, although I could be wrong there.
Or do you mean that that's client side? Even the damage_per_second?
Perhaps the problem is that the lua api is on a different, higher, level. Maybe some structural problem doesn't let them expose the collision logic to lua or they can't access the node definitions table. But I don't think the problem is overhead for checking the collisions.
I had already done that, they use timers. Just a different way to apply the same approach used with ABMs. It's doable, just not very efficient.stu wrote:I suggest you take a look at how the mesecons pressure plates or player detectors work as those are reasonably responsive and iirc they do not rely on ABMs
Thank you! :)afeys wrote:Wow... just looked at your mod. looks very impressive.
Re: Post your modding questions here
I believe you are referring to collision.cpp.Doesn't the engine already handle that? I mean.. how does it know a player can't go forward if there's a wall in front? or how does it know you are touching fire and should get damaged? I guess the server checks for collisions.
Or do you mean that that's client side? Even the damage_per_second?
Many of my mods are now a part of Minetest-mods. A place where you know they are maintained!
A list of my mods can be found here
A list of my mods can be found here
Re: Post your modding questions here
I'm guessing you could use an on_destruct handler (or whatever it's called) to remove nodes from maze_closer. Other than that, you'd never want to remove nodes from that table – it's supposed to be all the closers in the world. For that use case, though, the ABM is much too agressive. Every few seconds, with less than certain probability, should get you just as far.Ferk wrote:It's faster because it uses globalstep. But that's also very hacky, and it doesn't look like he ever removes the node from the maze_closer table.. and you still have both an ABM and a globalstep handler running.
I've done that in a mod, but I also had to make sure the surrounding nodes around my special node were still there. Otherwise, nowadays, I'd try handling on_place and on_destroy, and saving the maze_closer table to disk.
Wasn't it every 0.1 seconds? And in my experience, CPU is "free" nowadays. Or at least you should profile first, optimize later. I once found that a loop I was worried over took about 100 microseconds, and stopped worrying ;-)Ferk wrote:globalstep gets called every I think 0.05 seconds or something, if you don't keep track of the dtime (which it doesn't look like that code does) you are killing the CPU with that. Please correct me if I'm wrong.
(One tip to save CPU time: don't compare the distance to a threshold, compare the square of the distance to the square of the threshold. Saves you a math.sqrt call. But then agan, free nowadays.)
(Another tip: don't use maze_closer as a list and then iterate with ipairs to find a node with a given position, use it as a map / directory / hash and test against maze_closer["x.y.z"]. Use pairs if you do need to iterate. Yes, I understand it's someone else's code in this example, but this irked me, and I'd like to throw this out there.)
For actual collisions as in "standing on" or "standing in", I've been iterating over all players and testing get_node() at the relevant positions. This probably won't work for "pushing against" or "standing near", but it seems to work. Or am I doing it wrong?Ferk wrote:…And all these approaches are workarounds, I still think it would be way better to have a handler on collision from the engine.
Re: Post your modding questions here
@Ben you are correct, it's 0.1
About the distance calculation, perhaps the best is to use vector.distance(p1, p2)
We have a very convenient API in Minetest for operating with vectors, it's a shame most mods don't use it.
About the distance calculation, perhaps the best is to use vector.distance(p1, p2)
We have a very convenient API in Minetest for operating with vectors, it's a shame most mods don't use it.
That's what I'm doing as well for a pacman mod I'm working on. Seems to work fine for collecting the pellets. The only problem is that sometimes there are rounding issues and some pellets were getting missed so I actually have to check 2 positions instead of 1. I tried minetest.find_node_near but I have to either do a get_node anyway or do it a second time for the other type of "touchable" nodes, so I decided against it. Also even radius 1 was too big, probably get_node is faster.For actual collisions as in "standing on" or "standing in", I've been iterating over all players and testing get_node() at the relevant positions. This probably won't work for "pushing against" or "standing near", but it seems to work. Or am I doing it wrong?
My i7 processor roars like a tiger when playing pacman. In singleplayer. I have yet to test it on a server.in my experience, CPU is "free" nowadays
Last edited by Ferk on Fri Oct 23, 2015 20:51, edited 1 time in total.
Re: Post your modding questions here
I just looked up vector.distance: it's still implemented in Lua, and calls math.hypot twice. I've got a mind to make a pull request for vector.distance2 or similar. But that would be premature optimization ;-PFerk wrote: About the distance calculation, perhaps the best is to use vector.distance(p1, p2)
Yeah, I should have qualified my remark a bit: I code websites for a living, where anything done in-process is practically invisible when compared to I/O :-PFerk wrote:My i7 processor roars like a tiger when playing pacmanBen wrote:in my experience, CPU is "free" nowadays
- stu
- Member
- Posts: 923
- Joined: Sat Feb 02, 2013 02:51
- GitHub: stujones11
- Location: United Kingdom
Re: Post your modding questions here
Collision detection is indeed client side, that's exactly how hacked clients can get fly/no-clip on servers. Maybe someday this sort of thing will be possible with client-side modding, meanwhile the polling approach (however you trigger it) is really the only way you can do itFerk wrote:Doesn't the engine already handle that? I mean.. how does it know a player can't go forward if there's a wall in front? or how does it know you are touching fire and should get damaged? I guess the server checks for collisions.
Or do you mean that that's client side? Even the damage_per_second?
Perhaps the problem is that the lua api is on a different, higher, level. Maybe some structural problem doesn't let them expose the collision logic to lua or they can't access the node definitions table. But I don't think the problem is overhead for checking the collisions.
Re: Post your modding questions here
I see, thanks, I understand now. I thought Minetest already was preventing cheating at that level.stu wrote:Collision detection is indeed client side, that's exactly how hacked clients can get fly/no-clip on servers. Maybe someday this sort of thing will be possible with client-side modding
Personally, I can accept giving up on cheat prevention on some levels. I think it's a trade-off, I'd rather have a fun game with many possibilities powered by client-side algorithms than a limited game full of bugs caused by the lag because of being afraid of the players cheating. I don't think Minetest is intended for any sort of professional cheat-protected tournament anyway. So I'd be happy to use client side APIs when available.
If this is really what everyone is using and / or people think it's worth it to do it in the server rather than the client, then maybe it would make sense to actually have either a "standard" lua library (or mod) to do it that can be peer reviewed and improved, or actually added to the engine as a server side check that only runs the polling whenever it makes sense. I guess there are ways in which this could be further optimized, even if it wasn't done using the client-side physics engine. Perhaps having a centralized system for it would help, so that we only iterate over the list of players once.meanwhile the polling approach (however you trigger it) is really the only way you can do it
Last edited by Ferk on Sat Oct 24, 2015 13:24, edited 1 time in total.
- stu
- Member
- Posts: 923
- Joined: Sat Feb 02, 2013 02:51
- GitHub: stujones11
- Location: United Kingdom
Re: Post your modding questions here
Yes, of course there are anti-cheat mechanisms you can enable but I don't think that cheating is really that big of a problem. This is pretty much how all games of this nature work and it's just down to good server moderation to remove/ban any cheaters.Ferk wrote:I see, thanks, I understand now. I thought Minetest already was preventing cheating at that level.
Personally, I can accept giving up on cheat prevention on some levels. I think it's a trade-off, I'd rather have a fun game with many possibilities powered by client-side algorithms than a limited game full of bugs caused by the lag because of being afraid of the players cheating. I don't think Minetest is intended for any sort of professional cheat-protected tournament anyway. So I'd be happy to use client side APIs when available.
One possibility for your pacman game would be make it so that you have to dig the pips in order to move, not ideal I admit though it would save you a lot of problems.
Re: Post your modding questions here
We don't want to dig the pips. We want it like the original where you walk past it and it gets eaten.
Many of my mods are now a part of Minetest-mods. A place where you know they are maintained!
A list of my mods can be found here
A list of my mods can be found here
- rubenwardy
- Moderator
- Posts: 6972
- Joined: Tue Jun 12, 2012 18:11
- GitHub: rubenwardy
- IRC: rubenwardy
- In-game: rubenwardy
- Location: Bristol, United Kingdom
- Contact:
Re: Post your modding questions here
I scrolled back a bit and couldn't find any context for this, other than it's pacman.Don wrote:We don't want to dig the pips. We want it like the original where you walk past it and it gets eaten.
Couldn't you just modify the pick up code from PilzAdam's mod? So when you run over a pip entity, it is sucked up.
Re: Post your modding questions here
Look upa few posts to stu. His last paragraph.rubenwardy wrote:I scrolled back a bit and couldn't find any context for this, other than it's pacman.Don wrote:We don't want to dig the pips. We want it like the original where you walk past it and it gets eaten.
Couldn't you just modify the pick up code from PilzAdam's mod? So when you run over a pip entity, it is sucked up.
The pips are nodes. The pacman pellets. Ferk has them working good but would work better if there was an on_collision function.
Many of my mods are now a part of Minetest-mods. A place where you know they are maintained!
A list of my mods can be found here
A list of my mods can be found here
Re: Post your modding questions here
Yes, we are working together on the pacman mod.
I just checked PlizAdam's mod (I guess this one: https://github.com/PilzAdam/item_drop )
He uses a globalstep, along with get_objects_inside_radius. The pellets are nodes not object. If they were objects it might not work that well since there are more than 200 of them and they will probably constantly get loaded/unloaded.
The node "equivalent" function find_node_near has other problems, I mentioned that some comments above. It only returns positions so I ahve to either call it multiple times (once for each type of item to collect.. like the powerup or the fruits) or I'll have to do a get_node anyway for each of the nodes it finds.
I just checked PlizAdam's mod (I guess this one: https://github.com/PilzAdam/item_drop )
He uses a globalstep, along with get_objects_inside_radius. The pellets are nodes not object. If they were objects it might not work that well since there are more than 200 of them and they will probably constantly get loaded/unloaded.
The node "equivalent" function find_node_near has other problems, I mentioned that some comments above. It only returns positions so I ahve to either call it multiple times (once for each type of item to collect.. like the powerup or the fruits) or I'll have to do a get_node anyway for each of the nodes it finds.
- paramat
- Developer
- Posts: 3700
- Joined: Sun Oct 28, 2012 00:05
- GitHub: paramat
- IRC: paramat
- Location: UK
Re: Post your modding questions here
My trail mod has code for changing nodes walked on, it's not very lightweight though, but reasonable https://github.com/paramat/trail
- stu
- Member
- Posts: 923
- Joined: Sat Feb 02, 2013 02:51
- GitHub: stujones11
- Location: United Kingdom
Re: Post your modding questions here
I like the idea of a pacman mod so I thought I would give something a quick try.Don wrote:We don't want to dig the pips. We want it like the original where you walk past it and it gets eaten.
This idea uses the lua voxel manipulator so the maze position must be known in advance (pmin, pmax)
Code: Select all
local timer = 0
minetest.register_node("pacman:pip", {
description = "Pacman Pip",
tiles = {"pacman_pip.png"},
walkable = false,
on_collision = function(pos)
minetest.remove_node(pos)
end,
})
minetest.register_globalstep(function(dtime)
timer = timer + dtime
if timer > 0.1 then
local pmin = {x=-20, y=0, z=-20}
local pmax = {x=20, y=0, z=20}
local vm = VoxelManip(pmin, pmax)
for _,player in ipairs(minetest.get_connected_players()) do
local pos = player:getpos()
local node = vm:get_node_at(pos)
local ref = minetest.registered_nodes[node.name]
if type(ref.on_collision) == "function" then
ref.on_collision(vector.round(pos))
end
end
timer = 0
end
end)
I have no idea how well this would perform on a public server but it seems to work ok in singleplayer, even on my crappy old pc :/
Building on this idea, I guess you could do away with the vm and simply use a pre-defined array of pip locations. This way you only need to check if a player's current position matches one of the known pip locations which I reckon you can safely do on every server step.
Code: Select all
pacman = {
pips = {},
}
minetest.register_node("pacman:pip", {
description = "Pacman Pip",
tiles = {"pacman_pip.png"},
walkable = false,
})
minetest.register_abm({
nodenames = {"pacman:pip"},
interval = 1.0,
chance = 1,
action = function(pos, node)
local id = minetest.hash_node_position(pos)
pacman.pips[id] = 1
end,
})
minetest.register_globalstep(function(dtime)
for _,player in ipairs(minetest.get_connected_players()) do
local pos = vector.round(player:getpos())
local id = minetest.hash_node_position(pos)
if pacman.pips[id] then
minetest.remove_node(pos)
pacman.pips[id] = nil
end
end
end)
Re: Post your modding questions here
Isn't allocating a new vm each cycle too much if you just want to check one or two nodes per step? We actually have already a working pacman that works ok in singleplayer. it's just that the discussion about the on_collision has been dragged for a few days in this thread :P ..it didn't even start with pacman.
Btw, what if I kept the same voxelmanip around and reused it in the globalstep? Does the vm keep the list of nodes in memory so it wouldn't need to poll the map every time and work pretty much like the list of pips in your second idea? It would use some more memory but then it doesn't need an abm.
I'm now writing some api to keep a list of highscores. The idea is actually to make a modpack with different arcade games. Hopefully pacman would be the first of many.
That's clever, it would probably be much faster. We still have to test the game in a remote server, though, maybe the current approach is already enough, but that would be an interesting alternative.use a pre-defined array of pip locations. This way you only need to check if a player's current position matches one of the known pip locations which I reckon you can safely do on every server step
Btw, what if I kept the same voxelmanip around and reused it in the globalstep? Does the vm keep the list of nodes in memory so it wouldn't need to poll the map every time and work pretty much like the list of pips in your second idea? It would use some more memory but then it doesn't need an abm.
I'm now writing some api to keep a list of highscores. The idea is actually to make a modpack with different arcade games. Hopefully pacman would be the first of many.
-
- Member
- Posts: 58
- Joined: Fri Feb 13, 2015 21:31
Re: Post your modding questions here
Hello. How can I make a node that lays flat on the node face it is placed? like the ladder in the image:
http://pasteboard.co/1D4bL4Lm.png
thanks!
http://pasteboard.co/1D4bL4Lm.png
thanks!
Re: Post your modding questions here
Add this to your node defminetestcr wrote:Hello. How can I make a node that lays flat on the node face it is placed? like the ladder in the image:
http://pasteboard.co/1D4bL4Lm.png
thanks!
Code: Select all
on_place = minetest.rotate_node
Many of my mods are now a part of Minetest-mods. A place where you know they are maintained!
A list of my mods can be found here
A list of my mods can be found here
-
- Member
- Posts: 58
- Joined: Fri Feb 13, 2015 21:31
Re: Post your modding questions here
thanks Don... I tried, but I'm doing something wrong, I added the code like this:Don wrote: Add this to your node def
Code: Select all
on_place = minetest.rotate_node
Code: Select all
minetest.register_node("stj:laminaverde", {
description = "lámina verde",
tiles = {
"paredverde.png",
"paredverde.png",
"paredverde.png",
"paredverde.png",
"paredverde.png",
"paredverde.png"
},
drawtype = "nodebox",
paramtype = "light",
on_place = minetest.rotate_node,
material = minetest.digprop_constanttime(1.0),
groups = {snappy=3,cracky=3,oddly_breakable_by_hand=3,},
node_box = {
type = "fixed",
fixed = {
{-0.5, -0.5, 0.4375, 0.5, 0.5, 0.5}, -- NodeBox1
}
}
})
}
Re: Post your modding questions here
You need paramtype2 set
Code: Select all
paramtype2 = "facedir",
Many of my mods are now a part of Minetest-mods. A place where you know they are maintained!
A list of my mods can be found here
A list of my mods can be found here
Who is online
Users browsing this forum: No registered users and 6 guests