> For the complete documentation index, see [llms.txt](https://docs.otherside.xyz/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://docs.otherside.xyz/odk-docs/odk-plugin/persistence.md).

# Persistence

The persistence system in the ODK can be used to store data remotely. Examples of it's use might be: storing player progression or storing high scores for a mini game. On the backend, the storage system is simply a map of keys and values as string. You could imagine that for the high scores example, you might want to store the data using "high\_scores" as a key and a json encoded object string for the data in this form.

```
"high_scores" : "{"simon": 10, "david": 3}"
```

### The Persistence Service

The main class to be concerned with is `BP_ODK_PersistenceWorldService`. This world service provides functions in the following flavours: ReadValue, RegisterInterest and Save. The full list is:\
\
\- ReadIntValue\
\- ReadJsonObjectValue\
\- ReadStringValue\
\- ReadMultipleStringValues\
\- RegisterIntValueInterest\
\- RegisterJsonValueInterest\
\- RegisterStringValueInterest\
\- SaveIntToPersistence\
\- SaveJsonValueToPersistence\
\- SaveStringToPersistence

When interfacing with these functions, you will need to pass in a string "Key" parameter and an enum "Scope" value. The scope parameter allow you to limit the access of this data. The enum has these values:\
\
\- World: Only players on this world have access to this key's persistence data\
\- Project: Players can access the persistence data on any world that share the same project.\
\- Organization: Players can access the persistence data on any world that share the same organization.

As a brief reminder your organization will contain all of your experiences. You may have multiple projects in your organization corresponding to different experiences. An example might be you have a concert experience and shooter game experience as part of your organization. In a given project, you may have multiple worlds. This might be a different world for a variety of maps in a shooter game.

The RegisterInterest and ReadValue functions have callback params to let you know when the data has been recieved. In the case of ReadValue callbacks, they contain a "Value" parameter and a "Success" parameter. The key may not exists in the database in which "Success" will be false. RegisterInterest will not immediately get the value for you. Instead it will listen for any future updates to the value and inform you when it changes by calling the callback you provided.

### Server and Client Stores

Different key value stores are used for different users. This means that you will only be able to access a player's data on the auth client. Similarly, the server has it's own store which can not be accessed by clients.

This allows for the same key to be used across multiple stores. That is to say that multiple users and the server can all use the same key if so wished.


---

# Agent Instructions
This documentation is published with GitBook. GitBook is the documentation platform designed so that both humans and AI agents can read, navigate, and reason over technical content effectively. Learn more at gitbook.com.

## Querying This Documentation
If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter:

```
GET https://docs.otherside.xyz/odk-docs/odk-plugin/persistence.md?ask=<question>
```

The question should be specific, self-contained, and written in natural language.
The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
