FileStorage API¶
Local persistent storage for Worlds. Used for save data, configuration, cached world state, and access to raw user-provided files placed in the LocalStorage directory.
Files are stored at: /AppData/Local/ChilloutVR/LocalStorage/[WorldId]/[fileName]
Info
Only Worlds may use FileStorage. Avatars and Props cannot access FileStorage.
Is this safe?¶
We understand that any API involving file access raises concerns. Here's the short version:
FileStorage is a save-data system. Think of it like a game's save folder. Each world gets its own folder, and that's the only place it can read or write. It cannot see, access, or interact with anything else on your computer. Not your browser, not your documents, not your registry, nothing. The world can't even use this folder until you say yes to a permission prompt, and you can take that permission back whenever you want.
If a world asks for "Read Raw Files", that just means it wants to read files you put in its folder yourself, like ROMs for an emulator or a custom config. It still can't look anywhere else.
The sections below go into the technical details if you want them.
Security Scope¶
- FileStorage is completely sandboxed. All reads and writes are confined to the world's own
LocalStoragefolder listed above. The API has no ability to access any other location on your computer. - Filenames are sanitized by stripping all characters that the OS considers invalid in a filename, including
/and\. Path traversal (e.g.../../) is not possible. - Filenames are limited to 100 characters. Worlds are limited to 1000 files and a user-configurable total size cap.
- A world cannot use FileStorage at all until the user explicitly grants permission. This permission can be revoked at any time.
- FileStorage cannot access your browser data, system files, or anything outside its sandbox.
Obfuscation¶
- Files written by this API are obfuscated on disk using a per-file XOR key stored in the file header and a randomized file name.
- This exists to prevent worlds from writing files that could be mistaken for or executed as something else (e.g.
.exe,.dll). It is not encryption and should not be treated as secure storage for sensitive data.
Raw User Files¶
- Users can manually place files into a world's
LocalStoragefolder for that world to read (e.g. custom textures, ROM files for an emulator, configuration files). - These files require a separate user permission ("Read Raw Files") that must also be explicitly granted.
- Raw files are read-only to the world. The world cannot modify or delete them.
- Raw files are not counted against the world's storage limit set by the user.
- This permission still only allows reading files inside the world's own
LocalStoragefolder. It does not grant access to any other directory.
FileStorage¶
WasmScripting.FileStorage
FileStorage provides static methods for reading and writing files to persistent local storage for the current world.
Static Methods¶
| Signature | Description |
|---|---|
| CVRFile ReadFile(string fileName) | Reads the entire file |
| CVRFile ReadFile(string fileName, int offset, int length) | Reads a segment of a file |
| void WriteFile(string fileName, Span<byte> bytes) | Writes all bytes (overwrite) |
| void WriteFile(string fileName, Span<byte> bytes, int offset) | Writes bytes at a specific offset |
| void DeleteFile(string fileName) | Deletes a file |
| void RenameFile(string oldFileName, string newFileName) | Renames a file |
| bool FileExists(string fileName) | Checks if a file exists |
| string[] GetFiles() | Returns all file names |
| int GetFileSize(string fileName) | Returns file size in bytes |
| long GetTotalSize() | Total size of all stored files |
| long GetTotalCapacity() | Maximum allowed storage size |
| bool CanUseFileStorage() | Whether the world can use FileStorage |
| void RequestUseFileStorage(Action<bool> onResult) | Prompts the user once for permission |
CVRFile¶
WasmScripting.CVRFile
CVRFile represents a file returned by FileStorage.ReadFile.
Instance Properties¶
| Member | Type | Description |
|---|---|---|
| Bytes | Span<byte> | The file's raw byte buffer |
| Length | int | Number of bytes returned |
Bytes is a live span referencing unmanaged memory.
Do not store it long-term; copy data if needed.