I have an adventure map with a say command that activates after a certain mob is killed. This can be problematic, because if you die while fighting the mob, it sends you to a town, and automatically makes the difficulty set to peaceful. This in turn kills the mob and sets off the say command without the player actually killing it. With this situation, can I make a say command that is only seen by players that are within a certain radius? I do not want a say command that is only set off when a player enters a certain radius.
Minecraft – How to limit the radius that a say command can be seen from
minecraft-commandsminecraft-java-edition
Related Solutions
Here's a compacted device that will do what you want. Two command blocks are necessary; one for the player detector, and one for the message. I've labeled the blocks with example commands to use.
Explanation:
The six blocks in the top-left form a basic clock, which repeatedly triggers the testfor command. (The faster the clock, the quicker the detection, but higher CPU cost ("server lag") to run it.)
The torch of the clock activates the testfor
command block at left, and (towards the right) its output is detected by the comparator, amplified by the repeater, and goes in to the command block at the right to trigger the message.
The signal then also goes to the left-pointing repeater and into the block holding the torch. This stops the clock, so that the player test will not run again. This means that left command block's output remains on, so the right command block won't say anything again since it's waiting to see the signal turn on.
Then, to reset the mechanism (after testing, say), push the button at the bottom, which reruns the player test and thus reenables the clock, while you are out of range. (It'll need to be longer than shown to be actually out of range.)
The redstone dust on top of the command block is not actually necessary (it just looks better), and if you omit it the entire mechanism is only one block high so it'll fit easier under a floor.
If you want to do the same kind of thing for something other than a message, you can just omit the command block on the right and use the redstone output for whatever you want (as long as it also loops back to stop the clock).
By the way: as a matter of game design, I would recommend that you not do exactly this, unless the message is purely flavor and not an important hint. Don't make an NPC say something only once, because the player could easily miss it the first time around, or assume they could get the information again later since most games do that.
If you simply omit the part which stops the clock (the left-pointing repeater and the wire going to it), then there will be a message each time the player enters the detection range (but not any repetitions while they are in it).
Adding a bit more redstone logic could do things like giving a long message the first time the player is detected and a short one later times.
Good question. I have spent a few hours playing with the mechanics of target selectors. I have reread the wiki a few times. I came up with a solution but it does not involve radius.
The problem is the initial target selector: @a[y=166,r=59]
This will select any player within a 59 block radius of y=166 directly above or below the command block. (If x and z are not specified it defaults to the command execution position) This radius means above and below y=166. When x and z of player are same coordinates as command block this would select anyone from y=107 to y=225.
If you use a volume argument to specify y, it only selects players inside the specified zone that also happens to be within the radius. Which without x and z seems to be only a few cubes directly above/below command block. Also doesn't work.
Also, I don't recommend using the execute command. Technically your command is finding a player based on the above criteria and then teleporting the nearest player(@p
) to that position. Just use the tp command directly while targeting the player you want to with the target selector
One solution would be to specify a zone to target. This would use volume arguments instead of the radius argument. It requires a bit more.
/tp @a[x=X,dx=DX,y=166,dy=0,z=Z,dz=DZ] -12.5 118 -27.5
X and Z specify one corner of the zone tested.
DX and DZ specify the distance from X and Z respectively. (they are a distance, not a coordinate)
Note: Relative coordinates can not be used in the target selector.
Example:
/tp @a[x=-25,dx=50,y=166,dy=0,z=-25,dz=50] -12.5 118 -27.5
This will select and teleport any player between (-25,y,-25) and (25,y,25). This could sort of replace a radius of 50. It is not perfect, it seems to select any player above 164 and below 167.
In your case of a player falling off of a structure it will teleport them once they hit y=166.
Also, the command block has to be located in a loaded chunk. You could use a command block per zone of your map to have small targeted zones or you could put the command block in the spawn chunks and use one large zone that covers your entire map area.
Example of the latter:
/tp @a[x=-5000,dx=10000,y=166,dy=0,z=-5000,dz=10000] -12.5 118 -27.5
This would select and teleport any players between (-5000,y,-5000) and (5000,y,5000) at the correct y level.
Best Answer
You can't specify a radius for the command
/say
. You should learn json and use/tellraw
instead. If you want to send the message to everyone within a radius of 100 blocks, do/tellraw @a[r=100]
.Basic JSON formatting:
/tellraw @a[r=100] {text:"Hello world!"}
With colours:
/tellraw @a[r=100] {text:"Hello world!",color:"aqua"}
These colours have different names than wool colours, for example cyan is
dark_aqua
. These names can be found on the Minecraft wiki here.You can do lots more with JSON than you can do with /say. Check out this awesome json generator: https://www.minecraftjson.com/