Skip to content

Vectors

Quick Start: Spice it up with twists.

3D math on location primitives: distances, directions, and shifts. The one-line forms live in the cheatsheet. Twins: <pdir> also ships <rdir> and <gdir>; see Role and global twins.

Every vec. op reads its vectors from 3-element lists or 6-element location primitives (first three indices); anything else warns and yields null. The 2d variants instead take [x, z] pairs, triples converted as x=x, y=z (height dropped by design), or 6-element primitives read at indices 0 and 2. All 3D tags keep requiring all three indices explicitly. <pdir:player> is the player's unit look direction, y-up (straight up is [0, 1, 0]); offline or unknown players resolve null silently. Normalizing the zero vector yields [0, 0, 0] silently, never a warning.

Tag Meaning
<vec.add:a,b> [a0+b0, a1+b1, a2+b2].
<vec.sub:a,b> A minus B: the direction from B to A.
<vec.mult:vec,scalar> [v0*s, v1*s, v2*s]; a non-numeric scalar warns plus null.
<vec.normalize:vec> The unit vector ([0, 0, 0] for zero).
<vec.mag:vec> Euclidean length of one vector (0 for zero).
<vec.mag2d:vec> Length over X and Z: pair, triple, or primitive.
<vec.sqrdist:a,b> Squared distance.
<vec.dist:a,b> Euclidean distance.
<vec.sqrdist2d:a,b> Squared distance over X and Z.
<vec.dist2d:a,b> Euclidean distance over X and Z.
<vec.dot:a,b> Dot product scalar.
<vec.cross:a,b> Cross product vector.
<loc.shift:loc,dir,dist> Base plus direction times distance, as [x, y, z, world, pitch, yaw].
<ploc:player> Alias of <plocation:player>.
<pdir:player> Unit look direction, y-up, else null.
<raycast:point,dir,reach,mask> True when the ray hits an included layer.
<raycastext:point,dir,reach,mask,ignore,spread> paid [layer, [[x, y, z], target]] on a hit, null on a miss.

<loc.shift:location,direction,distance> needs a full 6-element base and uses the direction as given, so callers normalize first when they need unit steps; world, pitch, and yaw carry over verbatim from the base. Aim from yourself at Alex, then spawn five blocks ahead of yourself:

- '<gflag:aim,<vec.normalize:<vec.sub:<ploc:Alex>,<ploc:<p>>>>>'
- '<gflag:ahead,<loc.shift:<plocation:<p>>,<pdir:<p>>,5>>'
- 'summon minecraft:armor_stand <list.get:<gflag:ahead>,0> <list.get:<gflag:ahead>,1> <list.get:<gflag:ahead>,2>'

<raycast:point,dir,reach,mask> casts from a located 6-element point [x, y, z, world, pitch, yaw] along a direction up to reach blocks (clamped to 1000): true when an included layer hits, false on a clean miss, null on misuse or an unknown world. The direction is normalized for you, so [2, 0, 0] still aims east. The mask defaults to block+player; write block, player, liquid, all, or +-joined combos like block+liquid. Blocks are occluding cubes, liquids are water and lava, players are body boxes; unloaded chunks never block. Shout when a wall is ahead:

- '<if:"<raycast:<plocation:<p>>,<pdir:<p>>,30,block> == true","<pmsg:<p>,Wall ahead!>" />'

<raycastext:point,dir,reach,mask,ignore,spread> shares the shape, the block+player mask default, and the 1000 clamp, but reports [layer, [[x, y, z], target]] on a hit and null on a miss. The layer is block, player, or liquid; the point is the exact hit coords; the target is the lower-case block name (dirt, stone, chest, water) or the exact player name (Steve, Alex). The optional 5th arg names one player to skip: an eye-point cast starts inside the caster's own box and would otherwise self-hit, so shooter checks pass the shooter. Blank, null, or unknown names skip nobody. The optional 6th arg is an aim cone in degrees: when the exact ray is not a player hit, the nearest unignored body within that many degrees of the ray is acquired instead, as long as its block line from the origin is clear (cover still wins). The cone reports the along-ray distance to the closest approach; blank, null, or missing means exact aim, and negative values warn plus null. Read the layer with <list.get:<gflag:shot>,0> and the target with <list.get:<list.get:<gflag:shot>,1>,1>:

- '<gflag:shot,<raycastext:<loc.shift:<plocation:<p>>,[0,1,0],1.62>,<pdir:<p>>,180,block+player,<p>>>'

Next Steps