UI Designer
On this page
- Your code lives in the hook scripts
- What an install changes
- Update with Send to Studio (easiest)
- Update with a .rbxmx file
- When the new design has new buttons
- If the new design has a different name
- Security: the client asks, the server decides
- What UI.Server already does for you
- What you do in your handlers
Updating a UI, and security
Made a better design? You can install it over the old one and keep all your code. This page shows what an install changes, how to update each way, and the rules that stop exploiters from giving themselves free stuff.
Your code lives in the hook scripts#
Keep your game code for a UI in its two hook scripts (or in your own scripts), never inside the runtime or the blueprint:
<Name>_UIHooks, a LocalScript in StarterPlayer > StarterPlayerScripts: what happens on the player's screen.<Name>_ServerHooks, a Script in ServerScriptService: everything that gives, sells, checks or saves.
Every export includes them, written from your design by UI.Blueprint.Integration and tagged with your UI's name (the attributes BloxUIHooks, BloxUIHooksSide and BloxUIHooksHash). The tags let an install tell your edited scripts apart, so it never overwrites a hook script you've edited. Leave the attributes on.
What an install changes#
| In the Explorer | When you install a new version |
|---|---|
ReplicatedStorage.BloxUI (the runtime) | Replaced when the new one is a newer build, otherwise kept. |
ReplicatedStorage.BloxUI_Blueprints.<Name> | Replaced with the new design. Changes you made to it by script are gone. |
BloxUI_BlueprintLoader | Kept. It's only added when it's missing. |
<Name>_UIHooks, <Name>_ServerHooks | Send to Studio: added when missing, updated to the new design when you haven't edited them, kept as they are when you have. The .rbxmx: this UI's hook scripts already in place are kept. |
Extras (BloxGame folders) | Send to Studio: new and updated files come in, files you've edited (like GameSettings) are kept, and the files of Extras you switched off are removed unless you edited them. |
| Your own scripts, models and data | Not touched. |
Update with Send to Studio (easiest)#
- Export the new design on the website (Getting started).
- Open your place in Studio and go to the BloxMaps Cloud plugin's UIs tab. Press Refresh.
- Press Insert next to the new design. If something looks wrong, Ctrl+Z undoes the whole install.
- Run your Command Bar edits again (product ids, logo text, colours), because the blueprint was replaced.
- Press Play and test.
Update with a .rbxmx file#
- Download Add to my game (.rbxmx) for the new design and drop it into Studio. A folder
BloxUI_<Name>appears in Workspace. - In that folder, delete
<Name>_UIHooksand<Name>_ServerHooks. Your own copies are already in the right places. - Delete the old
ReplicatedStorage.BloxUI_Blueprints.<Name>, then drag the new<Name>StringValue from the folder'sBloxUI_BlueprintsintoReplicatedStorage.BloxUI_Blueprints. - Replace
ReplicatedStorage.BloxUIwith the folder'sBloxUI, so you have the newest runtime. - With Extras: replace
ServerScriptService > BloxGameandStarterPlayerScripts > BloxGamewith the ones in the folder'sBloxUI_Extras(keep your ownGameSettingsif you edited it), and tick Enabled onBloxGame > Main. - Delete the rest of the folder (the extra loader and
BloxUI_Setup). - Run your Command Bar edits again, then press Play.
When the new design has new buttons#
A new design can fire events or sell products the old hook scripts have no handler for. For Remote actions Output tells you, with lines such as no handler for "Rebirth".
- You haven't edited the hook scripts: Send to Studio replaces them with the new design's. Nothing else to do.
- You have: your scripts are kept, so get fresh ones next to them and move your code over.
- Rename your two hook scripts, for example to
NeonStrike_UIHooks_oldandNeonStrike_ServerHooks_old, and turn off their Enabled box. - On each, delete the
BloxUIHooksattribute (Properties window > Attributes). Without it, installs no longer treat them as the UI's scripts. - Send the UI to Studio again: fresh hook scripts are added. (Or make them with the Command Bar block in If the scripts are missing.)
- Copy your code from the old scripts into the matching handlers of the new ones, or ask an AI to (how).
- Test, then delete the
_oldscripts.
If the new design has a different name#
The loader builds every UI in BloxUI_Blueprints, so an old and a new UI with different names both show up. To switch to the new one:
- Stop the old UI from being built: select
ReplicatedStorage.BloxUI_Blueprints.<OldName>and set itsEnabledattribute tofalsein the Properties window, or delete it. - Your hook scripts wait for the UI by name (
UI.Blueprint.waitFor("<OldName>")). Move your code into the new UI's hook scripts, as in When the new design has new buttons. - Delete the old hook scripts, so only one
UI.Server.startruns.
Security: the client asks, the server decides#
Exploiters can change anything on their own device: LocalScripts, the UI, the values it sends. They can't touch your server scripts. So:
What UI.Server already does for you#
- Prices come from the server's own copy of the blueprint. A player can't change what something costs.
- Buying with coins or gems is refused until the player's data has loaded, then the currency is taken and the item given on the server.
- The
BloxUI_Actionremote is rate-limited (20 events a second per player) and every message is shape-checked before your handler sees it. - Server-only events such as
PurchaseandBought:<itemId>can't be fired by a client. - Robux purchases are only marked as done after the grant and the purchase id are saved together, and game passes are checked with Roblox, not with what the client says.
- Spins, cases and rewards are rolled and decided on the server.
What you do in your handlers#
- Check every value a client sends in
UI.Server.onhandlers: its type, its range, and whether the player is allowed (enough coins, owns the item, cooldown over). The generated stubs start with these checks: keep them. - Never trust an amount or price from the client. Work it out on the server.
- Never give things from notification events (
Purchase,Bought:...). They tell you something already happened. - Give each Robux purchase once. Remember the purchase id and return
truefromonReceiptonly after the player really has the item (how).
-- WRONG: the client says how many coins to add. An exploiter sends 999999.
UI.Server.on("ClaimCoins", function(player, elementId, payload)
UI.Server.grant(player, "coins", payload.amount)
end)
-- RIGHT: the server decides the amount and checks the cooldown.
local lastClaim = {}
UI.Server.on("ClaimCoins", function(player, elementId, payload)
local now = os.time()
if lastClaim[player] and now - lastClaim[player] < 60 then
return -- too soon: ignore
end
lastClaim[player] = now
UI.Server.grant(player, "coins", 50)
end)More examples of checked handlers are in Scripting your UI.