
Roblox Core
- 68 installs
- 10 repo stars
- Updated May 27, 2026
- stackfox-labs/luau-skills
Helps with ai & agent building tasks.
About
roblox-core is a Claude Code skill for ai & agent building. It helps solo builders move faster with AI-assisted development.
- roblox-core
- AI & Agent Building
- AI-coding skill
Roblox Core by the numbers
- 68 all-time installs (skills.sh)
- +1 installs in the week ending Aug 5, 2026 (Skillselion tracking)
- Ranked #5,858 of 16,546 AI & Agent Building skills by installs in the Skillselion catalog
- Data as of Aug 5, 2026 (Skillselion catalog sync)
npx skills add https://github.com/stackfox-labs/luau-skills --skill roblox-coreAdd your badge
Show developers this skill is listed on Skillselion. Paste this into your README.
| Installs | 68 |
|---|---|
| repo stars | ★ 10 |
| Last updated | May 27, 2026 |
| Repository | stackfox-labs/luau-skills ↗ |
What it does
Helps with ai & agent building tasks.
Files
roblox-core
When to Use
Use this skill when the task is primarily about core Roblox runtime structure and everyday gameplay scripting:
- Choosing whether logic belongs on the client, server, or both.
- Deciding where
Script,LocalScript, andModuleScriptinstances should live. - Organizing code across
ServerScriptService,ServerStorage,ReplicatedStorage,ReplicatedFirst,StarterPlayer,StarterGui, andWorkspace. - Using services, module reuse, attributes, and bindables inside normal gameplay code.
- Working with common Studio scripting workflows like playtesting, Explorer layout,
WaitForChild(), and Output-driven debugging. - Implementing straightforward input, camera, raycasting, collision, and
CFramebehavior as part of ordinary experience scripting.
Do not use this skill when the task is mainly about:
- Exhaustive engine API lookup or class-by-class reference browsing.
- Cross-boundary remote design, advanced remote security, or server-authority architecture.
- Persistence, memory stores, messaging, Open Cloud, OAuth, or external automation.
Decision Rules
- Use this skill if the main question is structural: where code lives, what runs where, what replicates, or how to organize reusable Roblox logic.
- Use this skill for foundational engine patterns that appear in most experiences: services, modules, attributes, bindables, basic input, workspace access, collisions, raycasts, camera, and
CFrame. - If the task centers on
RemoteEvent,RemoteFunction, trust boundaries, request validation, or multiplayer message design, hand off toroblox-networking. - If the task is mainly "which API/member do I call" across a large Roblox surface area, hand off to
roblox-api. - If the task centers on saving, loading, quotas, versioning, cross-server state, or ephemeral shared state, hand off to
roblox-data. - If the task involves Open Cloud, web APIs, credentials, OAuth, or external tooling automation, hand off to
roblox-cloudorroblox-oauth. - If a request mixes core structure with out-of-scope systems, answer only the foundational Roblox portion and explicitly exclude the rest.
- If unsure, prefer the narrower interpretation and omit material that would overlap networking, data, cloud, or API-reference skills.
Instructions
1. Start by identifying the runtime side for each responsibility:
- Server for authoritative world state, spawning, rule enforcement, and shared simulation.
- Client for player-local input, camera, moment-to-moment presentation, and local feedback.
- Shared modules only when both sides need the same code or constants.
2. Place code in containers that match replication behavior:
ServerScriptServicefor server-only scripts and modules.ServerStoragefor server-only assets or modules that do not need to replicate.ReplicatedStoragefor shared modules and replicated assets.ReplicatedFirstonly for earliest client startup work.StarterPlayerScripts,StarterCharacterScripts,StarterGui, andStarterPackfor client behavior copied into each player.
3. Prefer explicit script intent:
- Use
LocalScriptorScriptwithRunContext = Clientfor client code. - Use
ScriptwithRunContext = Serveror normal server placement for server code. - Use
ModuleScriptfor reusable logic and configuration.
4. Retrieve services once near the top of a script with game:GetService() and keep names aligned with service names. 5. Use WaitForChild() when accessing replicated objects from the client unless the load order is guaranteed by the container being used. 6. Treat ModuleScript return values as cached per Luau environment:
- Require once per script and reuse the returned table or function.
- Avoid circular requires.
- Keep shared modules side-agnostic unless the module is intentionally server-only or client-only.
7. Use attributes for lightweight per-instance state and configuration that should live on the instance itself. 8. Use bindables only for communication on the same side of the client-server boundary. Prefer module-owned bindables when they simplify a local event API. 9. For input and camera code, keep implementation client-side and adapt to the player's active input mode rather than assuming desktop-only controls. 10. For workspace scripting:
- Read and write object state through clear references.
- Use raycasts for intentional spatial queries.
- Use collision groups or part properties for collision behavior.
- Use
CFrameoperations when orientation and relative transforms matter.
11. Keep examples and guidance at the foundational level. Do not drift into persistence, advanced networking security, or exhaustive reference lookups.
Using References
- Open
references/scripting-overview.mdfor the basic Roblox scripting workflow in Studio and the standard service-module-function-event script shape. - Open
references/client-server-runtime.mdto reason about authority, replication, edit versus runtime data models, and what each side can safely assume. - Open
references/script-locations-and-script-types.mdwhen deciding betweenScript,LocalScript,ModuleScript, run contexts, and container placement. - Open
references/services.mdfor the coregame:GetService()pattern and which container or gameplay services matter most in foundational code. - Open
references/modulescripts-and-reuse-patterns.mdfor module caching, shared code placement, configuration modules, and encapsulation patterns. - Open
references/attributes.mdfor per-instance state, replication-order cautions, and change-detection patterns. - Open
references/bindable-events.mdfor same-side script communication, async events, sync callbacks, and argument-shape cautions. - Open
references/input-overview.mdfor client-side input handling and adapting to preferred input type across devices. - Open
references/workspace-basics-camera-raycasting-collisions-and-cframes.mdfor the most common world-facing runtime patterns.
Checklist
- Each responsibility is assigned to the correct runtime side.
- Script and module placement matches replication and visibility needs.
- Shared code is in
ModuleScriptform instead of duplicated across scripts. - Client code uses
WaitForChild()where replication order is uncertain. - Services are retrieved once and reused.
- Attributes are used for lightweight instance state, not arbitrary module data.
- Bindables are only used on one side of the client-server boundary.
- Input and camera code stays client-side.
- Raycasts, collisions, and
CFrameoperations are used intentionally for spatial logic. - No advanced remote-security design is included.
- No persistence, Open Cloud, OAuth, or external API automation guidance is included.
- No exhaustive API catalog material is included.
Common Mistakes
- Putting server-only logic in
ReplicatedStorageor other replicated containers. - Expecting a plain
Scriptto run everywhere without considering location orRunContext. - Using
LocalScriptwhere a sharedModuleScriptshould hold reusable logic. - Assuming replicated objects already exist on the client and skipping
WaitForChild(). - Treating bindables as cross-network communication tools.
- Mutating a module return value without realizing the cached reference is reused within that environment.
- Using attributes for large structured data that belongs in a module or system object.
- Driving camera or input code from the server.
- Using
Touchedfor non-physical overlap logic that should be a raycast or explicit spatial query. - Moving parts with raw position logic when relative transforms or facing direction require
CFrame.
Examples
Choose placement by responsibility
-- ServerScriptService/SpawnController
-- Spawns and manages shared world state on the server.-- StarterPlayer/StarterPlayerScripts/InputController
-- Reads player input and drives local presentation on the client.-- ReplicatedStorage/Shared/Constants
-- Shared module used by both sides.
local Constants = {
MaxHealth = 100,
RoundLength = 120,
}
return ConstantsUse the standard script shape
local Players = game:GetService("Players")
local ReplicatedStorage = game:GetService("ReplicatedStorage")
local RoundConfig = require(ReplicatedStorage:WaitForChild("RoundConfig"))
local function onPlayerAdded(player)
print(player.Name, "joined; round length:", RoundConfig.RoundLength)
end
Players.PlayerAdded:Connect(onPlayerAdded)Keep client-only camera code local
local Workspace = game:GetService("Workspace")
local camera = Workspace.CurrentCamera
camera.CameraType = Enum.CameraType.Scriptable
camera.CFrame = CFrame.lookAt(Vector3.new(0, 10, 20), Vector3.new(0, 5, 0))
camera.Focus = CFrame.new(0, 5, 0)Use attributes and bindables for local structure
local part = script.Parent
part:SetAttribute("Active", true)
local changed = Instance.new("BindableEvent")
changed.Event:Connect(function(state)
print("State changed:", state)
end)
changed:Fire(part:GetAttribute("Active"))Attributes
Key Concepts
- Attributes are custom per-instance values stored directly on an instance.
- They are useful for lightweight state and configuration that should travel with the object.
- Clients cannot assume replicated attributes arrive in lockstep with unrelated signals or property changes.
- Attribute change signals are often the safest way to react to replicated state changes.
Rules
- Use
SetAttribute(name, value)to create or update an attribute. - Use
GetAttribute(name)for one value andGetAttributes()for the full dictionary. - Delete an attribute by setting it to
nil. - Use
GetAttributeChangedSignal()orAttributeChangedwhen behavior depends on seeing updates. - Use
WaitForChild()before reading from replicated instances whose existence is not guaranteed yet.
Patterns
Create and read attributes
local part = script.Parent
part:SetAttribute("Active", true)
local active = part:GetAttribute("Active")
print(active)Read all attributes
local attributes = script.Parent:GetAttributes()
for key, value in attributes do
print(key, value)
endReact to one attribute change
local part = script.Parent
part:GetAttributeChangedSignal("GrowthRate"):Connect(function()
print(part:GetAttribute("GrowthRate"))
end)Examples
Simple cooldown flag
local part = script.Parent
if not part:GetAttribute("Busy") then
part:SetAttribute("Busy", true)
task.wait(1)
part:SetAttribute("Busy", false)
endRemove an attribute
script.Parent:SetAttribute("Busy", nil)Bindable Events
Key Concepts
BindableEventandBindableFunctioncommunicate only on the same side of the client-server boundary.BindableEventis asynchronous and one-way.BindableFunctionis synchronous and yields untilOnInvokereturns.- Tables passed through bindables are copied, not shared by identity.
Rules
- Use bindables only for server-to-server or client-to-client script coordination.
- Prefer
BindableEventfor notifications andBindableFunctiononly when synchronous return values are necessary. - Do not rely on handler execution order when multiple functions connect to the same bindable event.
- Do not pass mixed tables with numeric and string keys through bindables.
- Avoid metatable-dependent table behavior across bindable calls; metatables are not preserved.
Patterns
Basic bindable event
local bindableEvent = Instance.new("BindableEvent")
bindableEvent.Event:Connect(function(message)
print(message)
end)
bindableEvent:Fire("Round started")Basic bindable function
local bindableFunction = Instance.new("BindableFunction")
bindableFunction.OnInvoke = function(a, b)
return a + b
end
print(bindableFunction:Invoke(2, 4))Module-owned bindable API
local RoundSignals = {}
local started = Instance.new("BindableEvent")
RoundSignals.Started = started.Event
function RoundSignals.fireStarted()
started:Fire()
end
return RoundSignalsExamples
Same-side event coordination
local ServerScriptService = game:GetService("ServerScriptService")
local event = ServerScriptService:WaitForChild("RoundStarted")
event.Event:Connect(function()
print("Update local server systems")
end)Avoid cross-boundary misuse
-- Bindables do not replace RemoteEvent or RemoteFunction.
-- Use them only when both scripts run on the same side.Client-Server Runtime
Key Concepts
- Roblox experiences are multiplayer by default and run in a client-server model.
- The server is the authority for shared experience state and keeps clients synchronized through replication.
- Each client gets its own runtime view of the experience and handles local player presentation.
- Edit-time objects in Studio become runtime objects on the server and then replicate to clients according to container rules.
Rules
- Put shared world rules and durable game-state transitions on the server.
- Put input reading, local UI behavior, and camera control on the client.
- Do not assume the client sees every workspace object immediately, especially with streaming enabled.
- Do not assume a property change and a later signal arrive on the client in the same order unless the API guarantees it.
- Use client-server reasoning to decide placement before writing code.
Patterns
Divide responsibility by runtime side
- Server: spawn world objects, validate state changes, manage player-facing shared state.
- Client: read controls, drive camera, show local feedback, react to replicated state.
- Shared: constants and pure helpers in
ReplicatedStoragemodules.
Replication-aware access
local ReplicatedStorage = game:GetService("ReplicatedStorage")
local SharedState = require(ReplicatedStorage:WaitForChild("SharedState"))- Server-created or server-modified instances may not be available to clients immediately.
- Client code should use
WaitForChild()when load order is uncertain.
Client-local camera
local Workspace = game:GetService("Workspace")
local camera = Workspace.CurrentCamera
camera.CameraType = Enum.CameraType.ScriptableExamples
Shared constant module used on both sides
local Config = {
WalkSpeed = 16,
}
return ConfigServer handles shared world state
local Workspace = game:GetService("Workspace")
Workspace.SpawnLocation.Transparency = 0Input Overview
Key Concepts
- Input handling is client-side work.
- Roblox supports keyboard and mouse, touch, gamepad, and other device inputs.
UserInputService.PreferredInputis a practical way to adapt UI and controls to the player's active primary input mode.- The Input Action System helps define gameplay actions independently from specific hardware buttons.
Rules
- Read player input from client scripts, not server scripts.
- Adapt to preferred input instead of assuming desktop-only controls.
- Use action-oriented bindings when you need one gameplay action to map across multiple devices.
- Use
GetPropertyChangedSignal("PreferredInput")to react when the player's active input mode changes. - Keep core guidance at the overview level; do not turn this skill into a full per-device control catalog.
Patterns
Detect preferred input
local UserInputService = game:GetService("UserInputService")
local function updateInputMode()
local preferredInput = UserInputService.PreferredInput
if preferredInput == Enum.PreferredInput.Touch then
print("Touch")
elseif preferredInput == Enum.PreferredInput.Gamepad then
print("Gamepad")
else
print("KeyboardAndMouse")
end
end
updateInputMode()
UserInputService:GetPropertyChangedSignal("PreferredInput"):Connect(updateInputMode)Action-based thinking
- Define actions like jump, sprint, interact, or fire.
- Map those actions to multiple input types.
- Update on-screen prompts and UI based on preferred input.
Examples
Client-only input controller
local UserInputService = game:GetService("UserInputService")
UserInputService.InputBegan:Connect(function(input, gameProcessed)
if gameProcessed then
return
end
print(input.UserInputType)
end)ModuleScripts And Reuse Patterns
Key Concepts
ModuleScriptobjects package reusable Luau code and are loaded withrequire().- A module runs once per Luau environment and returns a cached value for later requires in that same environment.
- The returned value is usually a table, function, or configuration object.
- Shared modules often live in
ReplicatedStorage; server-only modules often live inServerScriptServiceorServerStorage.
Rules
- Make modules return exactly one non-
nilvalue. - Require modules once per script and reuse the returned reference.
- Avoid circular requires.
- Put modules in replicated or server-only containers according to who needs them.
- Keep shared modules side-agnostic unless they intentionally target only the client or server.
Patterns
Basic module shape
local module = {}
function module.greet(name)
return "Hello, " .. name
end
return moduleShared configuration module
local RoundConfig = {
LengthSeconds = 120,
MaxPlayers = 8,
}
return RoundConfigModule-owned custom event
local Switch = {}
local changed = Instance.new("BindableEvent")
Switch.Changed = changed.Event
function Switch.flip(state)
changed:Fire(state)
end
return SwitchExamples
Require a shared module on the client
local ReplicatedStorage = game:GetService("ReplicatedStorage")
local RoundConfig = require(ReplicatedStorage:WaitForChild("RoundConfig"))
print(RoundConfig.LengthSeconds)Require a server-only module
local ServerStorage = game:GetService("ServerStorage")
local EnemySpawner = require(ServerStorage:WaitForChild("EnemySpawner"))
EnemySpawner.start()Script Locations And Script Types
Key Concepts
- Roblox has three script types:
Script,LocalScript, andModuleScript. Scriptbehavior depends on container placement andRunContext.LocalScriptruns only on the client.ModuleScriptis reusable code loaded withrequire().- Location in the data model determines what replicates and what can run.
Rules
- Use
ServerScriptServicefor server-only scripts and modules. - Use
ServerStoragefor server-only assets or modules that do not need to replicate. - Use
ReplicatedStoragefor shared modules and replicated assets. - Use
ReplicatedFirstonly for earliest client initialization. - Use
StarterPlayerScripts,StarterCharacterScripts,StarterGui, andStarterPackfor client behavior that is copied into each player. - Prefer explicit
RunContextwhen you need aScriptto behave predictably outside legacy server-only placement.
Patterns
Choose script type by job
Script: server logic or explicit run-context logic.LocalScript: player-local behavior.ModuleScript: reusable functions, constants, configuration, or abstractions.
Shared module placement
-- ReplicatedStorage/Shared/InventoryConfig
local InventoryConfig = {
MaxSlots = 20,
}
return InventoryConfigSafe client containers
StarterPlayerScriptsfor general client controllers.StarterCharacterScriptsfor behavior attached to each spawned character.StarterGuifor client UI scripts.ReplicatedFirstfor minimal early-loading client work.
Examples
Server script placement
-- Script in ServerScriptService
print("Runs on the server")Client script placement
-- LocalScript in StarterPlayerScripts
print("Runs on the client")Module placement
-- ModuleScript in ReplicatedStorage
return {
DisplayName = "Arena",
}Scripting Overview
Key Concepts
- Roblox scripting is Luau code attached to objects in the data model.
- A common core script shape is: get services, require modules, define local functions, connect events.
- Studio workflow matters: create scripts in Explorer, run playtests, inspect Output, and use Script Editor navigation.
- Roblox development is organized around runtime containers and object hierarchies, not just source files.
Rules
- Prefer
localvariables and local helper functions inside scripts. - Retrieve services once at the top with
game:GetService(). - Use Output, warnings, and playtests to validate script behavior quickly.
- Treat Explorer location as part of the script's behavior, not just organization.
- Keep core examples grounded in Studio workflows, not external tooling or deployment systems.
Patterns
Standard script structure
local Players = game:GetService("Players")
local ReplicatedStorage = game:GetService("ReplicatedStorage")
local SharedConfig = require(ReplicatedStorage:WaitForChild("SharedConfig"))
local function onPlayerAdded(player)
print(player.Name, SharedConfig.RoundLength)
end
Players.PlayerAdded:Connect(onPlayerAdded)Output-driven debugging
- Use
print()for simple flow checks. - Use
warn()when something is unexpected but non-fatal. - Check Output during playtests instead of guessing whether code ran.
Basic Studio workflow
- Insert the script under the correct container.
- Rename it descriptively.
- Playtest after each small change.
- Use Ctrl-click navigation and Find to follow references across scripts and modules.
Examples
First server script shape
local ServerScriptService = game:GetService("ServerScriptService")
print("Server startup from", ServerScriptService.Name)Read from a parented object
local part = script.Parent
part.Name = "Checkpoint"Services
Key Concepts
- Services expose built-in Roblox engine functionality through
game:GetService(). - A common foundational pattern is: get services, require modules, define local functions, connect events.
- Some services are container services such as
Workspace,ReplicatedStorage, andServerScriptService. - Other services are gameplay helpers such as
Players,RunService,CollectionService, andUserInputService.
Rules
- Retrieve each service once per script and reuse the local reference.
- Keep the variable name aligned with the service name for readability.
- Choose services based on responsibility, then place the script where that responsibility belongs.
- Use
WaitForChild()when a service child may not be replicated yet to the current runtime side. - Avoid turning this skill into exhaustive service-by-service API lookup.
Patterns
Standard service retrieval
local Players = game:GetService("Players")
local ReplicatedStorage = game:GetService("ReplicatedStorage")
local Workspace = game:GetService("Workspace")Use container services intentionally
Workspacefor live world objects.ReplicatedStoragefor shared modules and replicated assets.ReplicatedFirstfor earliest client startup content.ServerScriptServiceandServerStoragefor server-only logic and assets.
Common foundational services
Playersfor player lifecycle events.RunServicefor frame-step or context checks.UserInputServicefor local input detection.PhysicsServicefor collision groups when collision behavior needs structure.
Examples
Connect a player lifecycle event
local Players = game:GetService("Players")
Players.PlayerAdded:Connect(function(player)
print("Joined:", player.Name)
end)Access workspace through a service reference
local Workspace = game:GetService("Workspace")
local baseplate = Workspace:WaitForChild("Baseplate")
print(baseplate.Name)Workspace Basics, Camera, Raycasting, Collisions, And CFrames
Key Concepts
Workspacecontains the live 3D world: parts, terrain, models, attachments, and scripts acting on world objects.- Each client has its own
Workspace.CurrentCamera; camera control is therefore client-side. - Raycasting is the standard way to query the world along a line with optional filtering.
- Collision behavior comes from part properties, touch events, and collision groups.
CFramecombines position and rotation and is the normal tool for facing, offsetting, and orienting objects in 3D.
Rules
- Access workspace through
game:GetService("Workspace"),workspace, orgame.Workspace; use one style consistently. - Keep camera scripting in local scripts and use
CameraType = Scriptableonly when you intend to replace default behavior. - Use
Workspace:Raycast()for directed spatial checks instead of relying on touch events for everything. - Use
CanTouch,CanCollide,CanQuery, and collision groups intentionally; they control different behaviors. - Remember that
Toucheddepends on physical simulation and does not fire for every scripted overlap case. - Use
CFrame.lookAt(),ToWorldSpace(), andLerp()when relative transforms matter more than raw coordinates.
Patterns
Basic workspace access
local Workspace = game:GetService("Workspace")
local baseplate = Workspace:WaitForChild("Baseplate")Scriptable camera
local Workspace = game:GetService("Workspace")
local camera = Workspace.CurrentCamera
camera.CameraType = Enum.CameraType.Scriptable
camera.CFrame = CFrame.lookAt(Vector3.new(0, 12, 18), Vector3.new(0, 4, 0))
camera.Focus = CFrame.new(0, 4, 0)Basic raycast with filtering
local Workspace = game:GetService("Workspace")
local params = RaycastParams.new()
params.FilterDescendantsInstances = {script.Parent}
params.FilterType = Enum.RaycastFilterType.Exclude
local result = Workspace:Raycast(Vector3.zero, Vector3.new(0, -50, 0), params)
if result then
print(result.Instance, result.Position)
endTouch detection with a simple guard
local part = script.Parent
part.Touched:Connect(function(otherPart)
print(part.Name, "touched", otherPart.Name)
end)Relative transform with CFrame
local anchor = workspace.Anchor
local target = workspace.Target
target.CFrame = anchor.CFrame:ToWorldSpace(CFrame.new(0, 2, -4))Examples
Point an object at another object
local turret = workspace.Turret
local goal = workspace.Goal
turret.CFrame = CFrame.lookAt(turret.Position, goal.Position)Collision group assignment
local PhysicsService = game:GetService("PhysicsService")
local part = workspace.Door
PhysicsService:RegisterCollisionGroup("Doors")
part.CollisionGroup = "Doors"