How to create a random spawnpoint off entities in Minecrat 1.17.1?

Solution 1:

Short answer

Longer answer at the end.

If you don't care about efficiency (You have a low amount of players in the world or just aren't bothered by it) you can run the following command on a Always active Repeat Unconditional command block:

/execute as @a run execute at @e[sort=random,type=minecraft:armor_stand,tag=Spawn,limit=1] run spawnpoint @s ~ ~ ~

This command means: For each player, do: Choose a random armor run Set the player's spawn to the armor's pos

Reason why your attempt didn't work

Here was your error in the command: When you use execute as Someone you can target this someone after the run using @s (self). In your atempt, you were disregarding the first @r by doing another @r, resulting in For each player, Choose another random player, making it possible for someone not being targeted.

How to use [@s] and [at @?]

How to use @s:

You can run the follwoing command:

/execute as @a run say @s

This translates to: Execute the next command on every player individually, where @s will be replaced by whoever the player is.

So this would go trough, lets say, you and me. First go trough me and change @s to Bunny and do /say Bunny as if I, the player, had typed that in chat. Then it would go trough you and do the same, but @s would be you.

How to use [at @someone]:

Now, note the second part at @e[...]. This will set the relative position of the command to the target's pos. So if we use ~ ~ ~, we would be using the @e[...]'s coordinates on the next command. Inside the brackets, we have the type, tag and sort and limit. They just mean "Select at a random order, only one, with this tag and type".

Extra: Why is there two executes?

If you run /execute as @a at @r, this will do: Choose a random player as a location and iterate on each player.

If you run /execute as @a run execute at @r, this will do: For each player, do: Choose a random player

The difference is subtle, but on the first one, the player choosen as location is the same for everyone, but on the second one each player gets their own random location.

Long answer

We can use scoreboards to detect when a player dies and use that as a trigger.

Scoreboard:
/scoreboard objectives add death deathCount
Commands:

First one in a Always active Repeat Unconditional and pointing to a second one Always active Chain Unconditional

/execute as @a[scores={death=1..}] run execute at @e[sort=random,type=minecraft:armor_stand,tag=Spawn] run spawnpoint @s ~ ~ ~
/execute as @a[scores={death=1..}] run scoreboard players set @s death 0
Translation:
For each player who has their death counter to at least one, At a random stand, set their spawn
For each player who has their death counter to at least one, set their score to 0