Example mod · theonaris.examples.thruster-tuner 1.0.0
Thruster Tuner
A building tool. Select thrusters, engines, servos or any other part and set their values from one window. The host can unlock limits past the game's normal ratings.
A building tool with its own window. Select thrusters, jet engines, servos or any other working part, click ⚙ Tuner on the building toolbar, and every adjustable number on the selection appears as a slider. The host can unlock a setting past its normal limit, for everyone on the server.
| You will learn | Where |
|---|---|
| Adding a button to the building toolbar | building.addTool |
| Reading the selection and each block's settings | building.selection, building.onSelectionChanged, Block:settings, Block.mechanism |
| Changing settings like the block's own panel does | Block:trySet (needs building.edit) |
| Raising limits for the whole server | building.raiseLimit, building.resetLimit (needs building.limits) |
| Never trusting a number from a client | net.handle in server.lua, which computes the new limit itself |
| Building interface rows from code | UiElement:addNew, Slider, :on("change") |
| Sending a dragged value a few times a second, not every frame | pending + timer.every(0.1) |
| Server settings the host controls | "scope": "server" in mod.json |
Try it
- Install, allow the permissions in Mods (Review permissions, Allow, Apply changes), and host a game. Raise part limits is marked high risk because it changes the balance for everyone on your server.
- Build something with a few thrusters and open the building editor.
- Select the thrusters and click ⚙ Tuner.
- Drag Thruster · Force. Each selected thruster changes.
- Click Unlock. The slider's range grows to 5× the normal limit (the server setting Unlock multiplier,
multiplierinmod.json). Everyone on the server gets the new limit, and Reset limit puts it back.
How limits work
Every mechanism setting has a normal maximum. building.raiseLimit("Thruster", "Force", 2500000) raises that ceiling for every block of that mechanism, on every machine. The game replicates it to clients and enforces it on the server when a value is set. Limits are keyed by mechanism (Block.mechanism, such as "Thruster"), not by block type, so every thruster-like block shares them.
A raised limit belongs to the mod that raised it. When the mod stops, its limits return to normal. If two mods raise the same limit, the higher ceiling wins.
Why the client never sends the number
The obvious message would be net.send("unlock", { mechanism = "Thruster", setting = "Force", max = 1e9 }). A modified client could then set any limit it liked. Instead the client sends which block it means, and the server reads the normal limit from that block and multiplies it by the host's own setting:
local slot = building.block(data.block):settings()[data.setting]
normal[k] = normal[k] or { max = slot.max, ... }
building.raiseLimit(block.mechanism, data.setting, normal[k].max * mod.settings.get("multiplier"))net.handle checks the shape of every request (a block id and a setting name, both strings) and how often each player sends one, and answers on "denied" by itself when a request is wrong. The handler checks the rest, such as whether the player may unlock at all, and returns false, reason to refuse; the client shows the reason.
Block:set is safe to call from a client for the same reason: the server checks ownership and clamps the value to the current limit, exactly as it does for the block's own panel. The client calls Block:trySet, which returns false and the reason instead of raising an error when a change is refused.
Files
mod.json
scripts/client.lua tool button, window, sliders, throttled sending
scripts/server.lua permission check, limit arithmetic, replicated list of unlocked settings
ui/tuner.uxml window frame (rows are created from code)
ui/tuner.uss
sounds/apply.wav, overdrive.wav, denied.wavAll files
| File | Size |
|---|---|
mod.json | 1 KB |
README.md | 4 KB |
scripts/client.lua | 7 KB |
scripts/server.lua | 3 KB |
sounds/apply.wav | 21 KB |
sounds/denied.wav | 69 KB |
sounds/overdrive.wav | 241 KB |
ui/tuner.uss | 2 KB |
ui/tuner.uxml | 760 B |