关于 scenario-roblox-environment
面向 Roblox Studio 环境美术师和搭建者的技能,依托 scenario-roblox-expert toolkit,涵盖灰盒、地形、材质、灯光、游玩测试和场景审计,并结合 Studio 实测流程。
主要功能
- 01从出生点视角搭建灰盒
- 02用代码创建并验证地形
- 03应用材质与地形覆盖
- 04设计并测量灯光效果
- 05测试碰撞与流式加载
- 06交付前审计场景
适用场景
- 01搭建 Roblox 环境灰盒
- 02塑造并验证地形表面
- 03通过灯光设定区域氛围
- 04检查通道与场景质量
安装
复制下面的命令,在终端中运行。
npx skills add https:/ / github.com/ scenario-labs/ skills --skill scenario-roblox-environment安装后在 Claude Code 中输入/scenario-roblox-environment确认已加载。
包含的文件
除 SKILL.md 外,安装时一起下载的参考资料和脚本。
references/critique.mdexpert-notes.mdfoliage.mdgui-paths.mdprocedures.mdsources.mdverification.mdscripts/rbx_environment.pyscripts/agentkit/environment/EnvAudit.luauGraybox.luauLooks.luaulune_env_audit.luauMaterialKit.luauScatter.luauTerrainKit.luauWorldCheck.luau详细介绍
Roblox 环境(构建者、环境美术师与灯光师)
目标:在 macOS 上使用 Roblox Studio(2026 年 10 月版本),通过 scenario-roblox-expert 工具包驱动。
Roblox 专业环境制作意味着:使用普通零件搭建灰盒场景;从生成点摄像机开始构建;用代码制作地形和材质,并检查其静默失败;先调整太阳方向,再添加后期效果,以氛围为依据设计灯光。本技能将这些规则延续自相关资料,并通过 Studio 0.743 中专门搭建的村庄、地形和室内场景的实时测试,以及用于构建、打光、测量和审计场景的工具包模块进行修正。如果此处提及的同级技能不在可用技能中,请要求用户安装它
(npx skills add scenario-labs/skills --skill <name>);若在无人值守的情况下,请依据工具架构继续操作,并标明这一缺失。
必需背景知识: scenario-roblox-expert(通道、审核流程、工具包、当前 Roblox 的陷阱)。
状态(2026-10-19): 2026-10-19 01:14 的实时运行在 Studio 0.743 中通过 14 项测试,共 14 项;离线测试 O1 至 O9 均通过。散布、流式加载测试和叠加层仅经过离线测试。后续一次运行因视口停止绘制而卡住(参见 references/procedures.md)。
立场(专业增量)
- 用基础部件搭建灰盒,从出生点摄像机视角开始构图。 使用基础几何体、一个网格 MaterialVariant、带下划线的文件夹,以及与墙壁颜色不同的地面颜色(Jalapeno,T--CNfkfBBQ [00:02:01 to 00:02:35, 00:08:13])。地标应使用醒目的占位物,并保持真实尺寸(RoBuilder,eRnnjqVOq7c [00:05:20])。门口和走廊至少宽 10 studs,墙壁至少高 10 studs(Roblox 灰盒教程)。以玩家出生点为起点进行构图,并计时测量在各地标之间行走所需的时间(Gino,vWx8UTxsi0A [00:11:49, 00:12:21])。
- 实测:模板的 SpawnLocation 背对村庄,所以第一眼看到的是山坡。将出生点转向第一个地标。
- 先用部件,再用 CSG;测试碰撞对开口的影响。 用部件切出轴对齐的孔洞,而不要使用联合体(Kaiwala,x9jg8kjH3Vs [00:04:41])。每个不同的联合体都是独立的网格和碰撞资源(Kaiwala,Ahn2P_4TDrU [00:20:40])。根据玩家是要穿过形状,还是只会碰到形状,来选择精度(Roblox 碰撞文档)。
- Kaiwala 发现 Default 碰撞会封住孔洞,因此改用 PreciseConvexDecomposition;对于简单形状,他建议用 Hull 或 Box 作为低成本修复方案(Ahn2P_4TDrU [00:01:54, 00:02:28])。
- 实测:Hull 和 Box 封住了 10 x 10 的门口;Default 和 PreciseConvexDecomposition 则保持开口畅通。逐个测试开口,不要仅凭精度名称判断。
GetPartBoundsInBox报告所有联合体门口均被堵住,因为它比较的是包围盒。使用GetPartsInPart或射线测试通行情况。
- 用代码创建地形,并通过读取体素进行检查。 先用部件搭建灰盒,再转换并平滑处理(BONES,-DoOf32pkPo [00:04:34, 00:09:57])。区域调用需要使用分辨率 4、与网格对齐的区域,并且每个区域最多包含 4,194,304 个体素(Terrain 参考)。
- 实测:
FillBlock的顶部若位于 y 0,可行走表面会留在 y 2 附近。TerrainKit.occupancy可以将表面放在精确位置。 - 实测:填充后立即进行射线检测时,未能检测到任何内容。
TerrainKit.surfaceY会从体素中读取高度。 - 草叶会从部件中穿出;应在这些位置涂上 LeafyGrass(SmartyRBX,CippiATeZ54 [00:01:40])。实测:所有设置在 Grass 上的地板都会被草叶穿透;
TerrainKit.paintUnder会重新涂刷地板下方。
- 实测:
- 材质按名称关联,且按基础材质区分;地形还需要额外设置。 重命名会影响所有使用该变体的部件(Roblox 材质文档)。地形只有通过覆盖才能使用变体,并且每种材质都需要单独覆盖:Grass 和 LeafyGrass 要分别设置(SmartyRBX,CippiATeZ54 [00:05:13, 00:05:47])。
- 实测:创建 Basalt 变体后,直到调用
SetBaseMaterialOverride才产生变化。 - 实测:覆盖后,地形仍呈现近乎黑色,因为地形材质颜色(Basalt 30, 30, 37)会与地图颜色相乘。使用
Terrain:SetMaterialColor提亮,正如 SmartyRBX 手动操作的那样 [00:02:44]。
- 实测:创建 Basalt 变体后,直到调用
- 先确定氛围,再调整太阳方向,最后调颜色。 先用一句话描述氛围,再设置 ClockTime(RingWorld,UlvSrWHESwA [00:01:06, 00:01:58])。调整太阳方向,让光线落在重要位置(DatBoiEle,aq0Fi0R2FAY [00:02:11];BONES 使用 GeographicLatitude 控制方向,zAoY8pxJM9c [00:08:36])。
- 实测:在默认纬度下,出生点摄像机正对太阳,只能看到阴影面,并被 Ambient 染色。
Looks.aimSun可以为任意方向找到对应的 ClockTime 和 GeographicLatitude,误差小于 1 度。
- 实测:在默认纬度下,出生点摄像机正对太阳,只能看到阴影面,并被 Ambient 染色。
- 暖光、冷影;最后逐步微调对比度。 Ambient 会给阴影染色,ColorShift_Top 会给光线染色;降低 EnvironmentDiffuseScale 可提高对比度(DatBoiEle [00:03:38, 00:05:48])。先追求逼真;Atmosphere Density 设为 0.3 到 0.4,Offset 设为 0;最后再用色彩校正调整对比度(Develuper,vkEXLmRAQgs [00:00:27, 00:01:04, 00:02:16])。以 0.05 为步长调整 ColorCorrection(DatBoiEle [00:08:09])。他的 Bloom 设置为:Threshold 约 0.03,Size 设得较大,然后按喜好降低 Intensity [00:07:37]。
- 夜景需要焦点光源和剪影。 BONES 的暗调设置适用于走廊:Atmosphere Color 和 Decay 设为黑色,Density 设为 0.495,Offset 设为 0.25,Haze 设为 5,Glare 设为 0,环境光缩放设为 0,ExposureCompensation 设为 -0.4(zAoY8pxJM9c [00:03:15 to 00:06:04])。室外则可以采用 RingWorld 的做法:降低 Brightness,减弱眩光,添加蓝色调,并设置近处和远处的光源(UlvSrWHESwA [00:06:44 to 00:07:54])。
- 判断条件:玩家是否需要看到天际线?实测:走廊设置会使 96% 到 100% 的远景变黑。
night_outdoor则让所有视角都清晰可见。
- 判断条件:玩家是否需要看到天际线?实测:走廊设置会使 96% 到 100% 的远景变黑。
- 室内:先确保窗户透光,再模拟光线反弹。 会投射阴影的玻璃会挡住阳光光束;关闭 CastShadow(DatBoiEle [00:09:16])。对于有窗光的房间,BONES 使用 Brightness 44、黑色环境光和环境光缩放 0。然后在窗户附近添加 PointLight [234, 255, 254],Range 设为 50,并开启 Shadows(zAoY8pxJM9c [00:06:14, 00:07:14])。三项设置均已实测确认。
首先确定
- 摄像机和类型:第三人称(默认)需要比第一人称更大的门和更高的天花板。
- 目标设备;移动端的可达范围更适合 Soft 光照和性能负责人设定的预算。
- 地图大小、StreamingEnabled,以及哪些模型必须始终存在于客户端。
- 每个区域用一句话描述氛围,并准备两到三张参考图片。
- 资源来源:Scenario 网格、纹理和天空盒,或仅使用 Roblox 材质。
- 文件工作流:仅使用 Rojo 或 Studio。有些设置只能通过文件配置(参见 Current Roblox 说明)。
默认值:Realistic 搭配 PrioritizeLightingQuality,灰盒网格变体的 StudsPerTile 为 8,门为 10
乘 10,目标是在出生点视角呈现 day_fantasy 风格。
流程
设置:import rbx_environment as E,然后运行
E.run(studio, code, kit=["Graybox", "TerrainKit", "MaterialKit", "Looks", "EnvAudit"])(它会查找
主工具包)。完整代码和记录的结果见:
references/procedures.md。
- 准备情况(P1)。 检查 LightingStyle、覆盖项和仅能通过文件配置的设置。**门槛:**值符合预期;脚本拒绝设置的项目已在场景文件或 Properties 面板中设置。
- 灰盒(P3)。 在
map_geo/<area>/<kind>下使用Graybox.house、wall、lantern、block; 放置地标占位物;将出生点朝向第一个地标。门槛:Graybox.clearance无任何问题;报告步行时间;出生点截图中能看到地标。 - 地形(P2、P13、P4)。 使用带高度函数的
TerrainKit.heightfield、water、fromParts和smooth,然后用paintUnder绘制地面。**门槛:**出生点地面(帧后groundY, 或surfaceY)位于设计高度;出生点和室内截图中,地板下方都没有草穿出地面。 - 开口和碰撞(P5)。 根据部件创建开口;任何联合体都保留 Default 保真度和
Opening属性。**门槛:**角色大小的GetPartsInPart探测和射线都能通过每个门口。 - 材质(P6)。 使用
MaterialKit.kit,按角色使用dress,每种地形材质设置一个覆盖项,并设置地形材质颜色。门槛:MaterialKit.links返回 0 个断开的链接;每个覆盖项都能读取到设置值;根据references/critique.md评审装饰完成后的截图。- 植被、岩石和树木:使用
Scatter.plan和Scatter.place,并为每个变体设置碰撞和 LevelOfDetail(参见references/foliage.md)。
- 植被、岩石和树木:使用
- 光照(P7 到 P10)。 创建快照,运行
Looks.apply和Looks.aimSun,在同一组摄像机位置拍摄前后截图,运行E.look_metrics,生成一张联系表。**门槛:**指标处于质量门槛范围内;联系表符合氛围描述。 - 游玩测试(P11)。 检查 Client Stats,逐个模型检查流式加载,并穿过一扇门。**门槛:**角色能进入室内;将数据交给性能负责人。
- 截图之外也可能失败的检查:半径为 64 时的流式加载、碰撞和隐形阻挡物叠加层、纹理尺寸和网格组(参见
references/verification.md)。
- 截图之外也可能失败的检查:半径为 64 时的流式加载、碰撞和隐形阻挡物叠加层、纹理尺寸和网格组(参见
- 审计并交接(P12)。 在 Studio 中运行
EnvAudit.all(game),对已保存的文件运行E.lune_audit(place)。**门槛:**没有错误或警告。
数值
| 数值 | 数量 | 来源 |
|---|---|---|
| 门口和走廊宽度;墙壁高度 | 至少 10 个 studs | 灰盒教程 |
| 默认 WalkSpeed;JumpHeight | 16 studs/s;7.2(教程中的 5 已过时) | Humanoid 参考 |
| 一个 stud | 约 28 cm;导入时不会转换 | 单位指南 |
| 网格变体瓦片 | StudsPerTile 8 | Jalapeno |
| Terrain 区域调用 | 分辨率 4,4,194,304 个体素 | Terrain 参考 |
| CSG 结果 | 最多 20,000 个三角形 | 实体建模文档 |
| Light Range | 写入时上限为 120(实时) | deltas |
| Atmosphere Density、Offset(白天) | 0.3 到 0.4,0 | Develuper |
| 暗色 Atmosphere | Density 0.495,Offset 0.25,Haze 5,Glare 0 | BONES |
| ExposureCompensation | -0.4,以小数调整 | BONES |
| 窗边采光的室内 | Brightness 44;假 GI [234, 255, 254],Range 50 | BONES |
| ColorCorrection 调整步长 | 0.05;Contrast 0.1 | DatBoiEle |
| Streaming 基线 | MinRadius 64,TargetRadius 1024,PauseOutsideLoadedArea,Opportunistic,Improved | Streaming 文档 |
| 2 GB 手机的每视图预算 | 500 次绘制调用,500k 个三角形 | McNeill,cWDNVvOh4o0(性能方面的依据) |
| 脚本限制(实时) | Atmosphere Glare 和 Haze 为 10,Density 和 Offset 为 1,ShadowSoftness 为 1;Brightness 和 Bloom Size 不设上限 | Studio 0.743 |
质量门槛
测量方法(每张截图取下半部分,skip_top=0.45,避免天空占主导):
- 白天外观:所有视角的
crushed都低于 0.05;分布比中性截图更宽。 - 户外夜景:所有视角的
crushed都低于 0.5;出生点附近有一个明亮的焦点。 - 有阳光的室内场景:地面光斑过曝(
clipped高于 0.05),且假反弹光会抬高mean_luma,同时保留该光斑。 Graybox.clearance、MaterialKit.links、EnvAudit:错误或警告级别的问题均为零。- 游戏测试:开发机上达到 60 fps;报告每个视角的绘制调用次数和三角形数量。
根据联系表目测评判(references/critique.md):氛围符合描述;灰度下的明暗结构清晰;从出生点能看到受光面;地标与背景有对比;材质不显塑料感,也不接近纯黑;远处的雾霾不会遮蔽轮廓。
常见错误
| 错误 | 修正 |
|---|---|
在脚本中设置 Lighting.Technology = Future | 使用 LightingStyle 和 PrioritizeLightingQuality;仅在场景文件中写入 Technology |
通过脚本设置流式传输半径或 Terrain.Decoration | 仅通过文件设置:使用 Rojo $properties 或 Properties 面板(实时设置会提示“不是有效成员”) |
半径较小时使用 LevelOfDetail = StreamingMesh | 静态模型使用 SLIM;只有 TargetRadius 达到 1000 或更高时才使用 StreamingMesh(Andrew,Wwj8EkMWFhI) |
| 门的尺寸为 4 × 8 | 至少为 10 × 10 |
| 用 Hull 或 Box 创建联合体门 | 使用零件,或使用 Default 保真度创建联合体 |
| 变体使用 BaseMaterial Grass,并期望地形随之改变 | 对 Grass 和 LeafyGrass 使用 SetBaseMaterialOverride,然后检查地形材质颜色 |
| 应用变体后重命名 | 保留名称;使用 MaterialKit.links 进行审核 |
| 在 Soft 下调整 ShadowSoftness,却在 Realistic 下评判 | 按实际发布的风格进行评判;每种风格分别截图 |
| 太阳方向尚未调整好就开始调色 | 先运行 Looks.aimSun |
| 在 Edit 截图中评判泛光效果 | Intensity 为 3 时,泛光对截图的影响不超过两张相同截图之间的差异(实时);应在游戏中或设备上评判 |
| 远处只放一个点光源 | 设置两个光源,分别位于近处和远处;Range 最大为 120 |
| 玻璃启用了 CastShadow | 关闭 CastShadow |
交接
| 交接对象 | 说明 |
|---|---|
| scenario-3d,然后是 scenario-roblox-assets | 在这里导入并检查 Scenario 网格(三角形、碰撞、SurfaceAppearance);此技能负责放置网格、设置保真度和 LevelOfDetail,并进行照明 |
| scenario-textures | 将可平铺的 PBR 贴图集转换为此处的 MaterialVariants(颜色、法线、粗糙度、金属度;OpenGL 法线);单网格贴图集则作为 SurfaceAppearance 交给 scenario-roblox-assets |
| scenario-skyboxes | 将六个面放入 Sky.SkyboxBk/Dn/Ft/Lf/Rt/Up;上传前需要征得用户同意;应结合场景效果判断天空,因为天空会影响场景的色彩 |
| scenario-game-assets | 在此处将贴花和标识放置到表面;UI 美术资源交给 scenario-roblox-ui |
| scenario-roblox-performance | 流式传输设置、预算和设备测试:发送 P11 Stats 和 EnvAudit 计数 |
| scenario-roblox-vfx-audio | 粒子、光束、环境音效;发送氛围描述句和光源位置 |
| scenario-roblox-gameplay | 碰撞组、命中框几何体、NPC 在灰盒场景中的导航 |
| scenario-roblox-tooling | 携带仅文件设置的 Rojo 项目 |
当前 Roblox 说明
Lighting.Technology已被LightingStyle(Soft 或 Realistic)和PrioritizeLightingQuality取代;脚本无法读取 Technology。- 脚本拒绝设置、仅限文件设置(实时验证):
StreamingTargetRadius和其他流式传输设置(StreamingEnabled除外)、Terrain.Decoration、GrassLength、MaterialService.<Material>Name。Rojo 7.7.1 会写入所有这些设置(Lune 回读验证)。 - 由 Rojo 构建的场景使用引擎默认设置:GlobalShadows 关闭、环境缩放值为 0、环境光为灰色,且没有 Sky 或 Atmosphere(实时验证)。
GeometryService:SubtractAsync及其同类方法已取代BasePart:SubtractAsync;结果返回时尚未设定父级;写入CollisionFidelity后需等待下一次 yield 才能读回(实时验证)。ReadVoxelChannels在结果表中返回Size,ReadVoxels则在材质数组中返回Size(实时验证)。- Terrain
Clouds位于Workspace.Terrain下,且可通过脚本创建(实时验证)。 - 游戏运行时,
ClockTime不会自行推进(实时验证)。
参考资料
references/procedures.md:P1 至 P13,实时测试运行的代码及其结果。references/critique.md:如何评判一次捕获;本技能自身捕获的发现。references/expert-notes.md:按来源整理的专家观点、共识、分歧和实时更正。references/gui-paths.md:仅限 GUI 的工具、对应的代码替代方案和菜单路径。references/foliage.md:散布、叶片卡片、碰撞、RenderFidelity 和 LevelOfDetail。references/verification.md:流式测试、叠加层、纹理和批处理审计。references/sources.md:所有来源及其公开 URL。- 套件:
Graybox、TerrainKit、MaterialKit、Looks、EnvAudit、Scatter、WorldCheck、lune_env_audit、rbx_environment.py。