跳到正文
cccskills
免费在 GitHub 公开

scenario-roblox-architecture

Structure Roblox game code by choosing script locations, separating server and client responsibilities, and organizing modules, services, signals, and tagged behavior. It also helps diagnose duplicate execution, require cycles, respawn problems, and leaked connections.

中文简介正在准备中。当前显示英语简介。

原文查看原文说明

Use when structuring Roblox game code: where scripts go (ServerScriptService, ReplicatedStorage, StarterPlayerScripts), Script vs LocalScript and RunContext, a module loader or framework (Knit or none), services and controllers, how systems talk (signals, BindableEvents, attributes), CollectionService tags, cleanup with Trove or Janitor, Rojo project layout, or a round-based game core. Also when code is spaghetti, a script runs twice, require errors with 'required recursively', a module is nil on the client, a tool stops working after respawn, or memory climbs from leaked connections.

scenario-labs/skills星标 1,170(GitHub 1,170 + cccskills 0)

实测评分 未实测

查看安装方法

适用场景

  • Planning a Roblox game's server and client code layout
  • Untangling a disorganized script structure
  • Diagnosing scripts that run twice or require cycles
  • Fixing tools or interfaces that break after respawn
  • Finding leaked event connections

包含的文件(53)

  • SKILL.md20.4 KB
  • references/critique.md4.9 KB
  • references/expert-notes.md22.3 KB
  • references/gui-paths.md11.5 KB
  • references/procedures.md73.8 KB
  • references/project-setup.md18.5 KB
  • references/sources.md15.7 KB
  • scripts/agentkit/architecture/ArchAudit.luau19.9 KB
  • scripts/agentkit/architecture/Binder.luau4.5 KB
  • scripts/agentkit/architecture/Loader.luau5.7 KB
  • scripts/agentkit/architecture/lune_arch_audit.luau1.1 KB
  • scripts/agentkit/architecture/lune_place_facts.luau2.1 KB
  • scripts/rbx_architecture.py13.7 KB
  • scripts/templates/arena/fixtures/first/FixtureLoadingModule.luau361 B
  • scripts/templates/arena/fixtures/FixtureDoor1/DoorScript.model.json332 B
  • scripts/templates/arena/fixtures/FixtureDoor1/init.meta.json25 B
  • scripts/templates/arena/fixtures/FixtureDoor1/Panel.model.json128 B
  • scripts/templates/arena/fixtures/FixtureDoor2/DoorScript.model.json332 B
  • scripts/templates/arena/fixtures/FixtureDoor2/init.meta.json25 B
  • scripts/templates/arena/fixtures/FixtureDoor2/Panel.model.json128 B
  • scripts/templates/arena/fixtures/FixtureSecondEntry.server.luau91 B
  • scripts/templates/arena/fixtures/FixtureTwiceProbe.client.luau445 B
  • scripts/templates/arena/fixtures/gui/FixturePerLife.model.json65 B
  • scripts/templates/arena/fixtures/gui/FixtureScreens/FixtureNested.model.json66 B
  • scripts/templates/arena/fixtures/replicated/CharacterCache.luau316 B
  • scripts/templates/arena/fixtures/replicated/CycleA.luau156 B
  • scripts/templates/arena/fixtures/replicated/CycleB.luau115 B
  • scripts/templates/arena/fixtures/replicated/FixtureRemote.model.json31 B
  • scripts/templates/arena/fixtures/replicated/GlobalRegistry.luau118 B
  • scripts/templates/arena/fixtures/replicated/LeakyClass.luau570 B
  • scripts/templates/arena/fixtures/replicated/LeakyServerModule.luau374 B
  • scripts/templates/arena/fixtures/replicated/Maps/FixtureMap.model.json245 B
  • scripts/templates/arena/fixtures/replicated/ReachesServer.luau286 B
  • scripts/templates/arena/fixtures/replicated/RemovalLogger.luau343 B
  • scripts/templates/arena/fixtures/replicated/ScoreGui.luau145 B
  • scripts/templates/arena/fixtures/replicated/ScoreService.luau428 B
  • scripts/templates/arena/src/assets/Maps/Crossroads.model.json2.5 KB
  • scripts/templates/arena/src/assets/Maps/Pillars.model.json3.2 KB
  • scripts/templates/arena/src/assets/Tools/Sword.model.json328 B
  • scripts/templates/arena/src/client/Controllers/RoundController.luau2.1 KB
  • scripts/templates/arena/src/client/Controllers/ShopController.luau1.3 KB
  • scripts/templates/arena/src/client/Main.client.luau778 B
  • scripts/templates/arena/src/first/Boot.client.luau342 B
  • scripts/templates/arena/src/gui/Shop.model.json632 B
  • scripts/templates/arena/src/server/Main.server.luau399 B
  • scripts/templates/arena/src/server/Services/MapService.luau5.3 KB
  • scripts/templates/arena/src/server/Services/PlayerService.luau1.9 KB
  • scripts/templates/arena/src/server/Services/RoundService.luau2.8 KB
  • scripts/templates/arena/src/server/Services/TeamService.luau1.7 KB
  • scripts/templates/arena/src/server/Services/WeaponService.luau3.3 KB
  • scripts/templates/arena/src/shared/Config.luau313 B
  • scripts/templates/arena/src/shared/RoundMachine.luau1.7 KB
  • scripts/templates/arena/src/shared/Signal.luau1.8 KB

SKILL.md(原文)

安装前可以查看交给 AI 代理的指令内容。

Roblox architecture (gameplay programmer and architect)

Target: Roblox Studio (October 2026 build) on macOS, driven through the scenario-roblox-expert toolkit.

Expert architecture on Roblox means placement and RunContext decide what runs where, one entry script per side boots every module in two phases, server modules own the truth that attributes mirror, and tags bind behavior to instances with an owner for every connection. This skill carries those rules from the sources, corrected by live tests in Studio 0.743, plus a tested arena core (round loop, teams, maps, HUD, shop, sword) and the tools that build and audit it. If a sibling skill named here is missing from your available skills, ask the user to install it (npx skills add scenario-labs/skills --skill <name>); unattended, proceed from tool schemas and flag the gap.

REQUIRED BACKGROUND: scenario-roblox-expert (channels, review loop, toolkit, current-Roblox traps).

Status (2026-10-19): 14 live tests pass in Studio 0.743; 8 offline checks pass (18 Lune unit tests, luau-lsp on both type solvers over code, fixtures and snippets, StyLua, selene).

Stance (the expert delta)

  1. Pin placement and RunContext: one entry Script per side. Use one Script with RunContext Server in ServerScriptService and one with RunContext Client in ReplicatedStorage (Roblox docs, Script locations; Ludius, n8IDTRW1EfM [00:01:34]; Leif, F3ASTJuO82A [00:03:18]). Everything else is a ModuleScript.

    • A Client Script in StarterPlayerScripts ran twice (live), with a "non-legacy RunContext" warning in Output.
    • Rojo 7.7.1 turns .client.luau into a LocalScript unless the project sets "emitLegacyScripts": false (verified). A LocalScript in ReplicatedStorage never runs.
  2. Boot in two phases through one loader. GetDescendants order is undefined, so no module may call another while loading (Suphi Kaner, YsXijBUUmmM [00:04:22]). Init sets up its own state and never yields; Start may yield and call others (Leif [00:02:25]; docs, start() on every module). Loader.luau adds what the sources skip [added]:

    • an explicit order, then the rest sorted by path; duplicate names fail (Suphi [00:01:50]);
    • one pcall per module, so one broken service does not stop the others;
    • an Init that yields is reported as an error;
    • a frozen registry and a boot report written as attributes.
  3. Server modules own the truth; attributes mirror it; UI owns nothing. A state service never requires its GUI; the GUI calls the service and listens (MrAsync [00:25:46 to 00:31:11]). Publish shared state as attributes on a Configuration that clients observe (Crusherfire, 6Q_p2ObUXSo [00:07:06]). Mirror absolute server times (EndsAt) so clients count down without a timer remote [added]. A property or attribute change and a remote are not ordered relative to each other (docs, Attributes; Server Authority): put the state in the remote payload, or publish it only as attributes and re-render on each change.

  4. Bind behavior by tag, filtered by ancestor. One module drives every tagged instance instead of a script per instance (B Ricey, Vi2FckNJv9w [00:02:44]; GnomeCode, UsPYgIW3rv8 [00:01:38]; docs). Two traps the sources miss [added]:

    • A tagged template in ServerStorage is in GetTagged too: bind only under chosen ancestors.
    • Moving a tagged part from ServerStorage back to Workspace fired no InstanceAdded (live): watch AncestryChanged.

    Binder.luau does both, connects the signals before GetTagged, and runs the cleanup that setup returns.

  5. Every connection has an owner with a lifetime. Wire cleanup to the owner that dies with it, for example a per-tycoon Trove instead of the player's (Crusherfire, 0moy04A9vFg [00:16:38]). Add to the cleanup object at creation (B Ricey, 2Msrw5w5cTs [00:09:27]). Set Workspace.PlayerCharacterDestroyBehavior to Enabled (Crusherfire, YWyJHwynM1M [00:12:34]). Under Deferred signals a Destroying handler runs after the destroy (Crusherfire, xz_G2n1Q8-U [00:12:45]). Live, the handler had not run before the yield and then read Parent nil: capture state before removal; removal handlers only clear tables. A listener connected inside another handler misses the fire already queued, and nested fires run breadth-first (Crusherfire [00:03:19 to 00:08:52]; live): connect every listener in Init.

    • Screens have a lifetime too: each spawn recopies StarterGui into PlayerGui, except direct children with ResetOnSpawn false; a Folder cancels false (docs, On-screen UI containers). Players die every round, so the HUD and shop use false (GnomeCode, oEWoyT-GBZY [00:14:38]) and their run-once controllers keep valid references (live).
  6. Server code and round content never sit in a replicated container. Exploiters can read ReplicatedStorage (Leif [00:01:00]; Crusherfire, 6Q_p2ObUXSo [00:09:13]). Maps stay in ServerStorage until needed, which cuts join traffic (docs, Data model). Clone one into Workspace per round and destroy it after (GnomeCode [00:11:03 to 00:13:51], who keeps them in ReplicatedStorage). Crusherfire relocates server modules from a system folder to ServerScriptService at start (6Q_p2ObUXSo [00:09:47]). Require siblings by relative path so a system can move (Crusherfire [00:23:46]).

  7. The client asks; remotes are made in code. Never create remotes by hand in Explorer (Leif, F3ASTJuO82A [00:04:28]). The client asks "can I build here?" and the server decides (Leif [00:05:39]). Check on the client to save bandwidth and again on the server (MrAsync [00:16:37]).

  8. Pick the framework by team, not taste. Knit-style frameworks decide for you, and everything depends on one service (B Ricey, MyK4o2pIpQw [00:17:58]); the 2025 sources build small loaders (Ludius, Leif, Crusherfire). Solo or small team: this loader, Signal and a cleanup module; an existing Knit codebase: keep it and add the audit [added]. A class only for several stateful instances (B Ricey [00:07:10]); a service is a singleton table (Leif [00:02:00]).

Establish first

  • Session shape: round-based, persistent world or hub; player count; teams.
  • New place or existing code: Rojo or Script Sync repository, Studio-only, or an existing framework to keep.
  • Team size and whether systems are shared across places (Roblox Packages for your own systems, Wally for third-party code).
  • Server Authority (AuthorityMode = Server): it forces Deferred signals and replicates only the first 64 attributes per instance.
  • StreamingEnabled, on in new places (these tests ran with it off): clients wait for streamed parts.

Defaults: Rojo project with emitLegacyScripts false, the arena skeleton below, Deferred signals, PlayerCharacterDestroyBehavior Enabled, --!strict.

Procedure

Setup: import rbx_architecture as A (it puts the lead's scripts on sys.path). Full code and recorded results are in references/procedures.md.

  1. Scaffold. A.scaffold(dest, name, fixtures=False) copies the arena skeleton plus Loader and Binder, writes the Rojo project and builds the place through rbx_env.new_place. GATE: A.place_facts(place) shows Server and Client RunContexts, SignalBehavior Deferred and PlayerCharacterDestroyBehavior Enabled; A.check(dest) returns 0 errors on both type solvers.

  2. Map the modules. Write the module map before code. Dependencies point from services to shared modules, never from a service to UI or from replicated code to the server.

    ModuleSideOwns
    PlayerServiceserverper-player and per-character tables, cleared on leave
    TeamServiceserverteam assignment and alive teams
    RoundServiceserverthe RoundMachine state, StateChanged, the GameState mirror
    WeaponServiceserverswords by tag: give, take, re-give on respawn
    MapServiceserverone map clone per round, rotation, pads, hazards by tag
    DamageService, ShopServiceserverhanded to scenario-roblox-gameplay and scenario-roblox-data
    RoundMachine, Config, Signalsharedpure logic, constants, signals (run in Lune)
    RoundController, ShopControllerclientHUD and shop, wired once, ResetOnSpawn false

    GATE: A.audit_file(place) reports 0 errors and 0 warnings, no require cycle and 0 unresolved requires.

  3. Boot. Each entry script calls Loader.boot(Loader.ordered(folder, order), {publish = script}). GATE: in a playtest, A.boot_report(pt) shows BootOk true, BootErrors 0 and BootCount 1 on both sides, with every init: before every start:. The console has no "required recursively" and no [Loader] line.

  4. State and mirrors. RoundService writes EndsAt, Winner, then RoundState; controllers re-render on every attribute change. Test_* attributes on GameState shorten the loop in Studio only. GATE: server state, client mirror and HUD text agree; capture the HUD, run image_checks and open the image.

  5. Tags and lifetimes. Bind tagged instances with Binder.bind(tag, setup, {ancestors = ...}). Clear player tables on PlayerRemoving and character tables on CharacterRemoving. Re-give round items on CharacterAdded, because a respawn empties the Backpack. MapService clones the map at Intermission and destroys it on the way to Lobby. GATE: five respawns mid-round leave one tracked character and one bound sword on the map. After a respawn, the HUD and shop are the same instances. In Lobby, Workspace holds 0 maps and 0 bound hazards, the instance count is back within 10, and frames meet the gate across a map load.

  6. Observe and iterate live. Open the place once with rbx_env.open_place inside rbx_env.place_slot(). After each edit, push sources with A.sync_sources(studio, dest) instead of reopening. GATE: A.run(s, "return ArchAudit.all(game)", kit=["ArchAudit"]) matches the offline tally, and tests/code/scenario-roblox-architecture/run_live.py exits 0.

Numbers

ValueNumberRelative to
Player latency100 to 300 msdocs, Client-server runtime
Studio playtest latency0 ms; simulate 50 to 150 ms each waydocs; Studio Settings, Network, or settings().Network
Module size smell500+ linesMrAsync [00:20:54]; ArchAudit module-size
Replicated attributes under Server Authorityfirst 64 per instance; names and strings up to 50 charactersdocs, Server Authority
Boot, measuredserver 5 services 1.56 to 2.52 ms; client 2 controllers 0.40 to 1.08 mslive, Studio 0.743
Client order, measuredReplicatedFirst ran 35 to 36 ms before client Main; IsLoaded false, then true; no character yetlive
Five respawns mid-roundinstances +3 or -3 (about 46,150); 1 character, 1 bound swordlive, 6 runs
Arena defaults2 players, 15 s intermission, 120 s round, 5 s ending, 0.25 s tick[added]
Frame gatep95 at most 20 ms, worst at most 33.3 ms at 60 fps (1.2 x and 2 x the budget)scenario-roblox-expert
Map cycle, measuredServer p95 17.3 ms, worst 17.5 to 20.0 ms across a clone; Lobby instance delta 0live, 3 runs

Quality gates

  • Measurable:
    • ArchAudit: 0 errors and 0 warnings outside fixtures; AgentKit Audit.all(game) has 0 errors.
    • Boot report on both sides: BootOk, BootErrors 0, BootCount 1.
    • Console: no "required recursively", "not a valid member", [Loader] or "non-legacy RunContext" lines.
    • Lifetimes: Characters equals the player count after respawns; in Lobby, 0 maps and 0 bound hazards, and the instance count is back within 10; Server and Client frames meet the gate.
    • run_live.py exits 0; the Lune unit tests pass; luau-lsp has 0 errors on both solvers (A.check); StyLua and selene are clean.
  • Visual: a capture during a round shows the HUD with the mirrored state; image_checks raises no flag and you open the image. A human reviewer gets an Explorer capture.

Common mistakes

MistakeSymptomFix
Client Script in StarterPlayerScriptsruns twice; Studio warns in Outputmove the entry Script to ReplicatedStorage, or use a LocalScript in StarterPlayerScripts
Rojo default emitLegacyScriptsclient entry in ReplicatedStorage never runsset "emitLegacyScripts": false
require of a live service from execute_luaufresh copy: fields nil, state emptyread the module's Studio-only attributes
Tagged template in ServerStoragetemplate gets behaviorancestors filter
Reparent within the DataModelbehavior missing after moving backAncestryChanged watch (Binder)
Round items given oncesword gone after respawnre-give on CharacterAdded during the round
Reading Parent in Destroying or CharacterRemovingnil under Deferredcapture state before destroy
Listener connected inside a handlermisses the fire already queuedconnect in Init, before anything fires
SetAttribute, then FireAllClients; the handler reads the attributecan read the old value on live serverssend the state in the payload
Maps in ReplicatedStorage or Workspaceevery client downloads every map at joinServerStorage, one clone per round (maps-replicated)
Run-once controller holding a ScreenGui with ResetOnSpawn trueHUD gone after the first deathResetOnSpawn false
ResetOnSpawn false on a ScreenGui inside a Folderrebuilt at every respawn anywaydirect child of StarterGui (reset-ignored-nested)
_G registry, duplicate module namessilent overwriteLoader registry; ordered errors on duplicates
Package with AutoUpdate offcopies never updateAutoUpdate on (Roblox Learn, AzKZy2BqIh8 [00:09:55])

Handoffs

  • Receives from: scenario-roblox-expert (brief, toolkit, place slot); scenario-3d and scenario-game-assets (models that arrive as tagged templates in ServerStorage).
  • Delivers to: scenario-roblox-networking (service layout, remote module slot), scenario-roblox-data (DataService boot slot, PlayerRemoving hooks), scenario-roblox-gameplay (hits and damage inside Binder setups), scenario-roblox-ui (controllers on GameState, the shop screen), scenario-roblox-luau (types, Signal, deferred events), scenario-roblox-tooling (Rojo project, CI), scenario-roblox-performance (leaks, streaming), scenario-roblox-animation (character scripts).
  • Form: the Rojo src/ tree, the module map, the ArchAudit report and results.json.

Current Roblox notes

  • Rojo 7.7.1 drops "Position" on a Part with exit 0 and leaves it at the origin: write a 12-number "CFrame" (verified).
  • Rojo 7.7.1 builds Script Sync's .local.luau and .legacy.luau as ModuleScripts named X.local and X.legacy (verified): do not mix the two suffix schemes.
  • require-by-string: ./, ../, @self and @game; special handling of Init modules is gone (version deltas row 23).
  • SignalBehavior: new templates and Server Authority use Deferred; Default still maps to Immediate in older places. workspace.SignalBehavior failed with "not a valid member" from execute_luau (live): read it in Properties or from the file with Lune.
  • PlayerCharacterDestroyBehavior is NotScriptable: set it in Properties or in the Rojo project.
  • CollectionService:CreateCollection is documented, but in Studio 0.743 it errored "Collections are not enabled" (live). Use tags and Binder.
  • Next Gen Studio UI is the default: menu paths in references/gui-paths.md.
  • Creator Store assets cannot require(assetId): vendor the code.

References

评价

还没有评价。欢迎分享你的使用感受。

评论

无需登录即可发表。欢迎分享使用感受、提问,或说明在哪些环境下无法运行。

还没有评论。来写第一条吧。

提交后会立即公开。请勿填写邮箱、电话等个人信息。URL 最多 2 个。

0 / 1000 字

此表单受 reCAPTCHA 保护,适用 Google 的隐私权政策和服务条款。

同一仓库的技能

Review unresolved GitHub pull request feedback, check each claim against the current code, fix warranted issues, and reply in the relevant threads. It can also push changes and report decisions or follow-up items, while leaving branch updates and thread resolution to explicit direction.

中文简介正在准备中。当前显示英语简介。

  • Triaging unresolved review threads on a pull request
  • Fixing valid feedback and replying with the pushed change
  • Answering reviewer questions without changing code
scenario-labs/skills11702026年10月27日 更新

Create a concise Conventional Commits squash message from a pull request’s net diff. The skill checks the repository’s commit rules, aligns the header with the PR title, and prepares the description for copying and display.

中文简介正在准备中。当前显示英语简介。

  • Preparing a squash message from a pull request’s changes
  • Checking a commit message against repository rules
  • Aligning a PR title with its squash commit header
scenario-labs/skills11702026年10月27日 更新

Rewrite the current pull request description to reflect the branch’s net changes and the repository’s own template. The skill discovers the correct base branch and conventions, preserves relevant human and bot notes, and updates the body through GitHub’s API.

中文简介正在准备中。当前显示英语简介。

  • Refreshing a PR description after the branch changes
  • Writing a summary that follows the repository template
  • Checking which base branch a stacked PR targets
scenario-labs/skills11702026年10月27日 更新

scenario

免费

Connect an AI agent to Scenario through MCP and guide generation of images, video, 3D, audio, and game assets. Find suitable models, prepare prompts and reference files, track generation jobs, and check project scope, usage, or access errors.

中文简介正在准备中。当前显示英语简介。

  • Connecting Scenario MCP to an AI agent
  • Finding a model for image, video, or 3D generation
  • Uploading reference files and tracking generation jobs
scenario-labs/skills11702026年10月27日 更新

Generate 3D models from text or images through Scenario, then refine meshes, retexture, unwrap UVs, rig characters, or retarget animation. Preview results and download assets in formats such as GLB or FBX for use in 3D tools and game engines.

中文简介正在准备中。当前显示英语简介。

  • Creating a 3D prop from a concept image
  • Retexturing or remeshing an existing asset
  • Preparing a character mesh for rigging
scenario-labs/skills11702026年10月27日 更新

Create explorable 3D environments and Gaussian splat scenes from text, images, panoramas, multi-view photos, or walkthrough video using Scenario. Preview a draft, adjust the scene, then generate a higher-quality version and download the resulting splat asset.

中文简介正在准备中。当前显示英语简介。

  • Turning a concept into a walkable 3D environment
  • Reconstructing a scene from photos or walkthrough video
  • Converting a panorama into a navigable splat
scenario-labs/skills11702026年10月27日 更新

查看 scenario-labs 的全部技能

报告此技能的问题