For whoever owns the repo One-time setup · benefits everyone

Studio Setup.

Every other page on this site teaches a person how to work with Claude. This one configures the studio so that nobody has to. Eight changes, made once, in the repo — after which every teammate's Claude arrives already knowing our conventions, already holding our playbooks, already blocked from the things it shouldn't touch. This is the difference between a tool people use well and a tool that's hard to use badly.

00 — WHO THIS PAGE IS FOR

Two people, one afternoon.

You do not need to read this to use Claude here. If you're looking for install steps, you want Get Started. This page is for the engineer who owns our repo configuration and whoever runs production — the two people whose one-time work turns into everyone else's default.

Owned by engineering

Everything in the repo

Code intelligence, the shared settings file, path-scoped rules, hooks, monitors, the permission allowlist, PR review. All of it lands as committed files, so it's reviewable and revertable like any other change.

Owned by production

The playbook marketplace

One private repo that distributes our skills to every machine automatically. This is the mechanism the homepage's fourth layer describes — without it, "shared skill library" means "someone remembers to tell people."

Owned by nobody yet

The part that decays

Config rots quietly. Whoever sets this up should own re-reading it once a quarter, because a hook that silently stopped firing is worse than no hook at all.

Order of operations

If you only do two of these, do 01 and 02.

Code intelligence pays off the same afternoon you install it, on every single C++ edit anyone makes. The playbook marketplace is the one that compounds — it's what makes a lesson one person learns on Tuesday show up in everyone's Claude on Wednesday. Everything after those two is refinement.

01 — CODE INTELLIGENCE

Give Claude a compiler's eyes.

This is the highest-value item on the page and it takes one line. Claude Code has a built-in language-server tool that stays dormant until you install a code intelligence plugin for your language. For C++, that's clangd-lsp — the same technology behind VS Code's code intelligence.

clangd-lspReal diagnostics on every editinstall studio-wide
What changes immediately

Automatic diagnostics. After every file edit Claude makes, the language server analyzes the change and reports errors and warnings back on its own — type errors, missing includes, syntax problems. If Claude introduces a mistake, it sees it and fixes it in the same turn, instead of discovering it forty minutes later when the build fails.

Real navigation. Jump to definition, find references, hover types, list symbols, trace call hierarchies. On a codebase our size that's dramatically more precise than grep — and it usually lowers context use, because a symbol lookup replaces reading three whole files.

Install
$ claude plugin install clangd-lsp@claude-plugins-official

The clangd binary has to be on the machine and on PATH — if the /plugin Errors tab says Executable not found in $PATH, that's all it means. Unreal projects generate compile databases, so point clangd at ours rather than letting it guess.

Watch the memory. Language servers on a large C++ tree can get heavy. If someone's machine struggles, claude plugin disable clangd-lsp@claude-plugins-official is a clean fallback — Claude reverts to its normal search tools.

Press Ctrl+O when the "diagnostics found" indicator appears to see them inline. Official plugins also exist for C#, Python, Lua, TypeScript, Rust, and more — worth installing for whatever our tooling is written in.

02 — DISTRIBUTE THE PLAYBOOKS

The missing half of "group knowledge."

This whole site tells people that when they solve something painful, the move is "add it to the skill." That's the contribution half. The distribution half — how the other fourteen people actually receive it — is a private plugin marketplace. It's the single change that makes the fourth layer on the homepage literally true instead of aspirational.

01

Create one private repo for the studio's playbooks

Call it something obvious — lastinglight/claude-plugins. Inside, a plugin is just a directory: a .claude-plugin/plugin.json manifest plus folders for the components it ships. All sixteen of our skills, plus custom agents and hooks, become one versioned, installable unit.

{
  "name": "lasting-light",
  "description": "Lasting Light studio playbooks, agents, and guardrails",
  "version": "1.0.0"
}

Directory layout — note that only plugin.json goes inside .claude-plugin/; everything else sits at the plugin root. Putting skills/ in the wrong place is the single most common mistake here.

lasting-light/
├── .claude-plugin/plugin.json
├── skills/            unreal-cpp/SKILL.md, build-and-cook/SKILL.md, …
├── agents/            crash-triage.md, asset-lint.md
├── hooks/hooks.json   the guardrails from section 04
└── monitors/monitors.json
02

Add a marketplace catalog so it's installable

A marketplace is a catalog file — .claude-plugin/marketplace.json — that lists the plugins in the repo. One repo can hold the catalog and the plugins together. Private repos work fine; anyone with git access to it can install from it.

03

Point the game repo at it, once, for everybody

This is the part that makes it automatic. In the game repo's .claude/settings.json — committed, shared — declare the marketplace and the plugins that should be on. When a teammate trusts the repo folder, Claude Code prompts them to install. Nobody has to be told.

{
  "extraKnownMarketplaces": {
    "lasting-light": {
      "source": { "source": "github", "repo": "lastinglight/claude-plugins" },
      "autoUpdate": true
    }
  },
  "enabledPlugins": {
    "lasting-light@lasting-light": true,
    "unreal-engine-skills-for-claude-code@claude-plugins-official": true,
    "clangd-lsp@claude-plugins-official": true
  }
}

With autoUpdate on, Claude Code refreshes the marketplace and updates installed plugins in the background shortly after each session starts — so a skill improved on Tuesday reaches everyone on Wednesday without a single message in a channel.

04

Version deliberately

Set an explicit version in the manifest and bump it when you want people to get changes. Leave it out and every commit counts as a new version, which is fine for a fast-moving internal library and noisy for a stable one. Pick one on purpose.

05

Test before you ship it to fifteen people

Load a plugin straight off disk without installing it, iterate, then commit once it behaves. /reload-plugins picks up changes mid-session.

$ claude --plugin-dir ./lasting-light

And validate the manifest before anyone else sees it:

$ claude plugin validate
Why this matters more than it sounds

Skills on laptops are lore. Skills in a marketplace are infrastructure.

A skill living in one person's .claude/ folder helps exactly one person and disappears when they change machines. The same skill in the marketplace is versioned, reviewable in a PR, updated everywhere at once, and still working after that person moves to a different project. Everything else on this page is a convenience. This one is the studio actually compounding.

03 — CONVENTIONS THAT LOAD THEMSELVES

CLAUDE.md, and the rules folder nobody knows about.

A CLAUDE.md at the repo root loads into every single session automatically — build commands, project structure, "never do X." It's the cheapest way to stop correcting the same thing twice. The catch: it's charged to context on every request, so it has to stay short. Keep it under ~200 lines.

Root level

CLAUDE.md — always loaded

Only things that are true everywhere: how to build, how to run tests, what "done" means here, the hard lines. If Claude gets a convention wrong twice, that's the signal to add a line — not to correct it again in chat.

Rule of thumb: if it's reference material rather than a standing rule, it belongs in a skill, which loads on demand instead.

The underused one

.claude/rules/ — loaded by path

A game repo has wildly different rules for engine code, content, and config. Rules files take a paths frontmatter field, so they only load when Claude is actually touching matching files — precise conventions with none of the context cost.

One file for Source/**/*.cpp (our C++ idioms, UPROPERTY conventions, logging macros), one for Content/** (naming, never hand-edit binary assets), one for Config/**. Each invisible until relevant.

The same trigger tells you when to update these: a repeated mistake or a review comment you've now left three times is a CLAUDE.md edit, not another correction.

04 — HOOKS

Turn our rules of the road into enforcement.

The homepage lists six habits. Right now every one of them is a request — Claude usually follows them, and "usually" is the problem. A hook fires on a lifecycle event whether or not anyone remembered to ask. If a rule has to hold every time, it belongs here rather than in a prompt.

PreToolUseProtect the content folderhighest value
The problem it solves

Binary assets can't be merged and our depot locks them for a reason. An instruction like "never hand-edit files under Content/" is a suggestion. A PreToolUse hook that returns a denial is a wall — and Claude gets told why, so it routes around it correctly instead of retrying.

The same hook is the right place to check that a file is actually checked out before Claude edits it.

In hooks.json
{
  "hooks": {
    "PreToolUse": [
      {
        "matcher": "Write|Edit",
        "hooks": [
          {
            "type": "command",
            "command": "${CLAUDE_PROJECT_DIR}/.claude/hooks/guard-content.sh"
          }
        ]
      }
    ]
  }
}

The script reads the tool call as JSON on stdin. Exit 2 blocks the action and feeds your stderr message back to Claude as the reason. Or return a decision explicitly:

{
  "hookSpecificOutput": {
    "hookEventName": "PreToolUse",
    "permissionDecision": "deny",
    "permissionDecisionReason":
      "Content/ is binary — check it out in P4 and edit in-editor."
  }
}
PostToolUseFormat on every editone-liner
Never review whitespace again

Run clang-format on whatever file Claude just touched. Style stops being a review comment, and diffs stay about the change instead of the formatting. The hook gets the tool call as JSON on stdin, so jq pulls the path out.

In hooks.json
{
  "hooks": {
    "PostToolUse": [
      {
        "matcher": "Write|Edit",
        "hooks": [
          {
            "type": "command",
            "command": "jq -r '.tool_input.file_path' | xargs clang-format -i"
          }
        ]
      }
    ]
  }
}

Hook output lands back in context, so a linter that complains gives Claude something to act on rather than something you find later.

StopStop babysitting the terminalquality of life
The forty-minute cook problem

Compiling and cooking takes long enough that people sit and watch it. A Stop hook fires when Claude finishes responding — turn that into a desktop notification and go do something else.

On Windows, swap the command for a PowerShell equivalent; hooks accept "shell": "powershell".

In hooks.json — macOS
{
  "hooks": {
    "Stop": [
      {
        "hooks": [
          {
            "type": "command",
            "command": "osascript -e 'display notification \"Claude finished\" with title \"Lasting Light\"'"
          }
        ]
      }
    ]
  }
}
SessionStartStart every session orientednice touch
Context nobody has to type

A SessionStart hook runs when a session begins or resumes. Have it print the current branch, the synced changelist, and whether last night's build passed — so Claude opens already knowing where it is, and nobody starts a session by explaining the state of the world.

What the script returns
{
  "hookSpecificOutput": {
    "hookEventName": "SessionStart",
    "additionalContext":
      "Branch: main · synced CL 41822 · nightly: PASS · milestone: Vertical Slice"
  }
}

Keep it to a few lines. This loads every session, so it's the same budget discipline as CLAUDE.md.

There are far more events than these four — PreCompact, SubagentStop, PermissionRequest, FileChanged, SessionEnd, and others. And a hook doesn't have to be a shell command: it can be an HTTP call, an MCP tool call, or even a prompt or subagent that judges whether an action is safe.

05 — BACKGROUND MONITORS

Let Claude watch the log itself.

The sleeper feature for a game studio. A plugin can declare background monitors that Claude Code starts automatically — each one runs a command for the life of the session and delivers every line of its output to Claude as a notification. Nobody has to say "go look at the log."

monitors/monitors.json

Tail the editor log

[
  {
    "name": "unreal-log",
    "command": "tail -F Saved/Logs/LastingLight.log",
    "description": "Unreal editor log",
    "when": "on-skill-invoke:verify-in-editor"
  }
]

Now when someone runs verify-in-editor, Claude sees the warnings and ensure-failures scroll past during the play session — in real time, without being asked to check. That's the "prove it" rule with actual evidence behind it.

The details that matter

How they behave

Gate them. "when": "always" is the default and starts at session start. "on-skill-invoke:<skill>" starts it the first time that skill runs — much better for anything noisy.

Paths. Commands support ${CLAUDE_PROJECT_DIR} and ${CLAUDE_PLUGIN_ROOT}, and run in the session's working directory.

Limits. Interactive sessions only, and they run unsandboxed at the same trust level as hooks — so treat a monitor command with the same care as a hook. Disabling a plugin mid-session doesn't stop a monitor that's already running; it ends with the session.

Same trick works on anything that streams: the build farm's output, a dedicated server's log during a replication test, a file watcher on the content folder.

06 — PERMISSIONS

Kill the prompt fatigue before it kills adoption.

Nothing makes someone quit a tool faster than approving the same command forty times a day. A shared allowlist in the repo's .claude/settings.json pre-approves the commands we run constantly — and, just as importantly, hard-denies the ones nobody should run through an agent. Permission rules merge across scopes, and deny always beats allow.

{
  "permissions": {
    "allow": [
      "Bash(p4 *)",
      "Bash(git status)",
      "Bash(git diff *)",
      "Read(./Source/**)",
      "Read(./Config/**)"
    ],
    "deny": [
      "Read(./.env)",
      "Read(./.env.*)",
      "Bash(p4 obliterate *)",
      "Bash(p4 submit *)"
    ]
  }
}

Allow freely

  • Read-only depot and git queries people run dozens of times an hour
  • Build and test invocations — UnrealBuildTool, RunUAT, the automation runner
  • Reads inside Source/ and Config/

Deny outright

  • Anything that submits, obliterates, or rewrites depot history
  • Reads of .env files and anything under a secrets path
  • Pushes to protected branches — a human presses that button

Tune this from real friction, not from imagination: ask people which prompt annoys them most this week and add that one. An allowlist assembled from guesses is either too tight to help or too loose to trust.

07 — SUBAGENTS AS FILES

Specialists that don't flood the conversation.

A subagent runs in its own isolated context and returns only a summary. That's the fix for the work that produces enormous output nobody will reread — a 200-file asset sweep, a crash-log triage across a week of builds. Drop a markdown file in .claude/agents/ and it's available to everyone who pulls; ship it in the plugin from section 02 and it's available across every repo.

agents/crash-triage.md

Crash triage

Reads callstacks and logs, correlates against recent changelists, returns a ranked list of suspects with reasoning. All the log reading happens out of your window — you get the conclusion.

agents/asset-lint.md

Asset lint

Walks the content folder against our naming, LOD, and texture-budget rules. Hundreds of file reads, one report. Pairs with the asset-lint skill.

agents/blueprint-review.md

Blueprint review

Reads a Blueprint graph and reviews it against our conventions before a human opens it. Preloads the blueprint-review skill so it starts with our standards rather than generic advice.

A custom agent can preload specific skills, restrict its own tools, and run on a different model than your main session. One important limitation to know: edits a background subagent makes land outside your session's checkpoints, so /rewind won't undo them — that's what the depot is for.

08 — REVIEW & AUTOMATION

A reviewer that never gets tired.

For whatever we keep in git — tools, build scripts, this site — Claude can review pull requests automatically and answer questions inside them. Run one command as a repo admin and it walks you through installing the GitHub App and adding the workflow.

$ /install-github-app
@claudeMention it in any PR or issueinteractive
How people use it

Tag @claude in a comment and it analyzes the context and responds — explains a diff, implements a fix, opens a PR from an issue description. It reads our CLAUDE.md, so it reviews against our standards, not generic best practice.

Requires repo admin to install, and the API key goes in repository secrets — never in a workflow file.

Two plugins worth adding

security-guidance reviews each change Claude makes for common vulnerabilities and has it fix what it finds in the same session — before anything reaches review.

$ claude plugin install security-guidance@claude-plugins-official

pr-review-toolkit adds specialized reviewing agents.

$ claude plugin install pr-review-toolkit@claude-plugins-official

A scheduled workflow can also run on a cron and post a digest — "what landed yesterday, what's still open" — which is production's status meeting writing itself. Watch the cost knobs: set --max-turns and a workflow timeout so nothing runs away.

09 — ROLLOUT

The order I'd actually do this in.

01

Install clangd-lsp and the Unreal plugin — day one

Both are one line and both pay off immediately. Add them to enabledPlugins in the repo settings so the whole team gets them rather than the three people who read this page.

02

Write CLAUDE.md — before anything clever

Thirty lines: build commands, test commands, what done means, the hard lines. Everything downstream works better once this exists, and it's the cheapest item here.

03

Stand up the playbook marketplace — first week

Move our sixteen skills out of documentation and into a real installable plugin. Until this exists, the flywheel this whole site describes is turning by hand.

04

Add the permission allowlist — after a week of real use

Deliberately later. Build it from the prompts that actually annoyed people, not the ones you predicted would.

05

Add hooks one at a time — and verify each

Start with the content-folder guard, since that one prevents real damage. Confirm each hook fires before adding the next: a hook you believe is protecting you but isn't is worse than none.

06

Then monitors, agents, and PR review

All genuinely useful, none urgent. Add them when someone hits the specific friction each one removes — which is also the rule for everything else on this site.

Last thing

Write down what you configured, and where.

Six months from now, somebody will wonder why an edit to Content/ gets refused, or why formatting changes appear on its own. Leave a short .claude/README.md next to these files explaining what each one does and who owns it. Config that nobody understands eventually gets deleted by someone who assumes it's dead.

← Back to
Connections