Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

code to new spam at join game, but how to if there is an already pointed #1

Closed
mckaygerhard opened this issue Oct 11, 2021 · 8 comments

Comments

@mckaygerhard
Copy link

i find this lokking for a best option agains the low performance of rspawn mod..

after lokking at the code it seems that this mod does not makes nothing if there's no implementation.. so i added a function to generated a random spamn point of each player just at each login if there's no already spawn set:

minetest.register_on_joinplayer(function(player)
    random_spawn(player)
end)

but there's no code for respawn cos i dont know how to distinge around already set poi8nt of player spawn or a random one

for now i use to have beds compatibility :

random_spawn.bedspawn = minetest.setting_getbool("enable_bed_respawn") ~= false

the ~= this means if get the value will set or like to false or will use the analog one?

for already joined users..i guess this will be the code, please help me if i am wrong:

minetest.register_on_respawnplayer(function(player)
    local name = player:get_player_name()
    if random_spawn.bedspawn == true and beds.spawn then
        local pos = beds.spawn[name]
        if pos then
            minetest.log("action", name.." respawns at "..minetest.pos_to_string(pos))
            player:setpos(pos)
            return true
        end
    else
        random_spawn(player)
    end
end)
@NathanSalapat
Copy link
Owner

NathanSalapat commented Oct 11, 2021

Your code for newly joining players looks good.

I don't think the random_spawn.bedspawn line will even work. ~= means does not equal, but you're reading the value of enable_bed_respawn and not comparing it with anything.

You could use the bed code for setting the respawn, something like this probably. The beds mod would handle respawning then so you wouldn't need to do any of that. I'm not sure exactly what happens for people that have already joined before adding the code but haven't slept in a bed yet.

function find_ground(pos, player)
   local node = minetest.get_node({x = pos.x, y = pos.y, z = pos.z})
   if node.name == 'air' or node.name == 'ignore' then --Theoretically above ground
      minetest.log('action', 'node is above ground, looking downwards.')
      local i = 1
      local finished = false
      repeat
         local node = minetest.get_node({x = pos.x, y = pos.y - i, z = pos.z})
         i = i-1
         if i == -30 then
            minetest.log('action', 'could not find ground, trying again.')
            random_spawn(player)
         end
         if node.name ~= 'air' and node.name ~= 'ignore' then
            local protection = minetest.is_protected({x = pos.x, y = pos.y - i + 1, z = pos.z}, player)
            if protection then
               minetest.log('action', 'area was protected, trying again.')
               random_spawn(player)
            else
               player:setpos({x = pos.x, y = pos.y - i + 2, z = pos.z})
               minetest.set_node({x = pos.x, y = pos.y + i +1, z = pos.z}, {name = 'default:torch', param2 = 1})
               finished = true
               minetest.log('action', 'everything worked, placed player.')
            end
         end
      until finished == true or i < -30
   elseif node.name ~= 'air' or node.name ~= 'ignore' then --Theoretically below ground
      minetest.log('action', 'looks like node is underground, traveling up')
      local i = 1
      repeat
         local node = minetest.get_node({x = pos.x, y = pos.y + i, z = pos.z})
         i = i + 1
         if i == 30 then
            minetest.log('action', 'could not find air, trying again.')
            random_spawn(player)
         end
         if node.name == 'air' then
           local protection = minetest.is_protected({x = pos.x, y = pos.y + i, z = pos.z}, player)
            if protection then
               minetest.log('action', 'area was protected, trying again.')
               random_spawn(player)
            else
               player:setpos({x = pos.x, y = pos.y + i, z = pos.z})
               minetest.set_node({x = pos.x, y = pos.y + i -1, z = pos.z}, {name = 'default:torch', param2 = 1})
               i = 35
               minetest.log('action', 'everything worked, placing player.')
               beds.spawn[player:get_player_name()] = {x = pos.x, y = pos.y + i, z = pos.z}
            end
         end
      until node.name == 'air' or i >= 30
   end
end

All I've done is add the beds.spawn line. This would require you to add beds into the dependencies for this mod. It would treat the first spawn position as a saved bed spot. The first time sleeping in another bed would reset the position of course.

@mckaygerhard
Copy link
Author

mckaygerhard commented Oct 12, 2021

thanks a lot! yes the code does not work inclusively it crash.. so i removed the random_spawn.bedspawn line and look at your proposition..

for people that have already joined before, i research a little and my code for minetest.register_on_joinplayer is wrong also.. cos on each join of players will not take in consideration the beds ..

i have two question:

         if i == -30 then
            minetest.log('action', 'could not find ground, trying again.')
            random_spawn(player)
         end

this recursively will loop and could happened a mem exhaustion?

and second.. you here suggest to use that find_ground .. and only added one line for beds.. if node is not air.. (below ground), but not if are above .. so its missing and must be use also right?

@NathanSalapat
Copy link
Owner

The code bit you copied runs in a loop, preventing the loop from executing more than thirty times. After the 30th attempt it will restart the searching process in another area. I don't think there is any way this could run out of memory as it's not actually storing anything.

I did forgot to put the line of code with the bed spawn portion in the first main if chunk of code.

You can probably check if a player has a bed.spawn point save on joining, and if they don't give them a random spawn location.

@mckaygerhard
Copy link
Author

mckaygerhard commented Oct 12, 2021

i am noted that is best to check if player already has bed

The code bit you copied runs in a loop, preventing the loop from executing more than thirty times. After the 30th attempt it will restart the searching process in another area. I don't think there is any way this could run out of memory as it's not actually storing anything.

umm i reefers that if there's no found a possible area...

I did forgot to put the line of code with the bed spawn portion in the first main if chunk of code.

yeah i noted.. that's why i ask .. ok got it

You can probably check if a player has a bed.spawn point save on joining, and if they don't give them a random spawn location.

ug that's is the missing part i noted .. in my code part..

also noteh you provide a default:torch as gif if people are under ground ! or at night!

@NathanSalapat
Copy link
Owner

If the code doesn't find a suitable area it will get another random selection on the map and check for an area again, and keep doing this until it finds an area. I developed this for a server that Cat5 was running, and I don't know of it ever causing any issues. I guess it's possible that it could try finding an area for hundreds or thousands of cycles, but I doubt if that would happen. I wrote this four years ago so I don't recall how the testing worked out, but I expect it was fairly quick. There is a testing block provided that you can use to see how long it takes for a suitable location to be found.
In the random_spawn function it provides a base elevation to base things off of. If you have a map with hilly terrain you might want to set it higher. It will look for ground within a 60 node range of the provided elevation, in the code that is set to 15. There is also a radius which can be used to decide how far from 0,0 an area should be looked for.
Feel free to change around any of the variables. Had I made this to be a more general purpose mod I would probably have created them as settings, but again I made it specifically for a server a friend was running.

@mckaygerhard
Copy link
Author

mckaygerhard commented Oct 16, 2021

hi @NathanSalapat i test your code but it seems does not work.. that line after a while will re-respawn the players again... i found a nasty solution and made a fork: https://git.minetest.org/minenux/minetest-mod-spawnrand marked solved at https://codeberg.org/minenux/minetest-mod-spawnrand/issues/1

heres is the code: https://git.minetest.org/minenux/minetest-mod-spawnrand/commit/2b50e329f0ee339090de76146ee6b440ab53527b i not used the minetest.register_on_joinplayer yet cos for already seet beds of players will need a better logic so i used minetest.register_on_newplayer ...

i take the freedown to rename the namespace of the mod (i guess is named as is, "namespaced") from ramdow_spawn to spawnrand .. so all the mods i set on my server related to spawn point will have spawn prefixed..

so the solution is nasty for now but solved at the VenenuX minetest repository, i will close this code when i clean and improve the code

@mckaygerhard
Copy link
Author

mckaygerhard commented Dec 13, 2021

for people interesting in that.. the findgroun it takes 5MB memory.. so it will get so many resources on huge servers..

This mod works prefectly with a local game with few players.. but has a recursive findground function.. that will be a problem in huge amoutn of players, it load 5MB per find. i track the issue in my fork.. .

2021-12-13 14:55:05: INFO[Emerge-0]: initialEmerge: area: (112,-48,-368)(223,63,-257)=112x112x112=1404928 (5MB)
2021-12-13 14:55:06: INFO[Emerge-0]: initialEmerge: area: (32,-48,352)(143,63,463)=112x112x112=1404928 (5MB)
2021-12-13 14:55:06: VERBOSE[ConnectionSend]: con(4/1)RE-SENDING timed-out RELIABLE to 181.208.196.62(t/o=0.424): from_peer_id=1, channel=0, seqnum=184
2021-12-13 14:55:06: VERBOSE[Server]: Server: Sending TOCLIENT_MOVE_PLAYER pos=(1880,390,-2840) pitch=81.49 yaw=33.58

EDIT: i solved the situation in the codeberg fork and also at minenux one.. also it has bed detection.

mckaygerhard added a commit to minenux/minetest-mod-spawnrand that referenced this issue Jan 5, 2022
* mod is autodetected and also detect if are already enabled
* fixed mod position when bed are available only if player has it
* fixed player respawn on dead.. must have else for no beds of player
* closed fixed close NathanSalapat#1
* close fixed closed https://codeberg.org/minenux/minetest-mod-spawnrand/issues/3
* property fixed adn closed https://codeberg.org/minenux/minetest-mod-spawnrand/issues/1
@mckaygerhard
Copy link
Author

already done at minenux@004e8da, thanks for your help

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants