-
-
Notifications
You must be signed in to change notification settings - Fork 202
World Persistence (PWI)
This feature aims to give content creators the ability to store user-machine-specific string data in a local database, thereby facilitating a level of data persistence within VRChat worlds not easily possible otherwise.
To make use of this system as a user, follow these steps:
- Make sure you have "Allow Untrusted URLs" enabled in your "Comfort & Safety" VRChat Settings.
- If you have Logging disabled, you will need to re-enable it. If you don't know what this means, it probably doesn't apply.
- Make sure that VRCX is open when you join a world supporting PWI
- If you close/re-open VRCX while the world is using PWI, there's a good chance the world will break or not work as expected.
If you're using the standalone quest client, this feature won't work for you.
https://github.com/vrcx-team/VRCX/issues/567
Without an easy, reliable way for VRChat worlds to maintain persistent data or save states, it is yet another way creators are limited when it comes to creating content in VRC. PWI tries to bridge this gap by providing a system to store arbitrary string data on a local database for each user.
- Users must have VRCX installed and VRChat logging enabled(enabled by default) for the API to function.
- Users must enable "Allow Untrusted URLs" to facilitate world-VRCX communication, as loopback URLs like 127.0.0.1 aren't whitelisted.
- Due to reliance on log files for data retrieval from worlds, this system isn't available to quest users.
VRCX operates a local webserver listening on port 22500 on 127.0.0.1. This server is your interface for retrieving data from the local database using VRChat's String Loading. However, due to limitations like the 5 second-per-request limit on string loading and static URL requirements in Udon/UdonSharp, other functions aren't feasible.
The data is stored as key-value pairs in the database with each world having a unique 'pool' of these pairs accessible only to that world.
-
Initialize a valid connection to VRCX. You can do this by either explicity calling the
/vrcx/data/init
endpoint, or just using any of the data request endpoints like/vrcx/data/getall
and they will initialize the current world automatically. This will provide a connection key in the response, necessary for storing new data. You can make this and the following requests with Udon String Loading -
Retrieve data using the
/vrcx/data/getx
endpoints to request data from the database. You can define the URLs needed for the keys you want to retrieve at compile time and request them afterwards. You don't need a connection key for this.
Example request: http://127.0.0.1:22500/vrcx/data/get?key=test
- Store data in the local database by logging data to VRChat's log file, adhering to the requestType's format. Not following the format or not providing a valid connection key will result in the data not being stored. Test your requests! Use VRCJson for parsing and serializing JSON.
Example request: [VRCX-World] {"requestType": "store", "connectionKey": "test-connection-key", "key": "test", "value": "testvalue"}
If your request is invalid or otherwise malformed, the request will fail and your data will not be stored. If you suspect this is happening, you can look at the VRCX.log file or use the /vrcx/data/lasterror
endpoint to see the last store error, if any.
Each individual world has a total data cap of 10MB shared across all their data entries. If the world hits this cap, all subsequent storage requests will fail.
PWI Manager is a simple but fully-featured implementation of this API that can be dropped into a project and used as-is.
https://github.com/GroovyTeacup/PWIManager
A world running this prefab and its example script can be found here: https://vrchat.com/home/world/wrld_ddbdbb3a-082b-4b23-bf51-a9fd391bbc55
The following request types are various ways that worlds can log in order to perform certain operations.
The store
requestType stores a string in the world database under a given key
with a value
.
If value
is null or empty, your request will fail. Use the delete
requestType to delete data.
JSON Format
-
requestType
: (string) The type of request -
connectionKey
: (string) The connection key for the current world. -
key
: (string) The key to storevalue
under in the database. Max length 255 -
value
: (string) Arbitrary string data.
Example Log Line: [VRCX-World] {"requestType": "store", "connectionKey": "test-connection-key", "key": "test", "value": "testvalue"}
The delete
requestType deletes a given key in the world database.
JSON Format
-
requestType
: (string) The type of request -
connectionKey
: (string) The connection key for the current world -
key
: (string) The key to delete
Example Log Line: [VRCX-World] {"requestType": "delete", "connectionKey": "test-connection-key", "key": "test"}
The delete-all
requestType deletes all data in the database under the current world.
JSON Format
-
requestType
: (string) The type of request -
connectionKey
: (string) The connection key for the current world.
Example Log Line: [VRCX-World] {"requestType": "delete-all", "connectionKey": "test-connection-key"}
The set-setting
requestType sets a given setting key
on a world to value
. Currently only supports changing externalReads
JSON Format
-
requestType
: (string) The type of request -
connectionKey
: (string) The connection key for the current world. -
key
: (string) The key of the setting to set -
value
: (string) What to set the setting to. May be parsed differently depending on setting.
Example Log Line: [VRCX-World] {"requestType": "set-setting", "connectionKey": "test-connection-key", "key": "externalReads", "value": "true"
externalReads - Setting this to true will allow other worlds to read from your data pool, given that they provide your world's ID in a data request. If false, which it is by default, other worlds will not be able to access your world's data entries.
The following URLs are the various endpoints for worlds to communicate with VRCX through the String Loading methods.
Description: This endpoint just returns a blank '200 OK' response when called. You can use it to check if VRCX is running and initialized on the user's machine.
Usage: http://127.0.0.1:22500/vrcx/status
Description: Initializes a connection to PWI.
URL: /vrcx/data/init
Parameters:
-
debug
: (boolean) If true, the current world ID will be set towrld_12345
and the connection key will be set and returned as12345
. This is useful for testing your implementation/requests without having to be in a world. You can request this and the other endpoints from your browser.
Response: JSON object with the following properties:
-
ok
: (boolean) Indicates whether the request was successful. -
connectionKey
: (string) The connection key for the current world. Null if request failed. (Yes this is a duplicate) -
data
: (string) The connection key for the current world. Null if request failed. -
error
: (string) Contains an error message if the request was not successful. Null otherwise.
Status Codes:
-
200 OK
: The request was successful. -
500 Internal Server Error
: VRCX failed to get the current world id for some reason. -
503 Service Unavailable
: The VRCX world data service is not yet initialized or is currently loading.
Description: Retrieves a single value from the local database.
URL: /vrcx/data/get
Example Request: http://127.0.0.1:22500/vrcx/data/get?key=test
Parameters:
-
key
: (string) The key to retrieve the value of. -
world
: (string) (Optional) A world ID to retrieve the given key from. The world in question must allow external reads otherwise the request will return null. If the world in question doesn't exist in the user's DB, it will also return null.
Response: JSON object with the following properties:
-
ok
: (boolean) Indicates whether the request was successful. -
connectionKey
: (string) The connection key for the current world. -
data
: (string) The value of the key in the local database. Null if request failed. -
error
: (string) Contains an error message if the request was not successful. Null otherwise.
Status Codes:
-
200 OK
: The request was successful. -
400 Bad Request
: The request was missing thekey
parameter. -
404 Not Found
: The key was not found in the local database. -
503 Service Unavailable
: The VRCX world data service is not yet initialized or is currently loading.
Description: Retrieves multiple values from the local database.
URL: /vrcx/data/getbulk
Example Request: http://127.0.0.1:22500/vrcx/data/getbulk?keys=test,test2
Parameters:
-
keys
: (string) A comma-separated list of keys to retrieve the values of. -
world
: (string) (Optional) A world ID to retrieve the given key from. The world in question must allow external reads otherwise the request will return null. If the world in question doesn't exist in the user's DB, it will also return null.
Response: JSON object with the following properties:
-
ok
: (boolean) Indicates whether the request was successful. -
connectionKey
: (string) The connection key for the current world. -
data
: (object) An object containing the values of the keys in the local database in a key:value format. Null if request failed. -
error
: (string) Contains an error message if the request was not successful. Null otherwise.
Description: Retrieves all values from the local database for your world. (This is limited to getting, at most, 10000 keys)
URL: /vrcx/data/getall
Example Request: http://127.0.0.1:22500/vrcx/data/getall
Parameters:
-
world
: (string) (Optional) A world ID to retrieve the given key from. The world in question must allow external reads otherwise the request will return null. If the world in question doesn't exist in the user's DB, it will also return null.
Response: JSON object with the following properties:
-
ok
: (boolean) Indicates whether the request was successful. -
connectionKey
: (string) The connection key for the current world. -
data
: (object) An object containing the values of the keys in the local database in a key:value format. Null if request failed. -
error
: (string) Contains an error message if the request was not successful. Null otherwise.