Khả năng của Script cho phép bạn kiểm soát các hành động mà script có thể thực hiện trong cây DataModel. Thay vì sử dụng hệ thống mặc định "tất cả hoặc không có gì", bạn có thể cài đặt một script chỉ có thể truy cập các danh mục nhất định, chẳng hạn như âm thanh, vật lý, kho dữ liệu và nhiều hơn nữa.
- Hệ thống này cho phép bạn giới hạn những gì các mô hình lấy từ toolbox có thể làm và giúp dễ dàng hơn trong việc bao gồm nội dung do người dùng tạo trong trò chơi.
- Nó cũng có thể giúp đảm bảo an ninh tốt hơn cho các trò chơi cho phép người chơi thực thi mã của riêng họ, vốn thường được thực thi trong một môi trường bị hạn chế hoặc giả lập.
- Nó cũng có thể được sử dụng để chia sẻ thư viện hạn chế những gì chúng có thể tự làm. Ví dụ, một thư viện cung cấp thêm các phương thức toán học có thể bị hạn chế ở tập hợp khả năng nhỏ nhất mà nó cần để các nhà phát triển khác sử dụng thư viện đó không phải xác thực toàn bộ mã nguồn để đảm bảo rằng nó không chứa mã độc.
Kích hoạt khả năng script
Để kích hoạt tính năng này, hãy thay đổi thuộc tính SandboxedInstanceMode từ Default thành Experimental trong cửa sổ Explorer và Properties.
Container bị hạn chế
Khả năng của script giới thiệu một khái niệm về container bị hạn chế. Models, Folders, Scripts hoặc các đối tượng kế thừa từ bất kỳ lớp nào trong số đó có thuộc tính Sandboxed có sẵn trong cửa sổ Properties.

Kích hoạt thuộc tính Sandboxed làm cho instance trở thành một container bị hạn chế trong cây DataModel, giới hạn các hành động mà các script bên trong container đó có thể thực hiện dựa trên tập hợp các giá trị trong thuộc tính Capabilities.
Các khả năng
Thuộc tính Capabilities là một tập hợp các giá trị kiểm soát các khía cạnh khác nhau của thực thi. Các khả năng này rơi vào các danh mục rộng sau:
- Kiểm soát thực thi - Quy định xem một script có thể chạy trên client hay server
- Kiểm soát truy cập instance - Quy định các phần DataModel mà một script có thể tương tác
- Kiểm soát chức năng script - Quy định các hàm Luau mà các script có thể gọi
- Kiểm soát truy cập API Engine - Quy định các phần của Roblox Engine API có thể được sử dụng
Khi một script cố gắng thực hiện một hành động không có trong tập các khả năng, Roblox sẽ báo cáo một lỗi. Các lỗi thường bao gồm hành động được thực hiện, mục tiêu của một hành động và khả năng đầu tiên mà thiếu:
Luồng hiện tại không thể sửa đổi 'Workspace' (thiếu khả năng AccessOutsideWrite)Luồng hiện tại không thể gọi 'Clone' (thiếu khả năng CreateInstances)Luồng hiện tại không thể gọi 'GetSecret' (thiếu khả năng Network)
Kiểm soát thực thi
Hai khả năng xử lý kiểm soát thực thi:
- RunClientScript - LocalScript hoặc Script với giá trị RunContext là Client được phép thực thi trên client
Nếu script được Enabled, nhưng khả năng tương ứng với vị trí mà nó cố gắng bắt đầu không có sẵn, một thông báo cảnh báo sẽ được hiển thị trong cửa sổ Output. Nếu một script không được phép chạy trong ngữ cảnh đó, hãy vô hiệu hóa hoặc xóa nó.
Lưu ý rằng ModuleScripts không cần có những khả năng thực thi này để được yêu cầu.
Khi một script không khởi động được vì thiếu khả năng kiểm soát thực thi, nó sẽ được báo cáo dưới dạng cảnh báo trong đầu ra, ví dụ:
Không thể khởi động script server 'Script' (thiếu khả năng RunServerScript)
Kiểm soát truy cập instance
Một khả năng duy nhất xử lý kiểm soát truy cập instance:
- AccessOutsideWrite - Script được phép xác định và nhận các instance từ bên ngoài container bị hạn chế
Khi khả năng này không có sẵn, script chỉ có thể tra cứu các instance ở bên trong chính container bị hạn chế của nó. Ví dụ, nếu script được đặt trực tiếp trong container bị hạn chế, script.Parent.Parent trả về nil.
Ngoài ra, bất kỳ sự kiện API Roblox nào truyền vào một Instance thì cũng trả vào nil cho bất kỳ Instance nào bên ngoài container bị hạn chế. Ví dụ, nếu BasePart.Touched được kích hoạt bởi một cú chạm từ một instance bên ngoài container bị hạn chế, sự kiện vẫn được nhận, nhưng đối số là nil.
Tránh thiết lập khả năng này; sự đảm bảo về sandbox để yếu hơn khi các script có thể tương tác với bất kỳ instance nào trong một trò chơi.
Truy cập vào các dịch vụ
Ngay cả khi không có AccessOutsideWrite, các script trong container bị hạn chế vẫn có thể truy cập game, workspace, và các dịch vụ. Quyền truy cập này được cung cấp để các script có thể gọi các phương thức hữu ích của các globals đó, như DataModel.GetService, nhưng quyền truy cập vào các child instance của chúng vẫn được xác thực.
Các instance được truyền qua nội bộ
Nếu một instance được truyền qua một cuộc gọi hàm không qua các API của Roblox, tham chiếu sẽ được bảo toàn. Tuy nhiên, nếu một ModuleScript được truyền theo cách này, nó không thể được yêu cầu mà không cần AccessOutsideWrite. Điều này là vì kết quả của ModuleScript thường có thể thay đổi và có thể bị một script trong một container bị hạn chế sửa đổi.
Kiểm soát chức năng script
Tập các khả năng này kiểm soát một số khía cạnh chung của các script:
- CreateInstances - Script được phép tạo các instance mới bằng cách sử dụng Instance.new, Instance.fromExisting, hoặc Instance:Clone()
- LoadString - Script được phép gọi loadstring
- LoadUnownedAsset - Script được phép gọi require với một ID tài sản hoặc AssetService:LoadAssetAsync()
Hãy nhớ rằng các hạn chế mặc định của hàm vẫn áp dụng. Ngay cả khi LoadString được kích hoạt, trò chơi vẫn phải kích hoạt nó trong ServerScriptService, và nó vẫn chỉ có sẵn trên server.
Để tạo các instance mới, ngoài CreateInstances, một khả năng API Engine bổ sung cung cấp quyền truy cập vào instance đó là cần thiết.
Kiểm soát truy cập API Engine
Nhóm cuối cùng của các khả năng kiểm soát quyền truy cập script đến các API Engine khác nhau:
- Animation - Quyền truy cập vào các instance liên quan đến hoạt ảnh
- AssetCreateUpdate - Quyền truy cập vào các API Engine liên quan đến việc tạo hoặc cập nhật tài sản
- AssetManagement - Quyền truy cập vào các API Engine liên quan đến các thao tác đối với tài sản không phải đọc, tạo hoặc cập nhật
- AssetRead - Quyền truy cập vào các API Engine liên quan đến việc lấy thông tin về tài sản
- Audio - Quyền truy cập vào các instance liên quan đến các API âm thanh
- AvatarAppearance - Quyền truy cập vào các instance liên quan đến các yếu tố hình ảnh của avatars
- AvatarBehavior - Quyền truy cập vào các API Engine liên quan đến việc điều khiển hoặc sửa đổi humanoid
- Basic - Quyền truy cập vào các API chung mà không có mối nguy hiểm lớn
- CSG - Quyền truy cập vào các instance và chức năng liên quan đến hình học rắn cấu trúc (CSG)
- CapabilityControl - Quyền truy cập để sửa đổi các thuộc tính Sandboxed và Capabilities của các instance
- Capture - Quyền truy cập vào các API Engine liên quan đến việc chụp ảnh màn hình hoặc video trên màn hình của người dùng
- Chat - Quyền truy cập vào các instance liên quan đến trò chuyện trong trò chơi
- Consequences - Quyền truy cập vào các API để trừng phạt người dùng (đá hoặc cấm)
- DataStore - Quyền truy cập vào API kho dữ liệu và kho nhớ
- DynamicGeneration - Quyền truy cập vào các API Engine liên quan đến việc sửa đổi tài sản một cách động
- Environment - Quyền truy cập vào các instance liên quan đến cách hiển thị môi trường
- Groups - Quyền truy cập vào các API Engine liên quan đến các nhóm/cộng đồng
- Input - Quyền truy cập vào các instance liên quan đến đầu vào của người dùng
- LegacySound - Quyền truy cập vào các API Engine liên quan đến âm thanh sẽ bị ngừng sử dụng
- LoadOwnedAsset - Quyền truy cập vào các API Engine để tải tài sản mà bạn sở hữu, được chia sẻ cho bạn, do Roblox sở hữu, hoặc là một loại tài sản không gây hại
- Logging - Quyền truy cập vào API ghi chép
- Material - Quyền truy cập vào các API Engine liên quan đến vật liệu
- Monetization - Quyền truy cập vào các API Engine liên quan đến việc kiếm tiền từ một trò chơi, không bao gồm hầu hết các PromptPurchases
- Network - Quyền truy cập vào các API mạng HTTP
- Physics - Quyền truy cập vào các instance liên quan đến vật lý
- PlatformAvatarEditing - Quyền truy cập vào các API Engine liên quan đến việc tạo hoặc cập nhật avatars, hoặc các API để hỗ trợ việc đó
- Players - Quyền truy cập vào các API Engine liên quan đến lớp Player hoặc biểu diễn/tương tác với Players.LocalPlayer
- PromptExternalPurchase - Cho phép quyền truy cập vào các API Engine liên quan đến việc yêu cầu mua tài sản tùy ý
- RemoteEvent - Quyền truy cập vào các instance cho các thao tác mạng nội bộ
- SensitiveInput - Quyền truy cập vào các API Engine liên quan đến việc thu thập đầu vào nhạy cảm từ người dùng, tức là các cảm biến phần cứng có độ riêng tư cao.
- ServerCommunication - Quyền truy cập vào các API Engine liên quan đến giao tiếp giữa các server, chẳng hạn như MessagingService
- Social - Quyền truy cập vào các API Engine liên quan đến các tính năng xã hội, chẳng hạn như bạn bè và lời mời
- Teleport - Quyền truy cập vào các API Engine liên quan đến việc dịch chuyển
- UI - Quyền truy cập vào các instance liên quan đến giao diện người dùng
Các khả năng của từng lớp, thuộc tính, phương thức, và sự kiện được hiển thị trong Tài liệu tham khảo API Engine. Ví dụ, Player:GetFriendsOnlineAsync() yêu cầu các khả năng Player và Social.
Một số phương thức của HttpService có sẵn mà không cần bất kỳ khả năng nào ngoài việc có thể thực thi các scripts:
Nếu một thuộc tính hoặc phương thức instance bị truy cập mà không có khả năng yêu cầu, một lỗi sẽ được báo cáo mô tả khả năng còn thiếu.
Cuối cùng, các khả năng không bao trùm mọi instance trong Roblox Engine ngày nay. Các instance không được liệt kê trong phần này hoặc phần tiếp theo không có sẵn để tương tác từ một container bị hạn chế và sẽ báo lỗi cho rằng khả năng Unassigned không có sẵn cho script hiện tại.
Một hạn chế bổ sung là các hàm getfenv() và setfenv() không có sẵn cho các script trong một container bị hạn chế. Gọi chúng từ một script bị hạn chế báo cáo:
Luồng hiện tại không thể gọi ['getfenv'/'setfenv'] - mục tiêu sử dụng các API không có sẵn trong sandbox hiện tại
Chỉ có quyền truy cập script đến các instance là bị hạn chế. Các instance tự chúng vẫn có thể tồn tại và hoạt động một mình bên trong một container bị hạn chế. Ánh sáng vẫn sáng, giao diện người dùng vẫn hiển thị, và các thiết lập âm thanh đã được kết nối phát âm thanh.
Tương tác giữa các container
Các container lồng nhau
Khi một container bị hạn chế được lồng bên trong một container khác, các instance của container bên trong có thể truy cập được từ phía bên ngoài.
Khả năng của container bên trong bị giới hạn bởi khả năng của container bên ngoài. Ví dụ, nếu container bên ngoài có các khả năng Basic, Audio và CSG, trong khi container bên trong có Basic và Network, chỉ có khả năng Basic là có sẵn cho container bên trong trong thời gian chạy.
Nếu không có khả năng chung nào giữa các container bên trong và bên ngoài, tập hợp khả năng kết quả sẽ rỗng.
Hàm và sự kiện có thể liên kết
BindableEvent và BindableFunction cung cấp cách tốt nhất để giao tiếp với container hoặc cho phép nó chạy các callback với các khả năng mà nó không được phép sử dụng trực tiếp.
Khi một sự kiện được kích hoạt hoặc một hàm được gọi, các kết nối được thực hiện trong ngữ cảnh của hàm đã đăng ký chúng. Điều này có nghĩa là nếu sự kiện hoặc callback hàm được đăng ký bởi container bị hạn chế, nó sẽ được gọi với các khả năng của container đó. Nếu callback được đăng ký bởi mã bên ngoài, khi các script của container bị hạn chế gọi chúng, chúng sẽ thực thi các hàm của bạn với các khả năng có sẵn cho các hàm của bạn.
Điều quan trọng cần lưu ý là ngay cả với khả năng AccessOutsideWrite, các script trong các container bị hạn chế không thể kích hoạt sự kiện hoặc hàm bên ngoài các container nếu chúng có tập hợp khả năng lớn hơn so với container đó.
Khi một script bị hạn chế cố gắng kích hoạt hoặc gọi một sự kiện hoặc hàm (BindableEvent, BindableFunction, hoặc RemoteEvent) có khả năng tổ tiên vượt quá khả năng của nó, lỗi sẽ chỉ ra thuộc tính cần kiểm tra.
Nếu mục tiêu không nằm bên trong bất kỳ container bị hạn chế nào:
Luồng hiện tại không thể kích hoạt '<Target>' vì '<Target>' đã có thuộc tính Sandboxed được thiết lập thành false nhưng luồng gọi là đã bị hạn chế
Để giải quyết điều này, hãy đặt Sandboxed thành true cho mục tiêu. Ngoài ra, bạn có thể sửa đổi nguồn của luồng gọi để có Sandboxed được thiết lập thành false, nhưng điều này không được khuyến cáo vì nó loại bỏ các lợi ích bảo mật mà sandboxing cung cấp.
Nếu mục tiêu bị hạn chế nhưng có các khả năng mà caller thiếu:
Luồng hiện tại không thể kích hoạt '<Target>' vì '<Target>' có các giá trị bổ sung cho thuộc tính Capabilities: <First Missing Capability> (và N cái nữa)
Để giải quyết điều này, hãy thu hẹp Capabilities của mục tiêu thành một tập hợp con của caller, hoặc mở rộng Capabilities của caller để khớp với mục tiêu.
yêu cầu mô-đun
Cấu trúc ModuleScripts bên trong có thể được yêu cầu bởi container bị hạn chế như thường lệ. Tuy nhiên, nếu instance mục tiêu nằm bên ngoài container, ModuleScript chỉ có thể được yêu cầu nếu tập hợp khả năng có sẵn cho nó nhỏ hơn hoặc bằng các khả năng có sẵn cho container.
Hạn chế này không áp dụng cho các khả năng RunClientScript và RunServerScript. Nếu ModuleScript được đặt trong một container chỉ có RunClientScript nhưng được yêu cầu từ một script có khả năng RunServerScript, thì điều này được phép thành công và chạy các hàm đó trên server.
Khi require() không thành công do sự không tương thích về khả năng, lỗi sẽ chỉ ra mô-đun mục tiêu và thuộc tính cần kiểm tra theo cách tương tự như các hàm và sự kiện có thể liên kết được mô tả trong phần trước.
Các hàm được gọi trực tiếp
Nếu một ModuleScript trong một container bị hạn chế được yêu cầu từ bên ngoài container, một số bảo vệ không có sẵn. Đặc biệt, hàm mục tiêu có khả năng truy cập tất cả các instance có sẵn cho caller. Nếu caller không nằm trong một container bị hạn chế, cuộc gọi hoạt động như thể AccessOutsideWrite có sẵn cho nó.
Các hạn chế về khả năng khác vẫn được áp dụng. Nếu bạn có khả năng truy cập DataStore, nhưng mô-đun mục tiêu không có, nó không thể gọi các phương thức của DataStore. Tuy nhiên, nếu bạn truyền hàm của riêng mình làm việc với DataStore, mô-đun mục tiêu có thể chạy nó trong cuộc gọi đó. Nếu mục tiêu lập lịch một luồng sử dụng các phương thức như từ task, các luồng đó mất khả năng gọi được hàm đó.
Các instance có thể được truyền cho mô-đun mục tiêu hoặc gán cho các trường của mô-đun.
Nếu cần thiết, nên gán các thành viên của bảng bằng cách sử dụng rawset để tránh việc chạy các phương thức biến đổi __index/__newindex có thể đã được thiết lập trên bảng.
Khuyến nghị chung là giao tiếp với BindableEvent và BindableFunction bất cứ khi nào có thể.
Di chuyển các instance
Hầu hết các instance không có hạn chế về việc di chuyển giữa các container. Tuy nhiên, các instance script chỉ có thể được di chuyển vào một container có cùng tập hợp các khả năng hoặc một tập con của các khả năng đó.
Điều này có nghĩa là một container bị hạn chế với AccessOutsideWrite không thể chỉ cần thay đổi cha của một script bên trong nó thành bên ngoài và có được nhiều khả năng hơn.