roblox-game-systems

Shows you how to build game systems like money, levels, combat, shops, and rewards in Roblox.

Installation
Run `npx skills add "https://github.com/el4cteo/roblox-skills" --skill "roblox-game-systems"` to install this skill, then follow its SKILL.md instructions for my next request.

Paste this into Claude Code, Cursor, or any agent that can run commands.

SKILL.mdShow the author's original SKILL.md
---
name: roblox-game-systems
description: Recipes for common systems built on server authority - currency service and leaderstats, XP/levels, round loops with intermission and teams, validated melee/ranged combat, inventory and tools, soft-currency shops, obby checkpoints, daily rewards, pets. Use when implementing or reviewing gameplay systems such as rounds, combat, weapons, inventories, shops, currencies, or progression.
---

# Game systems recipes

Every recipe follows the same contract:
1. **State lives on the server** in a service module; persistent parts go through the data layer
   (`roblox-data-stores`).
2. **Clients send intents** through validated, rate-limited remotes (`roblox-security`,
   `roblox-networking`) and render state they receive (attributes, snapshots/deltas).
3. **Config is data**: tunables in a shared/server config module (or live `ConfigService` configs).
4. **Lifecycle-safe**: handles late joiners, respawns, leaving mid-action, and server shutdown.

| System | Reference |
| --- | --- |
| Leaderstats, currency service, XP/levels, daily rewards, obby checkpoints | [references/progression.md](references/progression.md) |
| Round loop (intermission → match → results), teams, spawning | [references/round-system.md](references/round-system.md) |
| Melee and ranged combat with server validation, cooldowns, damage attribution | [references/combat.md](references/combat.md) |
| Inventory, equipping tools, shop purchases (soft currency), pets that follow | [references/inventory-shop.md](references/inventory-shop.md) |

## Currency service (the pattern every economy uses)

```luau
--!strict
-- ServerScriptService/Server/Services/CurrencyService.luau
local Players = game:GetService("Players")

type Balances = { [Player]: number }

local MAX_BALANCE = 1e12

local CurrencyService = {}
local balances: Balances = {}

local function publish(player: Player)
	player:SetAttribute("Coins", balances[player]) -- replicated to every client; UI listens
end

function CurrencyService.load(player: Player, saved: number?)
	balances[player] = math.clamp(saved or 0, 0, MAX_BALANCE)
	publish(player)
end

function CurrencyService.get(player: Player): number
	return balances[player] or 0
end

-- Positive amount only; returns the new balance.
function CurrencyService.add(player: Player, amount: number, _source: string): number?
	local balance = balances[player]
	if balance == nil or not math.isfinite(amount) or amount <= 0 then
		return nil
	end
	balances[player] = math.min(balance + math.floor(amount), MAX_BALANCE)
	publish(player)
	return balances[player]
end

-- Atomic check-and-spend; false if insufficient.
function CurrencyService.spend(player: Player, amount: number, _sink: string): boolean
	local balance = balances[player]
	if balance == nil or not math.isfinite(amount) or amount <= 0 or balance < amount then
		return false
	end
	balances[player] = balance - math.floor(amount)
	publish(player)
	return true
end

Players.PlayerRemoving:Connect(function(player)
	balances[player] = nil -- after the data layer has saved it
end)

return CurrencyService
```

- One module owns each resource; nothing else writes it. Log sources/sinks to analytics
  (`roblox-analytics-liveops`).
- The in-memory balance is saved by the data layer (ProfileStore `profile.Data.coins`) — or make the
  profile table the balance store directly.
- For display, clients read `player:GetAttribute("Coins")` and `GetAttributeChangedSignal("Coins")`.
  `leaderstats` (a Folder with `IntValue`s under the player) shows values in the player list.

## Design checklist for any new system

- [ ] Where does authoritative state live, and how is it persisted?
- [ ] What can the client request, and how is each request validated and rate-limited?
- [ ] What happens on join mid-session, respawn, leave, teleport, and server shutdown?
- [ ] How is it tuned (config) and measured (analytics)?
- [ ] How does it behave with 1 player, full servers, and high latency?
- [ ] Is it streaming-safe on the client?

## Related skills

`roblox-architecture`, `roblox-security`, `roblox-data-stores`, `roblox-networking`,
`roblox-characters-animation`, `roblox-monetization`, `roblox-ui`.

Ships with 4 supporting files:

  • references/combat.md
  • references/inventory-shop.md
  • references/progression.md
  • references/round-system.md

Mirrored from the author's public source. Install counts from the open skills registry.

The systems behind these skills get built for partners every week.

Partner with us