Player Management
Manage players and sessions in your Board game.
Overview
Board supports multiple players in a single session. Each player has a profile with a name, avatar, and unique identifier. The SDK tracks who is playing and associates save games with the right players.
Player Types
Board has three player types:
| Type | Description |
|---|---|
Profile |
A persistent identity stored on Board |
Guest |
A temporary player for the current session only |
AI |
A game-controlled player selected through the player selector |
Access the type via player.type:
using Board.Core;
using Board.Session;
foreach (var player in BoardSession.players)
{
if (player.type == BoardPlayerType.Profile)
{
// Persistent identity stored on Board
}
else if (player.type == BoardPlayerType.Guest)
{
// Temporary player for this session only
}
else if (player.type == BoardPlayerType.AI)
{
// Game-controlled AI player
}
}
Accessing Session Players
The current players are available through BoardSession.players:
using Board.Session;
// Get all players in the current session
BoardSessionPlayer[] players = BoardSession.players;
foreach (var player in players)
{
Debug.Log($"Player: {player.name}");
}
At launch, BoardSession.players contains the active profile. The session always requires at least one Profile player. This constraint is enforced by Board and cannot be bypassed.
Player Properties
Each BoardSessionPlayer provides:
| Property | Type | Description |
|---|---|---|
name |
string |
Display name (not guaranteed unique) |
playerId |
string |
App-specific persistent identifier |
sessionId |
int |
Unique identifier for this session |
avatarId |
string |
Avatar identifier |
avatar |
Texture2D |
Avatar texture (loads asynchronously) |
type |
BoardPlayerType |
Profile, Guest, or AI |
aiTypeIndex |
int |
Index into registered AI types (-1 if not an AI player) |
Player ID vs Session ID
playerId- Persistent across sessions for the same profile playing the same app. Use for tracking player-specific data like high scores or preferences. Guest players have randomly generatedplayerIdvalues that differ each session.sessionId- Unique only within the current session. Use for identifying players during gameplay.
// For persistent player data, use playerId
PlayerPrefs.SetInt($"highscore_{player.playerId}", score);
// For session-specific tracking, use sessionId
playerStates[player.sessionId] = new PlayerState();
Note: When loading a save game, if a profile associated with that save no longer exists, Board replaces it with a Guest player. The Guest inherits the original
sessionIdbut receives a newplayerId. This preserves in-game state keyed bysessionIdwhile breaking persistent data associations.
Responding to Player Changes
Subscribe to BoardSession.playersChanged to react when players join or leave:
void Start()
{
BoardSession.playersChanged += OnPlayersChanged;
}
void OnDestroy()
{
BoardSession.playersChanged -= OnPlayersChanged;
}
void OnPlayersChanged()
{
// Refresh player list UI
RefreshPlayerDisplay();
// Check if expected players are still present
ValidateGameState();
}
Active Profile
The system-wide active profile is available separately:
// Get the currently active Board profile
BoardPlayer activeProfile = BoardSession.activeProfile;
// React to profile changes
BoardSession.activeProfileChanged += OnActiveProfileChanged;
The active profile may or may not be in the current session’s players array.
Loading Avatars
Player avatars load asynchronously. Handle the avatarLoaded event:
void DisplayPlayer(BoardSessionPlayer player)
{
// Set placeholder or current avatar
playerImage.texture = player.avatar;
// Update when loaded
player.avatarLoaded += OnAvatarLoaded;
}
void OnAvatarLoaded(BoardPlayer player)
{
playerImage.texture = player.avatar;
}
For players not in the session (e.g., in save game UI), use the default avatar:
var defaultAvatar = await BoardPlayer.GetDefaultAvatar();
unknownPlayerImage.texture = defaultAvatar;
Adding Players
Present the player selector to add a player to the session:
public async void OnAddPlayerButtonPressed()
{
try
{
bool playerAdded = await BoardSession.PresentAddPlayerSelector();
if (playerAdded)
{
Debug.Log("New player added to session");
// playersChanged event will fire with updated list
}
else
{
Debug.Log("Player selector dismissed");
}
}
catch (InvalidOperationException e)
{
Debug.LogError($"Failed to present player selector: {e.Message}");
}
}
Note: Only one player selector can be open at a time. Attempting to open another throws an exception.
Replacing Players
Replace or remove an existing player:
public async void OnReplacePlayerPressed(BoardSessionPlayer player)
{
try
{
bool replaced = await BoardSession.PresentReplacePlayerSelector(player);
if (replaced)
{
Debug.Log("Player replaced or removed");
}
}
catch (InvalidOperationException e)
{
Debug.LogError($"Failed to replace player: {e.Message}");
}
}
Replace Selector Behavior
The selector options change based on how many Profile players are in the session:
When replacing the only Profile in the session:
- No “Remove player” button appears
- No Guest option is shown
- The player can only be replaced with another Profile
When there are multiple Profiles in the session:
- “Remove player” button appears in the top-right corner
- Guest option is available alongside other Profiles
- The player can be replaced, removed, or swapped with a Guest
This behavior ensures the session always has at least one Profile player. The native selector enforces this constraint automatically.
Note: Only one player selector can be open at a time. Attempting to open another throws an
InvalidOperationException.
AI Players
Board provides UI for users to add AI players to a session, but the game is responsible for all AI behavior. The SDK does not provide any AI logic. Instead, it gives your game a way to register the AI difficulty levels or play styles it supports, and Board surfaces those options in the player selector alongside profiles and guests.
Registering AI Types
Call BoardSession.SetAIPlayerTypes() at startup to register the AI options your game supports. Each BoardAIPlayerType has a display name and optional description that appear in the player selector:
using Board.Session;
void Start()
{
BoardSession.SetAIPlayerTypes(new BoardAIPlayerType[]
{
new BoardAIPlayerType { name = "Easy", description = "Plays conservatively" },
new BoardAIPlayerType { name = "Hard", description = "Aggressive strategy" },
new BoardAIPlayerType { name = "Master", description = "Expert-level play" },
});
}
A maximum of 8 AI types can be registered. If your game does not call SetAIPlayerTypes(), no AI option appears in the player selector.
How AI Players Behave
AI players are ephemeral, similar to guests. They do not have a persistent profile and do not carry over between sessions. When the user selects an AI type from the player selector, Board creates an AI player with a distinct avatar and adds it to the session like any other player.
The key difference is the aiTypeIndex property, which tells your game which AI type was selected. Use this to drive your game’s AI logic:
foreach (var player in BoardSession.players)
{
if (player.type == BoardPlayerType.AI)
{
int typeIndex = player.aiTypeIndex; // 0 = Easy, 1 = Hard, 2 = Master (from example above)
// Use typeIndex to select the appropriate AI behavior in your game
}
}
For non-AI players, aiTypeIndex returns -1.
Filtering AI Types in the Player Selector
You can control which AI types appear when opening the player selector. Both PresentAddPlayerSelector() and PresentReplacePlayerSelector() accept an optional aiTypeIndices parameter:
// Show only Easy and Hard options (indices 0 and 1)
await BoardSession.PresentAddPlayerSelector(new int[] { 0, 1 });
// Show all registered AI types (default)
await BoardSession.PresentAddPlayerSelector(null);
// No-parameter overload also shows all AI types
await BoardSession.PresentAddPlayerSelector();
This is useful if certain AI types should only be available in specific game modes.
AI Players in Save Games
AI players are stored in save game metadata just like other players. When loading a save, BoardSaveGamePlayer.aiTypeIndex preserves which AI type was active. Your game should use this to restore the correct AI behavior for that slot.
Resetting the Session
Reset players to the initial state (active profile only):
public void OnResetPlayersPressed()
{
bool success = BoardSession.ResetPlayers();
if (success)
{
Debug.Log("Players reset to initial state");
}
}
Best Practices
- Use
playerIdfor persistent data - Player IDs persist across sessions for the same profile. Use them for high scores, preferences, and unlocks. - Use
sessionIdfor in-game state - Session IDs are only unique within the current session. Use them for tracking player state during gameplay. - Subscribe to
playersChanged- React to players joining, leaving, or being replaced mid-session - Handle guest replacements - When loading a save, deleted profiles are replaced with guests. The guest keeps the original
sessionIdbut gets a newplayerId. - Register AI types early - Call
SetAIPlayerTypes()before presenting the player selector so AI options are available from the start.
See Also
- Profile Switcher - Show the profile switching UI
- Save Game System - Associate saves with players
- Pause Menu - System pause screen integration