roblox-base
CLAUDE.md1 starsChanged 4 months agoMITView on GitHub
Base environment for building Roblox games with Claude Code. Local development, Rojo file sync, Studio's built-in MCP for feedback. The user is not a developer and does not know Roblox. This shapes everything: - Solve anything technical yourself. Do not ask the user to run commands, edit config, or make technical choices you can make. - Do ask about gameplay, looks, and rules — that is the user's domain and only they can answer it. - Ask about technical matters…
- Reads credentials
In this repository32 other files it gives its agents.
- roblox-analyticsSkill
- roblox-animated-modelsSkill
- roblox-animation-vfxSkill
- roblox-architectureSkill
- roblox-assetsSkill
- roblox-audioSkill
- roblox-buildingSkill
- roblox-cameraSkill
- roblox-cloudSkill
- roblox-code-reviewSkill
- roblox-dataSkill
- roblox-debugSkill
- roblox-guiSkill
- roblox-inputSkill
- roblox-lightingSkill
- roblox-localizationSkill
- roblox-luau-coreSkill
- roblox-luau-patternsSkill
- roblox-luau-typesSkill
- roblox-monetizationSkill
- roblox-networkingSkill
- roblox-npc-aiSkill
- roblox-oauthSkill
- roblox-performanceSkill
- roblox-physicsSkill
- roblox-publish-checklistSkill
- roblox-securitySkill
- roblox-server-dataSkill
- roblox-sharp-edgesSkill
- roblox-studio-mcpSkill
- roblox-toolingSkill
- roblox-ui-designSkill
The file
Show its rules and text
We split this CLAUDE.md into the rules it gives an agent
39 rules. About 0 are common, 30 are distinctive, and 9 are very specific to this project.
≈0
Common · estimate
Many files like this have a rule of this kind.
≈30
Distinctive · estimate
This author's own choices. Worth a look.
9
Very specific
Tied to their project's names, files or tools. Probably skip.
- Common
- Distinctive
- Very specific
- Distinctive: line 12
Do ask about gameplay, looks, and rules — that is the user's domain and only they can answer it.
- Distinctive: line 14
Ask about technical matters only when the impact is large (money, publishing, irreversible actions).
- Distinctive: line 17
When you are blocked, do not surface a stack trace.
- Distinctive: line 19
Never leave the user with a half-finished game state.
- Distinctive: line 28
Do exactly what was asked — nothing more: No speculative features, no "while I'm here" extras, no abstractions for futures nobody requested.
- Distinctive: line 32
Prefer the smallest change that satisfies the request over a larger "cleaner" rewrite.
- Distinctive: line 103
When it really is unavoidable:
- Very specific: line 129
Stop the server afterwards.
- Very specific: line 139
Only if get_studio_state also fails is anything actually wrong.
- Very specific: line 161
When one shot genuinely needs more detail — small GUI text, a texture seam — put the word in the capture_id you were passing anyway:
- Very specific: line 174
Prefer not capturing at all where text will do: inspect_instance and execute_luau answer "is it there, where, what colour" far more cheaply.
- Very specific: line 194
If the asset moves - an animated creature or character - load roblox-animated-models instead.
- Distinctive: line 208
1. The server decides, never the client: Every RemoteEvent and RemoteFunction argument is hostile input: validate type, range, and …
- Very specific: line 214
2. Player data must survive: Every DataStore call goes through pcall with retries.
- Very specific: line 235
Read docs/jatek.md and the part of src/ it touches.
- Very specific: line 239
Write code under src/. The PostToolUse hook checks every Luau file you touch and hands you any error immediately — fix it before moving on.
- Distinctive: line 241
Verify: for anything visible or interactive, use the Studio MCP to inspect, playtest and screen capture.
- Very specific: line 247
Update docs/jatek.md — one line, in Hungarian, player's-eye view.
- Distinctive: line 248
Commit with a short Hungarian message describing what changed for the game.
- Distinctive: line 266
Stop hook, automatically, whenever Luau source changed)
- Distinctive: line 315
Read the root CLAUDE.md
- Distinctive: line 318
Read every CLAUDE.md found along each route
- Distinctive: line 319
If a parent CLAUDE.md lists a child CLAUDE.md whose scope contains the path, read that child and continue from there
- Distinctive: line 320
Use the nearest CLAUDE.md as the local contract and parent docs for repo-wide rules
- Distinctive: line 321
If docs conflict, the closer doc controls local work details, but no child doc may weaken COX
- Distinctive: line 323
Do not rely on memory. Re-read the applicable COX chain in the current session before editing.
- Distinctive: line 327
Every meaningful change requires a COX pass before the task is done.
- Distinctive: line 329
Update the closest owning CLAUDE.md when a change affects:
- Distinctive: line 348
Create a child CLAUDE.md when a folder becomes a durable boundary with its own purpose, rules, responsibilities, workflow, materials, or …
- Distinctive: line 362
Keep docs concise, current, and operational
- Distinctive: line 363
Document stable contracts, not diary entries
- Distinctive: line 364
Put broad rules in parent docs and concrete details in child docs
- Distinctive: line 365
Prefer direct bullets with explicit names
- Distinctive: line 366
Do not duplicate rules across many files unless each scope needs a local version
- Distinctive: line 367
Delete stale notes instead of explaining history
- Distinctive: line 373
Update nearest owning docs and any affected parents or children
- Distinctive: line 375
Remove stale or contradictory text
- Distinctive: line 376
Run existing verification when relevant
- Distinctive: line 381
When the user requests a durable behavior change, record it here or in the relevant child CLAUDE.md
≈ “Common” is an estimate: at least 1 in 5 of the 26,980 CLAUDE.md files we read have a rule of the same kind, not the same words. “Very specific” is our guess from the words: it names a file, a command, a setting or the project itself.
Files
roblox-base
Base environment for building Roblox games with Claude Code. Local development, Rojo file sync, Studio's built-in MCP for feedback.
Who you are working for
The user is not a developer and does not know Roblox. This shapes everything:
- Solve anything technical yourself. Do not ask the user to run commands, edit config, or make technical choices you can make.
- Do ask about gameplay, looks, and rules — that is the user's domain and only they can answer it.
- Ask about technical matters only when the impact is large (money, publishing, irreversible actions). Even then, phrase it in plain language with the consequence spelled out, never in jargon.
- When you are blocked, do not surface a stack trace. Say what needs to happen, in one or two sentences.
- Never leave the user with a half-finished game state. If something cannot be done, say so plainly and say what still works.
Scope and simplicity — non-negotiable
This is a small game maintained with limited resources. There is no capacity to keep over-engineered solutions alive long-term, so over-engineering is not allowed. For the project to stay viable, every change must hold to this:
- Do exactly what was asked — nothing more. No speculative features, no "while I'm here" extras, no abstractions for futures nobody requested.
- Do it the simplest way that works, and follow the conventions already in the surrounding
code and the nearest
CLAUDE.md. - Prefer the smallest change that satisfies the request over a larger "cleaner" rewrite.
This is a survival constraint, not a style preference — persistent over-engineering is grounds to stop the project. It is a matter of judgment and restraint: there is no package whitelist and no type budget, but that is not a licence to add complexity the task does not need.
Language
| What | Language |
| Everything you say to the user | Hungarian |
Documentation, specs, README, docs/ | Hungarian |
| Slash command bodies and their output | Hungarian |
| Code, code comments, identifiers | English |
| This file, agent definitions, skills | English |
| Commit messages | Hungarian |
Command names are English identifiers (/setup), their content is Hungarian.
Project layout
default.project.json Rojo mapping: which folder lands where in the DataModel
src/
client/ -> StarterPlayer.StarterPlayerScripts.Client (LocalScript)
server/ -> ServerScriptService.Server (Script)
shared/ -> ReplicatedStorage.Shared (ModuleScript)
assets/ .rbxm assets saved from Studio (version controlled)
scripts/ Helper scripts; scripts/hooks/ holds the check hooks
types/ Downloaded Roblox API definitions (gitignored)
docs/ Hungarian documentation for the user
build/ Generated .rbxl files (gitignored)File naming under src/:
| File name | Instance created |
Foo.luau | ModuleScript |
Foo.server.luau | Script |
Foo.client.luau | LocalScript |
init.luau in a folder | the folder itself becomes a ModuleScript |
The repo is the source of truth
Studio is a viewer and a test bench, not the place where work is stored. When
you change something in Studio through MCP and it matters, write it back into
src/ (or save it into assets/ as .rbxm). Anything that only exists inside
a Studio session is lost.
Restarting Studio is a last resort
Restart Studio ONLY when there is no other way to get the work done. NEVER out of convenience. A restart is the one thing that puts the MCP connection at risk, and you cannot reconnect it yourself - if it breaks, the user has to do it, and the session stalls. "It would be simpler", "it would be cleaner", "to be safe", "to pick up the change" are not reasons.
Almost everything can be done in the running session instead:
- Stale or missing module? Push it straight in -
multi_editcreates and replaces scripts by dot-path, andexecute_luaucan destroy the old one first. - Wrong property, object, lighting value? Set it with
execute_luau. - Need it to run again?
start_stop_play, not a restart.
Restart only when the place itself is broken beyond what a script can repair -
missing services, a wrecked Workspace - or when Studio is genuinely hung and
stops answering get_studio_state. Before restarting, state to yourself which
in-session route you tried and why it could not work; if you cannot name one,
do not restart.
When it really is unavoidable:
pwsh scripts/restart-studio.ps1It force-kills Studio - no "save changes?" dialog - and reopens
build/game.rbxl. Never ask the user to do this by hand. Run
rojo build default.project.json -o build/game.rbxl first if the place file is
stale, or Studio comes back with old code.
For a large generated file - a baked animation clip is tens of kilobytes - do not send it through the conversation at all. Serve it and let Studio fetch it:
python -m http.server 8731 --bind 127.0.0.1 # from the folder holding the filegame:GetService("HttpService").HttpEnabled = true -- test places only
local body = game:GetService("HttpService"):GetAsync("http://127.0.0.1:8731/Rig.luau")
local module = Instance.new("ModuleScript")
module.Source = body
module.Parent = game.ReplicatedStorage.SharedStop the server afterwards. HttpEnabled is a place setting, so only ever turn
it on in a throwaway test place, never as a side effect in a real game.
When MCP looks dead
list_roblox_studios returning {"studios":[]} proves nothing - it reports an
empty list even while the bridge is working, and following it into shell-level
diagnosis costs hours. Ask get_studio_state instead. If that answers, the
connection is fine; get on with the work.
Only if get_studio_state also fails is anything actually wrong. Then tell the
user, in one sentence, to reconnect Roblox_Studio from /mcp - that part is
theirs, not yours. Do not go process-hunting.
The order matters. Studio dials the bridge when it starts and does not retry.
So a /mcp reconnect while Studio is already open fixes nothing: the new bridge
is listening and Studio is still holding a dead socket. After any reconnect,
restart Studio - bridge first, Studio second. restart-studio.ps1 reports
"has not reconnected" from the same unreliable signal as list_roblox_studios,
so check get_studio_state before believing it.
Screenshots are expensive
A screen_capture from a maximized Studio costs around 1800 tokens, and the
image cannot be shrunk after it arrives — the Studio window size is the
resolution setting.
This is enforced, not left to you. scripts/hooks/pre-capture-resize.ps1 runs
as a PreToolUse hook on screen_capture and sizes the window first. It is a
no-op when the size is already right, so it costs nothing per capture. Do not
resize the window yourself around a capture.
When one shot genuinely needs more detail — small GUI text, a texture seam —
put the word in the capture_id you were passing anyway:
capture_id | Window |
ScreenCapture_4 | medium, the default |
ScreenCapture_hud_full | maximized, for that one capture |
ScreenCapture_4_small | small, for that one capture |
It is scoped to the single call on purpose. There is no mode to switch back, because a forgotten "full" makes every later capture expensive without anything visibly breaking — the next unmarked capture resizes back by itself.
Prefer not capturing at all where text will do: inspect_instance and
execute_luau answer "is it there, where, what colour" far more cheaply.
Capture to judge how something looks.
Skills
Thirty-two Roblox skills live in .claude/skills/. Load the relevant one
before writing code in that area — they carry current API details you should
not guess at. roblox-architecture for structure, roblox-networking for
remotes, roblox-data for saving, roblox-gui for interface, roblox-studio-mcp
for driving Studio, roblox-sharp-edges before anything ships.
Assets
Models, textures and sounds come from free CC0 sites (Kenney, Quaternius,
Poly Pizza, ambientCG, Poly Haven) - never from paid sources, and never as
Roblox Creator Store Models, which can hide backdoor scripts. Import geometry
and textures, which cannot execute code. Load roblox-assets before touching
any of this; the whole pipeline is documented there.
If the asset moves - an animated creature or character - load
roblox-animated-models instead. Roblox has no API that uploads an animation, so
the clips are baked out of the file and played by writing the joint transform
directly. Which pair to use is decided by the file, not by preference:
| The model is | Bake with | Play with | Example |
| separate part meshes | scripts/bake-gltf-animation.ps1 | src/shared/RigAnimator.luau | examples/pets/ |
| one skinned mesh with bones | scripts/bake-skinned-animation.py | src/shared/SkinnedAnimator.luau | examples/characters/ |
Non-negotiable rules
These three mistakes ruin Roblox games, and the user cannot catch any of them.
1. The server decides, never the client. Every RemoteEvent and RemoteFunction argument is hostile input: validate type, range, and ownership on the server. Rate limit anything a player can trigger. Currency, progress, purchases, and rewards are decided server-side only. A client that says "give me 1000 coins" gets nothing.
2. Player data must survive. Every DataStore call goes through pcall with
retries. Use session locking so two servers cannot write the same player.
Migrate old save formats instead of overwriting them. Losing a player's progress
loses the player.
3. Nothing executable comes in from outside. Imported content is geometry,
textures and audio only. A free Creator Store Model can contain a script that
gives its uploader control of the game; if one ever has to be used, run
AssetLoader.sanitize and report what it stripped.
Beyond these: do not disable or bypass the check hooks, and do not commit
secrets — API keys belong in .env, which is gitignored.
Workflow
The user does not type commands. They say what they want the game to do, in
their own words. That sentence is the trigger — run this lane whether or not
/feature was used:
- Understand it in gameplay terms. Ask only what nobody else can decide, one question at a time. Never push a technical choice onto them.
- Read
docs/jatek.mdand the part ofsrc/it touches. Much of what gets asked for builds on something that already exists. - Load the relevant skill(s) before writing code.
.claude/commands/feature.mdhas the routing table from "what the user asked for" to "which skill". - Write code under
src/. The PostToolUse hook checks every Luau file you touch and hands you any error immediately — fix it before moving on. - Verify: for anything visible or interactive, use the Studio MCP to inspect, playtest and screen capture. Do not claim something works because it compiles.
- Review — run
/review(theroblox-revieweragent) whenever the change touches currency, progress, saving, purchases, or anything the client sends the server. Not optional: these are the failures the user cannot catch. Skip it for purely cosmetic changes. - Update
docs/jatek.md— one line, in Hungarian, player's-eye view. - Commit with a short Hungarian message describing what changed for the game.
- Tell the user in Hungarian what changed and what they can try.
Commands
| Command | What it does |
/setup | One-time environment setup |
/new-game | Turn this copy of the template into an actual game, in place |
/design | Game design interview, writes docs/jatek.md |
/feature | Explicit alias for the lane above |
/assets | Get a model, texture or sound from a free CC0 source |
/review | Audit for exploitability and data loss |
/check | Full verification, reported in plain language |
Verification
pwsh scripts/check.ps1- formatting, lint, type check (also runs as the Stop hook, automatically, whenever Luau source changed)pwsh scripts/check.ps1 -Fix- same, but reformats instead of complainingpwsh scripts/update-types.ps1- refresh Roblox API definitionspwsh scripts/bake-gltf-animation.ps1- glTF animation clips -> Luau data module, for part-based models. Checks its own output against the rest pose before writing.python scripts/bake-skinned-animation.py- the same for skinned characters, drivingBone.Transform. Needs Python and, for.fbxinput,fbx2gltf; both are build-time tools, not runtime dependencies.- Studio MCP - the only way to check that something actually looks and behaves right
This repo is a template
It lives at https://github.com/szlay/roblox-base and is a GitHub template
repository. A game is started by cloning it into a new folder (or via "Use this
template" first), opening Claude Code there, and running /new-game — which
renames everything, cuts the clone loose from the template repo, and clears out
what only belonged to the template. The cloning is the user's step; /new-game
works in place.
So keep src/ minimal and generic: it is a starting point, not a game. Worked
examples belong in examples/, never wired into src/.
Because the repo is public, everything committed here is visible to anyone.
Nothing machine-specific, no account IDs beyond the example catalogs, no .env.
Child COX Index
docs/- Hungarian documentation for the user: the spec (roblox-base-specs.md) records decisions,jatek.mdis the running log of whatever game is being built. No child CLAUDE.md yet.examples/- self-contained worked examples, each with its own Hungarian README. Not part of the build; nothing insrc/may require them.
COX framework
- COX is highly performant CLAUDE.md hierarchy installed here
- Agent must follow COX instructions across any edits
Core Contract
- CLAUDE.md files are binding work contracts for their subtrees
- Work products, source materials, instructions, records, assets, and durable docs must stay understandable from the nearest applicable CLAUDE.md plus every parent CLAUDE.md above it
Read Before Editing
- Read the root CLAUDE.md
- Identify every file or folder you expect to touch
- Walk from the repository root to each target path
- Read every CLAUDE.md found along each route
- If a parent CLAUDE.md lists a child CLAUDE.md whose scope contains the path, read that child and continue from there
- Use the nearest CLAUDE.md as the local contract and parent docs for repo-wide rules
- If docs conflict, the closer doc controls local work details, but no child doc may weaken COX
Do not rely on memory. Re-read the applicable COX chain in the current session before editing.
Update After Editing
Every meaningful change requires a COX pass before the task is done.
Update the closest owning CLAUDE.md when a change affects:
- purpose, scope, ownership, or responsibilities
- durable structure, contracts, workflows, or operating rules
- required inputs, outputs, permissions, constraints, side effects, or artifacts
- user preferences about behavior, communication, process, organization, or quality
- CLAUDE.md creation, deletion, move, rename, or index contents
Update parent docs when parent-level structure, ownership, workflow, or child index changes. Update child docs when parent changes alter local rules. Remove stale or contradictory text immediately. Small edits that do not change behavior or contracts may leave docs unchanged, but the COX pass still must happen.
Hierarchy
- Root CLAUDE.md is the COX rail: project-wide instructions, global preferences, durable workflow rules, and the top-level Child COX Index
- Child CLAUDE.md files own domain-specific instructions and their own Child COX Index
- Each parent explains what its direct children cover and what stays owned by the parent
- The closer a doc is to the work, the more specific and practical it must be
Child Doc Shape
- Create a child CLAUDE.md when a folder becomes a durable boundary with its own purpose, rules, responsibilities, workflow, materials, or quality standards
- Work Guidance must reflect the current standards of the project or user instructions; if there are no specific standards or instructions yet, leave it empty
- Verification must reflect an existing check; if no verification framework exists yet, leave it empty and update it when one exists
Default section order:
- Purpose
- Ownership
- Local Contracts
- Work Guidance
- Verification
- Child COX Index
Style
- Keep docs concise, current, and operational
- Document stable contracts, not diary entries
- Put broad rules in parent docs and concrete details in child docs
- Prefer direct bullets with explicit names
- Do not duplicate rules across many files unless each scope needs a local version
- Delete stale notes instead of explaining history
- Trim obvious statements, repeated rules, misplaced detail, and warnings for risks that no longer exist
Closeout
- Re-check changed paths against the COX chain
- Update nearest owning docs and any affected parents or children
- Refresh every affected Child COX Index
- Remove stale or contradictory text
- Run existing verification when relevant
- Report any docs intentionally left unchanged and why
User Preferences
When the user requests a durable behavior change, record it here or in the relevant child CLAUDE.md
Does it work?
Reviews from people and from AI agents that ran it: what they used it for, and whether it worked.
No reviews yet
People and AI agents can review whether this works in practice. Say what you used it for, and whether it worked.
- It worked
- Partly
- It didn't
Using an agent? It can post a review for you after it has run the file: the MCP tool registry_write, action report. How to connect one.
Your trail
Files you open will collect here, so you can find them again.
Open two or more, and you can remix the rules you like from each into one list. Kept in this browser only.
Now do this for your own.
Bring your CLAUDE.md, AGENTS.md or skills. agentleFS shows which of your rules are common, which are yours and which only fit one project, and keeps one version your agents read everywhere.

