Le capacità degli script ti consentono di controllare quali azioni possono eseguire gli script all'interno del sottoalbero DataModel. Piuttosto che il "sistema tutto-o-niente" predefinito, puoi impostare uno script per poter accedere solo a determinate categorie, come audio, fisica, negozi di dati e altro ancora.
- Questo sistema ti consente di limitare cosa possono fare i modelli presi dagli strumenti e rende più facile includere contenuti generati dagli utenti all'interno del gioco.
- Può anche contribuire a garantire una maggiore sicurezza per i giochi che consentono ai giocatori di eseguire il proprio codice, che viene spesso eseguito in un ambiente ristretto o emulato.
- Può anche essere utilizzato per condividere librerie che limitano ciò che possono fare. Ad esempio, una libreria che fornisce metodi matematici aggiuntivi può essere limitata al set più piccolo di capacità necessarie affinché gli altri sviluppatori che utilizzano quella libreria non debbano convalidare l'intero codice per assicurarsi che non contenga codice maligno.
Abilitare le capacità degli script
Per abilitare questa funzione, modifica la proprietà SandboxedInstanceMode da Default a Experimental nella finestra Explorer e Properties.
Contenitore sandboxed
Le capacità degli script introducono un concetto di contenitore sandboxed. Models, Folders, Scripts o discendenti di una di queste classi hanno una proprietà Sandboxed disponibile nella finestra Properties.

Abilitando la proprietà Sandboxed, si designa l'istanza come contenitore sandboxed all'interno dell'albero DataModel, il che limita le azioni che gli script all'interno di quel contenitore possono eseguire in base al set di valori nella proprietà Capabilities.
Capacità
La proprietà Capabilities è un insieme di valori che controllano diversi aspetti dell'esecuzione. Le capacità rientrano nelle seguenti ampie categorie:
- Controllo dell'esecuzione - Specifica se uno script può essere eseguito su client o server
- Controllo dell'accesso alle istanze - Specifica con quali parti di DataModel uno script può interagire
- Controllo della funzionalità dello script - Specifica quali funzioni Luau possono essere chiamate dagli script
- Controllo dell'accesso all'API del motore - Specifica quali parti dell'API del motore di Roblox possono essere utilizzate
Quando uno script tenta di eseguire un'azione che non è nel set di capacità, Roblox riporta un errore. Gli errori includono tipicamente l'azione tentata, il target di un'azione e la prima capacità mancante:
Il thread corrente non può modificare 'Workspace' (mancanza della capacità AccessOutsideWrite)Il thread corrente non può chiamare 'Clone' (mancanza della capacità CreateInstances)Il thread corrente non può chiamare 'GetSecret' (mancanza della capacità Network)
Controllo dell'esecuzione
Due capacità gestiscono il controllo dell'esecuzione:
- RunClientScript - LocalScript o Script con un valore RunContext di Client è autorizzato ad essere eseguito sul client
- RunServerScript - Script con un valore RunContext di Server è autorizzato ad essere eseguito sul server
Se lo script è Enabled, ma la capacità corrispondente alla posizione in cui tenta di avviarsi non è disponibile, viene visualizzato un messaggio di avviso nella finestra Output. Se uno script non doveva essere eseguito in quel contesto, disabilitalo o eliminalo.
Nota che ModuleScripts non hanno bisogno di avere queste capacità di esecuzione per essere richiesti.
Quando uno script non riesce ad avviarsi perché la capacità di controllo dell'esecuzione è mancante, viene segnalato come avviso nell'output, ad esempio:
Impossibile avviare lo script server 'Script' (mancanza della capacità RunServerScript)
Controllo dell'accesso alle istanze
Una singola capacità gestisce il controllo dell'accesso alle istanze:
- AccessOutsideWrite - Lo script è autorizzato a recuperare e ricevere istanze dall'esterno del contenitore sandboxed
Quando la capacità non è disponibile, lo script può solo cercare istanze che si trovano all'interno del proprio contenitore sandboxed. Ad esempio, se lo script è collocato direttamente nel contenitore sandboxed, script.Parent.Parent restituisce nil.
Inoltre, qualsiasi evento dell'API di Roblox che passa un Instance invece passa nil per qualsiasi Instance all'esterno del contenitore sandboxed. Ad esempio, se il BasePart.Touched viene segnalato da un tocco di un'istanza esterna al contenitore sandboxed, l'evento viene comunque ricevuto, ma l'argomento è nil.
Evita di impostare questa capacità; le garanzie di sandboxing sono più deboli quando gli script possono interagire con qualsiasi istanza in un gioco.
Accesso ai servizi
Anche senza AccessOutsideWrite, gli script nel contenitore sandboxed possono ancora accedere a game, workspace e ai servizi. Questo accesso è fornito affinché gli script possano ancora chiamare metodi utili di quegli globali, come DataModel.GetService, ma l'accesso alle loro istanze figlie è comunque convalidato.
Istanze passate internamente
Se un'istanza viene passata tramite una chiamata di funzione che non passa attraverso le API di Roblox, il riferimento viene preservato. Tuttavia, se un ModuleScript viene passato in questo modo, non può essere richiesto senza AccessOutsideWrite. Questo perché il ritorno del ModuleScript è spesso mutabile e può essere modificato da uno script in un contenitore sandboxed.
Controllo della funzionalità degli script
Questo insieme di capacità controlla alcuni aspetti generali degli script:
- CreateInstances - Lo script può creare nuove istanze utilizzando Instance.new, Instance.fromExisting o Instance:Clone()
- LoadString - Lo script è autorizzato a chiamare loadstring
- LoadUnownedAsset - Lo script è autorizzato a chiamare require con un asset ID o AssetService:LoadAssetAsync()
Tieni presente che le restrizioni delle funzioni predefinite si applicano ancora. Anche se LoadString è abilitato, il gioco deve comunque abilitarlo in ServerScriptService, ed è ancora disponibile solo sul server.
Per creare nuove istanze, oltre a CreateInstances, è necessaria un'ulteriore capacità dell'API del motore che fornisca accesso a quell'istanza.
Controllo dell'accesso all'API del motore
Quest'ultimo gruppo di capacità controlla l'accesso degli script a varie API del motore:
- Animation - Accesso a istanze relative alle animazioni
- AssetCreateUpdate - Accesso alle API del motore relative alla creazione o all'aggiornamento degli asset
- AssetManagement - Accesso alle API del motore relative alle operazioni sugli asset che non sono lette, create o aggiornate
- AssetRead - Accesso alle API del motore relative all'ottenimento di informazioni sugli asset
- Audio - Accesso a istanze relative alle API audio
- AvatarAppearance - Accesso a istanze relative agli elementi visivi degli avatar
- AvatarBehavior - Accesso alle API del motore relative al controllo o alla modifica dell'umanoide
- Basic - Accesso a API generali che offrono poco rischio
- CSG - Accesso a istanze e funzioni relative alla geometria solida costruttiva (CSG)
- CapabilityControl - Accesso alla modifica delle proprietà Sandboxed e Capabilities delle istanze
- Capture - Accesso alle API del motore relative alla cattura di screenshot o video dello schermo dell'utente
- Chat - Accesso a istanze relative alla chat in-game
- Consequences - Accesso alle API per punire gli utenti (cacciate o ban)
- DataStore - Accesso alle API del negozio dati e del negozio in memoria
- DynamicGeneration - Accesso alle API del motore relative alla modifica dinamica degli asset
- Environment - Accesso a istanze relative al controllo di come viene visualizzato l'ambiente
- Groups - Accesso alle API del motore relative a gruppi/comunità
- Input - Accesso a istanze relative all'input dell'utente
- LegacySound - Accesso alle API del motore relative all'audio che sarà deprecato
- LoadOwnedAsset - Accesso alle API del motore per il caricamento di asset che sono di tua proprietà, condivisi con te, di proprietà di Roblox, o sono un tipo di asset benigno
- Logging - Accesso all'API di registrazione
- Material - Accesso alle API del motore relative ai materiali
- Monetization - Accesso alle API del motore relative alla monetizzazione di un gioco, escludendo la maggior parte dei PromptPurchases
- Network - Accesso alle API di networking HTTP
- Physics - Accesso a istanze relative alla fisica
- PlatformAvatarEditing - Accesso alle API del motore relative alla creazione o all'aggiornamento degli avatar, o API per aiutarli
- Players - Accesso alle API del motore relative alla classe Player o che restituiscono/interagiscono con Players.LocalPlayer
- PromptExternalPurchase - Consente l'accesso alle API del motore relative alla richiesta di acquisto di asset arbitrari
- RemoteEvent - Accesso a istanze per operazioni interne di networking
- SensitiveInput - Accesso alle API del motore relative alla cattura di input sensibile dall'utente, cioè sensori hardware ad alta privacy.
- ServerCommunication - Accesso alle API del motore relative alla comunicazione tra server, come MessagingService
- Social - Accesso alle API del motore relative a funzionalità sociali, come amici e inviti
- Teleport - Accesso alle API del motore relative al teletrasporto
- UI - Accesso a istanze relative alle interfacce utente
Le capacità di ciascuna classe, proprietà, metodo ed evento sono visualizzate nella riferimento API del motore. Ad esempio, Player:GetFriendsOnlineAsync() richiede le capacità Player e Social.
Diversi metodi di HttpService sono disponibili senza alcuna capacità, oltre alla possibilità di eseguire gli script:
Se una proprietà o un metodo di un'istanza viene accesso senza la capacità richiesta, viene riporta un errore che descrive la capacità mancante.
Infine, le capacità non coprono ogni istanza nel motore di Roblox oggi. Le istanze non elencate in questa sezione o nella seguente non sono disponibili per l'interazione da un contenitore sandboxed e generano un errore che indica che una capacità Non Assegnata non è disponibile per lo script corrente.
Un'ulteriore limitazione è che le funzioni getfenv() e setfenv() non sono disponibili per gli script in un contenitore sandboxed. Chiamarle da uno script sandboxed riporta:
Il thread corrente non può chiamare ['getfenv'/'setfenv'] - il target utilizza API non disponibili nel sandbox corrente
Solo l'accesso degli script alle istanze è limitato. Le istanze stesse possono comunque esistere e operare da sole all'interno di un contenitore sandboxed. Le luci continuano a brillare, le interfacce utente sono ancora visibili e le configurazioni audio già collegate riproducono suoni.
Interazioni tra contenitori
Contenitori annidati
Quando un contenitore sandboxed è annidato all'interno di un altro, le istanze del contenitore interno sono accessibili a quello esterno.
Le capacità del contenitore interno sono limitate dalle capacità di quello esterno. Ad esempio, se il contenitore esterno ha capacità Basic, Audio e CSG, mentre il contenitore interno ha Basic e Network, solo le capacità Basic sono disponibili per il contenitore interno a runtime.
Se non ci sono capacità in comune tra i contenitori interno ed esterno, il set di capacità risultante è vuoto.
Funzioni e eventi bindable
BindableEvent e BindableFunction forniscono il modo migliore per comunicare con il contenitore o consentirgli di eseguire callback con capacità che esso non è autorizzato a utilizzare direttamente.
Quando un evento viene attivato o una funzione viene invocata, le connessioni vengono eseguite nel contesto della funzione che le ha registrate. Ciò significa che se l'evento o il callback della funzione è registrato dal contenitore sandboxed, viene chiamato con le capacità di quel contenitore. Se il callback è registrato dal codice esterno, quando gli script del contenitore sandboxed li invocano, eseguono le tue funzioni con le capacità disponibili per le tue funzioni.
È importante notare che anche con la capacità AccessOutsideWrite, gli script nei contenitori sandboxed non possono invocare eventi o funzioni all'esterno dei loro contenitori se hanno un set di capacità superiore a quello del contenitore stesso.
Quando uno script sandboxed tenta di attivare o invocare un evento o una funzione (BindableEvent, BindableFunction o RemoteEvent) le cui capacità ancestrali superano le sue, l'errore nomina la proprietà da ispezionare.
Se il target non è all'interno di alcun contenitore sandboxed:
Il thread corrente non può attivare '<Target>' poiché '<Target>' ha la proprietà Sandboxed impostata su falso ma il thread chiamante è sandboxed
Per risolvere questo problema, imposta Sandboxed su true per il target. In alternativa, puoi modificare la sorgente del thread chiamante affinché abbia Sandboxed impostato su false, ma ciò non è raccomandato poiché elimina i vantaggi di sicurezza forniti dal sandboxing.
Se il target è sandboxed ma ha capacità che il chiamante non possiede:
Il thread corrente non può attivare '<Target>' poiché '<Target>' ha valori aggiuntivi per la proprietà Capabilities: <First Missing Capability> (e N altri)
Per risolverlo, restringi le Capabilities del target a un sottoinsieme di quelle del chiamante, o espandi le Capabilities del chiamante per corrispondere a quelle del target.
Requisiti del modulo
I ModuleScripts interni possono essere richiesti dal contenitore sandboxed come al solito. Tuttavia, se l'istanza target è all'esterno del contenitore, il ModuleScript può essere richiesto solo se il set di capacità disponibili è minore o uguale alle capacità disponibili per il contenitore.
Questa limitazione non si applica alle capacità RunClientScript e RunServerScript. Se il ModuleScript è collocato in un contenitore con solo RunClientScript ma viene richiesto da uno script che ha la capacità RunServerScript, è consentito il successo e l'esecuzione di quelle funzioni sul server.
Quando require() fallisce per un'incompatibilità di capacità, l'errore nomina il modulo target e la proprietà da ispezionare allo stesso modo delle funzioni e degli eventi bindable descritti nella sezione precedente.
Funzioni chiamate direttamente
Se un ModuleScript in un contenitore sandboxed viene richiesto da fuori dal contenitore, alcune delle protezioni non sono disponibili. In particolare, la funzione target è in grado di accedere a tutte le istanze disponibili per il chiamante. Se il chiamante non è in un contenitore sandboxed, la chiamata agisce come se la capacità AccessOutsideWrite fosse disponibile per esso.
Si applicano comunque altre restrizioni di capacità. Se hai una capacità di accesso DataStore, ma il modulo target non ce l'ha, non può chiamare i metodi di DataStore. Tuttavia, se passi la tua funzione che lavora con DataStore, il target può eseguirla durante quella chiamata. Se il target pianifica un thread utilizzando metodi come quelli di task, tali thread perdono la capacità di chiamare quella funzione.
Le istanze possono essere passate al modulo target o assegnate ai campi del modulo.
Se necessario, si raccomanda di assegnare membri delle tabelle utilizzando rawset per evitare di eseguire i metamodelli __index/__newindex che potrebbero essere impostati sulla tabella.
La raccomandazione generale è di comunicare con BindableEvent e BindableFunction ogni volta che è possibile.
Movimento delle istanze
La maggior parte delle istanze non ha restrizioni sul movimento tra i contenitori. Tuttavia, le istanze degli script possono essere spostate solo in un contenitore che ha lo stesso set di capacità o un sottoinsieme di quelle capacità.
Ciò significa che un contenitore sandboxed con AccessOutsideWrite non può semplicemente ri-genitorializzare uno script all'interno di sé per ottenere più capacità.