Skip to main content
skill Claude Code CX Codex Cursor GitHub Copilot

roblox-luau — Claude Code skill: write Luau scripts for Roblox

A skill that teaches Claude Code to write Luau scripts for Roblox: work with services, create Instances, handle events, and build secure client-server communication via RemoteEvents.

Install into Claude Code · Skills CLI (Vercel) All methods and platforms ↓
npx skills add gamedev-skills/awesome-gamedev-agent-skills --skill roblox-luau -a claude-code
Open on GitHub

What roblox-luau does

The skill gives the agent knowledge of the Roblox API and development patterns. It knows how to write server Scripts, client LocalScripts, and ModuleScripts; place logic correctly between server and client; get a service with game:GetService("Players"); create and parent an Instance; connect events like PlayerAdded or Touched; and send data from client to server via RemoteEvent without security risk.

The skill includes patterns for common tasks: leaderstats for the leaderboard, creating and configuring parts, handling touch events, purchases through RemoteEvent with server-side validation, per-frame updates with RunService, shared code in ModuleScripts. It reinforces critical rules: trust only the server during validation, don't parent an Instance until all properties are set, disconnect events when they're no longer needed.

For persisting data across sessions, use the roblox-datastores skill. Network protocol design, exploit hardening, and input systems are handled by other skills.

What it helps with

  • Write a server script that runs when a player joins
  • Create and configure an Instance (Part, Folder) with the right properties
  • Connect an event (Touched, Heartbeat) and disconnect it properly
  • Send a request from client to server and validate it on the server
  • Update objects every frame without desync

Example prompts for the agent

  • Write a server script to set up leaderstats with coins and experience
  • Create a RemoteEvent for buying items and validate the price on the server
  • Debug a loop with RunService.Heartbeat that rotates a spinner each frame

How to install roblox-luau

1Skills CLI (Vercel)

npx skills add gamedev-skills/awesome-gamedev-agent-skills --skill roblox-luau -a claude-code

2Manually: put the files in place

~/.claude/skills/roblox-luau/SKILL.md

Copy the whole skill folder; for one project use .claude/skills/roblox-luau/

From the same set40

The whole set →
game-feel gamedev-skills Teaches the agent to add feedback to game actions: camera shake, hit-stop, eased tweens, squash and stretch, knockback. For mechanics that work but feel weightless. Claude Code CX Codex Cursor +1 9,400installs game-ui-ux gamedev-skills Engine-neutral game UI architecture skill for responsive layouts, screen stacks, gamepad focus, and event-driven HUD updates. Claude Code CX Codex Cursor +1 9,200installs level-design gamedev-skills Plans playable game levels from blockout through playtesting, covering routes, pacing, gates and encounters. Use it when working on whiteboxes, critical paths or room flow. Claude Code CX Codex Cursor +1 7,500installs camera-systems gamedev-skills Engine-neutral patterns for 2D and 3D game cameras: smooth follow, deadzones, look-ahead, bounds clamping, and third-person collision. Claude Code CX Codex Cursor +1 7,100installs audio-design gamedev-skills A skill that treats game audio as a mixer graph: buses, gain in decibels, sidechain ducking, adaptive music and beat-synced events. Samples use Godot 4.7, Unity gets notes. Claude Code CX Codex Cursor +1 7,100installs performance-optimization gamedev-skills A skill that turns “the game runs slow” into a measured bottleneck and a specific fix: profile first, then pool objects, batch draw calls, cut allocations. Claude Code CX Codex Cursor +1 7,100installs game-ai gamedev-skills Designs NPC decision-making, behavior trees, steering forces, and A* pathfinding. Useful when building game enemy logic across engines. Claude Code CX Codex Cursor +1 7,100installs input-systems gamedev-skills Engine-neutral input system: map keys to named actions, rebinding with conflict detection, keyboard, gamepad and touch support, analog deadzones, input buffering and coyote time. Claude Code CX Codex Cursor +1 6,800installs

Similar

showcase-video rehan-remade Records the game window with the game's own audio, then cuts a short clip or trailer about a mod: titles, transitions, music, fade-out. Claude Code CX Codex Cursor +1 1,400installs fal-assets rehan-remade Generates sprites, tileable textures, 3D models, SFX, and music via fal. Built for modders and game developers who need ready-to-use visual and audio assets directly in their workspace. Claude Code CX Codex Cursor +1 1,400installs orbit-card heygen-com Adds a 10-second 1920×1080 HyperFrames motion block where a single feature card orbits a dot sphere using exported Blender camera paths. Claude Code CX Codex Cursor +1 9,800installs sdf earthtojake This skill authors and validates SDFormat files for models and worlds, then helps prepare them for simulator handoff. Claude Code CX Codex Cursor +1 10,500installs urdf earthtojake This skill helps create, validate, and debug URDF robot descriptions. Use it when working with links, joints, geometry, meshes, or inertial data. Claude Code CX Codex Cursor +1 10,400installs hatch-pet official openai Creates and packages animated pets and spritesheets for Codex. Use it to turn a character concept, reference image, or brand cues into a pet. Claude Code CX Codex Cursor +1 3,300installs gcode earthtojake Slices STL, 3MF, and OBJ models into printer-ready G-code through OrcaSlicer. Use it when you need a print file without connecting to the printer. Claude Code CX Codex Cursor +1 9,500installs dxf earthtojake Generates and validates 2D DXF drawings from Python build123d scripts: outlines, gaskets, panels, flat patterns for cutting. Claude Code CX Codex Cursor +1 9,100installs

Questions about roblox-luau

How do I install roblox-luau in Claude Code?

Run npx skills add gamedev-skills/awesome-gamedev-agent-skills --skill roblox-luau -a claude-code in the terminal, then open ~/.claude/skills/roblox-luau/SKILL.md to verify.

What does the roblox-luau skill do?

It teaches the agent to write Luau code for Roblox: work with services, create and configure objects, handle events, and safely pass data between client and server using RemoteEvents.

How should logic be split between server and client?

The server is the source of truth. The client sends a request via RemoteEvent (e.g., a purchase request), and the server always validates the data and applies changes, because the client can send anything.

Source text

SKILL.md · Apache-2.0
---
name: roblox-luau
description: >
  Script a Roblox experience in Luau: get services, create and parent Instances,
  connect events, run server Scripts vs client LocalScripts, and communicate across
  the client/server boundary with RemoteEvents/RemoteFunctions (server-authoritative).
  Use when building or debugging Roblox Studio scripts — when the user mentions
  Roblox, Luau, services, RemoteEvent, Instance.new, PlayerAdded, or client vs
  server. For saving player data use roblox-datastores.
---

# Roblox Luau Scripting

Script a Roblox experience in **Luau**: services, `Instance`s, events, the
server/client split, and secure cross-boundary communication. Targets the current
Roblox engine and Studio.

## When to use

- Use when writing Roblox scripts: getting services, creating/parenting instances,
  connecting events, deciding server vs client, or wiring `RemoteEvent`/
  `RemoteFunction` communication.
- Use when the project has `Script`/`LocalScript`/`ModuleScript` objects, `.rbxl(x)`
  places, or a Rojo `*.project.json`, and code calls `game:GetService(...)`.

**When *not* to use:** persisting data across sessions → `roblox-datastores`.
Remote protocol architecture, exploit hardening, rate limits, high-frequency replication, and
multi-client abuse testing → `roblox-networking`. Generic Lua questions unrelated to the Roblox
API. Engine-agnostic input/save architecture → `input-systems` / `save-systems`.

## Core workflow

1. **Get services with `game:GetService("Name")`.** Common ones: `Players`,
   `Workspace`, `ReplicatedStorage` (shared client+server), `ServerScriptService`
   (server-only code), `ServerStorage`, `RunService`, `UserInputService` (client).
2. **Know where code runs.** A `Script` runs on the **server**; a `LocalScript`
   runs on a **client** (in `StarterPlayerScripts`, `StarterGui`, or the player's
   character). A `Script` whose `RunContext` is `Client` also runs on clients, from
   `ReplicatedStorage`; check `RunContext` before deciding where a `Script` runs. A
   `ModuleScript` is shared code you `require`.
3. **Create instances deliberately.** `local p = Instance.new("Part")`, set its
   properties, then set `p.Parent` **last** (parenting triggers replication).
4. **React with events.** `:Connect` to signals like `Players.PlayerAdded`,
   `part.Touched`, or `RunService.Heartbeat`. Disconnect when done to avoid leaks.
5. **Cross the client/server boundary with Remotes — and never trust the client.**
   Clients request via `RemoteEvent:FireServer(...)`; the server validates and
   applies. The server is authoritative for all game state.
6. **Test in Studio** with **Test** / **Test Here** / **Server & Clients**; use the
   Output window and the Client/Server toggle to confirm where code ran.
7. **Run static checks before Studio when the project already has the tools.** Put
   `std = "roblox"` in the root `selene.toml`, then run `selene .`.
   For a Rojo project, write the sourcemap once with
   `rojo sourcemap default.project.json --output sourcemap.json`, then run
   `luau-lsp analyze --sourcemap=sourcemap.json src`, passing the Roblox type definitions
   with `--definitions` (`luau-lsp analyze --help` lists the flags). Studio Script Sync
   projects may not have a sourcemap.

## Patterns

### 1. Server Script: react to players joining (leaderstats)

```lua
-- ServerScriptService/Leaderboard.server.luau  (a Script = runs on the server)
local Players = game:GetService("Players")

local function onPlayerAdded(player: Player)
    local stats = Instance.new("Folder")
    stats.Name = "leaderstats"          -- this name makes it show on the leaderboard

    local coins = Instance.new("IntValue")
    coins.Name = "Coins"
    coins.Value = 0
    coins.Parent = stats

    stats.Parent = player               -- parent LAST
end

Players.PlayerAdded:Connect(onPlayerAdded)
```

### 2. Create and configure an instance

```lua
local Workspace = game:GetService("Workspace")

local part = Instance.new("Part")
part.Size = Vector3.new(4, 1, 4)
part.Position = Vector3.new(0, 10, 0)
part.Anchored = true                    -- won't fall under gravity
part.BrickColor = BrickColor.new("Bright blue")
part.Parent = Workspace                 -- set Parent last so it replicates once, fully
```

### 3. Connect an event (and disconnect to avoid leaks)

```lua
local debounce = false
local connection
connection = part.Touched:Connect(function(hit: BasePart)
    local character = hit.Parent
    local humanoid = character and character:FindFirstChildOfClass("Humanoid")
    if not humanoid or debounce then return end
    debounce = true
    humanoid.Health -= 10
    task.wait(1)                        -- task.wait, NOT the deprecated wait()
    debounce = false
end)

-- Later, when the part is removed or the round ends:
-- connection:Disconnect()
```

### 4. Client → server with a RemoteEvent (validate on the server!)

```lua
-- ReplicatedStorage: create a RemoteEvent named "BuyItem" (in Studio or via code).
-- CLIENT (LocalScript): request a purchase. The client can lie — this is only a request.
local ReplicatedStorage = game:GetService("ReplicatedStorage")
local buyItem = ReplicatedStorage:WaitForChild("BuyItem")  -- wait: may not have replicated yet
buyButton.MouseButton1Click:Connect(function()
    buyItem:FireServer("sword")        -- send the item id only; never the price/result
end)
```

```lua
-- SERVER (Script): the ONLY place the transaction is decided.
local ReplicatedStorage = game:GetService("ReplicatedStorage")
local buyItem = ReplicatedStorage:WaitForChild("BuyItem")
local PRICES = { sword = 100, shield = 75 }

buyItem.OnServerEvent:Connect(function(player: Player, itemId)
    -- TRUST NOTHING from the client. Validate types and values.
    if type(itemId) ~= "string" then return end
    local price = PRICES[itemId]
    if not price then return end                         -- unknown item
    local coins = player.leaderstats.Coins
    if coins.Value < price then return end               -- can't afford
    coins.Value -= price                                 -- server applies the change
    grantItem(player, itemId)
end)
```

### 5. A per-frame loop with RunService

```lua
local RunService = game:GetService("RunService")
-- Heartbeat fires every frame AFTER physics; dt is seconds since the last step.
RunService.Heartbeat:Connect(function(dt)
    spinner.CFrame *= CFrame.Angles(0, math.rad(90) * dt, 0)  -- 90deg/sec, frame-independent
end)
```

### 6. Shared code in a ModuleScript

```lua
-- ReplicatedStorage/GameConfig (a ModuleScript) — usable by server and client.
local GameConfig = {}
GameConfig.MaxHealth = 100
function GameConfig.damageFor(weapon: string): number
    return ({ sword = 25, bow = 15 })[weapon] or 0
end
return GameConfig
```

```lua
local GameConfig = require(game:GetService("ReplicatedStorage"):WaitForChild("GameConfig"))
print(GameConfig.MaxHealth)
```

## Pitfalls

- **Trusting the client is an exploit** → clients can send any arguments to a
  `RemoteEvent`/`RemoteFunction`. Validate every argument's type and range on the
  server and keep the server authoritative over health, currency, and inventory.
- **`LocalScript` doesn't run where you put it** → LocalScripts run in
  `StarterPlayerScripts`, `StarterCharacterScripts`, `StarterGui`, or tools — not in
  `Workspace` or `ServerScriptService`. Server `Script`s belong in
  `ServerScriptService`/`Workspace`. A `Script` with `RunContext = Client` placed in a
  `Starter*` container runs twice (original and copy); keep those in `ReplicatedStorage`.
- **Deprecated globals** → use `task.wait`/`task.spawn`/`task.delay`, not the old
  `wait()`/`spawn()`/`delay()` (worse scheduling and throttling).
- **Parenting first, then setting properties** → set properties first and `Parent`
  last so the instance replicates once in its final state.
- **`nil` on the client right after join** → objects stream/replicate over time; use
  `parent:WaitForChild("Name")` instead of indexing directly on the client.
- **Connections never disconnected** → long-lived `:Connect` handlers leak and can
  fire on destroyed objects; store the connection and `:Disconnect()` (or use
  `Instance:GetAttributeChangedSignal`/`:Once` where appropriate).
- **Using a RemoteFunction where a RemoteEvent fits** → `RemoteFunction` blocks
  waiting for a return and a malicious/slow client can stall the server; prefer
  one-way `RemoteEvent`s unless you genuinely need a reply.
- **Assuming the old type checker** -> Luau's New Type Solver reached general release
  (out of Studio Beta) in Nov 2025. `nocheck`/non-strict places get it automatically;
  strict-mode places opt in with the `UseNewLuauTypeSolver` workspace property, and
  `LuauTypeCheckMode` sets a place's default checking mode. It runs only at edit time
  (no runtime cost), so triage type warnings against the solver the place actually has
  enabled, not older behavior.

## References

- For the full client/server model (replication, `RemoteFunction` vs `RemoteEvent`,
  `:WaitForChild` timing, `BindableEvent` for same-context messaging, attributes,
  `CollectionService` tags, and `:Once`/connection cleanup), read
  `references/client-server.md`.

## Related skills

- `roblox-datastores` — persist player data across sessions (server-only).
- `roblox-networking` — production remote contracts, server validation, rate limits, replication,
  streaming, prediction, and multi-client testing.
- `save-systems` — engine-agnostic persistence concepts.
- `game-ai` / `input-systems` — portable AI and input patterns to implement in Luau.

© gamedev-skills · Apache-2.0 · gamedev-skills/awesome-gamedev-agent-skills

See also

Project sponsors

Companies that keep this analytics open
Gold sponsor

Impressions, clicks and code copies — open statistics. We keep the numbers public for the same reason NeBlask itself is public. Become a sponsor