Skip to content

Safety

Safety in Cluaupp is not a sandbox flag. It is a set of habits the compiler and libraries make cheap.

Net lets a client FireServer. The server must validate:

void OnBuy(Player player, int productId) {
if (productId < 1) {
return;
}
int price = PriceOf(productId);
Data data = DataService.Server.WaitFor(player);
if (data == null) {
return;
}
int coins = data.Get(DataService.Server.Paths.Currencies.Money);
if (coins < price) {
return;
}
data.Set(DataService.Server.Paths.Currencies.Money, coins - price);
}

Do not store coins only on the client. Do not let the client pass the new coin total — pass the intent (productId). Full systems: Shop, Combat.

Every Connect that outlives a player, a GUI, or a tool needs a Sweep. Leaving a step, destroying a character, or closing a menu should Cleanup() or LinkToInstance.

auto sweep = new Sweep();
sweep.LinkToInstance(player);
sweep.Add(players.PlayerAdded~>Connect(OnPlayer));

Leaked connections duplicate effects: double coins, stacked cameras, lingering highlights.

FindFirstChild returns null. WaitForChild can hang. Prefer FindFirstChild plus an early return on the hot path.

Keep distinguishes Get() (merged, includes transient admin overlays) from GetPersisted() (what Keep will save). Use SetTransient for test panels so you never persist cheat values. Only the server writes persisted paths. The save shape is your Template — the library does not ship Currencies.

Net packs arguments into a buffer. That is smaller and typed. Do not JSONEncode a whole inventory on every heartbeat. Send deltas. Cap array lengths the client can send.

Remote names (Net::Event("Coins")) are public protocol. Keep them const, short, and unique. Changing a name without a migration breaks old clients.

Next: organization, OOP, Examples.