Overview
Movement utilities provide functions for calculating movement angles, directional input, edge detection, and velocity manipulation.
Key Functions
getDegreesRelativeToView
Calculates the yaw angle difference between the player’s view and a target position.
fun getDegreesRelativeToView(
positionRelativeToPlayer: Vec3,
yaw: Float = RotationManager.currentRotation?.yaw ?: player.yRot
): Float
Parameters:
positionRelativeToPlayer - Relative position to the player
yaw - Reference yaw angle (defaults to current rotation)
Returns: Angle in degrees (-180 to 180)
Example:
val targetPos = target.position().subtract(player.position())
val degrees = getDegreesRelativeToView(targetPos)
if (abs(degrees) < 45f) {
// Target is in front of player
}
Converts an angle to directional input (forward/back/left/right).
fun getDirectionalInputForDegrees(
directionalInput: DirectionalInput,
dgs: Float,
deadAngle: Float = 20.0F
): DirectionalInput
Parameters:
directionalInput - Current directional input
dgs - Degrees relative to view
deadAngle - Dead zone angle (default 20°)
Returns: Modified DirectionalInput with appropriate directions
Example:
val targetDegrees = getDegreesRelativeToView(targetRelativePos)
val newInput = getDirectionalInputForDegrees(
directionalInput = DirectionalInput.NONE,
dgs = targetDegrees
)
// newInput now has correct forward/back/left/right for moving toward target
findEdgeCollision
Detects collision with edges while moving from one position to another.
fun findEdgeCollision(
from: Vec3,
to: Vec3,
allowedDropDown: Float = 0.5F
): Vec3?
Parameters:
from - Starting position
to - Target position
allowedDropDown - How far player can drop (blocks)
Returns: Position where edge collision occurs, or null if path is safe
Example:
val currentPos = player.position()
val targetPos = currentPos.add(moveVector)
val edgePos = findEdgeCollision(currentPos, targetPos)
if (edgePos != null) {
// Would fall off edge at edgePos
// Stop or change direction
}
stopXZVelocity
Stops horizontal velocity while preserving vertical velocity.
fun LocalPlayer.stopXZVelocity()
Example:
player.stopXZVelocity()
// Player stops moving horizontally but continues falling/jumping
Represents keyboard movement input.
data class DirectionalInput(
val forwards: Boolean,
val backwards: Boolean,
val left: Boolean,
val right: Boolean
)
Common Patterns
// No movement
val noInput = DirectionalInput(false, false, false, false)
// Move forward
val forwardInput = DirectionalInput(true, false, false, false)
// Strafe right
val strafeRight = DirectionalInput(false, false, false, true)
// Forward + right (diagonal)
val diagonalInput = DirectionalInput(true, false, false, true)
Movement Calculations
Strafe Movement
Moving in a direction while looking elsewhere:
val handler = handler<MovementInputEvent> { event ->
val targetPos = target.position().subtract(player.position())
val degrees = getDegreesRelativeToView(targetPos)
// Calculate input to move toward target
event.directionalInput = getDirectionalInputForDegrees(
directionalInput = event.directionalInput,
dgs = degrees
)
}
Safe Walk Implementation
val safeWalkHandler = handler<PlayerMoveEvent> { event ->
val currentPos = player.position()
val nextPos = currentPos.add(event.movement)
val wouldFall = findEdgeCollision(
from = currentPos,
to = nextPos,
allowedDropDown = 0.5f
)
if (wouldFall != null) {
// Stop movement to prevent falling
event.movement = Vec3.ZERO
}
}
Speed Calculation
fun getSpeed(): Double {
val dx = player.x - player.xOld
val dz = player.z - player.zOld
return sqrt(dx * dx + dz * dz)
}
Direction Angle
fun getMovementDirection(): Float {
var yaw = player.yRot
if (player.input.left) yaw -= 90f
if (player.input.right) yaw += 90f
if (player.input.backwards) yaw += 180f
if (player.input.left && player.input.backwards) yaw += 45f
if (player.input.right && player.input.backwards) yaw -= 45f
return yaw
}
Velocity Manipulation
Setting Velocity
// Set horizontal velocity
player.deltaMovement = Vec3(
x = sin(-yaw.toRadians()) * speed,
y = player.deltaMovement.y,
z = cos(-yaw.toRadians()) * speed
)
Boost Velocity
fun boost(multiplier: Double) {
player.deltaMovement = player.deltaMovement.multiply(
multiplier,
1.0, // Don't affect Y velocity
multiplier
)
}
Jump Boost
val jumpHandler = handler<PlayerJumpEvent> { event ->
// Increase jump height
event.motion *= 1.2f
}
Movement Events
Modify movement input before processing:
val inputHandler = handler<MovementInputEvent> { event ->
// Force forward movement
event.directionalInput = DirectionalInput(
forwards = true,
backwards = false,
left = false,
right = false
)
}
PlayerMoveEvent
Modify movement vector:
val moveHandler = handler<PlayerMoveEvent> { event ->
// Double movement speed
event.movement = event.movement.scale(2.0)
}
PlayerVelocityStrafe
Modify strafe velocity:
val strafeHandler = handler<PlayerVelocityStrafe> { event ->
// Custom strafe calculation
val customYaw = RotationManager.currentRotation?.yaw ?: player.yRot
event.velocity = Entity.getInputVector(
event.movementInput,
event.speed,
customYaw
)
}
PlayerStepEvent
Modify step height:
val stepHandler = handler<PlayerStepEvent> { event ->
// Increase step height to 1 block
event.height = 1.0f
}
Advanced Examples
Scaffold Walk Pattern
val scaffoldHandler = handler<PlayerMoveEvent> { event ->
val belowPos = player.blockPosition().below()
val isAir = world.getBlockState(belowPos).isAir
if (isAir) {
// Check if movement would cause fall
val nextPos = player.position().add(event.movement)
val edge = findEdgeCollision(
player.position(),
nextPos,
allowedDropDown = 0.1f
)
if (edge != null) {
// Slow down at edges
event.movement = event.movement.scale(0.3)
}
}
}
Sprint in All Directions
val handler = handler<MovementInputEvent> { event ->
if (event.directionalInput.backwards ||
event.directionalInput.left ||
event.directionalInput.right) {
// Convert any movement to forward for sprint speed
event.directionalInput = DirectionalInput(
forwards = true,
backwards = false,
left = false,
right = false
)
}
}
Auto-Jump
val jumpHandler = handler<GameTickEvent> {
if (player.horizontalCollision && player.onGround()) {
player.jumpFromGround()
}
}
Best Practices
Use findEdgeCollision for safe walk implementations to prevent falling off blocks.
Manipulating velocity directly can conflict with other movement modules. Use events when possible.
Movement calculations should account for rotation differences when using silent aim or rotation modifications.
See Also