脚本功能 是一个系统,可以控制脚本在 DataModel 子树内执行的操作。它提供更好的控制经验脚本而不是成为一个“全部或无”系统,其中任何脚本都可以做其他脚本可以做的任何事情。
- 该系统可以让你限制工具箱中获取的模型可以做什么,并且使用户生成内容更容易包含在体验中,即使是包含脚本的内容。
- 它还可以帮助确保允许玩家运行自己的代验证码的体验的更好安全,这通常在受限或模拟环境中执行。
- 它也可以用来分享限制自己能做什么的库。例如,提供额外数学方法的库可以限制到最小的功能集,以确保其他使用该库的开发人员不需要验证整个代码库来确保它不包含恶意验证码。
启用脚本功能
要启用此精选,在 Explorer 中将 SandboxedInstanceMode 设置从 Default 更改为 Experimental 以启用此功能。
当客户端测试版完成后,此步骤将不再需要。
沙盒容器
该系统引入了一个沙盒容器的概念 sandboxed container 。类型 、 、 或任何这些类别的子类的实例都有 Studio 属性窗口中可用的 属性,在 《权限》 部分下。

启用 Sandboxed 属性将实例指定为沙盒容器内的 DataModel 树中的容器,这将限制脚本内的容器中可以执行的操作,根据 Capabilities 属性集中的值进行。
能力
Capabilities 属性是一组控制执行的不同方面的值,分为四个组:
- 执行控制 - 指定是否允许脚本在客户端或服务器上运行
- 实例访问控制 - 指定脚本可以与哪些 DataModel 部分互动
- 脚本功能控制 - 指定哪些 Luau 函数脚本可调用
- 引擎 API 访问控制 - 指定哪些部分的 Roblox 引擎 API 可用
当脚本尝试执行不属于当前执行状态的能力集的行动时,将报告错误。错误通常包括正在尝试的行动作、行动目标以及缺少的第一个能力,例如:
The current thread cannot modify 'Workspace' (lacking capability AccessOutsideWrite)The current thread cannot call 'Clone' (lacking capability CreateInstances)The current thread cannot call 'GetSecret' (lacking capability Network)
执行控制
该集包括两个能力:
如果脚本是 Enabled,但对应的位置无法启动的能力不可用,在 输出 窗口中会显示警告消息。如果脚本不应在该上下文中运行,请禁用或删除它。
请注意,ModuleScripts 不需要具有这些执行功能的要求。
当脚本因缺少执行控制功能无法启动时,将在输出中报告为警告,例如:
Cannot start server script 'Script' (lacking capability RunServerScript)
实例访问控制
该集仅包含一个能力:
- 访问外部写入 - 脚本可以从沙盒容器之外获取和接收实例
当能力不可用时,脚本只能查找属于自己沙箱容器内的实例。例如,如果脚本直接放置在沙盒容器中,script.Parent.Parent 将返回 nil。
此外,任何 Roblox API 事件,如果传入 Instance 而不是传入 nil 到沙盒中的容器外部,都会传入 Instance 。例如,如果 BasePart.Touched 由外部沙盒容器之外的实例触发,事件仍然收到,但参数是 nil 。
避免设置此功能;沙盒保证在脚本可以与体验中的任何实例交互时更弱。
访问服务
即使没有 AccessOutsideWrite ,沙盒中的脚本仍然可以访问game、workspace和服务。这种访问提供了,以便脚本仍然可以调用那些全局的有用方法,例如 DataModel.GetService ,但仍然需要验证其子实例的访问。
内部传递实例
如果实例通过不经过 Roblox API 的函数调用传递,引用将被保留。然而,如果以这种方式传递 ModuleScript,它不能没有 AccessOutsideWrite 被要求。这是因为 ModuleScript 的返回通常是可变的,可以由沙盒容器中的脚本修改。
脚本功能控制
这组功能控制了脚本的一些通用方面:
- 资产需求 - 脚本可以调用 require 以获取资产ID
- 加载字符串 - 脚本可以调用 loadstring
请记住,默认功能限制仍然适用。即使 LoadString 已启用,体验仍然需要在 ServerScriptService 中启用它,并且仍然仅适用于服务器。
要创建新实例,除了 创建实例 外,还需要一个额外的引擎 API 功能,可以访问该实例。
引擎 API 访问控制
最后一组功能控制脚本访问各种引擎 API:
- 基础 - 访问简单实例和必需的构建块
- 音频 - 访问与音频 API 相关的实例
- 数据存储 - 访问数据存储和内存存储API
- 网络 - 访问 HTTP 网络 API
- 物理学 - 访问与物理相关的实例
- 用户界面 - 访问与用户界面相关的实例
- CSG :访问与建造性固体几何(CSG)相关的实例和函数
- 聊天 :访问与体验聊天相关的实例
- 动画 : 访问与动画相关的实例
- 虚拟形象 :访问与虚拟形象相关的实例
- 输入 : 访问与用户输入相关的实例
- 环境 : 访问与环境显示控制相关的实例
- 远程事件 :访问内部网络操作的实例
还有一些情况可以执行脚本,但没有任何功能,例如无法执行脚本。这些包括以下方法 HttpService:
如果实例属性或方法没有使用必需的能力访问,将报告错误描述缺少的能力。
最后,能力目前不能覆盖 Roblox 引擎中的每个实例。本节或下一节中未列出的实例无法从沙盒容器中与互动,并且会抛出一个错误说明未分配的 能力 不适用于当前脚本。
另一个限制是 getfenv 和 setfenv 函数在沙盒容器中不可用于脚本。
仅限脚本访问实例。实例本身仍然可以存在并在沙盒容器内自行运行。灯光仍然闪亮,用户界面仍然可见,已连接的音频设置仍然播放声音。
引擎 API 功能分配
以下是每个引擎 API 功能的实例和方法列表(如果与实例功能不同):
基础 * Attachment
数据存储 * DataStore , OrderedDataStore , GlobalDataStore
物理 * AlignOrientation , AlignPosition , DynamicRotate
UI * BasePlayerGui , PlayerGui , BillboardGui , GuiBase , GuiBase2d , GuiBase3d , LayerCollector , ScreenGui , SurfaceGui , SurfaceGuiBase , UIBase
- UIComponent , UICorner , UIDragDetector , UIFlexItem , UIGradient , UIGridLayout , UIGridStyleLayout , UILayout , UIListLayout , UIPadding , UIPageLayout , UIScale , UIStroke , UITableLayout
CSG * GeometryService
- IntersectOperation (也需要 基础 ),NegateOperation (也需要 基础 ),PartOperation (也需要 基础 ),UnionOperation (也需要 基础 )
动画 * Bone (还需要 基础 )
环境 * Atmosphere , Clouds , Lighting , Sky
容器之间的互动
嵌套容器
当一个沙盒容器被另一个容器包含时,内部容器的实例可以访问外部容器。
内部容器的功能受外部容器的功能限制。例如,如果外部容器具有 基础 、 音频 和 CSG 功能,而内部容器具有 基础 和 网络 功能,那么在执行时间时,只有 基础 功能可用于内部容器。
如果内部和外部容器之间没有共同的能力,那么得到的能力集是空的。
可绑定的函数和事件
BindableEvent 和 BindableFunction 提供与容器通信的最佳方式或允许它运行回调,其自身不允许直接使用的功能。
当事件或函数发生时,连接在注册它们的函数的上下文中执行。这意味着如果事件或函数回调被沙箱容器注册,它将使用该容器的功能来调用。如果回调由外部代码注册,当沙箱容器脚本调用它们时,它们会执行你的函数,使用你的函数可用的功能。
值得注意的是,即使在 AccessOutsideWrite 功能启用的情况下,沙盒中的脚本也无法在容器外触发事件或函数,如果它们的功能集比容器本身更大。
模块需1) 必填 2)需要
内部 ModuleScripts 可以像往常一样被沙盒容器要求。然而,如果目标实例位于容器外,那么 ModuleScript 只能要求,如果它可以使用的能力集小于或等于容器可用的能力,才能使用。
此限制不适用于 运行客户端脚本 和 运行服务器脚本 功能。如果 ModuleScript 放置在只包含 RunClientScript 但需要从具有 RunServerScript 功能的脚本中获取的容器中,它可以成功并在服务器上运行这些函数。
直接调用函数
如果沙盒中的容器中需要 ModuleScript 从容器外,那么一些保护措施无法使用。特别是,目标函数可以访问调用者可以访问的所有实例。如果调用者不在沙盒容器中,调用就像如果 AccessOutsideWrite 可用于它一样。
其他能力限制仍然适用。如果您有一个 数据存储 访问能力,但目标模块没有,它无法调用 DataStore。然而,如果你通过自己的函数与 DataStore 工作,目标在那个调用期间可以运行它。如果目标使用方法如 task 从中调度线程,那些线程将失去调用该函数的能力。
实例可以传递到目标模块或分配到模块字段。
如果需要,建议使用 rawset 分配表成员,以避免运行可能在表上设置的 __index / __newindex 虚拟方法。
整体建议是尽可能与 BindableEvent 和 BindableFunction 通信。
实例移动
大多数情况下,容器之间的移动没有限制。但是,脚本实例只能移至具有相同集功能或这些功能的子集的容器中。
这意味着沙盒容器 AccessOutsideWrite 无法只将内部的脚本重新传给外部,获得更多功能。