Player control
Lesson 12.9
Mods often change how a player moves, looks or plays: a broken leg, a missing arm, a cursed item that can’t be dropped, a cutscene that walks for you. This lesson does all of that on the server, so every player sees the same thing and nobody rubber-bands.
Slow them down
player:add_movement_modifier{ id = "broken_leg", speed_mult = 0.6, can_sprint = false, sway = 2 }
player:remove_movement_modifier("broken_leg")
print(player:movement().speed_mult)
Each modifier has an id, so several stack (speed_mult values multiply) and you can remove one alone. jump_mult, can_jump = false and step_height work the same way. Speed, jump and step height are vanilla attributes, so even players without Celestial move correctly. sway makes the camera wobble a little (Celestial clients).
Change the model
player:set_part_visible("left_arm", false)
player:set_part_model("right_leg", "my_mod:models/peg_leg.glb")
player:set_part_model("right_leg", nil) -- the normal leg again
The parts are head, hat, body, jacket, left_arm, left_sleeve, right_arm, right_sleeve, left_leg, left_pants, right_leg, right_pants and cape.
For animations, register a glTF file whose nodes are named like the parts once, then play its clips on the player:
cl.on("lifecycle.register", function() cl.render.player_animations("my_mod:models/player/moves.glb") end)
player:anim_play("wave", { layer = 1 })
Hands, slots and keys
player:set_hand_disabled("off_hand", true)
player:lock_slot(0) -- can't move, drop or swap the item in slot 0
player:unlock_slot(0)
player:set_input_override{ crouch = true } -- the player crouches until you clear it
player:clear_input_override()
Food and air
player:set_food(4)
player:exhaust(2)
player:set_air(100)
player:set_natural_regen(false) -- no healing from a full food bar
The camera (client)
if cl.camera.is_first_person() then cl.log("first person at %s", tostring(cl.camera.position())) end
Exercise
Make a command /curse that locks the selected slot of the player, slows them to half speed, and undoes both after 10 seconds.
Show a solution
cl.on("server.command_register", function()
cl.cmd.register(cl.cmd.literal("curse"):executes(function(ctx)
local p = ctx:player()
if not p then return 0 end
local slot = p:selected_slot()
p:lock_slot(slot)
p:add_movement_modifier{ id = "curse", speed_mult = 0.5 }
cl.spawn(function()
cl.sleep_ticks(200)
p:unlock_slot(slot)
p:remove_movement_modifier("curse")
end)
return 1
end))
end)
Recap: movement modifiers change speed, jumps and sprinting, part functions change the model, player_animations animates it, hands, slots and keys can be locked or forced, and food, air and healing are yours to set. More in the guide Player Control.