腳本能力 讓您控制腳本在 DataModel 子樹中可以執行的操作。與默認的“全有或全無系統”不同,您可以將一個腳本設置為只能訪問某些類別,例如音頻、物理、數據存儲等。
- 此系統讓您限制從工具箱中獲取的模型可以做的事情,並使在遊戲中包含用戶生成的內容變得更容易。
- 它還可以幫助確保允許玩家運行自己代碼的遊戲的更好安全性,這通常在受限或模擬環境中執行。
- 它還可以用來共享限制自己能做什麼的庫。例如,提供附加數學方法的庫可以限制為它所需的最小能力集,以便使用該庫的其他開發人員不必驗證整個代碼庫以確保它不包含惡意代碼。
啟用腳本能力
要啟用此功能,請在 Explorer 和 Properties 窗口中將 SandboxedInstanceMode 屬性從 Default 更改為 Experimental。
沙盒容器
腳本能力引入了一個 沙盒容器 的概念。Models、Folders、Scripts 或這些類別的後代在 Properties 窗口中都有一個可用的 Sandboxed 屬性。

啟用 Sandboxed 屬性將該實例指定為 DataModel 樹中的沙盒容器,限制該容器中的腳本可以根據 Capabilities 屬性中設置的值執行的操作。
能力
Capabilities 屬性是一組控制執行不同方面的值。能力分為以下幾個大類:
- 執行控制 - 指定腳本是否可以在客戶端或服務器上運行
- 實例訪問控制 - 指定腳本可以與哪些 DataModel 部件互動
- 腳本功能控制 - 指定腳本可以調用哪些 Luau 函數
- 引擎 API 訪問控制 - 指定可以使用 Roblox 引擎 API 的哪些部分
當腳本試圖執行不在能力集中的操作時,Roblox 會報告錯誤。錯誤通常包括正在嘗試的操作、操作的目標和第一個缺失的能力:
當前線程無法修改 'Workspace' (缺少能力 AccessOutsideWrite)當前線程無法調用 'Clone' (缺少能力 CreateInstances)當前線程無法調用 'GetSecret' (缺少能力 Network)
執行控制
兩個能力處理執行控制:
如果腳本是 Enabled,但試圖啟動的位置所對應的能力不可用,則會在 Output 窗口中顯示警告信息。如果某個腳本不應該在該上下文中運行,請禁用或刪除它。
注意,ModuleScripts 不需要這些執行能力。
當腳本因執行控制能力缺失而無法啟動時,會在輸出中報告為警告,例如:
無法啟動伺服器腳本 'Script' (缺少能力 RunServerScript)
實例訪問控制
一個能力處理實例訪問控制:
- AccessOutsideWrite - 腳本被允許從沙盒容器外部獲取和接收實例
當該能力不可用時,腳本只能查找其自己的沙盒容器內的實例。例如,如果腳本直接放置在沙盒容器內,script.Parent.Parent 會返回 nil。
此外,任何 Roblox API 事件傳入的 Instance 會替換為沙盒容器外部的 nil。例如,如果 BasePart.Touched 是由沙盒容器外部的實例觸發的,事件仍然會被接收,但參數是 nil。
避免設置此能力;當腳本可以與遊戲中的任何實例互動時,沙盒保證的安全性更弱。
對服務的訪問
即使沒有 AccessOutsideWrite,沙盒容器中的腳本仍然可以訪問 game、workspace 和服務。這種訪問是提供的,以便腳本仍然可以調用這些全局對象的一些有用方法,例如 DataModel.GetService,但對其子實例的訪問仍然是經過驗證的。
內部傳遞實例
如果通過不通過 Roblox API 的函數調用傳遞實例,該引用會被保留。然而,如果以這種方式傳遞 ModuleScript,則在沒有 AccessOutsideWrite 的情況下無法被要求。這是因為 ModuleScript 的返回通常是可變的,並且可以被沙盒容器中的腳本修改。
腳本功能控制
這組能力控制腳本的一些一般方面:
- LoadString - 腳本被允許調用 loadstring
請注意,默認的函數限制仍然適用。即使啟用了 LoadString,遊戲仍然需要在 ServerScriptService 中啟用它,而且它仍然僅在服務器上可用。
要創建新實例,除了 CreateInstances,還需要一個提供對該實例訪問的額外引擎 API 能力。
引擎 API 訪問控制
這最後一組能力控制腳本對各種引擎 API 的訪問:
- Animation - 訪問與動畫相關的實例
- AssetCreateUpdate - 訪問與創建或更新資產相關的引擎 API
- AssetManagement - 訪問與資產操作相關的引擎 API,但不涉及讀取、創建或更新
- AssetRead - 訪問與獲取有關資產的信息的引擎 API
- Audio - 訪問與音頻 API 相關的實例
- AvatarAppearance - 訪問與角色的視覺元素相關的實例
- AvatarBehavior - 訪問與控制或修改人形的引擎 API
- Basic - 訪問提供很小風險的一般 API
- CSG - 訪問與構造實體幾何 (CSG) 相關的實例和函數
- CapabilityControl - 訪問修改實例的 Sandboxed 和 Capabilities 屬性
- Capture - 訪問與在用戶屏幕上捕獲截圖或視頻相關的引擎 API
- Chat - 訪問與遊戲內聊天相關的實例
- Consequences - 訪問用於懲罰用戶的 API(踢出或禁止)
- DataStore - 訪問數據存儲和內存存儲 API
- DynamicGeneration - 訪問與動態修改資產相關的引擎 API
- Environment - 訪問與控制環境顯示方式相關的實例
- Groups - 訪問與組/社區相關的引擎 API
- Input - 訪問與用戶輸入相關的實例
- LegacySound - 訪問與即將被淘汰的聲音相關的引擎 API
- LoadOwnedAsset - 訪問用於加載您擁有的資產、與您共享的資產、由 Roblox 擁有的資產或是良性資產類型的引擎 API
- Logging - 訪問日誌 API
- Material - 訪問與材料相關的引擎 API
- Monetization - 訪問與貨幣化遊戲相關的引擎 API,但不包括大多數 PromptPurchases
- Network - 訪問 HTTP 網路 API
- Physics - 訪問與物理相關的實例
- PlatformAvatarEditing - 訪問與創建或更新角色相關的引擎 API,或協助處理這些的 API
- PromptExternalPurchase - 許可訪問與提示購買任意資產相關的引擎 API
- RemoteEvent - 訪問內部網絡操作的實例
- SensitiveInput - 訪問與捕獲用戶的敏感輸入相關的引擎 API,即高隱私硬件傳感器。
- ServerCommunication - 訪問與跨服務器通信相關的引擎 API,例如 MessagingService
- Social - 訪問與社交功能相關的引擎 API,例如朋友和邀請
- Teleport - 訪問與傳送相關的引擎 API
- UI - 訪問與用戶界面相關的實例
每個類、屬性、方法和事件的能力在 引擎 API 參考 中顯示。例如,Player:GetFriendsOnlineAsync() 需要 Player 和 Social 能力。
幾個 HttpService 方法在執行腳本時不需要任何能力即可使用:
如果訪問某個實例屬性或方法時缺少所需的能力,將報告描述缺失能力的錯誤。
最後,能力並未涵蓋當前 Roblox 引擎中的每個實例。未在本節或下一節中列出的實例無法從沙盒容器中進行交互,並會抛出一個錯誤,說明當前腳本無法訪問的 Unassigned 能力。
另一個限制是 getfenv() 和 setfenv() 函數對沙盒容器中的腳本不可用。從沙盒腳本調用它們會報告:
當前線程無法調用 ['getfenv'/'setfenv'] - 目標使用了當前沙盒中不可用的 API
僅限於腳本訪問實例的限制。實例本身仍然可以在沙盒容器中自行存在和運行。燈光仍然亮著,用戶界面仍然可見,已經接駁的音頻設置播放聲音。
容器之間的交互
嵌套容器
當一個沙盒容器嵌套在另一個沙盒容器內時,內部容器的實例對外部容器可訪問。
內部容器的能力受外部容器能力的限制。 例如,如果外部容器擁有 Basic、Audio 和 CSG 的能力,而內部容器擁有 Basic 和 Network,則在運行時僅內部容器可以使用 Basic 能力。
如果內部容器和外部容器之間沒有共同的能力,則結果能力集為空。
可綁定的函數和事件
BindableEvent 和 BindableFunction 提供與容器進行通信的最佳方式,或允許其運行具有其自己無法直接使用的能力的回調。
當一個事件被觸發或一個函數被調用時,連接在註冊它們的函數上下文中執行。這意味著如果事件或函數回調由沙盒容器註冊,則它是在該容器的能力下調用的。如果回調由外部代碼註冊,當沙盒容器腳本調用它們時,它們是在調用函數可用的能力下執行的。
需要注意的是,即使具有 AccessOutsideWrite 能力,沙盒容器內的腳本也無法調用超出其容器的事件或函數,如果這些事件或函數的祖先能力超過了其自身。
當一個沙盒腳本試圖觸發或調用其祖先能力超過自身的事件或函數(BindableEvent、BindableFunction 或 RemoteEvent)時,錯誤會命名要檢查的屬性。
如果目標不在任何沙盒容器內:
當前線程無法觸發 '<Target>',因為 '<Target>' 的 Sandboxed 屬性為 false,但調用線程是沙盒的
要解決此問題,請將目標的 Sandboxed 設置為 true。另外,您可以修改調用線程的源,使其 Sandboxed 設置為 false,但這不建議,因為這會消除沙盒提供的安全益處。
如果目標被沙盒化,但擁有調用者缺少的能力:
當前線程無法觸發 '<Target>',因為 '<Target>' 擁有 Capabilities 屬性中的額外值: <First Missing Capability> (以及 N 個其他)
要解決此問題,請將目標的 Capabilities 縮小到調用者的子集,或擴展調用者的 Capabilities 以與目標匹配。
模塊要求
內部的 ModuleScripts 可以像往常一樣由沙盒容器要求。 但是,如果目標實例在容器外部,則只能在可用的能力集與容器的能力相同或更小的情況下對 ModuleScript 進行要求。
此限制不適用於 RunClientScript 和 RunServerScript 能力。如果 ModuleScript 放置在僅具有 RunClientScript 的容器中,但從具有 RunServerScript 能力的腳本中進行要求,則允許成功並在服務器上運行這些函數。
當 require() 在能力不匹配時失敗時,錯誤會命名目標模塊和要檢查的屬性,與上一節中描述的可綁定函數和事件相同。
直接調用的函數
如果從沙盒容器外部要求沙盒容器中的 ModuleScript,一些保護將無法使用。具體來說,目標函數能夠訪問調用者可用的所有實例。如果調用者不在沙盒容器內,該調用則如同 AccessOutsideWrite 可用。
其他能力限制仍然適用。如果您擁有 DataStore 訪問能力,但目標模塊沒有,則無法調用 DataStore 方法。然而, 如果您傳遞自己的與 DataStore 交互的函數,目標可以在該調用期間運行它。 如果目標使用諸如來自 task 的方法調度了一個線程,則這些線程將失去調用該函數的能力。
實例可以被傳遞到目標模塊或分配給模塊字段。
如有必要,建議使用 rawset 來分配表成員,以避免運行可能設置在表上的 __index/__newindex metamethods。
總體建議是盡可能與 BindableEvent 和 BindableFunction 進行通信。
實例的移動
大多數實例在容器之間移動沒有任何限制。然而,腳本實例只能移動到具有相同或子集能力的容器中。
這意味著一個具有 AccessOutsideWrite 的沙盒容器不能僅僅將一個腳本重新分類到其外部而獲得更多能力。