关于 scenario-roblox-tooling
面向 Roblox Studio 的技能,指导团队从代码仓库构建游戏场景并验证发布流程,涵盖 Rojo 或 Script Sync、本地检查、引擎测试、CI 和受控发布。
主要功能
- 01从代码仓库构建场景
- 02Luau 类型、Lint 与格式检查
- 03Lune 和引擎共用测试规范
- 04Studio 同步状态检查
- 05多场景 CI 与发布流程
适用场景
- 01搭建 Roblox 项目构建流程
- 02发布前发现代码问题
- 03在 Lune 和 Studio 运行共用测试
- 04协调多个场景的版本发布
MCP 相关
说明如何使用 Studio MCP 工具运行引擎测试、检查同步状态并验证绑定的测试场景。
安装
复制下面的命令,在终端中运行。
npx skills add https:/ / github.com/ scenario-labs/ skills --skill scenario-roblox-tooling安装后在 Claude Code 中输入/scenario-roblox-tooling确认已加载。
包含的文件
除 SKILL.md 外,安装时一起下载的参考资料和脚本。
references/critique.mdexpert-notes.mdgui-paths.mdprocedures.mdsources.mdscripts/rbx_tooling.pyscripts/agentkit/tooling/ShipCheck.luauSyncCheck.luauTestRunner.luauscripts/template/.gitignore.luaurc.styluaignoredefault.project.jsonplaces.jsonrokit.tomlselene.tomlship.project.jsonstylua.tomlscripts/template/.github/workflows/ci.ymlpublish.ymlscripts/template/src/client/Main.client.luauscripts/template/src/server/Main.server.luauscripts/template/src/shared/Damage.luauDamage.spec.luauRemotes.model.jsonRemotes.studio.spec.luauscripts/template/tools/check_key.luaucloud_luau.luaumerge_place.luauplace_versions.luau详细介绍
Roblox 工具链与构建流水线
目标环境:macOS 上的 Roblox Studio(2026 年 10 月版),通过 scenario-roblox-expert 工具包驱动。
此处的专家级标准是:从空白状态重建每个场景、在信任检查通过前先观察它失败,并为 Lune 和引擎使用同一种规范格式。只有经过批准的发布任务才能发布。
如果你的可用技能中缺少此处提到的同伴技能,请让用户安装它
(npx skills add scenario-labs/skills --skill <name>);如果是在无人值守的情况下,请根据工具架构继续操作,并标明这一缺口。
必备背景知识: scenario-roblox-expert(频道、审查循环、工具包、当前 Roblox 陷阱)。
原则(专家级增量要求)
- 从仓库构建场景。 绝不发布手动编辑的开发场景:删除的对象可能会悄无声息地随之发布(CJ_Oyer,Connect 2023,00:42:51)。
- 检查关卡的目的就是失败。 类型和 lint 错误会阻止发布;这能捕获他所说的“90 percent”的拼写错误类问题,而非设计问题,因此大型版本发布前仍要进行游玩测试(CJ_Oyer 00:12:50 至 00:13:55)。[新增] 每项检查都植入一个故障,并确认恰好对应的步骤变为红色,然后再信任绿色结果。
- 只有流水线可以发布,且必须一次发布所有场景。 人员和 Agent 都可以访问仓库(CJ_Oyer 00:22:44)。旧版场景读取新版 DataStore 结构时会报错,因此所有场景必须在一次运行中发布(00:26:27)。[新增] 先将所有场景上传为 Saved,再将它们全部提升为 Published。
- 每个文件夹只使用一种同步工具。 Script Sync 适合只处理代码、以 Studio 为中心的团队;Rojo 适合整个项目的构建、Wally 和 CI(Distracted Games,2026;Script Sync 文档)。Rojo 仍可与 Script Sync 并行运行,但仅用作 sourcemap 生成器(xlxnmAFmu6c 00:12:57)。
- 你发布的软件包就是随附的代码。 Wally 软件包可能封装不当,缺少入口模块;应 require 实际入口(
lib)或复制该模块(xlxnmAFmu6c 00:01:44)。ShipCheck 的package-entry检查会因此类软件包而失败。 - 一种规范格式,两种运行时。 [新增] 规范通过字符串引用其测试对象(
require("./Damage")),因此同一个文件可在lune run、Studio 或 Open Cloud 中运行。纯逻辑在 Lune 中以毫秒级速度运行;引擎相关事实则在引擎中运行。 - 通过代码而非目测进行验证。 官方设置视频要求 Agent 在任何提交之前触及每个已同步文件夹、读取
InstanceFileSyncService:GetStatus并进行游玩测试(Roblox Learn,2026,02:45 至 03:34)。Script Sync 可能会静默停止(SmartyRBX,00:12:19):请轮询状态。 - 面向 Agent 使用类型化 Luau。 roblox-ts 会失去 Studio 编辑能力、Luau 行号和快速 API 类型支持(Adam,Last Level Studios,00:06:01);通过 MCP 驱动 Studio 的 Agent 应坚持使用 strict Luau。
首先确定
- 正在使用的同步工具:
*.project.json(Rojo)或 Script Sync 链接(InstanceFileSyncService:GetAllInstances()不为空)。不要在同一文件夹中添加第二种工具。 - 地图归谁所有: Rojo 无法实时同步 Terrain、CSG 或
MeshPart.MeshId,因此建造者的工作会以项目中的.rbxmx文件形式进入发布版本,或作为基础 place 与代码构建合并(P15)。 - 谁编辑什么: 建造者在构建体验中使用 Team Create;脚本编写者在代码仓库中工作,每个同步脚本由一人负责,因为两个人同步同一个脚本会相互覆盖(Script Sync 文档);只有发布作业持有生产密钥(P16)。
- 体验中的 Places: universe id、place ids、起始 place。它们应写入
places.json。 - CI 主机和密钥: 默认使用 GitHub Actions。用户创建所有密钥;Agent 绝不创建、打印或存储密钥。每个作业使用一个密钥,且仅授予其所需的作用域(见下表);对于群组体验,使用专用账号上的密钥,并授予最低限度的群组角色;关闭 IP 限制,因为 GitHub 托管运行器的 IP 会变化(API 密钥指南;CJ_Oyer 00:38:26)。
- 单独的测试 universe 用于引擎测试 [新增]:Luau Execution 的 DataStore 调用会访问真实数据。
- 未指定时的默认值: 使用下方模板、
emitLegacyScripts: false、将客户端入口设为ReplicatedStorage.Client中的 RunContext Client Script、严格模式、制表符。
流程
完整代码、测试和结果:procedures.md。运行器脚本: rbx_tooling.py。
- 搭建脚手架。 运行
python3 scripts/rbx_tooling.py scaffold <repo> --name <game>,然后运行rokit install和wally install。它会将 模板、 TestRunner 和 ShipCheck 模块复制到tools/testkit/。门禁:rbx_tooling.py lint <repo>/default.project.json不报告任何错误(它也会捕获 Rojo 静默丢弃的属性)。 - 本地门禁。
rbx_tooling.py gate <repo>会按顺序运行 CI 步骤:Wally、rojo sourcemap --include-non-scripts、两次 luau-lsp、Selene、StyLua、Lune 测试、发布构建、 ShipCheck。luau-lsp 1.70.1 默认运行旧求解器,除非传入--flag:LuauSolverV2=true;而 Studio 对非严格脚本使用新求解器,因此门禁会同时运行两者(P2)。门禁:每个步骤均以 0 退出,然后每个植入的故障(类型、仅求解器、lint、格式、失败的规范、发布版本中的测试)都恰好导致对应步骤失败。门禁需要此技能的脚手架(tools/、ship.project.json);在其他仓库中,使用负责人的rbx_check和lint_project运行门禁。 - 在 Studio 中进行引擎测试。 构建一个开发场景,并使用
rbx_env.place_slot()内的rbx_env.open_place打开一次(绑定方式:负责人的流程)。然后rbx_tooling.check_target(s)会通过list_roblox_studios检查是否绑定了一个窗口且其中打开了测试场景(P18); 请先将 Studio MCP 工具加入允许列表,否则每次调用都会卡在提示词上(编码工具教程)。 在 Edit 模式下通过rbx_run.run运行 CI 单行命令,然后在Playtest中的服务器上运行:
门禁:return require(game:GetService("ServerStorage").TestKit.EngineTests)()failed == 0且total > 0。未能加载的规范也计为失败。 - 客户端脚本位置探测。 在信任布局之前,统计一次 playtest 中客户端脚本的运行次数 (P7)。门禁:每个条目在每位玩家的客户端上运行一次。
- 同步健康状况(Script Sync 团队)。
使用 SyncCheck 运行
rbx_tooling.run_kit(studio, "return SyncCheck.run(game)", kit=["SyncCheck"]),并在磁盘上对文件夹运行rbx_tooling.lint_scriptsync(folder)。 门禁:没有错误发现;每个根节点都显示为 SyncedAsRoot。 - CI。 提交 ci.yml:每个拉取请求都运行一个不含密钥的
static任务,并为推送和同一仓库的拉取请求运行一个engine任务。引擎任务会检查密钥及其作用域(tools/check_key.luau --require-scope ...),将开发构建作为测试场景的 Saved 版本上传,并通过 Open Cloud Luau Execution 运行单行命令(tools/cloud_luau.luau --expect-tests)。- 一个场景最多接受 10 个未完成任务,之后返回 HTTP 429(Open Cloud 参考文档):引擎任务共用一个并发组,且
cloud_luau会在遇到 429 时采用退避策略重试。门禁:rbx_tooling.check_workflow正常,且 actionlint 退出码为 0;第一个拉取请求为绿色,植入的故障会使其变红。
- 一个场景最多接受 10 个未完成任务,之后返回 HTTP 429(Open Cloud 参考文档):引擎任务共用一个并发组,且
- 发布。 publish.yml 会在打标签时或手动触发,并在受保护的
production环境中运行:检查密钥,运行tools/place_versions.luau(获取每个构建人员场景的 Version History 最新编号),构建发布版本, 运行tools/merge_place.luau --manifest places.json --live-versions ...(对每个基础场景合并代码,然后运行 ShipCheck),接着运行tools/publish.luau --manifest places.json --published。P10 会引用整个任务。- 构建人员通过 File > Save to File 将场景交接到
assets/<place>.rbxl,并将该次保存对应的 Version History 编号记录为baseVersion(P15)。过期副本会静默发布旧地图,因此合并会拒绝baseVersion早于最新版本的情况。 - 场景发布 API 不会更新 PartOperation(CSG)、SurfaceAppearance、EditableImage、EditableMesh 或 BaseWrap 内容(场景发布指南):遇到这些内容时,
merge_place会以 2 退出,并保留合并后的文件,供人员从 Studio 发布。 - 重启过期服务器(
tools/restart_servers.luau、Open Cloud:restartServers)仅在手动运行时设置restart_servers才会执行。门禁:在检查freshness并审查dropped和baseScripts后,合并以 0 退出;在上传任何 Published 版本之前,每个场景都必须有 Saved 版本。Agent 仅运行阶段 1 或--dry-run,绝不重启服务器。
- 构建人员通过 File > Save to File 将场景交接到
- CI Mac 上的 Studio 命令行。 使用负责人的封装器
rbx_run.run_headless(place, code): 只要有任何 Studio 正在运行,它就会拒绝执行,并解析结果标记(尚无实时运行)。RobloxStudio --task RunScript本身(此处运行 4 次,每次 6.0 秒)即使发生运行时错误也会以 0 退出;在 macOS 上,它还接管了已打开的 Studio 并关闭其窗口(P12)。门禁:以解析出的标记为准,绝不以 RunScript 的退出码为准。 API 密钥,每个作业一个;范围字符串来自 Open Cloud 参考文档;每个作业的check_key --require-scope列表与其所在行匹配(P13):
| 作业 | 范围 |
|---|---|
ci.yml static | 无需密钥 |
ci.yml engine、test experience | universe-places:write(保存测试场景的上传)和 universe.place.luau-execution-session:write(Luau 执行) |
| publish.yml、production | universe-places:write;重启服务器需要 universe:write;过时基础版本检查需要 universe.place:read(构建者的 experience) |
check_key(内省) | 无额外范围 |
各项检查的运行位置。Studio 列需要在负责人的 gui-paths.md 中开启 Studio 的 MCP 服务。
| 检查 | Lune 或 CLI(CI) | 通过 MCP 使用 Studio | Open Cloud |
|---|---|---|---|
| 类型、lint、格式 | 是 | 否 | 否 |
| 纯规格测试 | 是,耗时毫秒 | 是 | 是 |
| 引擎规格测试 | 否 | Edit、Server、Client | 是,无物理模拟,不运行场景脚本 |
| 发布树审计、基础场景合并 | ShipCheck、merge_place | game 上的 ShipCheck | 否 |
| Playtest、输入、捕获 | 否 | 是 | 否 |
| 同步状态 | 仅磁盘 lint | InstanceFileSyncService | 否 |
数值
每个固定版本的工具都已安装在 macOS 测试机器上;离线套件会检查每个工具的 --version。
| 数值 | 相对于 | 来源 |
|---|---|---|
| Rojo 7.7.1、Wally 0.3.2、Rokit 1.2.0、Lune 0.11.0、Selene 0.32.0、StyLua 2.6.0、luau-lsp 1.70.1、actionlint 1.7.12 | rokit.toml 中固定的版本(actionlint 未固定) | 已安装、已检查版本、已运行 |
| Gate 1.9 秒:旧求解器 1.2 秒,新求解器 0.7 秒 | 模板项目、本 Mac | 已测试 |
EngineTests 在 Edit 中耗时 0.07 秒;首次 open_place 耗时 19.7 秒 | 5 个测试、2 个文件 | Studio 0.743 |
| 每个根目录 10,000 个脚本,128 个根目录 | Script Sync 限制 | 文档 |
| 每分钟 5 次创建、200 次获取、45 次日志读取 | Luau Execution,按密钥所有者计算 | OpenAPI |
| 每个 place 有 10 个未完成任务(第 11 次创建返回 HTTP 429),默认超时 5 分钟 | Luau Execution | OpenAPI |
| 4 MB 脚本、4 MB 结果、450 KB 日志、保留 24 小时 | Luau Execution | OpenAPI |
| 未使用 60 天 | API 密钥自动过期,即使未设置过期日期 | API 密钥指南 |
质量门禁
可衡量:
- Gate 报告为 ok,且红色证明(P2)通过。
- Lune:
tests: N passed, 0 failed,其中 N 大于 0;engine:EngineTests 具有相同的计数。 - ShipCheck 在发布构建中无发现;开发构建中仅有
dev-container和test-code。 - 两个工作流的
check_workflow均为 ok;run:行中不得出现secrets.。 - SyncCheck 为 ok;P7 探测计数为每个条目 1 次。
视觉检查:流水线不需要。Script Sync 冲突对话框和 Rojo Connect 提示是 screen_capture 无法捕获的 GUI 模态窗口:请向用户求助(gui-paths.md)。使用
critique.md 评分。
常见错误
| 错误 | 症状 | 修复 |
|---|---|---|
Selene 未配置 std = "roblox" | 类型解析错误、字符串插值时崩溃 | 将其添加到 selene.toml |
| 出现一条 Selene 警告 | 退出代码为 1 | 在 selene.toml 中放宽该规则的选项,或允许单行例外;CI 中没有 --allow-warnings(P2) |
| luau-lsp 未配置 sourcemap | Key 'Shared' not found in external type 'ReplicatedStorage' | 先运行 rojo sourcemap,再使用 --sourcemap |
| 仅包含脚本的 sourcemap,且使用新求解器 | Key 'Remotes' not found in external type 'Folder' | rojo sourcemap --include-non-scripts |
| 仅使用旧求解器进行类型检查 | 实例路径拼写错误未被 CI 检出 | 使用 --flag:LuauSolverV2=true 进行第二轮检查 |
| 单独上传 Rojo 构建产物 | 线上游戏丢失地图 | 合并基础场景,或合并 .rbxmx 文件(P15) |
对服务使用 $path | 实时同步会删除 Studio 中创建的 RemoteEvent 和部件 | 映射子文件夹,或设置 $ignoreUnknownInstances: true |
在 $properties 或 *.model.json 中使用 "Position" 或 "Orientation" | rojo build 以 0 退出,但部件位于原点且没有旋转 | 使用 12 个数字的 "CFrame": [x, y, z, 1, 0, 0, 0, 1, 0, 0, 0, 1] |
Rojo 项目中包含 .local.luau | 创建名为 X.local 的 ModuleScript,且不报错 | Rojo 仅支持这些后缀:.server、.client、.plugin |
Rojo 默认启用 emitLegacyScripts | ReplicatedStorage 中的 .client.luau 会成为永不运行的 LocalScript | "emitLegacyScripts": false |
| StarterPlayerScripts 中有 RunContext Client Script | 每位玩家运行两次,并出现引擎警告 | 在此处使用 LocalScript,或将其移到 ReplicatedStorage |
| 一个文件夹中有两个 init 文件 | 其中一个会静默生效 | 每个文件夹只保留一个 init |
在 rojo serve 下修改 MeshId 或 HttpEnabled | Studio 仍保留旧值 | 重新构建并重新打开(P17) |
StarterPlayerScripts 键位于 StarterPlayer 之外 | 构建结果为 Folder | 使用 key-class 进行 lint(P17) |
init.meta.json 为空 | rojo build 退出代码为 1,并提示 "File contains no JSON value" | 写入有效的 JSON |
| 没有 Packages glob | wally ModuleScript 和包测试会被打包 | 使用模板中的 globIgnorePaths |
在 run: 中内联密钥 | 密钥出现在日志中,并可能导致 shell 注入 | 通过 env: 传入 |
| 在 fork 拉取请求上运行引擎作业 | 作业失败,且没有密钥 | 使用 head.repo.full_name 添加条件 |
| 密钥 60 天未使用 | 发布中途出现 401 | 先运行 tools/check_key.luau;重新启用或编辑密钥 |
| 引擎密钥仅具有 Luau Execution 范围 | 作业在 Saved 上传时失败,尚未运行任何测试 | 添加 universe-places:write(P13) |
| 基础场景在构建者最后一次修改前保存 | 发布版本使用旧地图,且不报错 | 使用 baseVersion 和 --live-versions(P15) |
| 重新打开后 Script Sync 已停止 | 磁盘修改无法同步到 Studio | 轮询 GetStatus,然后恢复同步 |
交接
- scenario-roblox-expert: channels、
rbx_run.run_headless、places 和 slots。工具不会重新实现这些内容。 - scenario-roblox-architecture: 文件夹布局和 RunContext 选择;工具将它们映射到项目文件并探测它们(P7)。
- scenario-roblox-luau: 修复两位求解者发现的问题;严格模式在
.luaurc中设置。 - scenario-roblox-networking: 漏洞利用和验证规范作为引擎测试在 CI 中运行。
- scenario-roblox-data: DataStore 规范,仅在测试 universe 上运行。
- scenario-roblox-assets: 发布 API 无法更新的内容(步骤 7)会将该版本发布流程转交给 Studio。
- scenario-roblox-performance: 接收 ShipCheck 报告和 Saved 版本号,并负责发布、更新和关闭。
当前 Roblox 说明
- Studio 内置 MCP 服务,Open Cloud 也提供 Luau Execution:“CI 中没有 Roblox 运行时”这一 2023 年的说法已过时。
- Rokit 取代了 Aftman 和 Foreman;TestEZ 和 run-in-roblox 都是 2023 年的工具。
- 现在密钥的 IP 限制是可选的;旧视频中关于
0.0.0.0和 runner-IP 的变通方法已经过时。
参考资料
- expert-notes.md:各位专家的原则,附时间戳。
- procedures.md:P1 至 P18,包含完整代码、测试名称和结果。
- critique.md:评估标准和报告格式。
- gui-paths.md:Team Create、Script Sync、Rojo、API 密钥、插件、版本历史。
- sources.md:视频、文档和工具页面。
- scripts/rbx_tooling.py:脚手架、lint、门禁、发布检查、工作流检查、
run_kit。 - scripts/agentkit/tooling/:TestRunner、ShipCheck、SyncCheck。
- scripts/template/:团队项目,包含 tools/test.luau、 tools/cloud_luau.luau、 tools/publish.luau、 tools/merge_place.luau、 tools/check_key.luau、 tools/place_versions.luau、 tools/restart_servers.luau 和 tools/testkit/EngineTests.luau。