Movement New

Forward, left and up movement of the cmd, the analog vector, and rotate_movement to keep the world direction when the yaw changes.

The movement of a cmd is relative to the yaw of the view: forward and left, each from -1 to 1, plus an up value for flying, swimming and jumping.

At a glance

Method Returns Purpose
get_move() number, number, number forward, left, up
set_move(forward, side, up) nothing sets forward and left, and up when given
get_forward_move(), set_forward_move(value) number / nothing forward alone
get_left_move(), set_left_move(value) number / nothing left alone
get_up_move(), set_up_move(value) number / nothing up alone
get_analog_move(), set_analog_move(forward, side) number, number / nothing gamepad vector, authinput only
rotate_movement(yaw) nothing keep the world direction of the movement after a yaw change

Conventions

Value Positive Negative Notes
forward forward (W) backward (S)  
left (side) left (A) right (D) Bedrock convention: Source sidemove is positive to the right
up rise sink see below

A vector longer than 1 is scaled down to length 1, as the game does: W+D gives 0.707, -0.707.

  createmove authinput
forward, left written to MoveInputComponent: direction flags, analog vector, game vector (times 0.3 while sneaking) and raw vector the Move Vector field, copied to Raw Move Vector; up, down, left, right follow
up > 0 jump_down (jump held) ascend
up < 0 sneak_down (sneak held) descend
up 0 neither neither

Every setter takes finite numbers only: NaN or infinity raises bad argument #n to '<method>' (finite number expected), with n the position of the argument.


Functions

cmd:get_move(): number, number, number

cmd:get_move(): number, number, number

Returns: forward, left, up. Up is 1, -1 or 0.

local forward, left, up = cmd:get_move()

cmd:set_move(forward, side, up)

cmd:set_move(forward: number, side: number, up: number = nil)
Name Type Description
forward number -1 to 1
side number -1 to 1, positive to the left
up number optional: positive, negative or 0; nil keeps the current value

Returns: nothing.

Errors: a component out of -1 to 1: move components must be finite and within [-1, 1].

cmd:set_move(1, 0)
cmd:set_move(0, 0, 1)

cmd:get_forward_move(): number, cmd:set_forward_move(value)

cmd:get_forward_move(): number
cmd:set_forward_move(value: number)
Name Type Description
value number -1 to 1

Sets forward and keeps the left value.

Returns: get_forward_move returns the forward value.

Errors: as set_move.

if cmd:get_forward_move() < 0 then cmd:set_forward_move(0) end

cmd:get_left_move(): number, cmd:set_left_move(value)

cmd:get_left_move(): number
cmd:set_left_move(value: number)
Name Type Description
value number -1 to 1, positive to the left

Sets left and keeps the forward value.

Returns: get_left_move returns the left value.

Errors: as set_move.

cmd:set_left_move(-1)

cmd:get_up_move(): number, cmd:set_up_move(value)

cmd:get_up_move(): number
cmd:set_up_move(value: number)
Name Type Description
value number positive rises, negative sinks, 0 neither

See the conventions table. In createmove, set_up_move(1) is the same as set_button("jump_down") plus releasing sneak_down.

Returns: get_up_move returns 1, -1 or 0.

cmd:set_up_move(1)

cmd:get_analog_move(): number, number, cmd:set_analog_move(forward, side)

cmd:get_analog_move(): number, number
cmd:set_analog_move(forward: number, side: number)

The Analog Move Vector field, filled by a gamepad stick and 0, 0 with a keyboard. authinput only.

Name Type Description
forward number -1 to 1
side number -1 to 1, positive to the left

Returns: get_analog_move returns forward, side.

Errors: in createmove, analog_move is only available in authinput; components as set_move.

local forward, side = cmd:get_analog_move()

cmd:rotate_movement(yaw)

cmd:rotate_movement(yaw: number)

The movement was meant for a view at yaw; rewrite it for the current yaw of the cmd so that the player moves in the same world direction. Call it after set_view_angles with the yaw you had before.

Name Type Description
yaw number degrees, the yaw the movement was written for

The world direction of a movement at yaw y is, in x, z:

world.x = left * cos(y) - forward * sin(y)
world.z = left * sin(y) + forward * cos(y)

rotate_movement(from) turns (left, forward) by from - yaw, which keeps world unchanged. In authinput the move, raw and analog vectors turn together and up, down, left, right are set again from the new vector; the length is kept. In createmove each component is kept within -1 to 1.

Returns: nothing.

Errors: bad argument #1 to 'rotate_movement' (finite number expected).

local _, yaw = cmd:get_view_angles()
cmd:set_view_angles(0, yaw + 90)
cmd:rotate_movement(yaw)

In authinput, lock_angles() does this for you at the end of the callbacks.


Complete example

Strafe left and right every 10 ticks while the player walks forward, and keep the server movement aligned on a packet only yaw.

xiao.cmd.hook("createmove", "zigzag", function(cmd)
    local forward = cmd:get_forward_move()
    if forward <= 0 then return end
    local side = (math.floor((cmd:command_number() or 0) / 10) % 2 == 0) and 1 or -1
    cmd:set_move(forward, side)
end)

xiao.cmd.hook("authinput", "offset", function(cmd)
    if cmd:native_aim() then return end
    local pitch, yaw = cmd:get_view_angles()
    cmd:set_view_angles(pitch, yaw + 15)
    cmd:rotate_movement(yaw)
end)