Example mod · theonaris.examples.host-tools 1.0.0
Host Tools
Multiplayer example. The host can bring every player to them with one button. Players can make the host glow in a colour of their choice, with a light floating above them that only they see.
A multiplayer example with two sides that trust each other only as much as they should:
- The host gets a Summon everyone button (F6) that brings every player to them, standing in a circle.
- Other players get Highlight host (F9), which makes the host glow in a colour of their choice, with a small light floating above them. Only they see it.
| You will learn | Where |
|---|---|
| Splitting a mod into server and client scripts | mod.json → entry |
| Client asks, server decides: validating a request | net.send in client.lua, net.handle in server.lua |
| Moving players (server only) | Player:teleport |
| Telling everyone, and remembering it for late joiners | net.broadcast, net.state |
A panel from .uxml + .uss | ui/host-tools.uxml, ui/host-tools.uss |
| Key bindings kept as settings, with defaults | "type": "key" settings, input.bind |
| Highlighting a player that only you see | Player:highlight, Player:clearHighlight |
| A light that follows a player around | world.shape, Object:followPlayer, Object:addLight |
Try it
You need two computers with the game (it runs one copy per computer): host on one and join from the other.
- Install the mod on the host. Players who join are offered the download automatically, because
"network": "required". - Host a game. Join from the second computer and walk somewhere else.
- On the host, press F6 or the button. The other player lands next to you, and both hear it.
- On the other player, press F9. The host glows in the highlight colour, with a small light above them.
Both keys, the highlight colour, the circle's size and the time between summons are settings declared in mod.json: change their defaults there, or from a script with mod.settings.set. The last two are server settings, so the host's values apply to everyone.
Why the server checks everything
A client script runs on a player's own computer and can be changed by that player. The client therefore only asks (net.send("summon")), and server.lua decides:
net.handle("summon", nil, function(player)
if not player:isHost() then return false, "Only the host can summon everyone." end
-- cooldown check, then the teleports
end, { rate = 2 })The player argument is filled in by the game from the network connection. A client cannot pretend to be someone else. net.handle also caps how often each player may ask (rate, here twice a second), and returning false, reason answers that player on the denied channel, which client.lua shows as a message.
The highlight
Player:highlight(look) takes a colour and draws a soft glow over the player, seen only by the player who asked for it. It also accepts one of your materials, from assets.material, if you want a different look. Player:clearHighlight() removes it again; a player who leaves takes their highlight with them, which is why the script checks isValid() before clearing.
The floating light is an ordinary world object: a small sphere from world.shape, attached to the host with Object:followPlayer and lit with Object:addLight. Changing the colour setting while the highlight is on redraws both.
Files
mod.json
scripts/server.lua permission checks, cooldown, teleports, replicated counter
scripts/client.lua panel, keys, highlight, reactions to server messages
ui/host-tools.uxml panel layout
ui/host-tools.uss panel styles (variables, hover and disabled states)
sounds/summon.wav, arrive.wav, ping.wavAll files
| File | Size |
|---|---|
mod.json | 2 KB |
README.md | 4 KB |
scripts/client.lua | 5 KB |
scripts/server.lua | 2 KB |
sounds/arrive.wav | 172 KB |
sounds/ping.wav | 103 KB |
sounds/summon.wav | 276 KB |
ui/host-tools.uss | 1 KB |
ui/host-tools.uxml | 620 B |