# Update session data

> Modify session data and properties to reflect changes in game state or session configuration.

The session host is the only player that can update the session’s data. Other players can read this data depending on the visibility option. Refer to [Session data](./session-data-and-player-data.md) for more information on the available types of data.

Session-level data can be used in various ways:

* Public indexed session properties can be used in query filters to find matching sessions.

  * For example, your game can use game mode as a custom public, indexed property, and players can search for `game mode = foo` in their queries to find matching sessions.

* Members-only session properties can be set by the host but are visible to all members.

  * This can be used to share data with just session members.

* Private lobby data is only visible and set by the host

  * This can be used to set data that might be used on reconnects or for the next host if there is a host migration.

### Update session data

The following code sample demostrates how to update session data:

```cs
using Unity.Services.Multiplayer;
using Unity.Services.Authentication;
using System.Collections.Generic;
using UnityEngine;

// ...

try
{
    // Obtain the host session interface (only the host can perform these operations).
    // Assume 'session' is an ISession instance from creating/joining.
    var hostSession = session.AsHost();

    // 1. Update basic session metadata
    // These properties map to Name, MaxPlayers, and IsPrivate in Lobby.
    hostSession.Name = "testLobbyName";
    hostSession.MaxPlayers = 4;
    hostSession.IsPrivate = false;

    // 2. Change the host if necessary
    // The host is set automatically on creation. 
    // To transfer hosting duties to another player, use ElectHostAsync:
    // await hostSession.ElectHostAsync("newPlayerId");

    // 3. Define custom session data (Lobby Data)
    // Visibility options include Public, Member, and Private.
    var properties = new Dictionary<string, SessionProperty>
    {
        {
            "ExamplePrivateData", new SessionProperty(
                value: "PrivateData", 
                visibility: VisibilityOptions.Private)
        },
        {
            "ExamplePublicData", new SessionProperty(
                value: "PublicData", 
                visibility: VisibilityOptions.Public)
        }
    };

    hostSession.SetProperties(properties);

    // 4. Save all changes to the backend in a single request
    await hostSession.SavePropertiesAsync();
    
    Debug.Log("Session updated successfully.");
}
catch (SessionException e)
{
    // The Multiplayer Services SDK uses SessionException for API errors.
    Debug.LogError($"Failed to update session: {e.Message}");
}
```

### Query sessions

The following code sample demonstrates how to fetch a list of available sessions and optionally poll for updates:

```cs
using Unity.Services.Multiplayer;
using System.Threading.Tasks;
using UnityEngine;

public class SessionQueryExample : MonoBehaviour
{
    // Store the results object if you intend to use its built-in polling
    private QuerySessionsResults _currentResults;

    public async Task QueryAvailableSessionsAsync()
    {
        try
        {
            // 1. Configure the query options
            var options = new QuerySessionsOptions
            {
                // You can configure pagination and filtering here
                // Skip = 0 // Use this alongside the ContinuationToken for pagination
            };

            // 2. Perform the query
            // (If using a specific injected SessionQuerier, this would be: await sessionQuerier.QueryAsync(options))
            _currentResults = await MultiplayerService.Instance.QuerySessionsAsync(options);

            Debug.Log($"Found {_currentResults.Sessions.Count} available sessions.");

            // 3. Read the basic session data
            // The query returns public metadata for sessions where IsPrivate is false
            foreach (var sessionInfo in _currentResults.Sessions)
            {
                Debug.Log($"Session ID: {sessionInfo.Id} | Name: {sessionInfo.Name} | Max Players: {sessionInfo.MaxPlayers}");
            }

            // 4. (Optional) Auto-Polling for Server Browsers
            // Unlike the Lobby SDK, the QuerySessionsResults object has built-in polling.
            // If you are displaying a live server browser UI, you can start polling to automatically refresh the list.
            // _currentResults.StartPolling();
        }
        catch (SessionException e)
        {
            // Multiplayer Services uses SessionException for API errors
            Debug.LogError($"Failed to query sessions: {e.Message}");
        }
    }

    private void OnDestroy()
    {
        // If you utilized StartPolling(), ensure you stop it when the user 
        // leaves the server browser UI or the object is destroyed.
        _currentResults?.StopPolling();
    }
}
```
