Keybinds
Status: Implemented. Keybinds show in Options → Controls, can be rebound to keys and mouse buttons and save in
options.txt. FOV, mouse and camera events (for a smooth zoom) are Planned.
Goal: a Dash key that asks the server to push the player forward, and a Ruby info key that shows a client-side message. Both appear in Controls under “Ruby Tools”.
Language: Lua, with C++ at the end. APIs: Input and keybinds, Networking.
1. Register the keybinds
local dash, info
cl.on("lifecycle.client_setup", function()
dash = cl.keybind.register{ id = "my_mod:dash", default_key = "key.keyboard.r", category = "Ruby Tools", label = "Dash" }
info = cl.keybind.register{ id = "my_mod:info", default_key = "key.mouse.4", category = "Ruby Tools", label = "Ruby info" }
end)
- The option name is
key.<ns>.<path>(key.my_mod.dash). A lang entry with that key names it; otherwiselabeldoes. categoryis a lang key or plain text; empty means your mod’s name.default_keyis a vanilla key name:key.keyboard.r,key.keyboard.left.shift,key.mouse.4,key.keyboard.unknown(unbound).
2. Presses: consume_click on the client tick
cl.on("tick.client_post", function()
if not dash then return end
while dash:consume_click() do
cl.net.send_to_server("my_mod:dash", cl.buf.create(0))
end
while info:consume_click() do
local p = cl.entity.client_player()
if p then cl.client.message("You carry " .. p:count_item("my_mod:ruby") .. " rubies (" .. info:key() .. ")") end
end
end)
consume_click returns true once per press, including presses that happened between ticks, like vanilla KeyMapping. is_down() tells whether the key is held right now.
3. The server side of the dash
The client never moves itself: it asks, and the server decides.
local last = {}
cl.on("lifecycle.register", function()
cl.net.payload_register{ id = "my_mod:dash", dir = "to_server", max_size = 8, handler = function(sender)
local now = sender.level:game_time()
if last[sender.uuid] and now - last[sender.uuid] < 40 then return end -- 2 seconds cooldown
last[sender.uuid] = now
local p = sender.pos
sender:teleport(cl.vec(p.x, p.y + 0.5, p.z)) -- motion APIs are planned; a small hop for now
end }
end)
4. C++
void on_client_setup() override {
clight::keybind::add("my_mod:dash", "key.keyboard.r", [] {
auto b = clight::net::buf_create(0);
clight::net::send_to_server("my_mod:dash", b);
}, {.category = "Ruby Tools", .label = "Dash"});
}
The function runs once per press for the mod’s lifetime.
5. Raw key events
When a keybind isn’t enough (a key combination inside your own screen), subscribe to client.key; cancel it to consume the key. Prefer keybinds: players can rebind them.
Planned
Keybinds with modifier keys and toggle mode, mouse and scroll events, FOV and camera events for a smooth zoom, and setting the player’s motion from the server.