Blog ·
There is no right-click event in a datapack
We wanted a blaster: right click, a bolt everyone can see leaves the muzzle, and a blocky little explosion where it lands. No mods, no plugin, vanilla clients only. Three things stand in the way and each one has exactly one answer.
1. Nothing tells you somebody right-clicked
There is no event, no trigger, no on_use. What exists is a
scoreboard criterion: Minecraft keeps a statistic for every item a player
has used, and you can watch it.
scoreboard objectives add fired minecraft.used:minecraft.carrot_on_a_stick Then in your tick function, anybody whose score has gone up since the last tick has just clicked, and you reset it:
execute as @a[scores={fired=1..}] at @s run function ns:fire
scoreboard players reset @a fired The item matters enormously. A carrot on a stick counts as used the instant it is right-clicked. A crossbow does not — it counts as used when it fires, after a draw — so a blaster built on one will never fire on a click, and will say nothing about why. That cost us an evening. Warped fungus on a stick behaves like the carrot; almost nothing else does.
And the statistic counts every right click, including the one that opened a door. Gate it on what is in the hand, by its exact model:
execute unless items entity @s weapon.mainhand \
minecraft:carrot_on_a_stick[minecraft:item_model="ns:blaster"] run return 0 2. A summoned entity does not face where you are facing
This is the one that looks impossible. You need a projectile that travels where the player is aiming, and commands cannot turn a look direction into a velocity vector — there is no trigonometry available to you.
You do not need any. Copy the shooter's rotation onto the projectile and then move it forward along its own facing with local coordinates, which is what the caret notation is for:
tag @s add shooter
execute anchored eyes run summon block_display ^ ^ ^0.8 {Tags:["bolt","new"]}
execute as @e[tag=new] run data modify entity @s Rotation \
set from entity @a[tag=shooter,limit=1] Rotation
tag @s remove shooter After that, the whole of the movement is one line per tick:
execute as @e[type=block_display,tag=bolt] at @s run tp @s ^ ^ ^1.1
The tag exists for exactly one command. Using @p from the
bolt instead would work almost always and pick the wrong player in a
crowd, which is the worst kind of bug: correct in testing, wrong in a
game.
3. Making an explosion look like Minecraft
Smoke and flame particles look like every other game. The
block particle is a genuine fragment of a block texture, so
an explosion made of them is pixelated by construction rather than by
trying to make smoke look square:
particle block{block_state:{Name:"minecraft:orange_concrete"}} ~ ~ ~ .35 .35 .35 .12 45
A handful of small block_display shards thrown outward and
shrunk away over six ticks does the rest. Six ticks is a blink, which is
what an explosion should be.
Collision, without a list of every solid block
The obvious way to test whether a bolt has hit something is to ask whether the block it is in is solid. There is no tag for that, and a hand-written list of every solid block is wrong the day somebody installs a mod. Invert it: define a block tag of what a bolt flies through — air, water, grass, flowers, torches, rails — and burst on anything else. Grass and flowers matter more than they sound like they do. A bolt that bursts on a daisy is a bolt nobody will use.
Two silent bugs, both caught by tests
The rotation copy read the bolt's own rotation onto itself. A no-op. Every bolt would have flown due south regardless of aim, and nothing anywhere would have complained.
The held-item check tested for "any custom item". The blaster fired when you opened a door.
Both are the same shape of fault: a thing that works in the happy path and is wrong in a way no error message will ever tell you about. In a datapack that shape is the norm, not the exception — which is why every rule we generate now gets its commands read back and checked, rather than trusted because the pack loaded.
The finished thing is on the examples page, being played by four bots on a staged arena: right click, a visible bolt, and a burst of orange cubes where it lands.
Keep reading
The other notes
- There is no right-click event in a datapack No event, no trigger, no on_use. One statistic is the only thing that reports a click.
- We were wrong about modded worlds We said it could not join a modded world. We went and tried, and we were wrong.
- A ladder that is not a ladder 286 blocks in the palette and not one of them worked. So it drew the ladder instead.
- A datapack that installs perfectly and does nothing It loaded, enabled and reported success. Then it answered "Unknown function" for its own tick.
- The six redstone wire rules nobody reasons their way to A repeater faces its input, not its output. Six rules measured, not derived.
- Why a survival benchmark needs a fixture world Every run scored worse than the last. It was eating the forest it was being tested in.
- Digging is not mining Break a block from three steps back and a perfect run scores nothing.