agentleFS
szlayszlay/roblox-base/CLAUDE.md

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

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
  1. Distinctive:

    Do ask about gameplay, looks, and rules — that is the user's domain and only they can answer it.

    line 12
  2. Distinctive:

    Ask about technical matters only when the impact is large (money, publishing, irreversible actions).

    line 14
  3. Distinctive:

    When you are blocked, do not surface a stack trace.

    line 17
  4. Distinctive:

    Never leave the user with a half-finished game state.

    line 19
  5. Distinctive:

    Do exactly what was asked — nothing more: No speculative features, no "while I'm here" extras, no abstractions for futures nobody requested.

    line 28
  6. Distinctive:

    Prefer the smallest change that satisfies the request over a larger "cleaner" rewrite.

    line 32
  7. Distinctive:

    When it really is unavoidable:

    line 103
  8. Very specific:

    Stop the server afterwards.

    line 129
  9. Very specific:

    Only if get_studio_state also fails is anything actually wrong.

    line 139
  10. Very specific:

    When one shot genuinely needs more detail — small GUI text, a texture seam — put the word in the capture_id you were passing anyway:

    line 161
  11. Very specific:

    Prefer not capturing at all where text will do: inspect_instance and execute_luau answer "is it there, where, what colour" far more cheaply.

    line 174
  12. Very specific:

    If the asset moves - an animated creature or character - load roblox-animated-models instead.

    line 194
  13. Distinctive:

    1. The server decides, never the client: Every RemoteEvent and RemoteFunction argument is hostile input: validate type, range, and …

    line 208
  14. Very specific:

    2. Player data must survive: Every DataStore call goes through pcall with retries.

    line 214
  15. Very specific:

    Read docs/jatek.md and the part of src/ it touches.

    line 235
  16. Very specific:

    Write code under src/. The PostToolUse hook checks every Luau file you touch and hands you any error immediately — fix it before moving on.

    line 239
  17. Distinctive:

    Verify: for anything visible or interactive, use the Studio MCP to inspect, playtest and screen capture.

    line 241
  18. Very specific:

    Update docs/jatek.md — one line, in Hungarian, player's-eye view.

    line 247
  19. Distinctive:

    Commit with a short Hungarian message describing what changed for the game.

    line 248
  20. Distinctive:

    Stop hook, automatically, whenever Luau source changed)

    line 266
  21. Distinctive:

    Read the root CLAUDE.md

    line 315
  22. Distinctive:

    Read every CLAUDE.md found along each route

    line 318
  23. Distinctive:

    If a parent CLAUDE.md lists a child CLAUDE.md whose scope contains the path, read that child and continue from there

    line 319
  24. Distinctive:

    Use the nearest CLAUDE.md as the local contract and parent docs for repo-wide rules

    line 320
  25. Distinctive:

    If docs conflict, the closer doc controls local work details, but no child doc may weaken COX

    line 321
  26. Distinctive:

    Do not rely on memory. Re-read the applicable COX chain in the current session before editing.

    line 323
  27. Distinctive:

    Every meaningful change requires a COX pass before the task is done.

    line 327
  28. Distinctive:

    Update the closest owning CLAUDE.md when a change affects:

    line 329
  29. Distinctive:

    Create a child CLAUDE.md when a folder becomes a durable boundary with its own purpose, rules, responsibilities, workflow, materials, or …

    line 348
  30. Distinctive:

    Keep docs concise, current, and operational

    line 362
  31. Distinctive:

    Document stable contracts, not diary entries

    line 363
  32. Distinctive:

    Put broad rules in parent docs and concrete details in child docs

    line 364
  33. Distinctive:

    Prefer direct bullets with explicit names

    line 365
  34. Distinctive:

    Do not duplicate rules across many files unless each scope needs a local version

    line 366
  35. Distinctive:

    Delete stale notes instead of explaining history

    line 367
  36. Distinctive:

    Update nearest owning docs and any affected parents or children

    line 373
  37. Distinctive:

    Remove stale or contradictory text

    line 375
  38. Distinctive:

    Run existing verification when relevant

    line 376
  39. Distinctive:

    When the user requests a durable behavior change, record it here or in the relevant child CLAUDE.md

    line 381

≈ “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.

Keep what fits and drop the rest. Your version, ready for your agents.
Files
CLAUDE.md

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

WhatLanguage
Everything you say to the userHungarian
Documentation, specs, README, docs/Hungarian
Slash command bodies and their outputHungarian
Code, code comments, identifiersEnglish
This file, agent definitions, skillsEnglish
Commit messagesHungarian

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 nameInstance created
Foo.luauModuleScript
Foo.server.luauScript
Foo.client.luauLocalScript
init.luau in a folderthe 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_edit creates and replaces scripts by dot-path, and execute_luau can 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.ps1

It 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 file
game: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.Shared

Stop 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_idWindow
ScreenCapture_4medium, the default
ScreenCapture_hud_fullmaximized, for that one capture
ScreenCapture_4_smallsmall, 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 isBake withPlay withExample
separate part meshesscripts/bake-gltf-animation.ps1src/shared/RigAnimator.luauexamples/pets/
one skinned mesh with bonesscripts/bake-skinned-animation.pysrc/shared/SkinnedAnimator.luauexamples/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:

  1. Understand it in gameplay terms. Ask only what nobody else can decide, one question at a time. Never push a technical choice onto them.
  2. Read docs/jatek.md and the part of src/ it touches. Much of what gets asked for builds on something that already exists.
  3. Load the relevant skill(s) before writing code. .claude/commands/feature.md has the routing table from "what the user asked for" to "which skill".
  4. Write code under src/. The PostToolUse hook checks every Luau file you touch and hands you any error immediately — fix it before moving on.
  5. Verify: for anything visible or interactive, use the Studio MCP to inspect, playtest and screen capture. Do not claim something works because it compiles.
  6. Review — run /review (the roblox-reviewer agent) 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.
  7. Update docs/jatek.md — one line, in Hungarian, player's-eye view.
  8. Commit with a short Hungarian message describing what changed for the game.
  9. Tell the user in Hungarian what changed and what they can try.

Commands

CommandWhat it does
/setupOne-time environment setup
/new-gameTurn this copy of the template into an actual game, in place
/designGame design interview, writes docs/jatek.md
/featureExplicit alias for the lane above
/assetsGet a model, texture or sound from a free CC0 source
/reviewAudit for exploitability and data loss
/checkFull 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 complaining
  • pwsh scripts/update-types.ps1 - refresh Roblox API definitions
  • pwsh 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, driving Bone.Transform. Needs Python and, for .fbx input, 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.md is 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 in src/ 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

  1. Read the root CLAUDE.md
  2. Identify every file or folder you expect to touch
  3. Walk from the repository root to each target path
  4. Read every CLAUDE.md found along each route
  5. If a parent CLAUDE.md lists a child CLAUDE.md whose scope contains the path, read that child and continue from there
  6. Use the nearest CLAUDE.md as the local contract and parent docs for repo-wide rules
  7. 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

  1. Re-check changed paths against the COX chain
  2. Update nearest owning docs and any affected parents or children
  3. Refresh every affected Child COX Index
  4. Remove stale or contradictory text
  5. Run existing verification when relevant
  6. 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

Download now (ZIP)

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
What did you use it for? e.g. Reviewing pull requests in a Rails app

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.