Professional Documents
Culture Documents
PlayFab
What is PlayFab?
Game Manager
What is Game Manager?
Quickstart
Reference
Tutorials
Create a PlayFab Account
API Feature Settings in the PlayFab Game Manager
Audit Logs
Encrypted Logins
Player Encryption Services
PlayFab user roles
Secret Key Management
Two-Factor Authentication
Build
Authentication
PlayFab Authentication
What is Authentication
Player login
Overview
Login basics and Best Practices
Quickstart
Platform specific authentication
Overview
Tutorials
Running an HTTP server for testing
Setting up PlayFab authentication using Facebook and HTML5
Setting up PlayFab authentication using Facebook and Unity
Setting up PlayFab authentication using Google and HTML5
Setting up PlayFab authentication using Google Play Games Sign-In in Unity
Setting up PlayFab authentication using Kongregate and HTML5
Setting up PlayFab authentication using Kongregate and Unity
Setting up PlayFab authentication in Phaser.io
Setting up PlayFab authentication using Steam and Unity
Setting up PlayFab authentication using Twitch and HTML5
Setting up PlayFab authentication using Universal Windows Platform
Setup Sign In with Apple for PlayFab
Integrating the Universal Windows Platform with PlayFab
Azure Active Directory Authentication for Game Manager
Overview
Automation
PlayFab Automation
What is Automation
CloudScript (Legacy)
Overview
Quickstart
Tutorials
ES6 features in CloudScript (Legacy)
Handling errors in CloudScript (Legacy)
Making Webhook calls from CloudScript (Legacy)
SDK error handling best practices
Writing custom CloudScript (Legacy)
CloudScript using Azure Functions
Overview
Quickstart
Tutorials
Using CloudScript context models
Local Debugging for Cloudscript using Azure Functions
Debugging CloudScript using Azure Functions with Visual Studio Code
Debugging CloudScript using Azure Functions with Visual Studio
Debugging CloudScript using Azure Functions with the Azure Portal
Actions and rules
Overview
Quickstart
Tutorials
Bulk Actions for an entire player segment
Using CloudScript actions with PlayStream
Scheduled tasks
Overview
Quickstart
Playstream
Overview
Custom Tags
PlayStream with entity events
Rewarded Ads
Overview
Quickstart
Multiplayer
PlayFab Multiplayer
Introduction to Multiplayer
Servers
Overview
Host multiplayer games
Get started
Enable feature for game title
Create VMs
Create your first server
Build definition
Builds overview
Servers overview
Game server and container basics
Terminology
Author a game server
Author a game server build
Integrate game server build with GSDK
Determining required DLLs
Integrate Unity with GSDK
Manage VMs
Deploy builds using Game Manager
Deploy builds using PowerShell/API
Create Linux container images
Server build lifecycle
Build region lifecycle
Game server lifecycle
OS patch level updates for Windows
Use aliases to aggregate and manage multiple VM builds
Archive and retrieve server logs
VM performance metrics (preview)
Debugging game servers
LocalMultiplayerAgent
LocalMultiplayerAgent Overview
Debug Process-based game server
Debug Container-based game server
Connect directly to debug game servers
Locally debugging game servers and integration
Enabling automatic collection of crash dump
Attaching a profiler
Scaling game servers
Scaling Standby
Dynamic Standby
Scheduled Standby
Scaling Programmatically
Connecting clients and requesting servers
Use QoS beacons to measure player latency to Azure
Allocate game servers and connect VS debugging tools
Connecting clients to game servers
Limits and billing
Request and review quota changes
Get increased core limits and additional Azure regions
Enterprise Agreement (EA) billing
PlayFab services billing
Detailed price sheet
Incident response commitment
Monitor server capacity
Track server consumption
Samples and resources
Samples and resources
Wrapper
MpsAllocator
Windows Runner C#
Deploy Windows builds using Game Manager
Deploy Windows builds using PowerShell/API
SDKs
GSDKs
Unreal GSDK
Overview
Unreal Plugin GSDK
Matchmaking
Overview
Quickstart - Client SDK
Quickstart - REST API
Tutorials
Configuring matchmaking queues
Displaying queue statistics in your title
Handling common error cases
Integrating with PlayFab Multiplayer Servers
Matchmaking scenario and configuration examples
Specifying attributes with your tickets
Using server backfill tickets
Analyzing Your Matchmaking Queue Usage
Workaround for peer-to-peer connection
Lobby and Matchmaking real-time notifications
Lobby
Overview
Quickstart
Tutorials
Create a lobby
Invites
Join lobbies
Lobby properties
Create searchable lobbies
Find lobbies
Owner requirements and privileges
Lobby ownership changes
Use lobby and matchmaking together
Lobby and Matchmaking real-time notifications
Reference
Client SDK reference
Release notes
C++ SDK Release notes
Party
Overview
Features
Get started
Get started
Samples
Enable Party in Game Manager
Party SDK quickstart
Party objects and their relationships
Chat
Overview
Accessibility
Text-to-speech and text input UX guidelines
Speech-to-text and text display UX guidelines
Chat permissions and muting
Custom voice effects via real-time audio manipulation
Troubleshooting voice chat
Using text moderation
Networking and security
Invitations and the security model
Integrate discovery with Party
Transport options
Direct peer-to-peer connections
Port Usage and Firewall Requirements
Multiple network usage
Pricing
Regions and QoS
QoS
Supported Azure regions
Release notes
Insights
PlayFab Insights
Overview
Connectivity
Overview
Creating an Azure Application for Insights
Connecting Power BI to Insights
Connecting Kusto Explorer to Insights
Connecting Azure Data Explorer to Insights
Connecting Azure Data Factory to Insights
Connecting Grafana to Insights
Connecting Python to Insights
Connecting Kusto C# SDK to Insights
Data Explorer
Overview
Quickstart
Tutorials
Getting started with Data Explorer basic mode
Getting started with Data Explorer advanced mode
Schemas
Overview
Quickstart
Tutorials
About the events.all table
Performance Levels and Retention
Insights Scheduled Scaling
Exporting Data
Insights Management Commands
Pricing
Best Practices and FAQ
Social
PlayFab Social
What is Social
Friends
Overview
Quickstart
Tutorials
Friends Leaderboards
Groups, Guilds and Clans
Overview
Quickstart
Tutorials
Using Shared Group Data
Tournaments and Leaderboards
Overview
Quickstart
Tutorials
Accessing Archived Tournament Results
Using Prize Tables
Using resettable statistics and leaderboards
Using the Profile for Advanced Leaderboards
Friends Leaderboards
Trading
Overview
Quickstart
Leaderboards v2 [BETA]
Overview
Quickstart
Tutorials
Getting Started
Child Leaderboards
Engagement
Economy
PlayFab Economy
Economy
Overview
Quickstart
Tutorials
Coupons and Promotions
Currencies
Getting a Player's Value-to-Date (VTD)
Getting started with PlayFab, Unity IAP, and Android
Non-Receipt Payment Processing
Items
Overview
Quickstart
Tutorials
Catalogs
Drop Tables
Timed Consumables
Stores
Overview
Quickstart
Tutorials
Best Practices for Store segmentation
Custom Stores for Player Segments
Stores and Sales
User Generated Content
Overview
Quickstart
Search
Moderation
Ratings and Reviews
Settings
Item Visibility
ETags
Pricing
Limits
Tutorials
Publish UGC
Engagement (Player retention)
PlayFab Engagement
What is Engagement
Title News
Overview
Quickstart
Tutorials
Setting default languages
Push Notifications Templates
Overview
Quickstart
Tutorials
Getting Started with Android Push Notifications
Push notification templates
Push Notifications for Android
Push Notifications for iOS
Email Templates
Overview
Quickstart
Tutorials
Localized email templates
Setting up an SMTP server with add-ons
Using a rule to verify a contact e-mail address
Using e-mail templates
Analyze
Data
PlayFab Data
What is PlayFab Data
Player Data
Overview
Quickstart
How to set internal player data
How to get internal player data
How to set read-only player data
How to get read-only player data
How to modify read-only or internal player data from CloudScript
How to use player publisher data to grant a reward for playing multiple titles
Tutorials
Getting Player Profiles
Player Inventory
Using the Players page
Using Player details
Player Logins report
Player Ban System
Player Segments
Player Segment configuration
PlayFab GDPR
Using player statistics
Title Data
Overview
Quickstart
Tutorials
Using publisher data
Entities
Overview
Quickstart
Available built-in Entity types
Migration information
Entity files
Use entity objects to store player data
Tutorials
Entity Groups
Entity API Restructure Upgrade Tutorial
Data Connections
Overview
Quickstart
Manage Events with sampling
Overview
Quickstart
Content Delivery Network (Legacy)
Overview
Quickstart
Webhooks
Analytics
PlayFab Analytics
What is PlayFab Analytics
Experiments
Overview
Quickstart
Exclusion Groups
Recommendations
Key-terms
Billing for Experiments
Metrics
Overview
Metrics and terminology
Real-Time Analytics - Core Concepts
Quickstart
Tutorials
Generating PlayStream events
Set up an Amazon S3 bucket
Sessions
Reports
Overview
Quickstart
Tutorials
Daily A/B Test KPI Report
Daily Abuse Reports History Report
Daily and Monthly CDN Usage Report
Daily and Monthly Top Items Report
Daily and Monthly Top Spender Report
Daily and Monthly Top Details Report
Daily and Monthly Rolling 30-Day Overview and Totals Reports
Thirty-day New User Conversion Report
Thirty-day New User Retention Report
Thirty-day Retention Report
Segmentation
Overview
Quickstart
Tutorials
Segment Configuration
Export Players of a Segment
A/B testing
Overview
Quickstart
Tutorials
A/B testing with Stores and test buckets
A/B testing with Title data
Personas
Business Intelligence
Developer
Pricing
PlayFab Pricing
Billing Summary and Base Rates
Development Mode Titles
Pricing Meters
Meters Overview
Profile Reads
Profile Writes
Content & Configuration Reads
Content & Configuration Writes
Technical Support
Updating Account Pricing
Account Upgrades
Title Launches
Consumption Best Practices
Roadmap
Roadmap
Release notes
2022 SDK Release Notes
2021 SDK Release Notes
2020 SDK Release Notes
2019 SDK Release Notes
2018 SDK Release Notes
2017 SDK Release Notes
2016 SDK Release Notes
2015 SDK Release Notes
Reference
REST API
Overview
Reference
Real-time notifications for Lobby and Matchmaking
Overview
SignalR Hub
Subscribing To Resources
Client methods
ReceiveMessage
ReceiveSubscriptionChangeMessage
Server methods
AddEntityToSession
EndSession
RemoveEntityFromSession
StartOrRecoverSession
Type reference
EndSessionRequest
EndSessionResponse
Message
ResponseStatus
SharedSessionRequest
SharedSessionResponse
StartOrRecoverSessionRequest
StartOrRecoverSessionResponse
SubscriptionChangeMessage
Party C/C++ API
Overview
Classes
PartyAudioManipulationSinkStream
Methods
GetConfiguration
GetFormat
SubmitBuffer
GetCustomContext
SetCustomContext
PartyAudioManipulationSourceStream
Methods
GetConfiguration
GetFormat
GetAvailableBufferCount
GetNextBuffer
ReturnBuffer
GetCustomContext
SetCustomContext
PartyChatControl
Methods
GetLocal
GetDevice
GetEntityId
GetNetworks
GetCustomContext
SetCustomContext
ConfigureAudioManipulationVoiceStream
GetAudioManipulationVoiceStream
PartyDevice
Methods
GetLocal
GetChatControls
GetCustomContext
SetCustomContext
PartyEndpoint
Methods
GetLocal
GetEntityId
GetNetwork
GetDevice
GetUniqueIdentifier
GetCustomContext
SetCustomContext
PartyInvitation
Methods
GetCreatorEntityId
GetInvitationConfiguration
GetCustomContext
SetCustomContext
PartyLocalChatControl
Methods
GetLocalUser
SetPermissions
GetPermissions
SendText
SetAudioInput
GetAudioInput
SetAudioOutput
GetAudioOutput
PopulateAvailableTextToSpeechProfiles
GetAvailableTextToSpeechProfiles
SetTextToSpeechProfile
GetTextToSpeechProfile
SynthesizeTextToSpeech
GetLanguage
SetTranscriptionOptions
GetTranscriptionOptions
SetTextChatOptions
GetTextChatOptions
SetAudioRenderVolume
GetAudioRenderVolume
SetAudioInputMuted
GetAudioInputMuted
SetIncomingAudioMuted
GetIncomingAudioMuted
SetIncomingTextMuted
GetIncomingTextMuted
GetLocalChatIndicator
GetChatIndicator
ConfigureAudioManipulationCaptureStream
GetAudioManipulationCaptureStream
ConfigureAudioManipulationRenderStream
GetAudioManipulationRenderStream
PartyLocalDevice
Methods
CreateChatControl
DestroyChatControl
PartyLocalEndpoint
Methods
GetLocalUser
SendMessage
FlushMessages
GetEndpointStatistics
PartyLocalUser
Methods
GetEntityId
UpdateEntityToken
GetCustomContext
SetCustomContext
PartyManager
Methods
GetSingleton
SetOption
GetOption
GetErrorMessage
SerializeNetworkDescriptor
DeserializeNetworkDescriptor
SetMemoryCallbacks
GetMemoryCallbacks
SetProfilingCallbacksForMethodEntryExit
GetProfilingCallbacksForMethodEntryExit
SetThreadAffinityMask
GetThreadAffinityMask
SetWorkMode
GetWorkMode
Initialize
Cleanup
StartProcessingStateChanges
FinishProcessingStateChanges
DoWork
GetRegions
CreateNewNetwork
ConnectToNetwork
GetLocalDevice
CreateLocalUser
DestroyLocalUser
GetLocalUsers
GetNetworks
GetChatControls
PartyNetwork
Methods
AuthenticateLocalUser
RemoveLocalUser
CreateInvitation
RevokeInvitation
GetInvitations
CreateEndpoint
DestroyEndpoint
LeaveNetwork
GetEndpoints
FindEndpointByUniqueIdentifier
GetDevices
GetLocalUsers
GetNetworkDescriptor
GetNetworkConfiguration
ConnectChatControl
DisconnectChatControl
GetChatControls
GetNetworkStatistics
GetCustomContext
SetCustomContext
GetDeviceConnectionType
PartyTextToSpeechProfile
Methods
GetIdentifier
GetName
GetLanguageCode
GetGender
GetCustomContext
SetCustomContext
Callbacks
PartyAllocateMemoryCallback
PartyFreeMemoryCallback
PartyProfilingMethodEntranceCallback
PartyProfilingMethodExitCallback
Structures
PartyAudioFormat
PartyAudioManipulationSinkStreamConfiguration
PartyAudioManipulationSourceStreamConfiguration
PartyDataBuffer
PartyInvitationConfiguration
PartyLocalUdpSocketBindAddressConfiguration
PartyMutableDataBuffer
PartyNetworkConfiguration
PartyNetworkDescriptor
PartyProfilingMethodEntranceEventData
PartyProfilingMethodExitEventData
PartyRegion
PartySendMessageQueuingConfiguration
PartyTranslation
State changes
PartyAuthenticateLocalUserCompletedStateChange
PartyChatControlCreatedStateChange
PartyChatControlDestroyedStateChange
PartyChatControlJoinedNetworkStateChange
PartyChatControlLeftNetworkStateChange
PartyChatTextReceivedStateChange
PartyConfigureAudioManipulationCaptureStreamCompletedStateChange
PartyConfigureAudioManipulationRenderStreamCompletedStateChange
PartyConfigureAudioManipulationVoiceStreamCompletedStateChange
PartyConnectChatControlCompletedStateChange
PartyConnectToNetworkCompletedStateChange
PartyCreateChatControlCompletedStateChange
PartyCreateEndpointCompletedStateChange
PartyCreateInvitationCompletedStateChange
PartyCreateNewNetworkCompletedStateChange
PartyDataBuffersReturnedStateChange
PartyDestroyChatControlCompletedStateChange
PartyDestroyEndpointCompletedStateChange
PartyDestroyLocalUserCompletedStateChange
PartyDisconnectChatControlCompletedStateChange
PartyEndpointCreatedStateChange
PartyEndpointDestroyedStateChange
PartyEndpointMessageReceivedStateChange
PartyInvitationCreatedStateChange
PartyInvitationDestroyedStateChange
PartyLeaveNetworkCompletedStateChange
PartyLocalChatAudioInputChangedStateChange
PartyLocalChatAudioOutputChangedStateChange
PartyLocalUserRemovedStateChange
PartyNetworkConfigurationMadeAvailableStateChange
PartyNetworkDescriptorChangedStateChange
PartyNetworkDestroyedStateChange
PartyPopulateAvailableTextToSpeechProfilesCompletedStateChange
PartyRegionsChangedStateChange
PartyRemoteDeviceCreatedStateChange
PartyRemoteDeviceDestroyedStateChange
PartyRemoteDeviceJoinedNetworkStateChange
PartyRemoteDeviceLeftNetworkStateChange
PartyRemoveLocalUserCompletedStateChange
PartyRevokeInvitationCompletedStateChange
PartySetChatAudioInputCompletedStateChange
PartySetChatAudioOutputCompletedStateChange
PartySetTextChatOptionsCompletedStateChange
PartySetTextToSpeechProfileCompletedStateChange
PartySetTranscriptionOptionsCompletedStateChange
PartyStateChange
PartySynthesizeTextToSpeechCompletedStateChange
PartyVoiceChatTranscriptionReceivedStateChange
Enumerations
PartyAudioDeviceSelectionType
PartyAudioInputState
PartyAudioOutputState
PartyAudioSampleType
PartyAudioSourceType
PartyChatControlChatIndicator
PartyChatPermissionOptions
PartyChatTextReceivedOptions
PartyDestroyedReason
PartyDeviceConnectionType
PartyDirectPeerConnectivityOptions
PartyEndpointStatistic
PartyGender
PartyInvitationRevocability
PartyLocalChatControlChatIndicator
PartyLocalUdpSocketBindAddressOptions
PartyLocalUserRemovedReason
PartyMessageReceivedOptions
PartyNetworkStatistic
PartyOption
PartySendMessageOptions
PartyStateChangeResult
PartyStateChangeType
PartySynthesizeTextToSpeechType
PartyTextChatFilterLevel
PartyTextChatOptions
PartyThreadId
PartyTranslationReceivedOptions
PartyVoiceChatTranscriptionOptions
PartyVoiceChatTranscriptionPhraseType
PartyWorkMode
Typedefs
Party Unity API
Overview
Classes
PlayFabLocalPlayer
Properties
IsChatControlAvailable
LanguageCode
PlatformSpecificUserId
PlayFabPlayer
Properties
ChatState
EntityKey
IsLocal
IsMuted
VoiceLevel
PlayFabMultiplayerManager
Properties
LocalPlayer
LogLevel
NetworkId
RemotePlayers
SpeechToTextMode
State
TextToSpeechMode
TranslateChat
Methods
SendChatMessage
SendChatMessageToAllPlayers
CreateAndJoinNetwork
Get
LeaveNetwork
SendDataMessage
SendDataMessageToAllPlayers
UpdateEntityToken
Events
partyunityonchatmessagereceived
partyunityondatamessagereceived
partyunityondatamessagenocopyreceived
partyunityonerroreventhandler
partyunityonnetworkchanged
partyunityonnetworkjoined
partyunityonnetworkleft
partyunityonremoteplayerjoined
partyunityonremoteplayerleft
Enums
AccessibilityMode
ChatMessageType
ChatMessageState
DeliveryOption
DirectPeerConnectivityOptions
LogLevelType
PlayFabMultiplayerManagerErrorType
PlayFabMultiplayerManagerState
Party Xbox Live Helper
Overview
Classes
PartyXblChatUser
Methods
GetLocal
GetXboxUserId
GetCustomContext
SetCustomContext
PartyXblLocalChatUser
Methods
GetAccessibilitySettings
GetRequiredChatPermissionInfo
GetCrossNetworkCommunicationPrivacySetting
PartyXblManager
Methods
GetSingleton
GetErrorMessage
SetMemoryCallbacks
GetMemoryCallbacks
SetThreadAffinityMask
GetThreadAffinityMask
Initialize
Cleanup
StartProcessingStateChanges
FinishProcessingStateChanges
CompleteGetTokenAndSignatureRequest
CreateLocalChatUser
CreateRemoteChatUser
DestroyChatUser
GetChatUsers
LoginToPlayFab
GetEntityIdsFromXboxLiveUserIds
Structures
PartyXblAccessibilitySettings
PartyXblChatPermissionInfo
PartyXblHttpHeader
PartyXblXboxUserIdToPlayFabEntityIdMapping
State changes
PartyXblCreateLocalChatUserCompletedStateChange
PartyXblGetEntityIdsFromXboxLiveUserIdsCompletedStateChange
PartyXblLocalChatUserDestroyedStateChange
PartyXblLoginToPlayFabCompletedStateChange
PartyXblRequiredChatPermissionInfoChangedStateChange
PartyXblStateChange
PartyXblTokenAndSignatureRequestedStateChange
Enumerations
PartyXblChatPermissionMaskReason
PartyXblCrossNetworkCommunicationPrivacySetting
PartyXblLocalChatUserDestroyedReason
PartyXblStateChangeResult
PartyXblStateChangeType
PartyXblThreadId
Typedefs
Lobby and Matchmaking C/C++ API
Overview
PFMultiplayer overview
PFLobby overview
PFMatchmaking overview
Functions
PFMultiplayerGetErrorMessage
PFMultiplayerInitialize
PFMultiplayerSetEntityToken
PFMultiplayerSetMemoryCallbacks
PFMultiplayerSetThreadAffinityMask
PFMultiplayerUninitialize
PFLobbyAddMember
PFLobbyForceRemoveMember
PFLobbyGetAccessPolicy
PFLobbyGetConnectionString
PFLobbyGetCustomContext
PFLobbyGetLobbyId
PFLobbyGetLobbyProperty
PFLobbyGetLobbyPropertyKeys
PFLobbyGetMaxMemberCount
PFLobbyGetMemberProperty
PFLobbyGetMemberPropertyKeys
PFLobbyGetMembers
PFLobbyGetMembershipLock
PFLobbyGetOwner
PFLobbyGetOwnerMigrationPolicy
PFLobbyGetSearchProperty
PFLobbyGetSearchPropertyKeys
PFLobbyLeave
PFLobbyPostUpdate
PFLobbySendInvite
PFLobbySetCustomContext
PFMultiplayerCreateAndJoinLobby
PFMultiplayerFindLobbies
PFMultiplayerFinishProcessingLobbyStateChanges
PFMultiplayerGetLobbyInviteListenerStatus
PFMultiplayerJoinArrangedLobby
PFMultiplayerJoinLobby
PFMultiplayerStartListeningForLobbyInvites
PFMultiplayerStartProcessingLobbyStateChanges
PFMultiplayerStopListeningForLobbyInvites
PFMatchmakingTicketCancel
PFMatchmakingTicketGetMatch
PFMatchmakingTicketGetStatus
PFMatchmakingTicketGetTicketId
PFMultiplayerCreateMatchmakingTicket
PFMultiplayerDestroyMatchmakingTicket
PFMultiplayerFinishProcessingMatchmakingStateChanges
PFMultiplayerJoinMatchmakingTicketFromId
PFMultiplayerStartProcessingMatchmakingStateChanges
Enumerations
PFMultiplayerThreadId
PFLobbyAccessPolicy
PFLobbyDisconnectingReason
PFLobbyInviteListenerStatus
PFLobbyMemberRemovedReason
PFLobbyMembershipLock
PFLobbyOwnerMigrationPolicy
PFLobbyStateChangeType
PFMatchmakingStateChangeType
PFMatchmakingTicketStatus
Structures
PFLobbyArrangedJoinConfiguration
PFLobbyCreateConfiguration
PFLobbyDataUpdate
PFLobbyJoinConfiguration
PFLobbyMemberDataUpdate
PFLobbyMemberUpdateSummary
PFLobbySearchConfiguration
PFLobbySearchFriendsFilter
PFLobbySearchResult
PFMatchmakingMatchDetails
PFMatchmakingMatchMember
PFMatchmakingTicketConfiguration
State changes
PFLobbyAddMemberCompletedStateChange
PFLobbyCreateAndJoinLobbyCompletedStateChange
PFLobbyDisconnectedStateChange
PFLobbyDisconnectingStateChange
PFLobbyFindLobbiesCompletedStateChange
PFLobbyForceRemoveMemberCompletedStateChange
PFLobbyInviteListenerStatusChangedStateChange
PFLobbyInviteReceivedStateChange
PFLobbyJoinArrangedLobbyCompletedStateChange
PFLobbyJoinLobbyCompletedStateChange
PFLobbyLeaveLobbyCompletedStateChange
PFLobbyMemberAddedStateChange
PFLobbyMemberRemovedStateChange
PFLobbyPostUpdateCompletedStateChange
PFLobbySendInviteCompletedStateChange
PFLobbyStateChange
PFLobbyUpdatedStateChange
PFMatchmakingStateChange
PFMatchmakingTicketCompletedStateChange
PFMatchmakingTicketStatusChangedStateChange
Callbacks
PFMultiplayerAllocateMemoryCallback
PFMultiplayerFreeMemoryCallback
Typedef
PFEntityKey - Client SDK
Lobby and Matchmaking Unity API
Overview
Classes
Lobby
Properties
AccessPolicy
ConnectionString
Id
MaxMemberCount
MembershipLock
OwnerMigrationPolicy
Methods
AddMember
ForceRemoveMember
GetLobbyProperties
GetMemberProperties
GetMembers
GetSearchProperties
Leave
LeaveAllLocalUsers
PostUpdate
SendInvite
TryGetOwner
LobbyArrangedJoinConfiguration
Constructors
LobbyArrangedJoinConfiguration
Properties
AccessPolicy
MaxMemberCount
MemberProperties
OwnerMigrationPolicy
LobbyCreateConfiguration
Constructors
LobbyCreateConfiguration
Properties
AccessPolicy
LobbyProperties
MaxMemberCount
OwnerMigrationPolicy
SearchProperties
LobbyDataUpdate
Constructors
LobbyDataUpdate
Properties
AccessPolicy
LobbyProperties
MaxMemberCount
MembershipLock
NewOwner
SearchProperties
LobbyError
Constructors
LobbyError
Constants
InvalidArg
Success
Methods
FAILED
SUCCEEDED
LobbyJoinConfiguration
Constructors
LobbyJoinConfiguration
Properties
MemberProperties
LobbyMemberUpdateSummary
Properties
ConnectionStatusUpdated
Member
UpdatedMemberPropertyKeys
LobbySearchConfiguration
Constructors
LobbySearchConfiguration
Properties
ClientSearchResultCount
FilterString
FriendsFilter
SortString
LobbySearchFriendsFilter
Properties
IncludeFacebookFriends
IncludeSteamFriends
IncludeXboxFriendsToken
LobbySearchResult
Properties
ConnectionString
CurrentMemberCount
Friends
LobbyId
MaxMemberCount
OwnerEntity
SearchProperties
MatchmakingMatchDetails
Properties
LobbyArrangementString
MatchId
Members
RegionPreferences
MatchmakingTicket
Properties
Status
TicketId
Methods
Cancel
GetMatchDetails
MatchmakingTicketMatchMember
Properties
AttributesJSON
EntityKey
TeamId
PFEntityKey
Constructors
PFEntityKey
Properties
Id
Type
PlayFabMultiplayer
Constructors
PlayFabMultiplayer
Properties
IsInitialized
LogLevel
Constants
LobbyClientRequestedSearchResultCountUpperLimit
LobbyMaxLobbyPropertyCount
LobbyMaxMemberCountLowerLimit
LobbyMaxMemberCountUpperLimit
LobbyMaxMemberPropertyCount
LobbyMaxSearchPropertyCount
Events
OnAddMemberCompleted
OnError
OnForceRemoveMemberCompleted
OnLobbyCreateAndJoinCompleted
OnLobbyDisconnected
OnLobbyFindLobbiesCompleted
OnLobbyInviteListenerStatusChanged
OnLobbyInviteReceived
OnLobbyJoinArrangedLobbyCompleted
OnLobbyJoinCompleted
OnLobbyLeaveCompleted
OnLobbyMemberAdded
OnLobbyMemberRemoved
OnLobbyPostUpdateCompleted
OnLobbySendInviteCompleted
OnLobbyUpdated
OnMatchmakingTicketCompleted
OnMatchmakingTicketStatusChanged
Delegates
OnAddMemberCompletedHandler
OnErrorEventHandler
OnForceRemoveMemberCompletedHandler
OnLobbyCreateAndJoinCompletedHandler
OnLobbyDisconnectedHandler
OnLobbyFindLobbiesCompletedHandler
OnLobbyInviteListenerStatusChangedHandler
OnLobbyInviteReceivedHandler
OnLobbyJoinArrangedLobbyCompletedHandler
OnLobbyJoinCompletedHandler
OnLobbyLeaveCompletedHandler
OnLobbyMemberAddedHandler
OnLobbyMemberRemovedHandler
OnLobbyPostUpdateCompletedHandler
OnLobbySendInviteCompletedHandler
OnLobbyUpdatedHandler
OnMatchmakingTicketCompletedHandler
OnMatchmakingTicketStatusChangedHandler
Methods
CreateAndJoinLobby
CreateMatchmakingTicket
FindLobbies
GetLobbyInviteListenerStatus
Initialize
JoinArrangedLobby
JoinLobby
JoinMatchmakingTicketFromId
ProcessLobbyStateChanges
ProcessMatchmakingStateChanges
SetEntityToken
StartListeningForLobbyInvites
StopListeningForLobbyInvites
Uninitialize
PlayFabMultiplayerErrorArgs
Properties
Code
Message
PlayfabMultiplayerEventProcessor
Constructors
PlayfabMultiplayerEventProcessor
Structs
MatchUser
Constructors
MatchUser
Properties
LocalUser
LocalUserJsonAttributesJSON
Enums
LobbyAccessPolicy
LobbyDisconnectingReason
LobbyInviteListenerStatus
LobbyMemberRemovedReason
LobbyMembershipLock
LobbyOwnerMigrationPolicy
LogLevelType
MatchmakingTicketStatus
PlayStream Events
Model reference
auth_token_validated
character_consumed_item
character_created
character_inventory_item_added
character_statistic_changed
character_statistic_deleted
character_vc_item_purchased
character_virtual_currency_balance_changed
client_focus_change
client_session_start
entity_created
entity_executed_cloud_script
entity_files_set
entity_language_updated
entity_logged_in
entity_objects_set
entity_virtual_currency_balances_changed
gamelobby_ended
gamelobby_started
gameserverhost_started
gameserverhost_stopped
group_created
group_deleted
group_members_added
group_members_removed
group_role_created
group_role_deleted
group_role_members_added
group_role_members_removed
group_role_updated
group_updated
matchmaking_match_found
matchmaking_ticket_completed
matchmaking_user_ticket_completed
matchmaking_user_ticket_invite
multiplayer_server_build_deleted
multiplayer_server_build_region_status_changed
multiplayer_server_build_region_updated
multiplayer_server_certificate_deleted
multiplayer_server_certificate_uploaded
multiplayer_server_create_build_initiated
multiplayer_server_game_asset_deleted
multiplayer_server_requested
multiplayer_server_state_changed
multiplayer_server_vm_assigned
multiplayer_server_vm_remote_user_created
multiplayer_server_vm_remote_user_deleted
multiplayer_server_vm_unassignment_started
player_action_executed
player_ad_activity_valued
player_ad_campaign_attribution
player_ad_closed
player_ad_ended
player_ad_opened
display_name_filtered
player_ad_rewarded
player_ad_started
player_added_title
player_banned
player_changed_avatar
player_completed_password_reset
player_consumed_item
player_created
player_data_exported
player_device_info
player_display_name_filtered
player_displayname_changed
player_executed_cloudscript
player_inventory_item_added
player_joined_lobby
player_left_lobby
player_linked_account
player_logged_in
player_matched_with_lobby
player_profile_memberships
player_profile_subscriptions
player_paid_for_purchase
player_password_reset_link_sent
player_photon_session_authenticated
player_ranked_on_leaderboard_version
player_realmoney_purchase
player_receipt_validation
player_redeemed_coupon
player_registered_push_notifications
player_removed_title
player_reported_as_abusive
player_set_profile_property
player_started_purchase
player_statistic_changed
player_statistic_deleted
player_tag_added
player_tag_removed
player_triggered_action_executed_cloudscript
player_unlinked_account
player_updated_contact_email
player_vc_item_purchased
player_verified_contact_email
player_virtual_currency_balance_changed
sent_email
sent_push_notification
session_ended
session_started
studio_created
studio_tier_updated
studio_user_added
studio_user_invited
studio_user_removed
tenancy_connector_onboard
title_aborted_task
title_added_cloudscript
title_api_settings_changed
title_catalog_updated
title_client_rate_limited_alert
title_completed_task
title_created_task
title_deleted
title_deleted_master_player
title_deleted_task
title_exceeded_limit
title_game_build_added
title_game_build_modified
title_high_error_rate_alert
title_initiated_player_password_reset
title_limit_changed
title_news_updated
title_permission_policy_changed
title_profile_view_constraints_changed
title_published_cloudscript
title_queue_config_updated
title_requested_limit_change
title_saved_survey
title_scheduled_cloudscript_executed
title_secret_key_changed
title_started_task
title_statistic_version_changed
title_store_updated
title_updated_task
API access policy
Global API method error codes
HTTP response status codes
SDKs
Overview
Request access
Lobby and Matchmaking SDKs
Overview
C++ SDK Release notes
Unreal Engine 4
Multiplayer Unreal Online Subsystem (OSS)
OSS quickstart
Get Party libraries
Cognitive Services interface
Using older versions of Unreal Engine 4
Unreal Engine 4 Release notes
Unity
Multiplayer Unity getting started
Multiplayer Unity plugin overview
Multiplayer Unity plugin quickstart
Multiplayer Server SDKs
Party SDKs
Overview
Android getting started
iOS getting started
Unity
Party Unity plugin overview
Party Unity plugin quickstart
Party Unity plugin API reference
Party Unity plugin release notes
Unreal Engine 4
Multiplayer Unreal Online Subsystem (OSS)
OSS quickstart
Get Party libraries
Cognitive Services interface
Using older versions of Unreal Engine 4
Unreal Engine 4 Release notes
Xbox and Xbox Live
Xbox XDK prerequisites
Xbox Requirements
Use Party with MPSD
Xbox Live free program FAQ
Xbox Live Helper Library
Overview
Release notes
API reference
PlayFab SDKs
Overview
Languages
Android Studio Project (Java)
C#
Quickstart
Java
Quickstart
Objective-C
Quickstart
C++
Quickstart - Linux
Quickstart - Windows
Quickstart - Xbox One
Frameworks
Cocos2d-x
Quickstart
Phaser.io
Photon
Quickstart
Game engines
Unity3D
Quickstart
Installing the PlayFab SDK for Unity
Unreal Engine
Quickstart
scripting
ActionScript
Quickstart
Javascript
Quickstart
Lua
Quickstart - Corona
Quickstart - Defold
NodeJS
Quickstart
Python
Quickstart
Recipes and samples
General PlayFab samples
Multiplayer Servers samples
Party samples
Recipes
Tools and utilities
SDK Generator
Quickstart
Postman
Quickstart
What is PlayFab?
5/24/2022 • 5 minutes to read • Edit Online
PlayFab is a complete backend platform for live games with managed game services, real-time analytics, and
LiveOps. Boost your revenue and increase player engagement while cutting costs. This topic provides a high-
level overview of the PlayFab features.
PlayFab's backend services reduce the barriers to launch for game developers, offering both large and small
studios cost-effective development solutions that scale with their games and help them engage, retain and
monetize players. PlayFab enables developers to use the intelligent cloud to build and operate games, analyze
gaming data and improve overall gaming experiences. The PlayFab platform is a natural complement to Azure
for gaming (Visit azure.com/gaming for more info). Azure, with locations in 42 regions worldwide, provides
world-class server infrastructure, allowing creators to focus on building great games with best-available global
reach. For gamers, this leads to a higher, faster degree of innovation and better experiences.
Using PlayFab you can:
Remove the challenges of building, managing, and running servers at scale with a complete back-end
solution.
Instantly scale dedicated multiplayer servers that deliver low latency and high reliability for real-time
gameplay.
Use multiple forms of built-in authentication to track players across devices.
Quickly create leaderboards to more deeply engage players.
Accelerate growth with economy services that let you create and track virtual currencies, manage stores of
items, and process payments.
To use PlayFab features, you must sign up for a PlayFab account.
PlayFab provides the following services:
Multiplayer Services
Cross-Network Identity and Data
Player Authentication : Start with frictionless authentication and let players link accounts to roam across
Windows, Xbox, Steam, PSN, Nintendo, Facebook, iOS, Android and more.
Player Data Management : Share player information and game state across devices.
Matchmaking - Use the proven capabilities of Xbox Live's SmartMatch on any platform to help players find
opponents.
Multiplayer Servers
Dedicated Ser vers : Deliver low-latency real-time gameplay for any platform.
24/7 Monitoring and DDoS Protection - Protect against DDoS attacks and other incidents.
Global Reach with Microsoft Azure : Get closer to players on a cloud with more global regions than any
other provider.
Control Costs : Dynamically scale server cores in response to demand.
Chat
Par ty : Connect players with low-latency peer-to-peer communication.
Text and Voice Chat : Facilitate accessible voice chat, transcription and translation.
Accessibility : Use automated speech-to-text transcription and voice synthesis to make communication simple
for everyone.
Real-Time Translation : Break down global barriers and grow player concurrency by translating voice and text
chat between more than 30 different languages.
Encr yption : Ensure secure player communications.
Leaderboards and Statistics
Tournaments and Leaderboards : Facilitate permanent or time-limited competitions amongst friends or
strangers.
Scheduling : Reset leaderboards on a schedule and archive standings so players can view past results.
Prizes : Reward players based on their actions and leaderboard ranks.
Cheat Prevention : Defend against unwanted behavior and remove fraudulent players and accounts.
LiveOps
Engagement and Retention
Game Manager Web Por tal : A shared space (with roles and access permissions) where studio members can
build, configure and operate your game.
Daily Repor ts : Evaluate your game's performance through the lens of the top metrics used across the industry,
pre-calculated for you daily.
Player Profiles : Track players across authentication services and platforms.
Customization : Use server-hosted player data and logic to build custom game mechanics.
Achievement Systems : Use the rule engine and custom player events to build a powerful achievements
system.
Real-Time Segmentation : Act immediately on targeted groups of players.
Player Communication : Talk to your community with push notifications, emails, and message-of-the-day pop-
ups.
Content Management
Title Data : - Manage your game configuration remotely.
Item Catalog : Configure your catalog of items available for in-app granting or purchase, and update at any
time.
Content Deliver y Network : Upload, host and deliver game assets via Game Manager.
A/B Testing
Player Buckets : Run experiments with randomly assigned groups of players.
Monetization
Stores and Sales : Target player segments with personalized store offers and support payments with Xbox,
Steam, Google, PayPal and more.
Vir tual Economy : Mint promotional coupons and virtual currencies with support for setting initial balances
and optional auto-recharge.
User Generated Content : Empower players to create, upload and search for moderated content.
Drop Tables : Craft attractive bundles for first-time or regular users and stimulate demand with item scarcity.
Fraud Prevention : Use server-side receipt validation to make sure purchases are genuine before completion.
Automation
CloudScript : Build lightweight logic processing when you want server authority without a dedicated server.
Task Scheduling : Set up pre-defined actions to manage anything from prices and events to messaging lapsed
players.
SDKs
SDKs are available for most popular engines and platforms.
Supported Languages
Android Studio (Java)
C#
Java
Objective-C (iOS)
PlayFab CPP (C++)
Frameworks
Cocos2D
Phaser.io (JavaScript)
Game Engines
Lua
Unity3D
Unreal Engine (Blueprints & C++)
Scripting
ActionScript
JavaScript
NodeJS
PHP
Python
Support
Documentation : Get started quickly with tutorials, samples, and comprehensive reference documentation.
Forums : Learn from experts and share your knowledge in the community forums.
Slack : Join channels for ongoing conversations with other developers and direct communication with PlayFab
Developer Success.
Real-Time Ser vice Health : Visit status.playfab.com for current and historical service health information.
Tickets : Get enterprise-level ticketed support.
24/7 Emergency Escalations : Get around-the-clock assistance on immediate-priority issues.
Game Manager overview
5/24/2022 • 2 minutes to read • Edit Online
This article introduces Game Manager, the PlayFab developer portal, identifies portal page elements, and helps
you get familiar with the portal experience.
Next steps
Game Manager quickstart - Sign up for a PlayFab account, create your studio, and your first game.
Game Manager reference - Learn about the functionality available Game Manager.
Quickstart: Game Manager
5/24/2022 • 2 minutes to read • Edit Online
Get started with PlayFab by using Game Manager to create your PlayFab account, create your Studio, and create
your first Title.
This reference familiarizes you with the high-level aspects of the Game Manager. For more detailed information,
you may select your specific topic of interest in the PlayFab documentation that follows.
To get the most value from this topic, you should have created your PlayFab account, logged in, and viewed the
Game Manager for your title, even if it's an empty title for now.
The sections provided below offer greater insight on each Game Manager area. Each time you perform an API
call or task, view the results in the Game Manager in the appropriate area for that task.
Title Overview
An overview of the recent and less-recent performance of your title.
Over view - shows your game's basic statistics and what you may have assigned as Key Performance Indicators
(KPIs). In the upper-right, you will find time period toggle buttons, and there are also filters for the tables.
4h : This will load data generated within the last 4 hours.
24h : This will load data generated within the last 24 hours.
3d : This will load data generated within the last 3 days.
7d : This will load data generated within the last 7 days.
mtd : This will load data generated within the current month.
NOTE
In Game Manager, all times are displayed in local time.
The tables in the Overview tab allow you to monitor PlayStream events in real time. They include the following:
Unique Users : The average number of unique players logging in per day.
API Calls : Indicates how many API calls were executed within the given time period.
CloudScript Processing Times : Provides the average processing time for your CloudScript functions to
execute.
LOGINS : The number of logins recorded for the selected time span.
NEW USERS : New users added in the time period.
PURCHASES : The USD value of real money transactions processed for the selected time span.
REPORTS : The Reports table consolidates several critical categories into a useful format. Specific reports are
also available under the Repor ts tab in Analytics.
Back to About the Game Manager
PlayStream Monitor - PlayStream is our latest and greatest addition to the PlayFab platform. It displays title
events as they are generated in real time, and you can visualize them at whatever granularity you prefer on the
world map. Use the sampling controls to gather more or less events per second.
Build
Provides the foundational elements and tools to configure your game.
Players
Players contains settings and data pertaining to your individual players, including player segmentation.
In this section of the Game Manager, a sorted list is presented, and organized by most recent login. Select any of
the records to display the Player's Overview. Use the Search box to search for players by ID , Username ,
Display Name , or Email .
Over view - this detailed screen provides a wealth of insight into the players' activities. The sub-menu contains
many links to other player-centric information, as shown below.
Some specific tools your team can use to remedy defrauded players and identify potential abusers are included
below.
Over view - View basic details and linked account status.
CloudScript - View and run CloudScript functions.
Multiplayer - View player match history from multiplayer sessions.
PlayStream - View player generated events.
Purchases - View a player's real money purchase history.
Statistics - View and edit player statistics.
Logins - View player login history.
Bans - View player ban history.
Characters - View player-owned characters and edit basic details.
Player Data - View and edit player data records.
Segments - View which segments a player has entered.
Multiplayer
Multiplayer allows you to configure server hosting and matchmaking.
Ser vers - Whether you are looking to hosting multi-player matches or just need a secure environment that can
reduce many common forms of hacking and abuse, the PlayFab Thunderhead servers work with many
architectures and game types. These servers provide an excellent alternative when compared with the overhead
of dedicated game servers.
Matchmaking - Set up your matchmaking queues by configuring match sizes, servers and statistics.
NOTE
You must be an Indie, Pro, or Enterprise subscriber in order to enable Parties.
Legacy Multiplayer - Here you can see your active and archived games, as well as server activity, game builds,
and game modes.
Additional information:
CloudScript Quickstart
Back to About the Game Manager
Groups
The Groups section allows you to create and manage groups of players designated by entity type and ID.
Automation
In the Automation area, you can run CloudScript, run A/B tests, assign Rules, and schedule tasks for your game
title using server-side logic for your game, including scripting, rules, and tasks. Configure and trigger actions
based on events generated by your title.
Add-ons
The control center for managing partner integrations.
To configure marketplace integrations for your title: Explore the Add-ons section of the Game Manager for
details on the various add-ons.
Setup instructions for each add-on may vary. Additional billing information may also be required.
Back to About the Game Manager
Engage
Engage allows you to facilitate connections with players.
Economy
This section provides all the tools needed to manage the virtual economy of your game.
Catalogs - At the center of PlayFab economies is the concept of catalogs. Catalogs are a collection of items,
stores, and drop tables.
As an example, the following image shows the primary catalogs for Unicorn Battle .
Items - An item within the catalog. Items can be of several different types.
Drop Tables - Control the item distribution when players open containers and bundles.
Stores - A subset of catalog items that can be set to prices that are different than those specified by the catalog.
NOTE
Select any catalog item to open a detailed editor for the properties of the item.
Currency - Trackers for each currency that can be exchanged for catalog items.
The following example shows the Edit Currency page for Great Game .
Additional Information:
Catalogs Tutorial
Currencies Tutorial
Back to About the Game Manager
User Generated Content
The User Generated Content tab displays all published content for your title. When enabled, all users can create,
discover, and consume content.
UGC Items - An item within the public catalog. UGC Items can be created by a player, by a title, or on behalf of a
player (by a title). UGC Items can contain Files and Images that can be downloaded by another player.
Settings - You can configure supported metadata values here (like Content Types and Tags), and specify specific
player IDs to receive elevated permissions (to assist with moderation scenarios).
Policies - Policies allow you to control the client access to the Economy APIs.
Additional Information:
UGC Overview
UGC Quickstart
Back to About the Game Manager
Leaderboards
The Leaderboards tab displays all the active leaderboards for your title. PlayFab leaderboards are driven by the
statistics you choose to use for your players. You can also configure the reset frequency and aggregation
method.
NOTE
There are varying time delays, depending on the type of file handling that is required. For detailed information, view the
online Help for the File Management tab.
Email Templates - Create, configure and manage email templates for game clients.
The following example shows the Email Templates tab for Great Game.
Back to About the Game Manager
Push Notifications Templates - create and manage new Push Notification templates.
Analyze
Analyze allows you to monitor and act on player behaviors.
Dashboards
Dashboards allow you to see Trends, run Reports and perform Diagnostics.
Data
In the Data area you can do a number of things to track and analyze data from your players' activities. There are
a number of graphing and reports capabilities that provide the ability to consolidate and visualize the data.
Trends - Configure and view trends for a number of statistics for time periods ranging from 7 days to 26
months. The Trends graph shows classic retention - only new players that have returned - for the chosen time
period. The 30-day retention report includes both new and returning players. Event Histor y - Search and
display a number of different Event History types, depending on the query you create. Use event name, date
range, or event values. Repor ts - Use Reports to view and download a number of different types of reports
based on player data and statistical values.
For additional or custom reports, please open a feature request in our community forums.
Webhooks - Webhooks allow you to have some or all of your PlayStream events forwarded to any web URL
you want. The event data is sent via POST in the request body as JSON.
Back to About the Game Manager
On the Audit History page, select any entry in the log to view the complete details. You can also navigate
through the Logs using the SEARCH button.
The Event time column exposes information about the time and the author of the change.
The Log type column gives you a clue about the kind of change that was made.
The String change and Value columns represent short details of the change.
The View column allows you to access a full JSON description of the change.
Billing - On the Billing page you can view your Contact Information and Credit Card information which PlayFab
invoicing references for payment.
IMPORTANT
This key should only be shared with trusted members of your development team, since it enables API calls that can affect
game data and player accounts. Never share your PlayFab API secret key with anyone; doing so may jeopardize your title's
security.
Email Preferences - Allows you to configure e-mail settings such as Subscription and Reply-To addresses.
Push Notifications - Configure notifications to be sent to android or iOS devices. Limits - Set limits on certain
PlayFab features, economic or otherwise in your game. Client Profile Options - Allows you to configure what
a Client can or cannot access and configure on their own for the title.
NOTE
Two-factor authentication improves the security of your developer accounts by requiring a code to be supplied when
logging in.
3. Save your changes and return to the My Studios and Titles page.
To edit an existing title
1. Select the gear icon on the title name you wish to edit and select Edit title info .
Before you can call any PlayFab API, you must have a PlayFab developer account. If you already have a PlayFab
account, you can skip this step.
Once you have a PlayFab account, navigate to the PlayFab home page, https://playfab.com, and log in.
Since PlayFab does not know the name of your game studio or the title of your game, when you create a studio,
a placeholder title called My Game is created for you. You can edit your title's information in the Create Title
screen at any time.
NOTE
The Title ID is unique to your game, which we refer to as a title. You will use this value when you make PlayFab API calls
(your Title ID will not be BCFE ).
Your first title is automatically generated by us. To create a new title, select New title from the Elipsis menu.
The API features in the PlayFab Game Manager are a handful of options for managing the behavior of PlayFab
APIs for your title. These options give you the tools for managing access, privacy, and other features.
To find the screen for configuring these options:
Go to the Game Manager .
Select Settings from the menu to your left.
Select the API Features tab.
Some of these check boxes are obvious, while some are not. In this tutorial, we will go into detail about several
of them.
NOTE
Several screenshots and demonstrations in this tutorial utilize Postman.
NOTE
This flag can be toggled on or off at any time. But, it's not retroactive. So existing values will not be affected. Only newly
written values will be validated.
If you attempt to pass invalid JSON as a value, it will reject the request with an
HTTP Status Code 400 "Bad Request" .
Disabling all API request access
Surprisingly, it can be useful to disable all API access to your titles.
If, for example, you are performing a sensitive migration with downtime, stray API requests could cause serious
interruptions. If you are retiring your game, this will guarantee your game really is off.
WARNING
Keep in mind, that marking this checkbox will literally break your game , so use it with caution!
Once you have decided you need to turn API access off, and you check the box, all API requests will begin to fail
within a few minutes.
PlayFab will return an HTTP Status Code 400 "Bad Request" , indicating that the title has disabled such usage.
These HTTP Status Code 400 responses will persist until you un-check the box. Again, un-checking may take a
few minutes to have effect.
NOTE
Enabling obfuscation will impact other features that use the IP address. In particular, IP-based geo-location and player
bans by IP are the two most directly impacted.
PlayFab automatically performs IP-based geo-location on logins. This helps you automatically determine where
on earth your players come from.
However, you may experience reduced accuracy, particularly at the city level, when using obfuscated IPs. This is
intentional, as the goal of obfuscating IPs is to avoid recording PII, including exact locations.
Additionally, obfuscating IPs can affect bans. When adding a ban, you can optionally ban an IP as well. Often
banning by IP is more practical than banning one account at a time, because the bad actor can just make new
accounts.
Banning an IP prevents the bad actor from making new accounts from the same internet connection. In many
cases, this is an effective tool.
However, with obfuscated IPs, banning an exact IP cannot work. Instead, you must use a ban on an IP with .0 as
the final octet.
Audit logs allow you to observe and analyze the history of important changes made to your title by you or other
developers. You are able to detect both important changes and destructive actions, and react accordingly.
The View column displays a button to access the JSON body of the change. JSON is displayed in a modal
window.
It contains:
1. The same data as the table.
2. Plus a raw JSON body specific for each change type.
Encrypted logins
5/24/2022 • 4 minutes to read • Edit Online
PlayFab allows you to reinforce application security by protecting certain client API calls with custom encryption.
This tutorial shows you how to enable encryption for your client.
The method we will be using allows you to protect any login API call. Since the process is always similar, we only
show how to protect one particular method, LoginWithCustomID .
IMPORTANT
Login encryption is meant to be used for all players after title creation, or not at all. This is not a feature that can be
enabled at a later date. You must use it from the very beginning or not at all. In particular, encrypted players will never be
able to log in un-encrypted, and non-encrypted players will never be able to become encrypted players.
NOTE
PlayFab makes the following disclaimer: "All of our API calls are already safely encrypted to modern standards, and the
standard API call encryption is everything most customers will need. This feature represents an additional layer of security
built around making it harder for players to use an unauthorized client. It is not foolproof - it merely increases the
difficulty bar for hackers. For most developers, the mild security increase will not be worth the extra effort required."
NOTE
Creating a new shared secret by a certain name will override the existing key with the same name, if any. In addition, you
may have several shared secrets registered under different names.
if (response.Error != null)
{
Console.WriteLine(response.Error.GenerateErrorReport());
}
else
{
Console.WriteLine(response.Result.SecretKey);
}
To run this code, you need a developer secret key. For more information about secret keys, see Secret key
management.
This application should print a newly created player-shared secret. Make sure to save it. If it is lost, you will have
to generate a new secret by running the application again.
The secret looks like this:
QC953WQ3TU6ZJTZMAT1FNJQIKR92FPUQTISW4Q6WD8SY841MQQ
if (result.Error != null)
{
Console.WriteLine(result.Error.GenerateErrorReport());
}
else
{
Console.WriteLine(result.Result.PlayFabId);
}
Normally, this would log in the user without a problem. However, now this API call is protected - and the code
will yield a Not Authorized error (not to be confused with Not Authenticated ).
We need to modify the client to properly encrypt the call payload. This is done in 2 steps:
1. Use the player-shared secret to fetch the title public key.
2. Use the title public key to encrypt the payload.
The code shown below illustrates this.
public static async Task DoEncryptedLogin()
{
Console.WriteLine("Begin DoEncryptedLogin");
Console.WriteLine("Encrypt request");
// Convert public key to bytes
var cspBlob = Convert.FromBase64String(titleKeyResult.Result.RSAPublicKey);
// Serialize certain part of the model into string (this will be encrypted).
var encryptionModel = JsonWrapper.SerializeObject(new LoginWithCustomIDRequest { CustomId =
"SOME_PLAYER_ID_ENCRYPTED" });
string encryptedPayload;
// RSA encryption
using (var rsa = new RSACryptoServiceProvider())
{
rsa.ImportCspBlob(cspBlob);
var bytesToEncrypt = Encoding.UTF8.GetBytes(encryptionModel);
var encryptedBytes = rsa.Encrypt(bytesToEncrypt, false);
encryptedPayload = Convert.ToBase64String(encryptedBytes);
}
Console.WriteLine("Call LoginWithCustomIDAsync");
// Finally execute the call
var result = await PlayFabClientAPI.LoginWithCustomIDAsync(model);
Console.WriteLine("LoginWithCustomIDAsync done");
bool successful = result.Error == null && result.Result != null;
if (!successful)
Console.WriteLine(result.Error.GenerateErrorReport());
else
Console.WriteLine("Login Successful" + result.Result.PlayFabId);
}
Once you run the code, you should be able to log in. Keep in mind that once a player-shared secret is created, it
must be hard coded into your client code, as there is no way to fetch or request it by using any API call.
Player encryption services
5/24/2022 • 3 minutes to read • Edit Online
NOTE
The standard fields TitleId , InfoRequestParameters and CreateAccount should not be included in the encrypted
payload.
{
CustomID = "my player's custom id",
PlayerSecret = "my player's individual secret"
});
string encryptedPayload;
Player secret
A part of the new registration system is a new field called PlayerSecret . If set, it allows you to sign request
headers that will be validated by the server during API calls to all services, including Login Requests.
The player secret can only be set once per user per title (a user with multiple titles in the same studio will need
to set the player secret for each one).
If the player secret isn't set during registration, it is possible to set it (if it is not already set) by calling
SetPlayerSecret. There are admin and server APIs that allow setting the player secret to a new value even if it
has previously been set.
NOTE
Once set, the player secret should be stored securely on the device, as it is not recoverable if lost, and no APIs exist to
recover it.
{
TitleId = "TITLEID",
CustomID = "my player's custom id",
CreateAccount = False
};
string signatureHeader;
string timestampHeader = DateTime.UtcNow.ToString("O");
string playerSecret; // the player secret that was sent during registration.
Any
True
False
NOTE
The default (if it is not set by the policy), is Any .
The following example policy will allow all API calls (except un-encrypted or missing header calls) to
LoginWithCustomID .
{
"PolicyName": "ApiPolicy",
"OverwritePolicy": true,
"Statements":
[
{
"Comment": "Require Headers on LoginWithCustomID",
"Action": "*",
"Principal": "*",
"Effect": "Deny",
"Resource": "pfrn:api--/Client/LoginWithCustomID",
"ApiConditions": { "HasSignatureOrEncryption": "False" }
},
{
"Comment": "Allow the rest policy",
"Action": "*",
"Principal": "*",
"Effect": "Allow",
"Resource": "pfrn:api--*"
}
]
}
Because the Deny statement is HasSignatureOrEncryption False , those requests that do not match it will be
rejected.
However, requests that have signature headers or encryption will be allowed by the Allow the rest policy .
PlayFab user roles
5/24/2022 • 4 minutes to read • Edit Online
PlayFab now supports roles as a more efficient way to manage user permissions within the Game Manager.
We're very pleased to have added this feature, since it's been one of the most frequently requested features.
With the introduction of roles, we are phasing out the ability to directly edit user permissions. This is no problem
for new titles - those can immediately begin using the new roles system.
However, existing titles that are using custom permissions must first migrate these custom permissions over to
the new roles system.
First, let's first see how the new roles work, then we'll discuss how to migrate them from the old permissions
system to the new roles system.
5. Select the New Custom Role button to create a new role. Give your new role a name, and check off the
permissions you wish to include. Generally, all permissions follow this pattern:
You can enable or disable the entire feature using the top-most option Permission (1) .
You can show or hide the navigation tab using the Permission tab (2) .
Each Permission has a read-only and read-write option. The read-write option has Edit at the end
(3) and (4) .
6. Select the Save Role button when you're done.
Assigning roles
Once you've created a role, you can assign the role to users in a title.
Roles apply at the title level. If you have five titles, and you wish a given user to have the same role for each title,
you must give the user that role for each title.
This gives you the most flexibility. Under this system, a given user could be a Title Admin for one title, a Product
Manager for another, and a Customer Service rep for a third, all under the same studio.
Here are the steps to assign a role:
1. Login to PlayFab with your developer account. As mentioned previously, make sure you are a Studio Admin.
2. Select Users and Roles from the list of options. You will see a list of users for your studio.
3. Select Settings for the user for whom you wish to assign roles.
4. Select the Roles tab. You will see a list of all titles in your studio, and any roles that user already has for each
title.
5. Select Assign Roles for each title for which you wish to give the user a role. You will see a list of your Roles.
Check any role you wish to give the user on that title.
6. After you have assigned Roles, be sure to select Save User , otherwise your role assignments will be lost.
Conclusion
Roles are a powerful and flexible new way to determine who can do what in Game Manager.
Going forward, you should use roles to assign permissions. Existing custom permissions will continue to
function, but you cannot change the permissions without migrating over to the new roles system.
Secret key management
5/24/2022 • 2 minutes to read • Edit Online
PlayFab developer secret keys allow your Title to make PlayFab Admin and Server API calls. A secret key, also
called a developer key, is strongly coupled with a PlayFab Title.
Using the Secret Keys page in Game Manager , you can create, delete, disable, and set your keys to expire.
This enables you to rotate the secret keys for your titles (which was difficult to do in the past.) It also allows you
to grant temporary access to your titles.
NOTE
Never include your developer Secret Key in a client build that you send to your customers. Doing so exposes your title to
abuse.
The Secret Keys page provides options to Delete keys, view the Status of each key, and its Name , Value , and
Expiration time, if it has one. This table lets you audit the keys that are available.
You can rename, enable, disable, or set expirations for existing keys via the dashboard. To see the options for a
key, simply select it. Each title starts with a default key.
To rotate your keys:
1. Select New Secret Key .
2. Enter the Name of the key, and an optional expiration date.
3. Update your code to use the new key.
4. Disable the old key. Select the old key and then on the Edit Secret Key page, select the Disable checkbox.
5. Select SAVE SECRET KEY .
IMPORTANT
If your old keys are compromised, rotate the keys to return your Title to a secured state.
This flow is zero-downtime, and you can safely roll back each step until you delete the old key. If there are issues
at the first step, you can delete your new key. No one should be using it.
At step two, both keys are active, so you can roll your code forward or back safely.
At step three, you can re-enable the key while you fix whatever was still depending on it.
When the process is complete, you do not need to delete the old key. If you delete that key, it cannot be
recovered. The delete is permanent and irrevocable.
Setting a key to Expire is useful when you need to give someone temporary access to your Title.
For example, if you have a contractor working on your game, you can give them keys that only have access for
as long as you expect them to need it. If they require access beyond the original expected expiration date, you
can reset the expiration date to extend the lifetime of the secret key.
Two-factor authentication
5/24/2022 • 2 minutes to read • Edit Online
Two-factor authentication allows you to reinforce security on your PlayFab Game Manager account by adding
one more step to the authentication process.
It does so by adding a device-factor to the authentication process, which only allows you to authenticate, if you
possess a certain device specifically registered for this purpose.
The second step will require you to use your two-factor code. The code is available at any time, and you can
access it using the application you installed on your device.
Once the correct two-factor code has been entered, you should be logged in.
This concludes setting up two-factor authentication for PlayFab.
What is PlayFab Authentication?
5/24/2022 • 2 minutes to read • Edit Online
PlayFab helps you leverage Authentication of your players using a breadth of providers. You can use
authentication based on the device and allow your players to link their favorite accounts to enable roaming and
recovery. Use this section to learn more about how PlayFab helps you enable Player Auth.
PlayFab also supports multiple methods for GameManager Login (SAML, AAD and PlayFab User Authentication).
You can explore these in the Azure Active Directory Authentication section.
Player login
5/24/2022 • 2 minutes to read • Edit Online
The first step in adding PlayFab to any game is to log in the player. Logging in the player returns a security token
that is required for all other API calls.
PlayFab provides a breadth of login providers to enable both anonymous and recoverable login mechanisms.
Best practices
You should begin by reading the login best practices guide. Make sure that your game enables your players to
join in and start playing quickly and easily, while providing them with a safe and secure method of getting
access to their game data on multiple devices.
Login basics and best practices
5/24/2022 • 4 minutes to read • Edit Online
NOTE
Binding a recoverable login is only required once per device. Once bound, the game can continue to use the anonymous
login with no drawbacks. See the next section.
An anonymous login is convenient for the player, but it is not required. Your game can rely exclusively on a
recoverable login mechanism. However, your players will be happier if they don't have to type a password every
time they log in.
TIP
Account recovery only requires one recoverable login, so don't pressure your player to use all of them.
Conclusion
Anonymous login is great, and it provides the user with a fully automated login process. The downside is
account recovery, which is sometimes impossible without a recoverable login.
The following flow chart describes anonymous login followed by adding a recoverable login mechanism.
Best practice
Use the appropriate anonymous login for your device, paired with one or more options for account recovery.
Account linking quickstart
5/24/2022 • 9 minutes to read • Edit Online
This Account linking quickstart demonstrates how to bind an account to multiple devices and login mechanisms.
A single PlayFab account can be accessed by many devices and login credentials. As we discuss in our tutorial
Login basics and Best Practices, there are two forms of user authentication:
1. Anonymous
2. Recoverable
NOTE
An anonymous login is still relevant, and can continue to be the primary frictionless login for the player. Many players will
only use these options again if they are attempting to recover their account, are using platform-specific features, or link a
second Anonymous device.
The focus of this tutorial is at the bottom of the preceding image, with the cells: AddUsernamePassword ,
LinkWithFacebook , or LinkWithGoogle . These indicate a few of the larger set of options available for
recoverable login mechanisms.
AddUsernamePassword is used to enable either/both of: LoginWithPlayFab and LoginWithEmailAddress.
These options store username/email/password credentials with PlayFab directly. In order for a player to
recover their account, your game, website, or customer service can trigger:
SendAccountRecoveryEmail for that email address. If a player enters a bogus email address, you can
still use the PlayFab Game Manager to update the email address for the player, though it's important
to make sure your customer service representatives are trained to watch out for common social
engineering tricks, so that they're only updating the email address of the actual owner of the account.
The third-party recoverable login mechanisms each involve prompting the user to log in via an appropriate SDK
or third-party API call. Linking that account to PlayFab generally follows the same pattern:
1. First, prompt the user to log into that service (more details in Login basics and Best Practices).
2. Once you have logged in, those services will provide some kind of token, which can be passed to PlayFab.
3. This allows PlayFab to safely link to that account without being aware of the user's credentials in that service.
NOTE
Some services require that PlayFab have some additional information, such as an Application ID, in order to make the
authentication call to that service for your game. Please be sure to check the Add-on Marketplace page for the service
in question as part of setting up your title.
Best practice
Use an anonymous login to create new players with zero friction. After a tutorial phase, gently encourage
players to link your preferred choice of recoverable credentials to their account.
If you're using a third-party authentication system, retrieve the appropriate token from that service (via API calls
or SDK functions), then call the appropriate PlayFab API to link the player's account from that service to their
PlayFab account: LinkFacebookAccount, LinkGameCenterAccount, LinkGoogleAccount, LinkKongregate,
LinkSteamAccount, LinkTwitch, LinkWindowsHello.
Best practice
For user privacy, do not save or store any user credentials (this is also one of many steps required for
COPPA compliance - and if that's a requirement for your title, please be sure to talk to your legal counsel
to confirm your compliance).
If you are using the PlayFab credentials, or calling a third-party API directly, you should clear their login
information from memory as soon as possible. Generally, the third-party SDKs take care of this for you.
Do not keep any identifiable or secure information in memory longer than you need it, and don't save it
to a file or remote location. The PlayFab APIs are designed to utilize only the minimum required
information.
NOTE
Even something as simple as writing the PlayFabId to a Cloud-based log file may save an account for a dedicated player.
Device1 State : Device ID is bound to the player account. Device2 State : Device ID is bound to the player
account.
At this point, both devices now play on the same account, and both devices can use frictionless login safely.
PlayFab supports a wide variety of authentication providers. This allows your title to support different
authentication methods and give your players options.
What this means is that your players can choose how they prefer to verify their identity and sign in using a
method that's most natural to them.
Select authentication providers based on what is most meaningful for the players on your target platforms and
distribution methods. For example, if your title is released on Xbox, it will make sense to offer Xbox Live sign-in
as a way to authenticate their identity.
Apple
Set up Apple sign-in for PlayFab
Facebook
Setting up PlayFab authentication using Facebook and HTML5
Setting up PlayFab authentication using Facebook and Unity
Google
Setting up PlayFab authentication using Google and HTML5
Setting up PlayFab authentication using Google Play Games Sign-In in Unity
Kongregate
Setting up PlayFab authentication using Kongregate and HTML5
Setting up PlayFab authentication using Kongregate and Unity
Phaser
Setting up PlayFab authentication in Phaser.io
PlayStation
Setting up PlayFab authentication using PlayStation (secure link)
If you're unable to access the above secure link, see Request access.
Steam
Setting up PlayFab authentication using Steam and Unity
Twitch
Setting up PlayFab authentication using Twitch and HTML5
Windows and Xbox
Authenticate Xbox Live users using PlayFab's Xbox Live Helper Library (recommended)
Setting up PlayFab authentication using Universal Windows Platform
Integrating the Universal Windows Platform with PlayFab
Platform-Specific Authentication Tutorials
5/24/2022 • 2 minutes to read • Edit Online
These tutorials provide basic information and best practices for setting up PlayFab authentication.
Login basics and Best Practices
Running an HTTP server for testing
These tutorials show you how to set up PlayFab authentication on specific platforms.
Setting up PlayFab authentication using Facebook and HTML5
Setting up PlayFab authentication using Facebook and Unity
Setting up PlayFab authentication using Google and HTML5
Setting up PlayFab authentication using Google Play Games Sign-In in Unity
Setting up PlayFab authentication using Kongregate and HTML5
Setting up PlayFab authentication using Kongregate and Unity
Setting up PlayFab authentication in Phaser.io
Setting up PlayFab authentication using Steam and Unity
Setting up PlayFab authentication using Twitch and HTML5
Setting up PlayFab authentication using Universal Windows Platform
Integrating the Universal Windows Platform with PlayFab
Running an HTTP server for testing
5/24/2022 • 3 minutes to read • Edit Online
In some scenarios, you may need to run a local HTTP server for test purposes. For example, if you are following
our tutorials for setting up PlayFab authentication using Facebook and HTML5, Google and HTML5, or Twitch
and HTML5, and you do not have a remote server with a domain, you may find this tutorial useful.
Prerequisites
Installed Node.JS
Serving files
Create a new folder on your system from where you want to serve your static files. There are no specific
restrictions for path on Windows.
On Mac OS, you may want to check for access on the folder. Inside of the newly created folder, create a file called
index.html .
Fill the file with the content provided below.
<!doctype html>
<html lang="en">
<head>
<meta charset="utf-8">
<title>My Page</title>
</head>
<body>
<p>Hello world!</p>
</body>
</html>
Run the command line/terminal and cd to the folder with your index.html file, then:
1. Execute http-ser ver .
2. HTTP-ser ver will start serving files from your current directory.
3. It will also print out all the IP endpoints that the server is listening for.
4. Use one of them to reach your web-server through the browser.
5. Observe your page being loaded.
You can optionally specify a port to run the server on.
Example : Execute http-server -p 80 to run your server on por t 80 . If a port is occupied, you will have to
find what application is using this port and shut it down before you attempt to run the HTTP server again.
Serving files with a custom domain name
When testing different SDKs, for example, Google or Facebook, you will notice that some services can only be
configured with a certain valid domain name.
For instance, they do not accept a plain IP address + port. Certain services use such a configuration to ensure
that your browser fetches your code from a specific, secure domain.
They also often use this configuration to ensure that a user can only log into your application from your domain,
and that nobody else can fake it and steal user data.
NOTE
While this is an important and useful security restriction, it may produce complications when trying to locally test your
code.
If you run your server on Port 80, and your use-case is simple enough, you can utilize the HOSTS file on your
operating system to access your HTTP server through a valid domain name.
The HOSTS file is a special file available on both Windows and Mac OS. It allows you to override certain domain
names with custom endpoints. Schematically, the HOSTS file looks like this:
IP_ADDRESS_1 DOMAIN_NAME_1
IP_ADDRESS_2 DOMAIN_NAME_2
IP_ADDRESS_3 DOMAIN_NAME_3
# This is comment
# IP_ADDRESS_4 DOMAIN_NAME_4 <- this entry is commented out and is inactive
...
Each line represents exactly one entry. When you try to reach DOMAIN_NAME_1 , your browser will direct your
request to IP_ADDRESS_1 .
The same applies for each entry in the HOSTS file. In the preceding example, entry number 4 starts with # .
This is a syntax for comment.
By commenting out certain entries you may disable them, without necessarily removing them from the HOSTS
file.
playfab.example is a valid domain name, but it is unlikely that your browser will reach any website with it. By
adding the following entry to your HOSTS file, you will be able to reach your local HTTP server with that domain
name.
127.0.0.1 playfab.example
WARNING
When entering your domain name in your browser address bar, always make sure to include the schema:
http://playfab.example.
Setting up PlayFab authentication using Facebook
and HTML5
5/24/2022 • 3 minutes to read • Edit Online
This tutorial is designed to guide you through PlayFab authentication using Facebook and HTML5/JavaScript.
Requirements
A Facebook account for testing.
A registered PlayFab title.
A familiarity with Login basics and Best Practices.
A minimal server, with a valid domain name to serve static HTML file.
NOTE
If you are unsure if you have the proper requirements for this activity, please consult the Running an HTTP server for
testing tutorial.
NOTE
Make sure to come up with your own unique application name and email, as shown in the example provided below.
NOTE
Copy your Application ID to a safe place, we will use it later to set up the Facebook SDK .
1. Go to the menu on the left of your screen and select the +Add Product item.
2. Locate Get Star ted in the Facebook Login area and select it.
NOTE
This will be playfab.example in your case.
NOTE
Make sure to replace YOUR-APPLICATION-ID and YOUR-PL AYFAB-TITLE with your own.
<!DOCTYPE html>
<html>
<head>
<script>
// This function will be called when Facebook SDK is loaded
window.fbAsyncInit = function() {
function loginWithPlayfab(accessToken){
function logLine(message) {
var textnode = document.createTextNode(message);
document.body.appendChild(textnode);
var br = document.createElement("br");
document.body.appendChild(br);
}
</script>
</body>
</html>
Request the following file from your server using the domain you set up during Facebook Application
configuration ( playfab.example in our case).
1. Once the Facebook Auth Example page opens, select Log In with Facebook button.
2. Follow any Facebook instructions in the pop-up window.
Watch the output.
You will obtain a PlayFab session ticket. At this point you have successfully configured PlayFab and Facebook
authentication using HTML5 and JavaScript.
Setting up PlayFab authentication using Facebook
and Unity
5/24/2022 • 6 minutes to read • Edit Online
This tutorial guides you through an example of PlayFab authentication using Facebook and Unity.
Requirements
Unity 5+ and a created project.
Facebook account for testing.
Facebook SDK imported into the project.
Registered PlayFab title.
PlayFab SDK imported into the project with a configured title reference.
Familiarity with Login basics and Best Practices.
Implementation
Registering a Facebook application
Start by navigating to the Facebook Developer Portal:
1. Move your mouse over the My Apps button.
2. Select Add a New App , as shown on the picture below.
NOTE
Make sure to come up with your own unique Application Name and Email, as shown on the picture below.
1. Navigate to the Settings tab.
2. Then move to the Basic sub-tab.
3. Locate your Application ID .
Copy it somewhere to a safe place that is easily accessed. We will use it later to set up the Facebook
SDK.
NOTE
If you do not have an assigned user token, request one using the button to the right of your screen. Refer to this page
whenever you need a fresh user token. If authorization fails during testing on a PC, token expiration may be the most
likely reason. Refresh the page to get a new user token and test again.
1. On your Application Manager page, navigate to + Add Products .
2. Locate the Facebook Login entry and select Get Star ted .
The Inspector window will display the current Facebook SDK configuration.
Enter your Application ID in the corresponding field, as shown in the following picture.
// Import statements introduce all the necessary classes for this example.
using Facebook.Unity;
using PlayFab;
using PlayFab.ClientModels;
using UnityEngine;
using LoginResult = PlayFab.ClientModels.LoginResult;
// This call is required before any other calls to the Facebook API. We pass in the callback to be
invoked once initialization is finished
FB.Init(OnFacebookInitialized);
}
private void OnFacebookInitialized()
{
SetMessage("Logging into Facebook...");
// Once Facebook SDK is initialized, if we are logged in, we log out to demonstrate the entire
authentication cycle.
if (FB.IsLoggedIn)
FB.LogOut();
// We invoke basic login procedure and pass in the callback to process the result
FB.LogInWithReadPermissions(null, OnFacebookLoggedIn);
}
/*
* We proceed with making a call to PlayFab API. We pass in current Facebook AccessToken and let
it create
* and account using CreateAccount flag set to true. We also pass the callback for Success and
Failure results
*/
PlayFabClientAPI.LoginWithFacebook(new LoginWithFacebookRequest { CreateAccount = true,
AccessToken = AccessToken.CurrentAccessToken.TokenString},
OnPlayfabFacebookAuthComplete, OnPlayfabFacebookAuthFailed);
}
else
{
// If Facebook authentication failed, we stop the cycle with the message
SetMessage("Facebook Auth Failed: " + result.Error + "\n" + result.RawResult, true);
}
}
// When processing both results, we just set the message, explaining what's going on.
private void OnPlayfabFacebookAuthComplete(LoginResult result)
{
SetMessage("PlayFab Facebook Auth Complete. Session ticket: " + result.SessionTicket);
}
Check the console output. It should render our debug statements, as shown on the picture below.
If you see no errors, this means that authentication was successful.
NOTE
Please make sure to create your own unique Package ID .
TIP
Optional step : Install Open SSL and add it to the PATH environment variable. If it is missing, Unity will produce a
harmless error during the build. This error does not stop the build, or effect the execution.
At this point you have successfully integrated Facebook Authentication for PlayFab.
Setting up PlayFab authentication using Google and
HTML5
5/24/2022 • 3 minutes to read • Edit Online
This tutorial guides you through the process of PlayFab authentication using Google and HTML5/JavaScript.
Requirements
You will need:
A Google account for testing.
A Registered PlayFab title.
Familiarity with Login basics and Best Practices.
At the minimum, a server with a valid domain name to act as a static HTML file. Consult the Running an HTTP
server for testing tutorial for information on how to set one up.
NOTE
It is normal for API Manager to take 10-20 seconds to generate the project.
Once the Project is created:
1. Navigate to the OAuth consent screen .
2. Make sure the correct email is selected.
3. Add a Name for your Application .
4. Select the Save button.
NOTE
Be sure to copy and save these values in a safe place that is easily accessible, as they will be used in the authorization
process shown later in this tutorial.
NOTE
As of July 2017, Google API Manager has a bad habit of not hooking the Allowed JS origin domain properly. If you
receive the following error:
"idpiframe_initialization_failed", details: "Not a valid origin for the client: somedomain.com..."
Please remove the credentials and recreate them. There is no need to delete the entire project - just the credentials.
NOTE
Please make sure to replace YOUR_CLIENT_ID and YOUR_PLAYFAB_TITLE with your own values.
<!DOCTYPE html>
<html>
<head>
<!-- Special meta tag allows you to pass Google Client ID. Replace the content attribute value with your
own Client Id -->
<meta name="google-signin-client_id" content="YOUR_CLIENT_ID"><!-- // TODO: PUT YOUR GOOGLE CLIENT_ID
HERE! -->
<!-- Load Google platform SDK-->
<script src="https://apis.google.com/js/platform.js" async defer></script>
<!-- Load PlayFab Client JavaScript SDK -->
<script src="https://download.playfab.com/PlayFabClientApi.js"></script>
</head>
<body>
<p>Google Access Token Auth Example</p>
<!-- Neat Google button gets styled automatically when Google platform SDK is loaded -->
<div class="g-signin2" data-onsuccess="onSignIn"></div>
<script>
// Invoked when user has signed in with Google
function onSignIn() {
// Retrieve access token
var accessToken =
gapi.auth2.getAuthInstance().currentUser.get().getAuthResponse(true).access_token;
// Execute LoginWithGoogleAccount API call using the access token. Please replace TitleID with
your own.
logLine("Attempting PlayFab Sign-in");
PlayFabClientSDK.LoginWithGoogleAccount({
AccessToken: accessToken,
CreateAccount : true,
TitleId: "YOUR_PLAYFAB_TITLE", // TODO: PUT YOUR TITLE ID HERE!
}, onPlayFabResponse);
}
function logLine(message) {
var textnode = document.createTextNode(message);
document.body.appendChild(textnode);
var br = document.createElement("br");
document.body.appendChild(br);
}
</script>
</body>
</html>
Remember to open this page using your web server, and make sure to access this page using the URL you
specified, while configuring Google Project, (PlayFab in our case).
1. Once the page opens, select G Signed In , and follow the general Google authentication flow.
2. When this is finished, the script will try to authenticate on the PlayFab side and output the result.
NOTE
If you already have a Google authentication session running, you will not have to select G Signed In . Everything will
happen automatically.
Setting up PlayFab authentication using Google
Play games sign-in in Unity
5/24/2022 • 6 minutes to read • Edit Online
Tutorial video
NOTE
The audio portion of the following video is currently unavailable. A new recording is pending, and will be available in the
immediate future.
Prerequisites
A project built using the Unity game engine.
A Google developer account.
A PlayFab developer account that has access to a game title in PlayFab.
The PlayFab Unity Editor Extensions & Unity SDK.
The Google Play Games SDK.
Familiarity with Login basics and Best Practices.
Getting started
First, we will start by setting up some basic things in Google Play. There are a few good guides on how to do
this, so we are not going to reinvent the wheel.
1. Create an Application - If you have not done so already, you will need to create an application in the Google
Play Developer Console.
2. Build your game APK, and upload it as an Alpha Build.
Select Manage Releases .
Select Manage Alpha .
Select Upload APK .
3. Setting Up Google Play Games Services - Watch the YouTube video, as the link here is dated, and does not
reflect the latest UI of Google Play Games services.
4. Download the Google Play Games SDK (if you have not done so already) and install it.
5. Install the PlayFab Unity SDK (if you do not know how to do this, follow the Unity3D quickstart guide).
Copy your Application ID from the Linked apps section of Game Ser vices in the Google Play Developer
Console, as shown in the example provided below.
Then, populate your app_id and package_name in the resource definition, as shown below.
NOTE
The Client ID that is generated for you when you link the App (shown in this image) is NOT the correct one!
In order to get the Google Sign-In working with PlayFab, you need to use a Web Client ID. To obtain your Web
Client ID, you must link a Web Application in the Game Ser vices section of the Google Play Console under
the Ser vices and API section.
IMPORTANT
You must change the default callback for Authorized redirect URIs. The proper URI is
https://oauth.playfab.com/oauth2/google . If you do not do this step you will get a mismatch redirect_uri error.
NOTE
You can get this License Key from the Google Developer Console under the Ser vices & APIs section. Look for a section
entitled YOUR LICENSE KEY FOR THIS APPLICATION. Copy and paste the Base64-encoded RSA Public Key into this
field.
The Google OAuth Client ID - This is the Web Client ID that you used in the Google Play Games SDK
setup in Unity.
The Google OAuth Client Secret - This is the secret key that you obtained in the last step.
TIP
Be sure to Save Settings !
NOTE
Make sure that you don't forget the using statements, so that you can use the Google Play Games SDK.
The next set of code, the OnSignInButtonClicked() function shown in the example provided below, is bound to a
Sign In button in the UI in our example.
private void OnSignInButtonClicked()
{
Social.localUser.Authenticate((bool success) => {
if (success)
{
PlayFabClientAPI.LoginWithGoogleAccount(new LoginWithGoogleAccountRequest()
{
TitleId = PlayFabSettings.TitleId,
ServerAuthCode = serverAuthCode,
CreateAccount = true
}, (result) =>
{
GoogleStatusText.text = "Signed In as " + result.PlayFabId;
}, OnPlayFabError);
}
else
{
GoogleStatusText.text = "Google Failed to Authorize your login";
}
});
The OnSignInButtonClicked() code can be a bit overwhelming, so let's break down exactly what is happening:
First, we log in with Social.localUser.Authenticate - This will return a boolean if we are able to successfully
login. Be aware that if you have not added your test account to your app, this will always return False when
testing.
When this happens - important step here - add your test account.
The link will take you to instructions on adding testers to your Google application.
NOTE
This is what will trigger the Google Play Games sign-in dialog to pop-up.
There is a callback which will have the results of your login to PlayFab. At this point, you should see a successful
login in your dashboard!
Hopefully, this guide has helped you. But if you have questions, feel free to ask them in our community forums.
You can download the sample for this tutorial here.
Setting up PlayFab authentication using Kongregate
and HTML5
5/24/2022 • 3 minutes to read • Edit Online
This tutorial shows you the minimal setup required to authenticate your players in PlayFab using Kongregate
and HTML5/JavaScript.
Requirements
A registered Kongregate account.
Familiarity with the Kongregate Developers Guide.
A registered PlayFab title.
Familiarity with Login basics and Best Practices.
<!doctype html>
<html lang="en-us">
<head></head>
<body>
<h1>Placeholder</h1>
</body>
</html>
If you receive no error message, then you have configured PlayFab title integration with your Kongregate
application.
<!-- Define elements with IDs to show current state of things and a couple of buttons -->
<body style='background-color:white'>
<span id='init'>Initializing...</span>
<div id='content' style='display:none'>
<div>Kongregate API Loaded!</div>
<div id='username'></div>
<div id='user_id'></div>
<!-- This button will invoke Kongregate Auth Box -->
<button id='login' style='display:none'
onclick='kongregate.services.showRegistrationBox()'>Sign in/register</button>
<!-- This button will invoke PlayFab authentication process -->
<button id='login'
onclick='loginInUsingPlayFab()'>PlayFab Login With Kongregate</button>
</div>
<script type='text/javascript'>
// forming request
var request = {
TitleId: PlayFab.settings.titleId,
AuthTicket: kongregate.services.getGameAuthToken(),
KongregateId : kongregate.services.getUserId(),
CreateAccount: true
};
console.log('logging in');
// Invoke LoginWithKongregate API call and visualize both results (success or failure)
PlayFabClientSDK.LoginWithKongregate(request,
function(result){
$('<div></div>').html('Authenticated via playfab').appendTo('#content')
console.log("success");
console.log("success");
},
function(err){
$('<div></div>').html('Problem occurred: ' + PlayFab.GenerateErrorReport(err)).appendTo('#content')
console.log("failure");
});
}
Testing
Remember that URL we asked you to save in a safe and accessible place a little earlier? Use it now to access your
Application Upload page.
1. Select index.html as your Game File .
2. Set up the screen size.
3. Make sure to accept all the required licenses.
4. Upload your application by selecting the Upload button.
Once the preview loads, wait for the Application to obtain the Kongregate User ID and Username .
When that has happened, select the PlayFab Login With Kongregate button.
After a brief pause, you should receive an Authenticated via PlayFab message.
At this point you have successfully logged in using PlayFab and Kongregate!
Setting up PlayFab authentication using Kongregate
and Unity
5/24/2022 • 4 minutes to read • Edit Online
This tutorial shows you the minimal setup required to authenticate your players in PlayFab, using Kongregate
and Unity.
Requirements
A registered Kongregate account.
Familiarity with the Kongregate Developers Guide.
A registered PlayFab title.
A Unity project with PlayFab configured for your title.
Unity WebGL support installed.
Familiarity with Login basics and Best Practices.
<!doctype html>
<html lang="en-us">
<head></head>
<body>
<h1>Placeholder</h1>
</body>
</html>
At ths point, if you do not receive an error message, you have configured PlayFab title integration with your
Kongregate application properly.
NOTE
We will only need one text label to display debug messages.
This GameObject will contain a KongregateHandler component with a wired text label for debug messages.
The code for the KongregateHandler component is provided below.
/*
* Important: execute Javascript in the external context to initialize
* Kongregate API, Unity Support and set up callback GameObject and Method.
* In this case, callback is set to a GameObject called Kongregate and a
* method called OnKongregateAPILoaded, which we define later in this class.
* Once Kongregate API is initialized, Unity will locate this object by name
* ("Kongregate") and execute a method "OnKongregateAPILoaded" passing in user
* info string as an argument.
*/
Application.ExternalEval(
"if(typeof(kongregateUnitySupport) != 'undefined'){" +
" kongregateUnitySupport.initAPI('Kongregate', 'OnKongregateAPILoaded');" +
"} else {" +
" console.error('No unity support!');" +
"};"
);
}
/*
* Executed once Kongregate API is ready. This method is invoked by KongregateAPI
* and receives a structured text with multiple pieces of data you must parse manually.
* The userInfo string parameter has the following structure: 'user_identifier|user_name|auth_token'
*/
public void OnKongregateAPILoaded(string userInfo)
{
SetMessage("Received user info! Logging though playfab...");
// We split userInfo string using '|' character to acquire auth token and Kongregate ID.
var userInfoArray = userInfo.Split('|');
var authTicket = userInfoArray[2];
var kongregateId = userInfoArray[0];
/*
* We then execute PlayFab API call called LoginWithKongregate.
* LoginWithKongregate requires KongregateID and AuthTicket.
* We also pass CreateAccount flag, to automatically create player account.
*/
PlayFabClientAPI.LoginWithKongregate(new LoginWithKongregateRequest
{
KongregateId = kongregateId,
AuthTicket = authTicket,
CreateAccount = true
}, OnLoggedIn, OnFailed);
}
/*
* The rest of the code serves as a utility to process results, log debug statements
* and display them using Text message label.
*/
Testing
The only way you can truly test the integration is by uploading your prototype to Kongregate.
1. Open the Build window and make sure WebGL is selected from your menu.
2. Then open the Player Settings by selecting the button.
Inside the Player Settings screen, locate the Settings for WebGL build:
1. Verify that you have the size set up correctly.
2. Then select the Kongregate Preloader Template .
Once the preview opens, you should be able to see your game live as the message changes.
At completion, the message should indicate successful login through PlayFab.
At this point, you have successfully integrated PlayFab and Kongregate.
Setting up PlayFab authentication in Phaser.io
5/24/2022 • 2 minutes to read • Edit Online
Phaser.io is a desktop and mobile HTML5 game framework that PlayFab now supports in our Javascript SDK.
Phaser.io supports plugins, so we at PlayFab thought that it would be useful for the Phaser.io community to have
a powerful back end system that works as a plugin to the Phaser.io engine.
This tutorial guides you through the procedure for setting up Phaser.io, and getting started with PlayFab within
Phaser.io.
Requirements
Knowledge of JavaScript.
Knowledge of setting up a web server.
General understanding of Phaser.io (a plus!).
NOTE
Alternately, you can refer to the Running an HTTP server for testing tutorial for information on how to set one up.
Setting up Phaser
The first step is to download Phaser from Phaser.io and set it up. For this tutorial, we advise you to just
download the min.js file.
Create a folder in your website root called js .
Download Phaser min.js and save it to your /js folder in the website root.
Setup code
Start by copying and pasting the code that follows into Index.html .
<!doctype html>
<html class="no-js" lang="">
<head>
<meta charset="utf-8">
<meta http-equiv="x-ua-compatible" content="ie=edge">
<title></title>
<meta name="description" content="">
<meta name="viewport" content="width=device-width, initial-scale=1">
<script src="https://code.jquery.com/jquery-1.12.0.min.js"></script>
<script src="js/phaser.min.js"></script>
</head>
<body>
Hello World!
</body>
</html>
You should see a page similar to the one in the image below, with Hello World! in the top left corner and the
rest of the page blank.
Next Steps
Add a new file in your /js folder called main.js .
Add the code shown below to main.js .
var game = new Phaser.Game(800, 600, Phaser.AUTO, '', { preload: preload, create: create, update: update });
function preload() {
}
function create() {
}
function update() {
}
You should now see that Phaser.io has initialized a blank canvas (like that shown in the example provided below).
This means that your Phaser.io installation is completed.
function create() {
game.PlayFab = game.plugins.add(Phaser.Plugin.PlayFab);
}
This tutorial guides you through the steps for logging into PlayFab using Steam through SteamWorks and Unity.
Prerequisites
Before beginning, you should have:
A Unity project with an imported PlayFab SDK, and a configured title ID.
A Steam Application with:
The AppID already set up. The AppID is usually acquired through the Steam Direct (Formerly
Greenlight) process.
A Steam Publisher Web API Key. Follow Creating a Publisher Web API Key in the Steamworks
documentation to generate a publisher key.
Familiarity with Login basics and Best Practices.
The following example shows the code for the SteamScript component.
(Thanks to Dylan Hunt for this example.)
// Import all the necessary namespaces
using System;
using System.Text;
using PlayFab;
using PlayFab.ClientModels;
using Steamworks;
using UnityEngine;
// Retrieve ticket; hTicket should be a field in the class so you can use it to cancel the ticket
later
// When you pass an object, the object can be modified by the callee. This function modifies the
byte array you've passed to it.
HAuthTicket hTicket = SteamUser.GetAuthSessionTicket(ticketBlob, ticketBlob.Length, out ticketSize);
Testing
You may test right inside the editor:
1. Run the scene and select the Log In button.
2. The console message should appear after a moment, indicating the authentication result Success! .
Setting up PlayFab authentication using Twitch and
HTML5
5/24/2022 • 3 minutes to read • Edit Online
This tutorial has been designed to guide you through the process of PlayFab authentication, using Twitch and
HTML5/JavaScript.
Requirements
Prior to beginning, you should have:
A Twitch Account for testing.
A Registered PlayFab title.
Familiarity with Login basics and Best Practices.
At the minimum, a server with a valid domain name to serve static HTML files.
NOTE
Consult the Running an HTTP server for testing tutorial for information on how to set up a server with a valid domain
name.
NOTE
Throughout this tutorial, we will assume your domain is http://localhost/.
At the very bottom of the page, select the Register your application (1) button, as shown below.
Once the application is registered, the page will be updated and reveal the Client ID for your application.
NOTE
Keep this Client ID in a safe and easily accessible place, as you will be using it later to configure your PlayFab title.
Configuring a PlayFab title
Once you acquire your Twitch Client ID, you may enable and configure a Twitch Add-on for your PlayFab title.
1. On your PlayFab Title screen, go to the menu and select the Add-ons item.
2. Then select the Twitch icon link.
Testing
Use the following HTML file to test PlayFab authentication using Twitch.
Make sure to replace TWITCH_CLIENT_ID_GOES_HERE and PLAYFAB_TITLE_ID_GOES_HERE with your own values.
<!DOCTYPE html>
<html>
<head>
<!-- Include JQuery - dependency of Twitch JS SDK -->
<script src="//code.jquery.com/jquery.min.js"></script>
<!-- Include Twitch SDK -->
<script src="https://ttv-api.s3.amazonaws.com/twitch.min.js"></script>
<!-- Include PlayFab SDK -->
<script src="https://download.playfab.com/PlayFabClientApi.js"></script>
</head>
<body>
<p>Twitch Auth Example</p>
<button onclick="login()">Login With Twitch</button>
<script>
// Establish Twitch Auth Callback (invoked when logged in with Twitch)
Twitch.events.addListener('auth.login', function() {
logLine("Logged in with Twitch!");
// Invoke login with PlayFab code and pass the token
loginWithPlayFab(Twitch.getToken());
});
function login() {
logLine("Logging in via Twitch...");
Twitch.login({
scope: ['user_read', 'channel_read']
});
}
function loginWithPlayFab(accessToken){
logLine("Logging in via PlayFab...");
function logLine(message) {
console.log(message);
var textnode = document.createTextNode(message);
document.body.appendChild(textnode);
var br = document.createElement("br");
document.body.appendChild(br);
}
</script>
</body>
</html>
1. Request the following file from your server, using the domain you set up during the Twitch application
configuration http://localhost in our case.
2. Once the page opens, wait for the message indicating that the Twitch SDK was initialized.
3. Then select the Login with Twitch button.
4. Follow any Twitch instructions in the pop-up window, and watch the output.
IMPORTANT
If you already have a Twitch auth session going when reaching the page, it is possible for callbacks to fire in a different,
unexpected order. This case is shown in the screenshot shown below. However, you should make sure that only Logging
in via PlayFab follows after Logged in with Twitch . This indicates that the token was received or restored from the
local storage, and we do not have to wait for the Twitch SDK to start signing in to PlayFab.
If PlayFab manages to acquire a SessionTicket , you have successfully integrated Twitch authentication with
your PlayFab app.
Setting up PlayFab authentication using Universal
Windows Platform
5/24/2022 • 9 minutes to read • Edit Online
This tutorial guides you through the procedure for PlayFab authentication using the Universal Windows
Platform (UWP).
IMPORTANT
This procedure serves as a very basic introduction on how you can obtain all entities, and commit authentication via
Windows Hello and PlayFab. For a more sophisticated example of Windows Hello and PlayFab authentication, consider our
UWPExample project.
Requirements
Follow the MSDN "Get Set Up" Guide to prepare Windows and Visual Studio for UWP development.
Have a registered PlayFab title.
Be familiar with Login basics and Best Practices.
NOTE
it is very important that you use the Windows 10 operating system, are logged in with a verified Microsoft account, and
have configured an access interface such as PIN. If these requirements are not met, the app will fail without any useful
explanation of why.
Once the Project is created, add the PlayFab SDK using the NuGet Package Manager .
1. First, select the Tools tab.
2. In the drop-down menu, select NuGet Package Manager .
3. Then select Manage NuGet Packages for Solution .
In the NuGet Manager window:
1. Select Browse and search for the PlayFabAllSDK package.
2. Select your target Project .
3. Then select the Install button.
Once finished, your basic project setup is complete. In the next section we will modify 2 classes that should be
automatically generated on project creation:
1. App
2. MainPage
Implementation
App.xaml.cs
This class will just set up our PlayFab SDK by setting a proper title ID. Do not forget to replace the title ID with
your own.
using System;
using Windows.ApplicationModel;
using Windows.ApplicationModel.Activation;
using Windows.UI.Xaml;
using Windows.UI.Xaml.Controls;
using Windows.UI.Xaml.Navigation;
namespace GettingStartedPlayfabUWP
{
// This class is generated upon project creation.
// While template on it's own contains a lot of xml comments, we are only interested in lines 17 and 27
sealed partial class App : Application
{
/// <summary>
/// Initializes the singleton application object. This is the first line of authored code
/// executed, and as such is the logical equivalent of main() or WinMain().
/// </summary>
public App()
{
// This is the only line of functional code we need to add to this class.
PlayFab.PlayFabSettings.TitleId = PlayfabTitleId;
this.InitializeComponent();
this.Suspending += OnSuspending;
}
/// <summary>
/// Invoked when the application is launched normally by the end user. Other entry points
/// will be used such as when the application is launched to open a specific file.
/// </summary>
/// <param name="e">Details about the launch request and process.</param>
protected override void OnLaunched(LaunchActivatedEventArgs e)
{
Frame rootFrame = Window.Current.Content as Frame;
// Do not repeat app initialization when the Window already has content,
// just ensure that the window is active
if (rootFrame == null)
{
// Create a Frame to act as the navigation context and navigate to the first page
rootFrame = new Frame();
rootFrame.NavigationFailed += OnNavigationFailed;
if (e.PreviousExecutionState == ApplicationExecutionState.Terminated)
{
//TODO: Load state from previously suspended application
}
if (e.PrelaunchActivated == false)
{
if (rootFrame.Content == null)
if (rootFrame.Content == null)
{
// When the navigation stack isn't restored navigate to the first page,
// configuring the new page by passing required information as a navigation
// parameter
rootFrame.Navigate(typeof(MainPage), e.Arguments);
}
// Ensure the current window is active
Window.Current.Activate();
}
}
/// <summary>
/// Invoked when Navigation to a certain page fails
/// </summary>
/// <param name="sender">The Frame which failed navigation</param>
/// <param name="e">Details about the navigation failure</param>
void OnNavigationFailed(object sender, NavigationFailedEventArgs e)
{
throw new Exception("Failed to load Page " + e.SourcePageType.FullName);
}
/// <summary>
/// Invoked when application execution is being suspended. Application state is saved
/// without knowing whether the application will be terminated or resumed with the contents
/// of memory still intact.
/// </summary>
/// <param name="sender">The source of the suspend request.</param>
/// <param name="e">Details about the suspend request.</param>
private void OnSuspending(object sender, SuspendingEventArgs e)
{
var deferral = e.SuspendingOperation.GetDeferral();
//TODO: Save application state and stop any background activity
deferral.Complete();
}
}
}
MainPage.xaml
This file contains the layout for our main page. This is a super trivial layout with 2 buttons, and a text input
combined in a vertically oriented grid.
The buttons are bound to specific methods, and the textbox is accessible via its name UsernameInput .
<Page
x:Class="GettingStartedPlayfabUWP.MainPage"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:local="using:GettingStartedPlayfabUWP"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
mc:Ignorable="d">
MainPage.xaml.cs
This is the functional class for the main page and it is the heart of the example. Please refer to the code
comments, and review the different methods that are designed to walk you through PlayFab+Hello register and
login.
The easiest approach to start learning the code is to review the methods that are triggered by the corresponding
buttons:
RegisterRequest
LogInRequest .
using System;
using System.Linq;
using System.Threading.Tasks;
using Windows.Foundation;
using Windows.Networking.Connectivity;
using Windows.Security.Credentials;
using Windows.Security.Cryptography;
using Windows.Security.Cryptography.Core;
using Windows.Storage.Streams;
using Windows.UI.Popups;
using Windows.UI.Xaml;
using Windows.UI.Xaml.Controls;
using PlayFab;
using PlayFab.ClientModels;
namespace GettingStartedPlayfabUWP
{
public sealed partial class MainPage : Page
{
// Shortcut to get current value of UsernameInput
public string Username => UsernameInput.Text;
public MainPage()
{
this.InitializeComponent();
}
/// <summary>
/// This method is invoked when you select the Register button
/// This method illustrates the flow for Registration process.
/// We operate on 2 entities:
/// - User Credentials of type KeyCredential
/// - Public Key of type String
/// We first check if user with this id already has Credentials. If so, we redirect to login
procedure.
/// Then we create new User Credentials. Check CreateKeyCredential for implementation details
/// Then we get Base64 encoded Public Key using the new User Credentials. Check GetPublicKeyBase64
for implementation details
/// Then we execute RegisterWithHello api call call. Check CallPlayFabRegisterWithHello for
implementation details
/// </summary>
private async void RegisterRequest(object sender, RoutedEventArgs e)
{
// Check if the user already exists and if so log them in.
KeyCredentialRetrievalResult retrieveResult = await KeyCredentialManager.OpenAsync(Username);
if (retrieveResult.Status == KeyCredentialStatus.Success)
{
// Redirect to login procedure
LogInRequest(sender, e);
return;
}
//
/// <summary>
/// This method is invoked when you select the Log In button
/// This method shows entities flow during the sign in process.
/// We have 4 different entities:
/// - User Credentials of type KeyCredential
/// - Public Key Hint of type String
/// - Challenge of type String
/// - SignedChallenge of type String
///
/// We first acquire the User Credentials. We do it based on Username. Check GetUserCredentials
method for implementation details
/// Next, we get Public Key Hint based on those credentials. Check GetPublicKeyHint for
implementation details.
/// Next we request a Challenge from PlayFab. Check GetPlayFabHelloChallenge for implementation
details
/// Next we sign the Challenge using User Credentials, so we obtain Signed Challenge. Check
GetPlayFabHelloChallenge for implementation details
/// Finally we use Signed Challenge and Public Key Hint to log into PlayFab. Check
CallPlayFabLoginWithHello for implementation details
/// </summary>
private async void LogInRequest(object sender, RoutedEventArgs e)
{
// Get credentials based on current Username.
var credentials = await GetUserCredentials(Username);
if (credentials == null) return;
// Credentials will give us Public Key. We use it to construct Public Key Hint, which is first
important entity for PlayFab+UWP authentication.
var publicKeyHint = GetPublicKeyHintBase64(credentials);
if (string.IsNullOrEmpty(publicKeyHint)) return;
if (publicKey == null)
{
await ShowMessage("Failed to get public key for credential");
return null;
}
return CryptographicBuffer.EncodeToBase64String(publicKey);
}
if (retrieveResult.Status != KeyCredentialStatus.Success)
{
await ShowMessage("Error: Unable to open credentials! " + retrieveResult.Status);
return null;
}
return retrieveResult.Credential;
}
if (challengeResponse.Error != null)
{
await ShowMessage($"Error during getting challenge: {challengeResponse.Error.Error}");
return null;
}
return challengeResponse.Result.Challenge;
if (opResult.Status != KeyCredentialStatus.Success)
{
await ShowMessage("Failed sign the challenge string: " + opResult.Status);
return null;
}
return CryptographicBuffer.EncodeToBase64String(opResult.Result);
}
if (loginResponse.Error != null)
{
await ShowMessage($"Failed to log in: {loginResponse.Error.Error}");
return null;
}
return loginResponse;
}
if (registerResult.Error != null)
{
await ShowMessage(registerResult.Error.GenerateErrorReport());
return null;
}
return registerResult;
}
return keyCreationResult.Credential;
}
Testing
To run the application:
1. Enter your username.
2. Select the Register With Hello button.
At this point you have successfully integrated PlayFab into your UWP application.
Setup Sign In with Apple for PlayFab
5/24/2022 • 2 minutes to read • Edit Online
This guide covers the series of steps needed to setup your PlayFab applications to take advantage of Sign in with
Apple.
NOTE
If you are creating a new identifier, select App IDs as the new identifier type.
4. Scroll through the list of capabilities and select Sign in with Apple .
5. Press Continue or Save on the Sign in with Apple setup popup.
6. Ensure you fully create and update your application identifier.
Save the identifier where you can access it easily. You will use in the next set of steps.
IMPORTANT
PlayFab only supports Sign in with Apple from IoS or MacOS Titles.
NOTE
At this point you need to choose whether you want to ignore the expiration date for identity tokens.
TIP
If you choose to ignore the expiration date for identity tokens, your Title should store the identity token that it obtains
from Apple locally. The identity token will be reused to log in each time.
Integrating the Universal Windows platform with
PlayFab
5/24/2022 • 3 minutes to read • Edit Online
This tutorial takes you through three key points of integration between PlayFab and the Universal Windows
Platform (UWP).
NOTE
We have created a GitHub repository with sample code to illustrate how to integrate Universal Windows Platform with
PlayFab.
Integrating the Universal Windows Platform (UWP) with PlayFab is very straightforward. There are really only
three things you need to worry about:
1. Linking a Windows Hello account to your PlayFab account.
2. Logging in the player via Windows Hello.
3. Validating a purchase made from the Windows store.
Let's take these three topics in order.
Further questions
If you have further questions, please post in our forums.
We'd also love to hear from you with any feedback on integrating your game with the Universal Windows
Platform!
Azure Active Directory Authentication for Playfab
Game Manager
5/24/2022 • 2 minutes to read • Edit Online
PlayFab now supports three methods of user authentication. The first two are the original PlayFab user
authentication system and SAML. The third is now Azure Active Directory (AAD).
To Create a New AAD User
1. Navigate to your studio's users section.
3. Assign roles as normal and send invite. The user will have the option to login with microsoft.
Sign-Up with AAD
You can start a new PlayFab studio with AAD.
1. Navigate to https://developer.playfab.com/en-US/sign-up.
2. Select Sign in with Microsoft .
PlayFab AAD Limitations
AAD authentication is functional for individual users, including AAD token exchange for programmatic
authentication. It does not support groups or graph.
Automation with PlayFab
5/24/2022 • 2 minutes to read • Edit Online
Automation is an important engineering process that greatly improves your efficiency. With PlayFab, you can
leverage features such as Actions and Rules, CloudScript, Custom Tags, and Scheduled Tasks. These features
provide means to automate processes according to a set of criteria, for example the scenario "upon receiving a
new player sign up, automatically send an email to their account and fire telemetry PlayStream events." You
have a lot of room to customize your automation, for example with Custom Tags you can enable scenarios such
as "when a player purchases an item that belongs to BFF, a custom game category that is tagged, give all their
friends 10 coins for free."
Please refer to individual feature pages under Automation for more detailed conceptual documentation and
tutorials.
CloudScript
5/24/2022 • 2 minutes to read • Edit Online
CloudScript is one of PlayFab’s most versatile features. It allows client code to request execution of any custom
server-side functionality you can implement, and it can be used in conjunction with virtually anything.
CloudScript enables you to build server-side logic and functionality that scales to meet your demand, without
worrying about servers or infrastructure. You can create CloudScript functions that can only be accessed via
your service, to prevent any tampering attempts from clients.
For example, you can have a client request a “daily reward” from your game, and trust your server-side
validation to prevent granting the reward twice.
Links
To get started with latest CloudScript release, CloudScript using Azure Functions, check out our CloudScript
Functions quickstart guide.
If you're still using the CloudScript (Legacy) offering and haven't migrated to CloudScript using Azure Functions
yet, you can find the old documentation here:
CloudScript (Legacy) quickstart
CloudScript (Legacy) tutorials
CloudScript (Legacy) quickstart
5/24/2022 • 2 minutes to read • Edit Online
CloudScript offers a fast, secure and scalable alternative to dedicated servers. Your custom JavaScript lives and
executes directly on PlayFab machines.
NOTE
CloudScript using Azure Functions supports more languages and has improved debugging workflows.
From here, your code can be called directly by your game clients - or indirectly via PlayStream actions.
Additionally, CloudScript (Legacy) methods have full access to PlayFab's Server API set.
This quickstart covers uploading and managing your CloudScript files in the PlayFab Game Manager.
NOTE
The Writing custom CloudScript tutorial covers writing the CloudScript (Legacy) code itself.
After you have added several revisions, you can select which submitted revision is live with the drop-down.
GitHub integration
You may also use GitHub to manage your CloudScript (Legacy) revisions. You must have a GitHub account, and
you must be logged in.
Select the USE GITHUB button (the gray button in the previous screenshot).
The next window will have an orange AUTHORIZE GITHUB ACCOUNT button.
Create a new, empty repository in GitHub .
Return to the GitHub page in the PlayFab Game Manager (refresh tab).
At this point, you should be able to select your GitHub repository, and bind it to your title.
Once bound to GitHub, the manual upload option is removed, and new CloudScript (Legacy) revisions are
automatically made for each GitHub commit to the "master" branch.
If you commit multiple files, they will be concatenated together into a single PlayFab CloudScript (Legacy)
revision. Live revision selection remains the same: new commits to GitHub must be set to live in Game Manager
as described above.
Conclusion
CloudScript (Legacy) allows you to upload files to PlayFab, and execute your code on our server. You can
manage your CloudScript (Legacy) files from the Automation option in the left side bar. You can upload files
manually from your own computer, or bind your title to a GitHub account.
This quickstart covers managing your code files and uploading them to PlayFab.
If you have more questions, the Writing custom CloudScript (Legacy) tutorial explains more about how to write
your CloudScript (Legacy) code files.
CloudScript Tutorials
5/24/2022 • 2 minutes to read • Edit Online
These tutorials show you how to write, use, and handle error information with CloudScript.
ES6 features in CloudScript (Legacy)
Handling errors in CloudScript (Legacy)
Making Webhook calls from CloudScript (Legacy)
SDK error handling best practices
Writing custom CloudScript (Legacy)
ES6 features in CloudScript (Legacy)
5/24/2022 • 3 minutes to read • Edit Online
The CloudScript (Legacy) runtime environment supports most of the modern ECMAScript 6 features. While a
majority of these features are syntactical tricks, you can use them to improve and clean your CloudScript
(Legacy) code.
A complete overview of ES6 features is available in this Cheat Sheet.
This tutorial shows several tricks you may use in your CloudScript.
NOTE
Some of the features require strict mode. Enable this mode by placing the following code as the very first line of your
CloudScript file: use strict;
String interpolation
When composing messages for your players, you may want to use multi-line interpolated strings. Use the back-
tick symbol to create an interpolated string. You may then insert data right into the string using ${ variable }
syntax.
This allows you to avoid string concatenation and improves code readability.
NOTE
Back-tick strings are verbatim and may be multi-line. This means you have to keep an eye on all indention, as any extra
space/tab will be captured into the string.
This operator, combined with the new Array.findIndex method, allows searching by predicate with the
following well-looking, succinct code.
// Search by predicate: find item in 'players' that has 'DisplayName' set to 'Bob':
const bobIndex = players.findIndex(p => p.DisplayName === 'Bob');
Object assignment
The Object.assign method allows you to easily extend any object with a new set of properties and methods.
Having a large variety of usages, this method is particularly useful for extending a handlers object and creating
groups of handlers.
let TestHandlers = {
TestLeaderboards : (args, ctx) => {
// Test leaderboards code
},
TestPrizes : (args, ctx) => {
// Test prizes code
}
// ...
}
let ProductionHandlers = {
CleanUp : (args, ctx) => {
// System clean up code
},
GrantTournamentAccess : (args, ctx) => {
// Another useful production code
}
// ...
}
// Comment out the group to disable it but keep the relevant code
// Object.assign(handlers, SomeOtherHandlers);
This not only allows you to quickly enable and disable handler groups, but it also gives you a point to process
your handlers and wrap them with useful code, such as exception handling.
The following code extends the previous snippet with automatic exception logging. As an example, we log the
problem (which is not always useful), but you can extend the behavior to your taste.
// Handlers installer wraps the handler to catch error
function installHandlers(handlersObject) {
for (let property in handlersObject) {
handlersObject[property] = wrapHandler(handlersObject,property)
}
Object.assign(handlers, handlersObject);
}
// Utility
function wrapHandler(obj, key) {
if (obj.hasOwnProperty(key) && typeof obj[key] === 'function') {
let original = obj[key]; // Take the original function
return function() { // return a new function that
try { // Wraps the original invocation with try
return original.apply(null,arguments); // Do not forget to pass arguments
} catch (error) { // If error occurs
log.error(error); // We log it, but you may want to retry / do something else
throw error; // Rethrow to keep the original behaviour
}
}
} else { // If property is not a function, ignore it
return obj[key];
}
}
Getters
One may use "Getters" to encapsulate common API calls into a more syntactically pleasing look and feel.
Consider the following Title Data state.
The following snippet shows how to retrieve Foo and Bar data from TitleData and then use them in a very
straightforward way.
'use strict'
// Define
let App = {
get TitleData() {
// Please, consider limiting the query by defining certain keys that you need
return server.GetTitleData({}).Data;
},
}
// Use
handlers.TestFooBar = () => {
// Client code is clean and does not show the fact of calling any functions / making api request
var titleData = App.TitleData; // Note that this implementation makes an API call every time it's
accessed
log.debug(titleData.Foo);
log.debug(titleData.Bar);
}
Handling errors in CloudScript (Legacy)
5/24/2022 • 2 minutes to read • Edit Online
This tutorial describes how to recognize and handle errors within your CloudScript (Legacy) handlers.
Identifying
The first step is identifying the error. While every uncaught error is logged and available from the response to
the caller (client), you can catch the error early by using a try/catch block.
Consider the following CloudScript (Legacy) snippet that produces and catches the error.
"use strict";
handlers.GenerateError = () => {
try {
server.GetPlayerStatistics({
PlayFabId : "non-existing-player-id"
});
} catch (ex) {
let error = ex.apiErrorInfo.apiError.error; // In this case - "InvalidParams"
let errorCode = ex.apiErrorInfo.apiError.errorCode; // In this case : 1000
}
}
Notice how the error codes were extracted within the catch block? Consult our Global API method error codes
documentation for a complete list of errors.
NOTE
The error code on its own is sufficient to identify the error.
Logging
Any unhandled error is added to the response, allowing the client to process the problem.
At the same time, it creates a CloudScript (Legacy) error entry and adds it to the total statistics available on your
CloudScript (Legacy) dashboard.
To force-log the exception in the form of a JSON string, use error logging via the log object.
"use strict";
handlers.GenerateError = () => {
try {
server.GetPlayerStatistics({
PlayFabId : "non-existing-player-id"
});
} catch (ex) {
log.error(ex);
}
}
Finally, you can write title/player events for later processing through analytics.
"use strict";
handlers.GenerateError = () => {
try {
server.GetPlayerStatistics({
PlayFabId : "non-existing-player-id"
});
} catch (ex) {
server.WriteTitleEvent({
EventName : 'cs_error',
Body : ex
});
}
}
Recovery
It's not always possible to recover from errors. Issues such as InvalidArguments leave you with no option but to
report the problem back to the player.
There are a subset of errors where a retry strategy can be applied. Retry-able error types are described in the
Global API Method Error Codes.
We ask that you make sure you meet the following requirements when applying a retry strategy:
With each retry, the delay between retries should increase exponentially. This increases your chances for a
successful call, and prevents your game from spamming the PlayFab server (which will result in more
rejected calls).
You should apply this retry strategy selectively, only using it for those codes that are worth retrying.
One of the less well-known features of CloudScript (Legacy) is that you can make Webhook calls from it to any
web API endpoint, using standard Representational State Transfer (REST) calls.
NOTE
We recommend you make webhook calls using the newer CloudScript Functions when possible.
This allows titles to make calls to basic informational services, but it also enables more complex scenarios (such
as using OAuth), to secure a communication to an endpoint you own.
This tutorial discusses making Webhook calls from CloudScript (Legacy), for both non-secure and secure
scenarios.
As a REST call, the structure of a Webhook call from CloudScript (Legacy) is simple. The elements to be specified
are:
The URL endpoint.
The REST method (post, get, put, or delete).
Any headers required.
The content type (most commonly application/JSON).
The content itself (body).
For example, a basic web API call to get the version number of your server-side logic might look something like
the example provided below.
// CloudScript (Legacy)
var url = "http://api.yoursite.com/playfab_call/GetVersion";
var method = "post";
var contentBody = "";
var contentType = "application/json";
var headers = {};
var responseString = http.request(url,method,contentBody,contentType,headers);
The body of the response is returned in stringified form, so that you can subsequently use it in the rest of the
script.
In this case, since we were querying version, you might write the response out to the log like the one provided
here.
// CloudScript (Legacy)
log.info(responseString);
The response back to the client at the end of running the CloudScript might look like this example provided
below.
//HTTP Response
{
"code": 200,
"status": "OK",
"data":
{
"FunctionName": "MyScript",
"Revision": 23,
"FunctionResult": true,
"Logs": [
{
"Level": "Info",
"Message": "{\"version\": 3}"
}],
"ExecutionTimeSeconds": 0.4309841,
"MemoryConsumedBytes": 29608,
"APIRequestsIssued": 0,
"HttpRequestsIssued": 1
}
}
If, however, you have a secure service you need to communicate with, you will first need to exchange credentials
with that service to establish identity.
For an OAuth solution, that means requesting a Bearer Access token, using your client ID and secret. This will
vary based upon your specific OAuth implementation, but your call could look something like the following
example.
//CloudScript (Legacy)
var url = "https://api.yoursite.com/playfab_call/request_token";
var method = "post";
var contentBody = "grant_type=client_credentials";
var contentType = "application/x-www-form-urlencoded";
var headers = {};
headers["client_id"] = clientId;
headers["client_secret"] = clientSecret;
Given a good response, you would then be able to parse the bearer_access_token from the response like this
(again, this does depend upon the specifics of your OAuth implementation, but this is a fairly common pattern
for this form of authentication).
//CloudScript (Legacy)
var parsedData = JSON.parse(tokenResponse);
var bearer_access_token = parsedData["access_token"];
This would then allow you to call into your OAuth-secured functionality by providing the bearer_access_token .
//CloudScript (Legacy)
var url = "https://api.yoursite.com/playfab_call/do_action";
var method = "post";
var contentBody = customActionBody;
var contentType = "application/json";
var headers = {};
headers["authorization"] = "Bearer " + bearer_access_token;
So the basic pattern in this case is that you use your application’s client ID and secret, in order to obtain the
unique Bearer Access token for the call - and then use it to secure that call.
As you can see, these calls would all be made using SSL, in order to help prevent man-in-the-middle attacks.
Using HTTP calls from CloudScript (Legacy), you can make calls into any other web API you need to for your
title. This allows you to extend your title functionality beyond even what PlayFab offers directly, giving you the
option to make and use your own custom services - or access others.
Because this all takes place within CloudScript (Legacy), it provides a server-authoritative context in which to
make those calls. This means that they will have the necessary protections in your CloudScript (Legacy) to help
prevent players from cheating, or accessing features and data they shouldn’t.
SDK error handling best practices
5/24/2022 • 2 minutes to read • Edit Online
This tutorial shows how to access, recognize, and handle API errors using the PlayFab SDK.
The practices described here are equally applicable to the admin, server, and client SDKs - but the patterns
depend highly on the language of your choice.
Simply put, the pattern of your choice will be valid for any SDK (admin/server/client) but implementation details
will be specific to your programming language and environment.
PlayFabClientAPI.LoginWithEmailAddress(new LoginWithEmailAddressRequest() {
Email = "doesnotexist@mail.com",
Password = "nevercorrect",
}, result => {
// success
}, error => {
// 'error' object is our point of access to error data
});
Generally, if an error object is defined (not null), it indicates that an error has occurred. We may then further
inspect the error.
NOTE
The code on its own is sufficient to recognize and process the error accordingly.
Let's take the LoginWithEmailAddress API method as an example. As stated in the documentation for this
method, the following internal errors may be thrown upon execution:
InvalidTitleId 1004
AccountNotFound 1001
InvalidEmailOrPassword 1142
RequestViewConstraintParamsNotAllowed 1303
The following method illustrates how to inspect and recognize such an error.
PlayFabClientAPI.LoginWithEmailAddress(new LoginWithEmailAddressRequest() {
Email = "doesnotexist@mail.com",
Password = "nevercorrect",
}, result => {
// success
}, error => {
// General purpose logging: GenerateErrorReport gives a bunch of information about the error
Debug.Log(error.GenerateErrorReport());
CloudScript is one of PlayFab's most versatile features. It allows client code to request execution of any kind of
custom server-side functionality you can implement, and it can be used in conjunction with virtually anything.
NOTE
CloudScript using Azure Functions improves on what made CloudScript (Legacy) great with more supported languages
and better debugging workflows.
This tutorial covers writing your CloudScript (Legacy) code. Please see the CloudScript (Legacy) quickstart for
help in uploading your CloudScript (Legacy) files to your title.
NOTE
This tutorial demonstrates Unity code samples, but CloudScript (Legacy) works similarly for all SDKs.
// CloudScript (JavaScript)
handlers.helloWorld = function (args, context) {
var message = "Hello " + currentPlayerId + "!";
log.info(message);
var inputValue = null;
if (args && args.hasOwnProperty("inputValue"))
inputValue = args.inputValue;
log.debug("helloWorld:", { input: inputValue });
return { messageValue: message };
}
WARNING
You should treat this object with zero trust. A hacked client or malicious user can provide any information here in any
format.
Context is an advanced parameter. In this example, it is null. This parameter is server-controlled and safe.
currentPlayerId is a global variable, which is set to the PlayFabId of the player requesting this call. This
parameter is server-controlled and safe. Note: When using ExecuteEntityCloudScript API this parameter
is null unless the entity has a MasterPlayerID in its entity chain.
log.info : log is a global object. It is primarily used for debugging your CloudScript (Legacy). The log
object exposes the following methods: info , debug , and error . There are more details later in this
tutorial.
return : any object you return is serialized as JSON, and returned to the caller. You may return any JSON
serialize-able object with any data you wish.
WARNING
It is your responsibility if your CloudScript (Legacy) returns secret data to your clients. A hacked client or malicious user
can examine the returned data, even if you don't display it to the user in regular game play.
NOTE
You can only call CloudScript (Legacy) methods attached to the handlers JavaScript object.
To execute CloudScript (Legacy) methods, you will need the following lines of code in your client.
NAME USE
ser ver Has access to all server-side API calls listed in the PlayFab
API reference documentation. They can be called
(synchronously) like so:
var result =
server.AuthenticateUserTicket(request);
In addition, all handler functions are passed two parameters, detailed below.
NAME USE
CloudScript (Legacy) functions can be called through the ExecuteCloudScript API, or by a preset PlayStream
event action.
Full details about the response to ExecuteCloudScript can be found in the ExecuteCloudScriptResult.
Putting both together, we can provide another example of how to pass arguments from client to CloudScript
(Legacy). Take the previous example, and modify the CloudScript (Legacy) code and your client code as shown
below.
handlers.helloWorld = function (args) {
// ALWAYS validate args parameter passed in from clients (Better than we do here)
var message = "Hello " + args.name + "!"; // Utilize the name parameter sent from client
log.info(message);
return { messageValue: message };
}
After making these changes, you can now easily send and receive data between CloudScript (Legacy) and your
clients.
NOTE
It is important to point out that any data coming from your clients is susceptible to hacking and exploitation.
You will always want to validate input parameters prior to updating your back end. The process for validating
input parameters will vary from title to title, but the most basic validation will check to ensure inputs are within
acceptable ranges and periods.
if(playerData.Data.hasOwnProperty("SaveState"))
{
previousState = playerData.Data["SaveState"];
}
if(result)
{
log.info(result);
}
else
{
log.error(result);
}
3. Right now, this Action is set to trigger on any PlayStream event. To test it:
Check the Publish results as PlayStream Event box.
Save the Action .
Then trigger an event.
In the PlayStream Debugger , a new event that corresponds to the CloudScript (Legacy) execution
should be present which contains the appropriate information.
For more information on checking a PlayStream event in the debugger, see the following section
Advanced: Debugging CloudScript (Legacy).
NOTE
Event actions can only use the live revision when calling CloudScript (Legacy) functions. If you cannot find the
helloWorld function in the drop-down, this is the most likely reason.
Logging
One of the most important tools for debugging code is logging. Our CloudScript (Legacy) provides a utility for
performing the function.
This takes the form of the log object, which can log any message desired using the Info , Debug , and Error
methods.
Additionally, the HTTP object will log any errors it comes across while making requests by setting the
logRequestAndResponse parameter. While setting these logs up is simple, accessing them takes a bit of finesse.
Here is an example of a CloudScript (Legacy) function that uses all 4 types of logs.
To run this example, add this function to your live revision before proceeding.
The logTest function can be called using ExecuteCloudScript as shown below.
void RunLogTest() {
PlayFabClientAPI.ExecuteCloudScript(new ExecuteCloudScriptRequest {
FunctionName = "logTest",
// duplicates the response of the request to PlayStream
GeneratePlayStreamEvent = true
}, null, null);
}
// Logs evaluated in next code block
Setting GeneratePlayStreamEvent makes the CloudScript (Legacy) function call generate a PlayStream event,
which includes the contents of the response. To find the contents of a PlayStream event:
Go to either the Game Manager home page for your Title or its PlayStream tab.
The PlayStream Debugger will display events as they come in.
When they arrive, select the small blue Info icon in the top right corner of the event, as shown below.
Selecting this will display the raw JSON of the event, which is detailed for each event here. An example of this
JSON can be seen in the following example.
If we add the LogScript MonoBehavior to the scene, running the game will yield this in PlayStream.
The result of an ExecuteCloudScript call includes a field called Logs , which is a list of log objects generated by
the CloudScript (Legacy) function.
You can see the three log calls, as well as the log from the invalid HTTP request. The HTTP request log also
makes use of the Data field, unlike the log calls.
This field is a JavaScript object that can be populated by any information relevant to the log statement. Calls to
log can make use of this field as well, using the second parameter, as indicated below.
These calls will all populate the Data field in the result with their second parameter.
Since the logs are included in the result, the client-side code can respond to log statements. The error in the
logTest function is forced, but the client code can be adapted to respond to it.
void RunLogTest()
{
PlayFabClientAPI.ExecuteCloudScript(
new ExecuteCloudScriptRequest
{
FunctionName = "logTest",
// handy for logs because the response will be duplicated on PlayStream
GeneratePlayStreamEvent = true
},
result =>
{
var error123Present = false;
foreach (var log in result.Logs)
{
if (log.Level != "Error") continue;
var errData = (JsonObject) log.Data;
object errCode;
var errCodePresent = errData.TryGetValue("errCode", out errCode);
if (errCodePresent && (ulong) errCode == 123) error123Present = true;
}
if (error123Present)
Debug.Log("There was a bad, bad error!");
else
Debug.Log("Nice weather we're having.");
}, null);
}
If this code is run, the output should indicate the presence of the error. Realistic error responses might be to
display the error in the UI, or save a value in a log file.
Advanced: Errors
In development, CloudScript (Legacy) errors will often not be manually triggered - as in the case of log.error .
Fortunately, the response to ExecuteCloudScript contains an ExecuteCloudScriptResult which includes a
ScriptExecutionError field. Adapting the last example from the logging section, we might use it as shown below.
void RunLogTest() {
PlayFabClientAPI.ExecuteCloudScript(new ExecuteCloudScriptRequest {
FunctionName = "logTest",
// handy for logs because the response will be duplicated on PlayStream
GeneratePlayStreamEvent = true
}, result => {
if(result.Error != null) {
Debug.Log(string.Format("There was error in the CloudScript function {0}:\n Error Code: {1}\n
Message: {2}"
, result.FunctionName, result.Error.Error, result.Error.Message));
}
},
null);
}
In the event that some error occurred, this code would display it in the log.
PlayFab CloudScript using Azure Functions
5/24/2022 • 2 minutes to read • Edit Online
PlayFab CloudScript using Azure Functions is a new feature that enables serverless compute on demand in the
language of your choice. In order to do this we leverage Azure Functions and provide you with a tight
integration via Visual Studio Code.
Using Azure Functions to run cloud code that is bound to a PlayFab title gives you the power of C# and strongly
typed code. It also gives you the ability to leverage any number of Azure features such as CosmosDB.
Basing CloudScript on Azure Functions brings a few key improvements:
1. Ability to write Cloudscript in C# as well as Javascript and the other supported Azure Functions languages
2. Ability to locally debug Cloudscript using Visual Studio or Visual Studio Code. In addition, we have released
an open sourced Visual Studio Code Extension for PlayFab that makes it easier to create CloudScript using
Azure Functions.
3. Ability to write queued Cloudscript functions that can run for extended periods of time since we
asynchronously wait for it to complete.
4. No limits to the number of API calls within the Azure Function code.
NOTE: For more information about Azure Functions please visit the Azure Functions documentation
In this quickstart, you write a CloudScript using Azure Functions with Visual Studio Code, Azure Functions C#
and Unity C#. After finishing this guide you will be able to link your new CloudScript to rules, scheduled tasks or
even call it from your client code.
Prerequisites
There are a couple of steps needed to get started with PlayFab C# CloudScript.
Visit the Visual Studio Code QuickStart: Create an Azure Functions project using Visual Studio Code and
return here once you are completely set up. The following prerequisites are covered in their quickstart guide:
An Azure account. Signing up for an Azure Account is free
An Azure Subscription
A Functions App resource configured in the Azure Portal
To minimize latency of your CloudScript using Azure Functions place them in the US-West, US-
West 2, or US-West 3 Azure regions.
Security Note: From a security perspective you should make sure to only use a given function
secret with PlayFab and not use it for calling the same function from any other source.
Security Note: For queued functions you should set up a distinct storage account for the
queues used for the queue trigger.
A PlayFab account
NOTE
PlayFab Azure Functions can use the Azure Functions V2 runtime or greater, and .NET Core 2 or greater. We recommend
that you use the latest version (currently Azure Functions V3 and .NET Core 3).
IMPORTANT
The "Create your first function using Visual Studio Code" guide instructs you to set the Authorization Level of your
Azure Function to Anonymous . This is done to simplify testing.
In a production environment, in most cases, you shouldn't use Anonymous authorization since it enables anyone
to call your function endpoint. To properly secure your function in the PlayFab environment, we recommend that
you use Function level authorization.
2. After you create and deploy your function, select the Register Function button in the top right hand
corner of the Functions (Preview) page.
NOTE
If your Azure Function uses Function level authorization, you must register the URL that passes the
Authorization key. For information on retrieving the URL with Authorization keys, see "Run the function in Azure"
in Quickstart: Create a function in Azure using Visual Studio Code.
3. For Name , enter a human-friendly name for your function. For Function URL , enter the HTTP Trigger
URL of the function. The URL can be found in the output of your deployment.
For more information about deploying Azure functions, see Deploy Azure Functions from Visual Studio Code.
using PlayFab;
using PlayFab.CloudScriptModels;
using System.Threading.Tasks;
using Microsoft.Azure.WebJobs;
using Microsoft.Azure.WebJobs.Extensions.Http;
using Microsoft.AspNetCore.Http;
using Microsoft.Extensions.Logging;
using Newtonsoft.Json;
using PlayFab.Samples;
namespace PlayFabCS2AFSample.HelloWorld
{
public static class HelloWorld
{
[FunctionName("HelloWorld")]
public static async Task<dynamic> Run(
[HttpTrigger(AuthorizationLevel.Function, "get", "post", Route = null)] HttpRequest req,
ILogger log)
{
FunctionExecutionContext<dynamic> context =
JsonConvert.DeserializeObject<FunctionExecutionContext<dynamic>>(await req.ReadAsStringAsync());
In the example, the CurrentPlayerId of the caller is available as it is in our traditional CloudScript
implementation. Parameters that you pass in the FunctionParameters field are available in the args. But, unlike
the Hello World example in Create your first function using Visual Studio Code guide, parameters are passed in
the POST body instead of the query string.
To call the HelloWorld Azure Function from a PlayFab SDK use ExecuteFunction .
Execution limits
CloudScript calls to Azure Functions have timeout limits. If your webhook takes too long to execute, the request
will time out in PlayFab. Make sure your code can execute fast enough to stay under the timeout limits.
PlayFab executes scripts through several mechanisms including execution through APIs, through scheduled
tasks, through PlayStream events, and when a player enters and exits segments. In many cases, the context in
which the script executes is important to how it runs. An example of this is knowing the Player ID of the player
on whose behalf the script is being run. The context in which your script is run determines the available data
model and provides context specific data that is used in your script.
In this tutorial, you learn how to:
Use the shared context model
Use the context model when executing via the ExecuteFunction API.
Use the context model when executing via Scheduled Task.
Use the context model when executing in the context of a Player.
Use the context model when executing in the context of an Entity.
// Shared models
public class TitleAuthenticationContext
{
public string Id { get; set; }
public string EntityToken { get; set; }
}
Use the context model when executing via the ExecuteFunction API
When you use the the ExecuteFunction API to execute a script, the context that is provided includes the following
information:
The Entity Profile of the caller
The Title Authentication Context
A boolean that indicates whether a PlayStream event is sent as part of the function being executed
The functions arguments used when calling the script
// Models via ExecuteFunction API
public class FunctionExecutionContext<T>
{
public PlayFab.ProfilesModels.EntityProfileBody CallerEntityProfile { get; set; }
public TitleAuthenticationContext TitleAuthenticationContext { get; set; }
public bool? GeneratePlayStreamEvent { get; set; }
public T FunctionArgument { get; set; }
}
NOTE
You can download the full CloudScript using Azure Functions helper class.
Tutorial: Local debugging for Cloudscript using
Azure Functions
5/24/2022 • 2 minutes to read • Edit Online
With Azure Functions, you can now test and debug your CloudScript code locally. After you have completed this
tutorial, you can run your local Azure Functions app under the debugger (e.g. in VS Code or Visual Studio), set
your breakpoints and run your game client.
In this tutorial you learn how to:
Add an implementation of ExecuteFunction to your local Azure Functions app
Add a settings file to tell the PlayFab SDK to call that local implementation from your game
Prerequisites
Currently local debugging is supported in the following SDKs:
PlayFab C# SDK
PlayFab Unity SDK
Unreal 4 Marketplace PlugIn for PlayFab
NAME VA L UE
PLAYFAB_DEV_SECRET_KEY Secret key for your title. You can find your secret keys in
Game Manager by clicking on the gear icon to the right of
your title's name and going to Title Settings > Secret
Keys .
For example:
{
"IsEncrypted": false,
"Values": {
"AzureWebJobsStorage": "...",
"FUNCTIONS_WORKER_RUNTIME": "dotnet",
"PLAYFAB_TITLE_ID": "B55D",
"PLAYFAB_DEV_SECRET_KEY": "AAAABBBBCCCCDDDDEEEEFFFFGGGGHHHHIIIIJJJJKKKKLLLLMM"
}
}
Configure PlayFab SDK to call local ExecuteFunction implementation
To tell the PlayFab SDK to redirect ExecuteFunction API calls to your local implementation, add a file called
playfab.local.settings.json to one of two places:
{ "LocalApiServer": "http://localhost:7071/api/" }
When you would like to stop local redirects and make ExecuteFunction call the PlayFab API server, simply delete
the playfab.local.settings.json file.
Additional resources
Azure Functions has a great guide on how to test and debug your Functions locally.
Here are some highlights from the above document.
Make sure that your Azure Functions Core Tools are installed
Configure your local settings file. For more information, Develop Azure Functions by using Visual Studio
Code
Set a break point in your code
Select F5 to start debugging
Tutorial: Debugging CloudScript using Azure
Functions with Visual Studio Code
5/24/2022 • 2 minutes to read • Edit Online
If you are using Visual Studio Code, you can use the Azure Functions extension to list your Azure Functions
applications and there is a Start Streaming Logs option:
The logs then show up in the Terminal Window in VS Code as your function runs. You can also get the same
under Logs using the Connect to Log Stream… option:
Tutorial: Debugging CloudScript using Azure
Functions with Visual Studio
5/24/2022 • 2 minutes to read • Edit Online
If you are editing your Azure Functions using the Azure portal, you can get logs directly in the portal.
To find the logs you can use the following steps:
1. Open the Azure portal
2. Navigate to your Azure Functions app
3. Select Platform features
4. Select Log Streaming under the Monitoring section
Use PlayStream Rules to react to PlayStream events in real time. A Rule consists of:
Only one Trigger
An optional list of conditions
One or more actions to take when that trigger is activated.
For example, if you want to send a reward to your players, and send a them a notification when they have more
than 10,000 XP you could:
Define a Segment for your users called “High XP Players”, and set the criteria as XP >= 10,000 .
Create a rule that is triggered by the PlayStream event of those players moving into the High XP Players
segment.
Set two actions for that rule:
1. Grant virtual currency to the player in the segment.
2. Send a push notification to congratulate the player and let them know what they've received.
Links
Actions & Rules quickstart
Actions & Rules tutorials
Actions and rules quickstart
5/24/2022 • 2 minutes to read • Edit Online
A PlayStream rule allows you to react to a subset of one type of PlayStream events in real time.
Requirements
Game Manager quickstart
Using player statistics (contains information that can help you with the example in this tutorial).
A quick glossary of relevant terms:
PlayStream : The group of features that make up the PlayFab Event pipeline.
A PlayStream Event is a JSON-formatted string describing an event about a Player or Title.
PlayStream Events have a maximum size based on your Automation feature tier.
Rule : Performs extra logic in response to one type of PlayStream Event in real time.
The sum of: One Event Trigger , an optional list of Conditions , and an optional list of Actions .
Trigger : The name of the Event which activates this Rule.
Condition : A content filter for Rules and other PlayStream features.
Performs a very lightweight evaluation of the PlayStream event JSON object, and skips events that
don't match requirements.
Action : The contextual work to be done on the appropriate entity.
A rule consists of exactly one Trigger, an optional list of Conditions, and typically at least one Action (not
required, but quite useless without it).
Triggers, Conditions, and Actions are also part of other systems: bulk actions and tournament leaderboards.
In this case, the client is manually reporting a custom ForumPostEvent (this does not currently correspond to any
Automatic Event in PlayFab or supported partners)
We will use a PlayStream Rule to count the number of times that a Player reports a forum post in this way.
Requirement : Your game must already be posting Events of this type before the Game Manager GUI will allow
you to create a Rule triggering on it.
Go to your Game Manager :
Navigate to your Title .
Select Automation .
Go to Rules .
Select New Rule .
As you can see, the custom ForumPostEvent automatically triggers the statistic that we set under Actions for our
new Rule.
Writing your CloudScript to react to PlayStream Rules is an advanced topic covered in our tutorial: using
CloudScript actions with PlayStream.
Actions & Rules Tutorials
5/24/2022 • 2 minutes to read • Edit Online
These tutorials show you how to make use of CloudScript with PlayStream hooks to perform actions on specific
player segments.
Bulk Actions for an entire player segment
Using CloudScript actions with PlayStream
Bulk Actions for an entire player segment
5/24/2022 • 5 minutes to read • Edit Online
This tutorial walks you through the steps needed to create a task to perform one or more actions on every
player in a segment.
Tasks are a vital part of live operations for any game. They give you a powerful set of tools for engaging with
your players.
Examples might include:
Give a special New Year’s gift to all players who logged in during the last 2 weeks.
Reward players who spent money in the last week (based on spending tiers), where the more money they
spent, the more valuable the gift.
Fixing corrupted Player state for all players affected by a recent game bug.
In this tutorial, based on our Unicorn Battle Sample App , we will grant a special gift to all players with more
than 2,725 XP .
Prerequisites
You will need to install the Unicorn Battle Sample App to run this tutorial. You can read more about it in our blog,
or go directly to the GitHub repository and follow the instructions there.
You will want to play several battles, in order to level up your character to at least Level 2 , which you reach at
2,725 XP points.
Step 1 - Create the segment
The first step is to create the segment that defines the group of players who will be affected by this action. In this
case, we need to create the High XP Segment , defined as all players who have more than 2,725 XP :
Select PlayStream from the menu on the left.
Choose the Segments tab.
Then select the New Segment button.
Make the Segment Name : High XP Players .
Define it as Player , where the Statistic Value called Total_XP Gained is greater than 2725 .
NOTE: The current scheduled task system can process 10-15 tasks per second per segment. When
designing your segments plan ahead for how large they will be and how long the task execution will run.
There is no limit for how long a task can run but if they task needs to be executed in a specific timeframe
then the segment needs to be sized properly.
Step 2 - Create a task for this segment
Select the Segments tab.
Then select RUN TASK …
This will take you to the Create Task view in the Ser vers ->Tasks tab, and will pre-populate various fields
based on your selected segment.
Step 3 - Add actions to the task
Next, you can finish setting up the task.
Change the name to Reward High XP Players
Add this description: Give a gift to Players who are level 2 or higher .
Select ADD ACTION
Type in Grant vir tual currency in the field provided.
Vir tual Currency code: GM (short for Gems ).
Amount: 20
Leave the scheduling set to Manually for now.
Select the SAVE AND RUN button to run the task.
Now, let's check out the task execution detail. Select the completed task in the previously run Tasks list. You will
see important information, such as:
How many players were processed.
When the task started.
How long it took to complete.
The parameters it had when it was launched.
Who ran it.
If it was scheduled manually, etc.
If the task is still in progress, you can check the Task Instance Detail view for the progress, and see the
estimated time remaining.
To verify that the task ran successfully:
Navigate to the Players tab.
Select your Player .
Then choose the Event Histor y tab.
The most recent event in the list should be a player_vir tual_currency_balance_changed , which should
show your Player ’s gems increasing by 20 .
NOTE
You can expand this event to see the details.
What’s next
This tutorial has introduced you to the steps involved in performing an action for every player in a segment, but
there’s a lot more you can do with tasks.
Here are a few ideas for other things you can try...
Schedule your tasks
You don’t need to run tasks manually - you can schedule a task to run automatically on a recurring basis. For
example, you could create a segment of all players who played the game in the last 24 hours, then run a
scheduled tasks each day to give those players an XP boost.
Run CloudScript for each player
The most powerful use of bulk actions is running an arbitrary CloudScript function for each player. This
CloudScript can do anything the PlayFab server API can do - grant items, currency, inspect and change player
data, and so on.
For example, imagine you have an event leaderboard that resets every week, and you want to go through all
players and give a reward based on the value of the last event before it reset. The example provided below is
using Unicorn Battle .
1. Create a new stat Event_QuestsCompleted , that resets weekly and uses the aggregation method Last .
2. Create a new PlayStream action that increments this Event_QuestsCompleted stat, whenever
Total_QuestsCompleted is changed.
3. Write a CloudScript function to be called by a Bulk Action task, which will go through players and give
rewards based on the last value.
// this function will be called as a bulk action by a scheduled task for players in a segment
handlers.GiveTieredReward = function (args, context) {
var profile = context.playerProfile;
try {
getStatRequest.PlayerResult = server.GetPlayerStatistics(getStatRequest);
} catch (e) {
};
5. You should notice events from this task appear in the PlayStream event debugger.
6. You can select any player triggered action executed CloudScript event (by selecting the time stamp), and
see the detailed result of CloudScript execution for each player. This includes useful diagnostic
information such as the snapshot of the player profile at the time of the CloudScript execution.
Using CloudScript actions with PlayStream
5/24/2022 • 4 minutes to read • Edit Online
When a CloudScript handler is launched from a PlayStream action, that handler has access to additional data on
why it is being run - the context - which you can use to drive your server-side logic.
This tutorial walks you through what all is available in the context, and how to make use of it in your CloudScript
handlers.
CloudScript basics
The key to getting the most out of CloudScript is knowing how to work with the inputs you have available –
namely, the args and context for your handler.
For example, here’s the helloWorld example from the starter CloudScript, loaded as Revision 1 in all newly
created titles (also available in our GitHub, shown below).
// The pre-defined "currentPlayerId" variable is initialized to the PlayFab ID of the player logged-in
on the game client.
// CloudScript handles authenticating the player automatically.
var message = "Hello " + currentPlayerId + "!";
// You can use the "log" object to write out debugging statements. It has
// three functions corresponding to logging level: debug, info, and error. These functions
// take a message string and an optional object.
log.info(message);
var inputValue = null;
if (args != null && args != undefined)
{
inputValue = args.inputValue;
}
log.debug("helloWorld:", { input: inputValue });
This example demonstrates the common use case of calling CloudScript from a client, via ExecuteCloudScript. It
checks for an argument passed in with the key inputValue , and uses the value for that key as part of the text
returned in the debug log info for the execution.
In the case of a PlayStream-triggered CloudScript call, the context contains 3 elements that can be used to drive
your server-authoritative handler's logic.
1. There’s the playStreamEvent , which you can see in the example code above. The playStreamEvent
contains the complete event which triggered the handler as a JSON object, with all the parameters you
see in the PlayStream event documentation. So for example, if you set up a rule in your title that called
handlePlayStreamEventAndProfile on any player_logged_in event , playStreamEvent.EventName would be
player_logged_in , etc. (here’s the complete set of parameters for that event).
2. Next, there’s the playerProfile , also shown in the previous example. This contains information about the
player that triggered the event. You can find all the details of the profile parameters here, but among
other things, it contains the complete set of statistics for the player in your title, as well as any custom
tags you have assigned to the player, so that you can use that data for very rich decision-making.
3. The last element of context is triggeredByTask . Unlike the first two, which are set when using Rules and
Segment Enter/Exit triggers, triggeredByTask is only applicable when the handler is running as a result of
a task, whether manual or on a timer. It contains only two parameters:
Name – The unique name you gave your task when you created it.
ID – The unique identifier automatically generated by PlayFab for your task.
For a task run against a user segment, you’ll also have the playerProfile , but you won’t have a
playStreamEvent .
And for a task that’s simply run against your game but without any segment, there won’t be a playerProfile ,
since the intent is to run something more general, like setting some title data for an event.
So name is the element you’ll want to use to use in your handler’s code flow, to determine the appropriate
action to take.
Scheduled tasks are a way to automate common game operation routines. Some examples are:
Updating Title Data to reflect changes for a current event.
Injecting virtual currencies into the game economy daily.
Modifying prices in a store according to the time of day.
Reaching out to lapsed players and encouraging them to re-engage.
Automated tasks can take predefined actions or execute CloudScript, which enables any custom server-side
functionality you want to implement.
Links
Scheduled Tasks quickstart
Scheduled tasks quickstart
5/24/2022 • 3 minutes to read • Edit Online
This quickstart shows you how to create a task that runs on a schedule. There are many game operation
routines that can be automated using a scheduled task, such as:
Modifying prices in a store according to the time of the day.
Updating title data to reflect changes for a current event.
Injecting virtual currencies into the game economy daily, etc.
In the example used in this quickstart, we'll show you how to modify a game variable called rareDropRate in
the title data at 12:00 UTC, and only on weekend days.
NOTE
For the sharp-eyed, don’t worry - there’s a bug in there on purpose. Make sure you deploy the new revision, so that it is
live in your game.
You can learn more about using CloudScript in our CloudScript quickstart, and in documentation for the method
ExecuteCloudScript.
handlers.adjustRareDropRate = function(args) {
// Tutorial demo CloudScript
serverAPI.SetTitleData({
"Key": "rareDropRate",
"Value": args.dropRate
});
}
Step 2 - Create a scheduled task
Now select Ser vers from the menu to the left.
Go to the Scheduled Tasks tab.
Select New Scheduled Task on the upper-right corner of your screen.
This will bring up the Create Task view.
In the Type of task field, choose Run a CloudScript function .
Below that, you’ll be able to pick a function from the currently deployed revision of CloudScript, and specify
arguments to pass in.
Choose the adjustRareDropRate Handler that you wrote in the previous step.
To set the schedule for this task:
Select On a schedule (UTC) under the SCHEDULE header.
A simple schedule builder lets you choose when the Task should run (every hour, day, week, etc).
For this example, we would like an advanced schedule, where we can specify which days of the week to run
the task.
So select CRON EXPRESSION .
The highly customizable Cron Expression allows you to build a very complex schedule, though it’s important to
note that we currently only allow schedules whose occurrences happen on 5-minute marks of the hour.
For example, you may specify a task to run on the 5th, 10th, 25th, or 50th minute of the hour, but you may not
specify a task to run on the 3rd, 11th, or 46th minute of the hour.
If you'd like to learn more about Cron Expression, crontab.guru provides rich information and an interactive
expression builder.
In this case, we want the task to run at 12:00 UTC on Saturdays and Sundays, which would be 00 12 * * 0,6
(zero minutes past twelve o’clock, every Sunday and Saturday).
Finally, make sure you save the new task before moving on to the next step.
The Task Instance Details view provides diagnostic information on why the task failed.
In this case, it’s pointing out that the call to ser verAPI.SetTitleData is incorrect. It should really be
ser ver.SetTitleData (for an explanation, see the Intermediate: Calling the Ser ver APIs section of the
Writing Custom CloudScript tutorial).
There is other important information on the Task Instance Details view as well - such as the start and end
times, the function that was called, any arguments passed in, the full CloudScript execution result, and more.
Step 5 - Test again (successfully)
Go ahead and fix the error we found in Step 4. The correct code snippet is shown below.
handlers.adjustRareDropRate = function(args) {
// Tutorial demo CloudScript
server.SetTitleData({
"Key": "rareDropRate",
"Value": args.dropRate
});
}
To confirm success:
Select Content in the menu to the left.
Go to the Title Data tab.
Verify that the Title Data entry was actually set.
PlayStream
5/24/2022 • 4 minutes to read • Edit Online
NOTE
PlayStream now offers support for entity events as well as classic PlayStream events. To learn more, please reference the
PlayStream with entity events article after you finish this one.
The PlayStream monitor is a real time stream of all the events for your game, including any custom events you
choose to send, using our WriteEvent API methods.
This is immensely valuable during development, as it gives you a way to immediately see what’s happening on
the back end as you test out your client- and server-side code. It also links you straight to the player accounts, so
that you can check them against the game logic you’re working on.
There are several selectable fields in each event. If you select the “(i)” information circle, you will see the raw
event JSON data.
You can also select the player’s ID to jump straight to the player’s profile. Certain other events also have
selectable fields.
Webhooks
You can also set up Webhooks, such that some or all of the events going through PlayStream will get pushed out
to an external service.
For example, you could use the feature shown below to call your own back end server on any player login.
PlayStream Webhooks are POST calls to your provided endpoint, which pass along all the data for the event in
the body of the call. Using this mechanism, you could then enable additional custom actions on your real-time
data, using your own custom services.
Event History
You can also access a historical archive of events. By default, events are kept for a certain period of time that
depends on your service tier. You can view the event history in two places - you can view all events for your title
in the PlayStream Event Histor y tab, or only events for a particular player on that player’s PlayStream tab.
You can select the arrow to the left of a particular event to see details only for that event, including its delivery
history. For example, the event shown below has been delivered to three different Marketplace Add-ons -
Appuri (both legacy and current), and Segment.com . You can click on the event name to filter the list of events
by all events of that name.
Custom Tags
The Custom Tags feature allows game developers to further enrich their standard PlayStream events with
business specific metadata.
This is a quality of life feature designed to make building on top of PlayFab easier and more extensible.
Custom Tags are a collection of key-value-pairs that studios can optionally include with every API request. They
are useful to enrich the standard PlayStream events with more studio specific metadata (e.g. build number,
external trace identifiers, etc.).
Custom Tags extend the ways in which you can use PlayStream events. The basic PlayStream schema is fixed and
lacks extensibility but allowed us to build common metrics and analytics. The fixed nature of the schema limited
game studios' ability to customize their data in an efficient and economic manner, as well as their ability to
collect specific data points. Custom Tags provide a way to extend the schema to allow greater flexibility and
functionality.
Data flow
Once Custom Tags are received from API request, the data becomes part of the PlaySteam event, which then
flows through the PlaySteam pipelines to be stored in Kusto, PlayFab's backend data warehouse.
Limitations
Custom Tags have the following restrictions:
No more than 10 key value pairs
Each key string cannot be more than 64 utf8 chars
Each value string cannot be more than 128 utf8 chars
Only supported with API calls (i.e. not supported by the Game Manager UI)
Getting Started
The following sample request show you how add Custom Tags to your JSON request. The CustomTags follow the
relevant PlayStream events as they flow through the data pipelines and you are able to access this data later for
actionable and analytical purposes.
Sample Request
POST https://titleId.playfabapi.com/Server/WritePlayerEvent
{
"PlayFabId": "{{PlayFabId}}",
"EventName": "player_defeated_enemy",
"Timestamp": "2016-03-07T00:00:00Z",
"Body": {
"Enemy": "guardian",
"Damage": 5,
"Coordinates": {
"X": 123.4,
"Y": 543.2
}
},
"CustomTags": {
"correlation_id": "123abc",
"build_number": "1.0.0.0",
"platform": "iOS"
}
}
Sample Response
Adding Custom Tags does not alter the response you receive from the call to the endpoint. The response after
you add the CustomTag node is identical to the one you receive when the node is not present.
PlayStream with entity events
5/24/2022 • 2 minutes to read • Edit Online
PlayFab has introduced the entity event model , a new event model that corresponds to the entity
programming model . An entity refers to any PlayFab concept that contains data. That can be a player, title,
character, group, etc.
In the classic event model, there existed different events and APIs for each type of entity. For example, when
creating a new entity you'd see an event like group_created , character_created , or player_created depending
on what type of entity was created. Under the entity event model, there's only a single event, entity_created , to
encompass all of the above.
With the new entity format, we were able to simplify the amount of different APIs and events that exist. You'll
continue to see classic events alongside entity events in the PlayStream monitor in order to support existing
titles as we finish migrating to the new event model.
Entity events support the following PlayFab features:
Batches of events - Write multiple entity events to PlayStream at once with the WriteEvents API.
A real-time rules engine - Set up rules that react in real time to entity events flowing through PlayStream,
and trigger a variety of actions. PlayFab supports the following actions on entity events:
Run custom CloudScript (including CloudScript with Azure functions)
Send emails
A real-time debugger - See entity events appear in the PlayStream monitor alongside classic events.
NOTE
Currently Playstream does not support creating rules for events with names longer than 40 characters.
Entity events are also supported for data and analytics features that allow you to discover pertinent information
about your game:
PlayFab Insights - Have the tools to examine all of your event data together, both classic and entity events.
Rewarded ads
5/24/2022 • 2 minutes to read • Edit Online
Rewarded video ads let your players choose to watch a short video in exchange for an incentive (usually in-
game currency, special items, etc). They are a great way of generating revenue, especially for free-to-play games.
What is an ad placement?
An ad placement consists of a list of defined rewards to grant once a player watches an ad. You control the odds
of a player recieving a randomized reward by giving each reward a different weight. Additional customization is
available by setting a limit on the number of times a player can be rewarded for watching an ad. For example,
it's common to set a limit of 3 times per day, per player. This incentivizes players to return to your game day
after day.
Addtionally, leverage player Segments to set overrides that allow different groups of players to receive different
rewards. For example, reward your VIP players with a special item while other players are rewarded with
currency.
Rewarded ads are a way of incentivizing your players to watch video ads in exchange for an reward. Each ad
with its associated rewards is considered an ad placement. In this quickstart you will set up an ad placement and
configure rewards for it.
Prerequisites
A PlayFab developer account.
An Application ID and Advertising Unit type from your ad provider.
Set up an Ad placement
In the Rewarded Ads tab, the first thing you'll see is the main dashboard for your ads. Here you'll find basic
KPIs for your ads, along with a graph showing your recent ad events (they also show up in the PlayStream
Debugger. At the top, select Placements .
Ad placements are the most fundamental part of the system. Think of a single placement as an "ad position": the
type of ad that will be displayed (banner, video, etc.) and at what point in the game the player will see it (level
interstitial, as a result of clicking on a "show me an ad", etc).
In the upper right corner, select New Ad Placement . Name your placement whatever you like, and enter the
Application ID and Advertising Unit type from your ad provider. If you're uncertain as to where to locate the
Application ID and Advertising Unit type for your specific provider, let us know and we can work with you to
identify them.
Add rewards
Now you'll need to add your specific rewards. For each possible reward for this placement, select New Reward .
Give your reward a name and enter any description text and asset package URL you want returned to the client
when the specific reward is given. Then, under Actions , select Add Action . Just as you can with regular
PlayStream actions, you can take a number different actions right now - running a Cloud Script handler, granting
items, etc. Usually, you'll be granting virtual currency or items here, but if you want to make use of the other
action types it'll all be processed the same way it is for a normal PlayStream action trigger.
After you have a couple of rewards defined, give each one a weight to set up the random distribution. If you've
defined Segments for your title, you can also set overrides in the Segment Assignment tool below Rewards .
For example, if you have a certain group of players that you want to always get a specific reward, set that
segment to that reward in the assignment list. The segment assignments are in priority order, so the first
segment that matches one for the current player is the one that is used. The following example defines an ad
placement that provides free gems 0% of the time, bonus experience points 30% of the time and a "key" item
70% of the time.
In the example we use Segment Assignment to provide rewards in a priority order. If the player is in the "High
XP Players" group, the normal random selection is made. But if the player is in the "VIP players" segment, we
grant that player the "gems" reward.
TIP
Consider creating a segment for players who are watching an ad for the first time, and grant them one of your more
desirable rewards. This can help incentivize your players to continue engaging with rewarded ads, and lead to a higher
retention rate overall.
Finally, you have the option to limit the number of times the player can be rewarded for an ad. In our example,
we limited this to 4 times per day, per player (daily resets on this counter occur at 00:00 UTC). You can have the
limit reset daily, hourly, or every two hours.
Reporting Ad Activity
We define four activity states for an ad - "Opened", "Closed", "Start", and "End". As you use Rewarded Ads, make
sure you're calling Client/ReportAdActivityRequest to update the activity state every time your ad SDK reports a
state change.
Rewarding Ad Activity
When your ad SDK reports that the ad view has successfully completed, call Client/RewardAdActivity to trigger
the reward. This call requires the PlacementId and RewardId returned by Client/GetAdPlacements. It first checks
that the reward is valid, then processes it for the player. Items are granted immediately, and the call then returns
a complete set of changes made to the player by the Grant Item, Grant Virtual Currency, and Increment Player
Statistic actions.
Finally, it's important to note that the reward ID is not bound to the player as part of the call to
GetAdPlacements. Based on the weightings you've provided, calling GetAdPlacements multiple times might
cause the reward to change. The call to RewardAdActivity only requires that the reward be valid for the player,
not that it was the last one returned from GetAdPlacements.
Multiplayer with PlayFab
5/24/2022 • 6 minutes to read • Edit Online
Multiplayer is a great addition to many titles, and PlayFab provides several services focused on multiplayer
scenarios:
While titles can use all of these services in combination, they can be used independently as well, and this is quite
common. For example titles might use PlayFab matchmaking but allocate servers from an alternative
multiplayer server hosting solution. Or games might use PlayFab multiplayer servers for hosting, but use their
own matchmaking system to bring players together.
Increasingly games are building cross-network experiences with players engaging each other from different
identity domains (e.g. Xbox Live players interacting with Steam players interacting with custom identity
systems). PlayFab's services were designed to support cross-progression and cross-network play.
UN SO L IC I
T ED
MAX # JO IN - IN -
GA M E OF L EA DERB M ATC H M IN VIT E P RO GRES SERVER
M O DE P L AY ERS O A RD A K IN G B A C K F IL L F RIEN DS S C H AT M O DEL
Single- 1 Yes No No No No No No
player
campaig
n
PlayFab Multiplayer Servers (MPS) is a server hosting service optimized for games. It enables you to
dynamically scale custom game servers according to demand.
Our servers are built on Azure Compute so it is a global distributed cloud service that offers a broad range of
compute capacity.
As a PlayFab customer, you can access our service and use a limited, free quota of multiplayer servers for
product evaluation and testing.
Features
Server infrastructure optimized for hosting multiplayer games
Cloud compute capacity that scales on demand
Multiple ways to manage scaling. Faster response time with the ability to schedule, dynamically, and
programmatically change the number of standby servers
Consistent test and production environment for game servers as they run as containerized applications
Deploy Windows or Linux game servers
VMs are built on global distributed Azure Compute services for low latencies
Full-fledged identity solution with managed end-point protection
Wide range of compute capacities for desired gaming experience
Works well with other PlayFab LiveOps and multiplayer features
See also
Using PlayFab Multiplayer Servers to host multiplayer games
Create your first server
Terminology
PlayFab Multiplayer Server SDKs
PlayFab Multiplayer Server API reference
Using PlayFab Multiplayer Servers to host
multiplayer games
5/24/2022 • 3 minutes to read • Edit Online
This topic explains how to use PlayFab Multiplayer Servers to host multiplayer game sessions—from creating
game servers that are ready to connect players for a game session to scaling them dynamically to meet
demands.
Using our service, you configure VMs to be automatically spun up globally as game servers according to your
budget and demand. In order to do so, you do not explicitly create VMs but define parameters that determines
how they get created on your behalf. This process is called deploying or creating a build.
As part of configuration process, you would upload a game server build that would run as a containerized
application on the VMs.
2. Deploy a build
Once you have a game server build that can run on PlayFab Multiplayer Game Servers as described in the step
above, you can move into configuring how you want the servers/virtual machines (VMs) to be created for you.
This step is known as creating or deploying builds.
You can specify the type of servers you want, regions they are in, what is on the server, and how they scale.
For details, see Deploy a build.
See also
Create your first server
Scaling game servers
Pricing
Terminology
Resources and samples
Enable PlayFab Multiplayer Server feature
5/24/2022 • 2 minutes to read • Edit Online
PlayFab Multiplayer Server is not automatically enabled when you sign up for a PlayFab account. In order to use
and view the servers, you need to enable the feature from Game Manager or use API/PowerShell.
You have to enable the feature using Game Manager if you do not yet have a payment method on the account.
Certain servers have limited free usage and capacity limits. They can be used during evaluation and
development. If you are enrolled in paid pricing plans, you may request for additional server cores. To learn
more, see Managing Server cores quota.
See also
Create your first server
Author a game server build
Deploy a build
Using PlayFab Multiplayer Servers to host multiplayer games
Create VMs
5/24/2022 • 2 minutes to read • Edit Online
This topic outlines the process to start deploying virtual machines (VMs) for your game servers.
Using our service, you configure VMs to be automatically spun up globally as game servers according to your
budget and demand. In order to do so, you do not explicitly create VMs but define parameters that determine
how they get created on your behalf. This process is called deploying or creating a build for the VMs.
For general steps to deploy a build, see the section below. If you already have a build and want to update it, see
Safe deployment using alias.
NOTE
The builds that you deploy for VMs are not game server builds. This build defines when and how VMs are deployed.
Game server builds run on servers, just like client builds run on clients. You upload the game server build as an asset or
include it as part of a container image, so it runs on the VMs when it gets created.
Steps
Details about each available option are provided in Build definition and configuration.
1. Select from a broad range of VMs distributed globally based on number of cores, storage space, and RAM.
For more information about the VMs, see Multiplayer Servers details and price
2. Select the OS for the VM—Windows or Linux. The way builds are deployed for Linux servers are similar to
Windows servers with a few important differences. To learn more, see Using Windows and Linux servers.
3. Upload your assets like the PlayFab Multiplayer Game Server Build. For more information on how to create
this, see Author a game server build.
4. Determine network settings—port number and protocol
5. Set other parameters such as maximum number of servers and number of standby servers for the regions
Once you've provided a valid build definition, the build starts deploying. You will be automatically directed to the
Ser ver page. In 5-10 minutes, you will see standby machines for your build, as shown below.
Ways to deploy
There are two ways to deploy or create a build for the VMs.
1. PlayFab portal—Game Manager
2. Using PowerShell/API
To help you evaluate and develop using our servers, certain servers have limited free usage and capacity limits.
For more information, see What comes with your basic PlayFab Core Services package?.
To start deploying a build using our samples, see Create your first server.
TIP
When you're not using the servers during development, remember to turn them off. Servers in all states, including
standby, are counted against your free allotment. You can set standby servers to zero using Game Manager under Region
settings. Alternatively, use the PowerShell/APImethod to set Regions.StandbySer ver=0 . You can also delete the build to
ensure all servers are turned off in Game Manager.
See also
Create your first server
Deploy a build using Game Manager
Deploy a build using PowerShell/API
Create your first server
5/24/2022 • 2 minutes to read • Edit Online
This topic describes how you can use our samples to create your first game server using PlayFab Multiplayer
Servers. We recommend using the wrapper sample to help you create your first server.
In order to use and view the servers, you need to enable the Servers feature from Game Manager. For
instructions, see Enable the PlayFab Server feature.
TIP
Certain servers have limited free usage and capacity limits. You can use them during evaluation and development. If you
are enrolled in paid pricing plans, you may request additional server cores. To learn more, see Managing Server cores
quota. It is also possible to use to test the set up and integration locally using LocalMultiplayerAgent.
Wrapper sample
The Wrapper sample, also known as wrappingGsdk, wraps an existing game so it can be used in the deployment
of builds for game servers that use Windows OS or Linux OS .
Instead of integrating your game server build with GSDK, it uses a wrapper as a workaround by processing the
standard output and error streams to call GSDK methods. Basically, the wrapper application converts your
typical game server build into one that can be used with PlayFab Multiplayer Servers.
IMPORTANT
A wrapper is a workaround by processing the standard output and error streams to call GSDK methods and it's not
meant for production use. There is additional info about GSDK integration in the sample, see Program.cs. For more
information, see Author a game server build.
Next steps
PlayFab Multiplayer Server API Reference
PlayFab Multiplayer Server resources and samples
PlayFab Multiplayer Server SDKs
Build definition and configuration
5/24/2022 • 3 minutes to read • Edit Online
This topic describes the parameters you need to specify when deploying/creating a Virtual Machine (VM)/game
server build.
A build is created by specifying its build definition and build configuration.
Build definition cannot be modified after it is created. This requires you to select what Virtual Machines (VMs)
you want, upload your PlayFab Multiplayer Game Server Build, assets, certificates, and more.
Build configuration determines how your game scales across Azure. This can be modified at any time in a
build's life.
You can also view the VM build definition and configuration on the New Build page in Game Manager. For
instructions, see How to view the New Build page using Game Manager.
Build definition
Build definition is determined by the following list of parameters.
For sample values you can use to deploy a simple server, see Walk-through of deploying builds using Game
Manager.
Build Name This is a string used to refer to the Easy identifier for the different builds
build. that you maintain
Virtual machine (VM) selection A drop-down list of global distributed Select the VMs based on what you
Azure VMs with different technical need—number of cores, RAM, storage,
specifications region. For details, see Multiplayer
Servers details and price sheet.
Container The container that will host your game For Windows, you can simply select
server. the managed Windows Server Core
containers. For Linux-based VMs, see
Deploying Linux-based builds.
PA RA M ET ER DESC RIP T IO N USA GE
Assets Files you want uploaded on the Asset filenames can only contain
servers. You can upload multiple assets alphanumeric characters, underscores,
but one of the assets must contain hyphens, and periods. You can use
your PlayFab Multiplayer Game Server C:\Assets as the typical mount path.
Build. What this means that PlayFab will
All assets combined should be less unzip your assets and mount it in the
than 10GB in size and must be in zip, container file-system (not the VM)
tar.gz or tar file type. as a folder in the C drive under Assets.
Each asset has a mount path
associated with it. This specifies where
it is mounted in the container file
system.
Certificate (optional) Upload certificates for the game server. Typically, the certificate for service-to-
This is a .pfx (Windows) or .pem (Linux) service authentication is installed
file containing the certificate to be through this configuration.
installed within the container.
Certificate names can only contain
letters and numbers. No spaces or
special characters such as dashes and
underscores.
Build configuration
Build configuration is determined by the following list of parameters. When selecting the virtual machine size
and regional configuration, keep in mind the overall usage limits configured for your PlayFab title. For more
information, see Accessing increased core limits and additional Azure regions.
PA RA M ET ER DESC RIP T IO N
NOTE
The Multiplayer Servers feature needs to be enabled in order to access and view the page. If you haven't done so, see
Enable PlayFab Multiplayer Server functionality
Next step
Create your first server
Walk-through of deploying builds using Game Manager
Using PlayFab Multiplayer Servers to host multiplayer games
Pricing
Terminology
Resources and samples
Builds overview page
5/24/2022 • 2 minutes to read • Edit Online
This article describes the Builds overview page for Multiplayer Servers in Game Manager.
From the Builds page, you can view summary information and edit shared settings for your servers. This
includes:
A broad overview of your build settings and their overrides
Access to managing components shared across builds such as assets and aliases
View complimentary services available to the build.
Build aliases
To access your aliases, select Manage on the Aliases card at the top of the Builds over view page. The manage
aliases page allows you to:
Create new build aliases
View details of aliases
Edit and delete aliases
Title assets
To access assets select on the Manage button on the Assets card to navigate to the Manage Assets page.
The Manage Assets page allows you to view and manage your title's assets. This includes:
Uploading new assets
Viewiewing assets associated with a build
Viewiewing assets unassociated with a build Both assets associated and unassociated with a build may be
downloaded to a local disk. Only assets unassociated with a build can be selected for deletion.
Services summary
Under the Ser vices summar y you can view your current cost, amount of free compute hour remaining, and
free network egress you have left for the month. For more information on billing, select the “View billing
summary” on the page. For an expanded view, select "More details".
See also
Servers Overview
VM performance metrics
Servers overview page
5/24/2022 • 2 minutes to read • Edit Online
This article describes the servers page for a specific build for Multiplayer Servers in Game Manager.
To get to this page, you'll need to select a build from the builds overview page and then select the Servers tab at
the top.
From the Servers page, you can see details of your Virtual Machines (VMs). This page will list all the VMs and
their servers. You can search for a specific server, filter, or request a server. Once you expand a VM, the following
information is available per server:
Session ID (only if currently active)
Host ID
Session state
Number of players connected
Latest Activity
To find more servers you can change the Region filter at the top of the page, search for a server, or sort based
on the filters next to Display . If you would like to request a server, you can select the Request ser ver button
located on the top right portion of the page.
For VM or Host ID, only the last seven characters of the ID are shown. To view the full VM or Host ID, hover over
the ID. If you would like to copy an ID select the ID itself, a checkmark will appear next to the ID when complete.
Search servers
When searching for servers, you can search based on any of the following criteria:
VM ID
Server Host ID
Server Session ID
Server IPv4/IPv6 Address
Server FQDN
Connected players
All search results will be sorted by the latest activity column.
Server details
Once a server becomes active, you can select on the Session ID to navigate to the Ser ver Details page.
On the servers details page, you can see more information about that specific server. Including but not limited to
connected players and region. You can also shut down your server or connect to the VM by selecting the buttons
in the top-right corner.
Archived servers
Once a server has been shut down, the state will be terminated and be moved to the Archived ser vers page. If
you would like to see an archived server, select the link at the bottom of the servers page called Archived
Ser vers . The list of archived servers will show you the last 30 days of servers that have been archived.
Server logs
If you find that you would like to learn more about your archived servers, you can download the logs found
under Archived Ser vers . Next to each server is a Download logs button if you select that it will download a
zip file of your logs from that file.
See also
Archiving and retrieving multiplayer server logs
Builds overview
Basics of a PlayFab game server
5/24/2022 • 3 minutes to read • Edit Online
PlayFab operates game servers as containerized applications. This tutorial describes how game servers are
packaged and integrated with PlayFab systems.
The StartGameCommand must start an application that uses the PlayFab Game Server SDK, to call ReadyForPlayers
when ready to serve game clients. The container will be terminated and recycled when the application process
exits.
Linux
On Linux, you create the container image yourself by packaging game executable and assets. Usage of assets
that are combined with the container image at runtime is optional. When a Linux build is created through Game
Manager or APIs like CreateBuildWithCustomContainer(), you can optionally specify the assets and where they
should be mounted within the container's file system. Specification of the shell command to start the game (
StartGameCommand ) is also optional, since this command can also be included in the container image.
NOTE
Check this page for more information regarding creating Linux container images for PlayFab Multiplayer Servers
When your game server is initialized, it will be put into a preparing state, with PlayFab waiting for your game
server to call ReadyForPlayers() .
Once this is called, the game server is put into a standing by state, and waits for allocation requests from your
matchmaking service into PlayFab via the RequestMultiplayerServer method.
The image displayed below shows the States of a PlayFab multiplayer server.
Ostensibly, calling ReadyForPlayers() is the only requirement to get your game server to run and continue
running. However, there are several callbacks/events that you may want to process in order to provide the best
user experience.
This topic explains the terms used for PlayFab Multiplayer Server. We understand that it can be confusing since
the word server is used in multiple places.
The internal structure of the PlayFab Multiplayer Server and general relationship of the various components is
also lightly covered here. For details, see Basics of a PlayFab game server.
Next steps
Using PlayFab Multiplayer Servers to host multiplayer games
Author a game server build
Deploy a build
Author a game server build
5/24/2022 • 2 minutes to read • Edit Online
This topic explains how to create a game server build for PlayFab Multiplayer Servers (MPS). A game server
build typically contains game assets and an executable that runs on the server.
When using PlayFab Multiplayer Servers, you need to make modifications to your regular game server build so
that it can work on them. This modified server build is called a PlayFab Multiplayer Game Server Build.
If you're unsure of the terms used, see Terminology.
NOTE
Consider using our open source debugging utility LocalMultiplayerAgent to test your game server before uploading it
into MPS. This will help prevent unnecessary costs in case your game server fails to start or is not properly integrated
with GSDK. You can download LocalMultiplayerAgent here and check the instructions here. LocalMultiplayerAgent can
also be used for iterative testing/debugging during the development of your game server.
Next step
When using Windows game servers, you have to use the managed Windows container image. So the PlayFab
Multiplayer Game Server Build can be uploaded as a zipped file combined with other dependencies (DLL files)
during the Deploy a build process. To help you determine what needs to be included in the zipped file, see
Determining required DLLs.
When using Linux game servers, you need to Create your custom Linux container image and the PlayFab
Multiplayer Game Server Build can be included as part of the image. Once your custom image is uploaded, you
would be able to Deploy a build.
See also
Determine DLL files to be included in the asset package for Windows servers
Local debugging and integration for Windows servers
Create Linux servers
Integrating game servers with the PlayFab Game
Server SDK (GSDK)
5/24/2022 • 9 minutes to read • Edit Online
Overview
The PlayFab Game Server SDK (GSDK) is provided in C++, C#, and Java versions. The GSDK connects your game
server to the PlayFab agent installed on the VM. This agent facilitates key server interactions with the PlayFab
Multiplayer platform.
Basic integration
For your game server to be able to communicate with the PlayFab multiplayer platform, you need to integrate
with the GSDK. At a minimum, you must implement the Start and ReadyForPlayers methods in your game
server.
int main()
{
// Call this while your game is initializing; it will start sending a heartbeat to our agent and put the
game server in an Initializing state
Microsoft::Azure::Gaming::GSDK::start();
/* Add any other initialization code your game server needs before players can connect */
// Call this when your game is done initializing and players can connect
// Note: This is a blocking call, and will return when this game server is either allocated or
terminated
if (Microsoft::Azure::Gaming::GSDK::readyForPlayers())
{
// readyForPlayers returns true when an allocation call has been done, a player is about to connect!
}
else
{
// readyForPlayers returns false when the server is being terminated
}
}
static void Main(string[] args)
{
// Call this while your game is initializing; it will start sending a heartbeat to our agent and put the
game server in an Initializing state
GameserverSDK.Start();
/* Add any other initializion code your game server needs before players can connect */
// Call this when your game is done initializing and players can connect
// Note: This is a blocking call, and will return when this game server is either allocated or
terminated
if (GameserverSDK.ReadyForPlayers())
{
// readyForPlayers returns true when an allocation call has been done, a player is about to connect!
}
else
{
// readyForPlayers returns false when the server is being terminated
}
/* Add any other initializion code your game server needs before players can connect */
// Call this when your game is done initializing and players can connect
// Note: This is a blocking call, and will return when this game server is either allocated or
terminated
if (GameserverSDK.readyForPlayers())
{
// readyForPlayers returns true when an allocation call has been done, a player is about to connect!
}
else
{
// readyForPlayers returns false when the server is being terminated
}
// This will add your log line to the GSDK log file, alongside other information logged by the GSDK
Microsoft::Azure::Gaming::GSDK::logMessage("Here is a sample log");
// Alternatively, you can log your own files to the log directory
std::string logFolder = Microsoft::Azure::Gaming::GSDK::getLogsDirectory();
// This will add your log line to the GSDK log file, alongside other information logged by the GSDK
GameserverSDK.LogMessage("Here is a sample log");
// Alternatively, you can log your own files to the log directory
string logFolder = GameserverSDK.GetLogsDirectory();
// This will add your log line to the GSDK log file, alongside other information logged by the GSDK
GameserverSDK.log("Here is a sample log");
// Alternatively, you can log your own files to the log directory
String logFolder = GameserverSDK.getLogsDirectory();
NOTE
PlayFab will only terminate game servers that are not currently active.
3. Azure will perform required maintenance on the virtual machine that is hosting your game server.
For (1) above: You control when it happens, and can perform any necessary cleanup before your application
exits.
For (2) and (3) above: The GSDK provides a way for you to know when they will occur, by specifying a callback
method.
// This method will be called in case #2, when PlayFab terminates the game server
void onShutdown()
{
printf("GSDK is shutting me down!!!\n");
/* Perform any necessary cleanup and end the program */
std::exit(0);
}
// This method will be called in case #3, when Azure will perform maintenance on the virtual machine
void onMaintenanceScheduled(tm t)
{
#ifdef WINDOWS
time_t local = _mkgmtime(&t);
double delta = difftime(local, time(NULL));
struct tm buf;
char str[26];
gmtime_s(&buf, &local);
asctime_s(str, sizeof str, &buf);
printf("UTC: %s", str);
localtime_s(&buf, &local);
asctime_s(str, sizeof str, &buf);
printf("local: %s", str);
printf("delta: %f", delta);
#else // Linux
time_t local = timegm(&t);
double delta = difftime(local, time(NULL));
printf("UTC: %s\n", asctime(gmtime(&local)));
printf("local: %s\n", asctime(localtime(&local)));
printf("delta: %f\n", delta);
#endif
int main()
{
Microsoft::Azure::Gaming::GSDK::start();
Microsoft::Azure::Gaming::GSDK::registerShutdownCallback(&onShutdown);
Microsoft::Azure::Gaming::GSDK::registerMaintenanceCallback(&onMaintenanceScheduled);
// This method will be called in case #2, when PlayFab terminates the game server
static void OnShutdown()
{
GameserverSDK.LogMessage("Shutting down...");
/* Perform any necessary cleanup and end the program */
}
// This method will be called in case #3, when Azure will perform maintenance on the virtual machine
static void OnMaintenanceScheduled(DateTimeOffset time)
{
/* Perform any necessary cleanup, notify your players, etc. */
}
// This method will be called in case #3, when Azure will perform maintenance on the virtual machine
private static void onMaintenanceScheduled(ZonedDateTime time)
{
/* Perform any necessary cleanup, notify your players, etc. */
}
void playerConnected()
{
// When a new player connects, you can let PlayFab know by adding it to the vector of players and
calling updateConnectedPlayers
players.push_back(Microsoft::Azure::Gaming::ConnectedPlayer("player_tag"));
Microsoft::Azure::Gaming::GSDK::updateConnectedPlayers(players);
}
// This method will be called on every heartbeat to check if your game is healthy, as such, it should return
very quickly
bool isHealthy()
{
// Return whether your game server should be considered healthy
return true;
}
int main()
{
Microsoft::Azure::Gaming::GSDK::start();
Microsoft::Azure::Gaming::GSDK::registerHealthCallback(&isHealthy);
// This method will be called on every heartbeat to check if your game is healthy, as such, it should return
very quickly
static bool IsHealthy()
{
// Return whether your game server should be considered healthy
return true;
}
// This method will be called on every heartbeat to check if your game is healthy, as such, it should return
very quickly
private static GameHostHealth getGameHealth()
{
// Return whether your game server should be considered healthy
return GameHostHealth.Healthy;
}
NOTE
Two of these settings are actually passed in to PlayFab by your clients, as part of the call to request a multiplayer server.
So those settings will not be available to your game server until it is allocated.
// Get all the configuration values
std::unordered_map<std::string, std::string> config = Microsoft::Azure::Gaming::GSDK::getConfigSettings();
if (it != config.end())
{
std::string sessionCookie = config[Microsoft::Azure::Gaming::GSDK::SESSION_COOKIE_KEY];
}
// Here some other useful configuration keys (the full list is in gsdk.h)
static constexpr const char* SERVER_ID_KEY; // ID given to your game server upon creation
static constexpr const char* LOG_FOLDER_KEY; // Path to the folder that should contain all log files
static constexpr const char* CERTIFICATE_FOLDER_KEY; // Path to the folder that contains any game
certificate files
static constexpr const char* TITLE_ID_KEY; // PlayFab Title ID for this game server
static constexpr const char* BUILD_ID_KEY; // PlayFab Build ID for this game server
static constexpr const char* REGION_KEY; // Azure Region this server is running in
// These two keys are only available after allocation (once readyForPlayers returns true)
static constexpr const char* SESSION_COOKIE_KEY; // The Session Cookie you passed into the allocation call
when you requested a server
static constexpr const char* SESSION_ID_KEY; // The Session ID you specified in the allocation call when you
requested a server
// Here are some other useful configuration keys (the full list is in the GameserverSDK class)
public static string ServerIdKey; // ID given to your game server upon creation
public static string LogFolderKey; // Path to the folder that should contain all log files
public static string CertificateFolderKey; // Path to the folder that contains any game certificate files
public static string TitleIdKey; // PlayFab Title ID for this game server
public static string BuildIdKey; // PlayFab Build ID for this game server
public static string RegionKey; // Azure Region this server is running in
// These two keys are only available after allocation (once readyForPlayers returns true)
public static string SessionCookieKey; // The Session Cookie you passed into the allocation call when you
requested a server
public static string SessionIdKey; // The Session ID you specified in the allocation call when you requested
a server
// Get all the configuration values
Map<String, String> config = GameserverSDK.getConfigSettings();
// Here are some other useful configuration keys (the full list is in the GameserverSDK class)
public static final String SERVER_ID_KEY; // ID given to your game server upon creation
public static final String LOG_FOLDER_KEY; // Path to the folder that should contain all log files
public static final String CERTIFICATE_FOLDER_KEY; // Path to the folder that contains any game certificate
files
public static final String TITLE_ID_KEY; // PlayFab Title ID for this game server
public static final String BUILD_ID_KEY; // PlayFab Build ID for this game server
public static final String REGION_KEY; // Azure Region this server is running in
// These two keys are only available after allocation (once readyForPlayers returns true)
public static final String SESSION_COOKIE_KEY; // The Session Cookie you passed into the allocation call
when you requested a server
public static final String SESSION_ID_KEY; // The Session ID you specified in the allocation call when you
requested a server
Determining required DLLs that need to be
included in the asset package
5/24/2022 • 2 minutes to read • Edit Online
This article helps you generate a list of DLLs required to run your Windows game server in PlayFab Multiplayer
Servers. By default, the managed container image includes many commonly used DLLs. To determine which
additional DLLs are needed, compare the list of DLLs for your game server with the list of DLLs included in the
manged container image. Any additional DLLs must be included in your asset zip file.
Replace "wsc-10.0.17134.950" with the tag of the docker image you downloaded in step 1. If you are not sure of
the correct tag, run docker images to list the downloaded images.
1. From the command line, locate the folders that correspond to the folders of the required DLLs on your local
machine. List the DLLs present in the container and compare to the list of required DLLs that you generated.
Any DLLs in the required list, but not present in the container, must be included in your asset zip file.
2. To end the cmd process and cause the container to stop, type exit .
Integrating the PlayFab GSDK into Unity
5/24/2022 • 2 minutes to read • Edit Online
Multiplayer Servers platform provides a GSDK library that you can integrate into your Unity game server. The
library is open source and can be found on the GSDK repository on GitHub.
Installation
You can copy the Assets/PlayFabSdk folder into your Unity project. After that, you need to enable the scripring
directive ENABLE_PLAYFABSERVER_API on your Unity Build settings (example). Alternatively, you can use the
provided Unity package file. You can find sample code in the MultiplayerServerSample project.
Usage
At a minimum, you need to implement PlayFabMultiplayerAgentAPI.Start() method and start a coroutine for
the PlayFabMultiplayerAgentAPI.ReadyForPlayers() method, like in the code below
//...
StartCoroutine(ReadyForPlayers());
//...
You would also want to register for when the game server becomes transitions to Active using the
PlayFabMultiplayerAgentAPI.OnServerActiveCallback , like in the example below:
PlayFabMultiplayerAgentAPI.OnServerActiveCallback += OnServerActive;
// ...
private void OnServerActive()
{
Debug.Log("Server Started From Agent Activation");
// players can now connect to the server
}
NOTE
For more information regarding game server states, check Basics of a PlayFab game server section here
Moreover, you can implement the following callbacks on your game server:
PlayFabMultiplayerAgentAPI.OnMaintenanceCallback triggered when Azure needs to perform maintenance on
the VM
PlayFabMultiplayerAgentAPI.OnShutDownCallback triggered when a termination notification is received
PlayFabMultiplayerAgentAPI.OnAgentErrorCallback triggered if there's any error between game server and
PlayFab VM Agent communication
NOTE
For more GSDK samples, you can take a look at our MPS Samples repository here
Deploy builds using Game Manager
5/24/2022 • 6 minutes to read • Edit Online
This article lists the general steps to deploy/create builds for VMs using Game Manager.
If this is your first time deploying a build, we recommend deploying a build using the Windows Runner C#
sample or Wrapper sample. Both will come with all the assets you need to actually deploy servers.
NOTE
In order to use and view the PlayFab Multiplayer Servers, you need to enable the feature from Game Manager. For
instructions, see Enable the PlayFab Server feature.
For details about the values you can use for each parameter, see Build definition.
6. Next we have the server details portion where you'll need to select an OS type either Windows or Linux .
Then you'll select your server type, either process or container based on the OS you choose.
NOTE
For Linux platform, you need to create your own container image. For more instructions, see Create and deploy Linux
container images. If you've already uploaded a container image, it will appear in the Image dropdown. To use it, select the
image.
Once you have selected your OS type, you can then choose the server type. Based on the OS/Server type you'll
have the following features you can enable.
Virtual Machine Metrics Preview: By enabling this it allows you to see system level metrics such as CPU,
memory, network, etc. To learn more, read our VM performance metrics (preview) article
Windows Core Preview: Allows you to test the newest versions of Windows operating system on test builds
to see how your game will run with the newer operation system. To learn more, read OS patch level updates
for Windows
Automatic Crash Dump Collection: Allows you to enable automatic crash dump collection on your Windows
Container server types. You can choose between doing a full, mini, or custom dump. To learn more, read
Enabling automatic collection of crash dumps
Server details for Process mode
Image below shows values used in the OS section when you select Windows as the platform but use Process
based server type. There is also the option of using Linux process based servers as well.
NOTE
Do not provide a mount path for process based servers.
Network settings
8. For network, set the port number, name, and protocol.
Setting port for container server types
If you're using a container server type, you should specify the port number.
For example, in Game Manager for a container server type, you could specify:
Port name: "gameServerPort"
Port number: 7777
Protocol: UDP
Then in your code you would do something like this
NOTE
In container mode, each game server runs on its own network namespace. This is the reason why every game server can
listen to the same port. The container port is dynamically mapped to a unique port on the virtual machine. However, on
process mode, all game servers run on the same network namespace. Having all game servers listen to the same port
would create conflicts, so this is why you'll need to get the ServerListeningPort from the GSDK.
var gp = gsc.Where(x=>x.Name=="gameServerPort").Single();
Start command
Start command for container based servers
Your start command should be the absolute path (including the mount path) to your game executable that
should include any required arguments. For example, your start command could look like C:\Assets\wrapper.exe
-g C:\Assets\fakegame.exe arg1 arg2. Adding in the "C:\Assets" portion to your absolute path for your start
command is only required if it's a Windows container based server. This is because that's the directory where
your game asset would be extracted from.
Start command for windows process based servers
Your start command is the relative path within the uploaded asset. If the executable is directly within the asset
folder, then you can just use <yourGameServerBuild.exe>. If it is within another folder (for example
GameDirectory), then the start command would be gameDirectory/YourGameServerBuild.exe.
9. Under Regions, select the region you want to deploy the servers. Then specify the number of standby and
maximum servers.
10. Select Save to start the deployment process. You'll be taken to the build home page. The build will display
the Deploying status as show in the image below.
In a couple minutes, your build should be in the Deployed state. This means that servers are deployed and can
be allocated. For more information on allocating game servers, you can check here whereas you can use the
MpsAllocatorSample to experiment with server allocation.
See also
Walkthrough: Deploy builds using Game Manager
Deploy a build using PowerShell/API
Create your first server
Wrapper C# sample
MPS Allocator Sample
Samples and resources
Deploy builds using PowerShell/API
5/24/2022 • 5 minutes to read • Edit Online
This topic provides an overview on how to deploy/create builds for VMs using Windows OS in PowerShell on a
Windows 10 development device.
When deploying a build using PowerShell/API, you are likely to be using a combination of using Game Manager
and the APIs. Hence, the PowerShell/API commands are listed by functionality below.
If this is your first time deploying a build, we recommend deploying a build using the Wrapper sample because
it comes with all the assets you need to actually deploy servers.
NOTE
In order to use and view the PlayFab Multiplayer Servers, you need to enable the feature. If you are a new user, we
recommend that you use the Game Manager method to enable this feature. For instructions, see Enable the PlayFab
Server feature.
Uninstall-Package PlayFabMultiplayer
To help you transition to the new module, see Mapping commands to find the new equivalent commands. Note
that both the commands and arguments could be different.
3. Install the new PlayFabMultiplayer API module
For detailed documentation about each command, see Cmdlet documentation.
4. Learn more about the cmdlets in the PlayFab Multiplayer PowerShell module by running the following
command. Or you can refer to the PlayFabMultiplayerApi cmdlet reference documentation.
Enable-PfMultiplayerServer
Upload an asset
Uploading an asset is mandatory when you are deploying a build for Windows servers. This is because your
assets customizes the managed Windows container image.
However, it is optional when deploying a build for Linux servers since you are able to customize the Linux
container image. To learn more, see Create Linux container images.
Run this command to upload an asset.
where:
Filepath : Path to the local file you want to upload
AssetName : Name of the asset to upload
For more details, see New-PfAsset reference documentation.
Create a build
When creating a build for Windows servers, you need to have uploaded an asset. If not, see Upload an asset.
When creating a build for Linux servers, you need to have uploaded your custom Linux container image to
your PlayFab container registry. To learn more, see Deploying Linux servers.
IMPORTANT
Make sure you use the correct values for $vmSize and $regions if you plan to take advantage of resources offered for
free evaluation.
Sample code below to help deploy builds for Windows game servers.
$vmSize = "Standard_D2as_v4"
$regions = @( @{ StandbyServers = 1; MaxServers = 1; Region = 'EastUS'; ScheduledStandbySettings = $NULL } )
$ports = @( @{ Name = 'tcp_port'; Num = 8080; Protocol = 'TCP' }, @{ Name = 'udp_port'; Num = 8081; Protocol
= 'UDP' } )
$gameAssets = @( @{ FileName = 'MyAsset.zip'; MountPath = 'C:\Assets' } )
# All PlayFabMultiplayerApi cmdlets return objects, so we can pass the returned object to ConvertTo-Json for
human readability.
$buildResponse | ConvertTo-Json -depth 5
Sample code below to help deploy builds for Linux game servers.
$vmSize = "Standard_D2as_v4"
$ports = @( @{ Name = 'tcp_port'; Num = 8080; Protocol = 'TCP' }, @{ Name = 'udp_port'; Num = 8081; Protocol
= 'UDP' } )
$regions = @( @{ 'MaxServers' = 1; 'Region' = 'AustraliaEast'; StandbyServers = 1;
'ScheduledStandbySettings' = $NULL } )
$containerImageReference = @{ ImageName = "MyLinuxContainerImage"; Tag = "0.2" }
# All PlayFabMultiplayerApi cmdlets return objects, so we can pass the returned object to ConvertTo-Json for
human readability.
$buildResponse | ConvertTo-Json -depth 5
$sessionId = New-Guid
$serverResponse = Request-PfMultiplayerServer -BuildId $buildResponse.data.BuildId -PreferredRegions
@('EastUS') -SessionId $sessionId
The response to that call includes an IPv4 address and port number that clients can connect to. In the case of
WindowsRunnerCSharp.exe, it hosts a simple webserver so you can browse to the IPv4 address and port
number to get a response:
curl "http://$($serverResponse.data.Ipv4Address):$($serverResponse.data.Ports[0].Num)"
This is the core of PlayFab multiplayer servers: within 3 seconds of your matchmaking service calling
RequestMultiplayerServer, PlayFab will allocate a new server.
These servers come from continuously refilled, standing-by server pools you configure on a per-region and per-
build basis.
Mapping commands
Table belows shows the new equivalent of the old commands. This is a quick mapping to help those who have
used the previous version of the PowerShell module and need to convert their existing commands.
Make sure to read the definition of each command to get full details of the change since some of the arguments
have also changed.
Add-PFMultiplayerAsset New-PfAsset
Add-PFMultiplayerCertificate Invoke-PfUploadCertificate
Enable-PFMultiplayerServer Enable-PfMultiplayerServer
Get-PFMultiplayerAsset Get-PfAssetSummary
Get-PFMultiplayerBuild Get-PfBuild
Get-PFMultiplayerCertificate Get-PfCertificateSummary
Get-PFMultiplayerContainerImages Get-PfContainerImage
Get-PFMultiplayerImageTags Get-PfContainerImageTag
Get-PFMultiplayerQosServer Get-PfQosServer
Get-PFMultiplayerServer Get-PfMultiplayerServer
Get-PFTitleEntityToken deprecated
New-PFMultiplayerBuild New-PfBuild
New-PFMultiplayerServer Request-PfMultiplayerServer
M ULT IP L AY ERP O W ERSH EL L C O M M A N D ( O L D) M P SP O W ERSH EL L A P I M O DUL E ( N EW )
Remove-PFMultiplayerAsset Remove-PfAsset
Remove-PFMultiplayerBuild Remove-PfBuild
Remove-PFMultiplayerCertificate Remove-PfCertificate
Remove-PFMultiplayerContainerImageTag Invoke-PfImageUntagContainer
Set-PFTitle Set-PfTitle
See also
Walkthrough: Deploy builds using PowerShell/API
Deploy a build using Game Manager
Create your first server
Wrapper sample
Samples and resources
Create and deploy Linux container images
5/24/2022 • 6 minutes to read • Edit Online
This topic outlines specific steps to help you create and deploy Linux container images.
As described in Create VMs, you configure VMs to be automatically spinned up as game servers globally
according to your budget and demand when using our service. In order to do so, you do not explicitly create
VMs but define parameters that determine how they get created on your behalf. This process is called deploying
or creating a build.
PlayFab Multiplayer Servers can deploy both Linux-based and Windows-based game servers. The way builds
are deployed for Linux containers are similar to Windows containers with a few important differences. To learn
more, see Windows and Linux container image differences. If you want to use PowerShell/API to manage Linux
containers, see Manage Linux container images using APIs.
When using Linux-based game servers, instead of using a managed container image, you have to create and
upload your container image to a container registry. To make it easy for you to upload containers, your account
comes with a Azure container registry.
Required knowledge
Docker containers
If you wish to use PowerShell/API, call the GetContainerRegistryCredentials API to retrieve a container registry
address, user name, and password.
docker login logs you into the Azure container registry as shown in Game Manager.
username: customer5555555
password: HRDFOdIebJkvBAS+usa55555555
TIP
When using Linux, run pwd to find out which directory you are currently at.
NOTE
You are able to fully customize your game servers whether you are using Windows or Linux container images. When using
Windows servers, you customize the managed container image by uploading assets.
The table below lists some differences when creating and using them.
DEVELO P ER O P T IO N S W IN DO W S L IN UX
Container image Straightforward deployment using our Additional work is needed because you
managed container image. You can still have to create your own custom
customize the container by uploading container image which gives you
additional files as assets. complete control.
1. Deploying/Deployed Regions
Deploying -> Deployed : All regions in Deploying are now in a Deployed state.
Deployed -> Deploying : One or more new regions were configured for the build. The new regions
are in Deploying state.
2. Deploying -> Unhealthy : One or more regions which were in Deploying state are now in Unhealthy
state.
3. Deploying/Deleting Regions
Deployed -> DeletingRegion (rare scenario): Regions which were in Deploying were requested to
be deleted.
DeletingRegion -> Deploying (rare scenario): All regions in Deleting completed deletion, and new
regions were added which are the new regions in Deploying state.
4. Deployed/Deleting Regions
Deployed -> DeletingRegion : One or more regions were requested to be deleted.
DeletingRegion -> Deployed : All regions that were requested to be deleted have been deleted. The
rest of the regions are in Deployed state.
NOTE
Start and Deleted are internal states and are not exposed.
Lifecycle of a multiplayer server build region
5/24/2022 • 2 minutes to read • Edit Online
NOTE
Even though a build region may configured for say 50 standBy servers, a build region will be marked as
Deployed , even if only one game server has reported StandingBy .
Deleting : The region is marked for deletion. All VMs are being de-provisioned.
The transitions between these states are depicted in the following image and described below:
1. Initialized -> Deploying : StandBy servers have been configured to be > 0 . A few VMs are being
provisioned in the region, and the build is being validated on those VMs (propping the assets and ensuring
game server can reach StandingBy state).
2. Deploying -> Deployed : At least one game server in the region has reached a StandingBy state, thus
validating the build (for that region).
3. Deploying -> Unhealthy : One of the following occurred:
All the initial set of VMs (from Step 1 above) are deemed Unhealthy . Some reasons include:
None of the game servers have sent a heartbeat via GSDK for more than 10 minutes after
being started. This usually indicates that the server is crashing, and you will see a
NoSer verHear tbeat health status for each VM in the region.
The PlayFab Multiplayer Agent itself is crashing, or not being initialized on the VM (rare
occurrence). Essentially the multiplayer service has not received a heartbeat from the Agent for
over 10 minutes.
None of the VMs have reached a Running state (mostly stuck in loading assets) for more than 90
minutes.
None of the game servers have reached a StandingBy state for more than 90 minutes (although they
are sending a heartbeat). This indicates an issue during game server initialization.
4. Deploying -> Deleting : This state transition is uncommon, and occurs when the developer requests to
remove a region while it is still deploying.
5. Deployed -> Deleting : The region was removed from the build configuration. Removing a build is
equivalent to removing each region from it (as far as build region status is concerned).
6. Unhealthy -> Deleting : The region was removed from the build configuration. Removing a build is
equivalent to removing each region from it (as far as build region status is concerned).
NOTE
Start and Deleted states are internal to the system and are not exposed.
If the number of standby servers for a region is configured to be 0 , the region will remain in the Initialized state.
In rare unexpected cases (outages), we might see a transition from Deploying to Unhealthy for a brief period.
Lifecycle of a multiplayer server
5/24/2022 • 3 minutes to read • Edit Online
NOTE
For more information on integrating your game server with GSDK, check the docs here.
At a minimum, your game server can integrate GSDK and run great on MPS just by calling the
ReadyForPlayers GSDK method. However, we recommend calling Star t as well when your game server
process starts so MPS is aware that the game server is initializing. Calling Star t is important in the case of a
game server that takes time to start, since MPS will take down the server if it does not receive heartbeats in a
timely manner when the game server starts.
NOTE
A Game server can never transition back to StandingBy state when it is in the Active state. Once the game state is set to
Active, the only way to get a new game server in StandingBy state is if your game server process exits.
NOTE
There is a method call on GSDK that, if used, will mark the game server as Unhealthy. At this time it is ignored by MPS,
but this may change in the future. If this feature is critical for you, please leave a note at the GSDK repository here.
Playfab Multiplayers Servers managed Windows containers undergo a methodical OS patch update process to
ensure game servers are operating with the latest security updates. Each month, Azure Compute certifies a
Windows OS image that is integrated into Multiplayer Servers for developers to choose from the "Windows
Server Core Preview" toggle during the build creation process. Developers are encouraged to test their non-
production game servers built with the "Windows Server Core Preview" option.
After 30 days, Multiplayer Servers will migrate the Windows Server Core Preview to the Windows Server Core
image option - signaling a PlayFab approved OS image for production readiness. This process will repeat every
30 days, cycling an OS preview image to its mainline OS core image. If a game server built with OS core version
that doesn’t match PlayFab’s OS core version, PlayFab will auto-update your game build server with the latest
mainline OS core image. This process is applied automatically with no build changes required by the developer.
Best Practices
1. Developers are encouraged to create and test their non-production game server builds with the OS preview
image option.
2. Developers with a mature build and continuous integration & deployment process should take into
consideration that OS image updates cycle every 30 days
Constraints
1. The patch update process occurs monthly
2. Developers cannot opt out of the monthly OS patch level updates
3. The patch update process is only applicable to Windows managed containers and does not apply to custom
containers or Linux.
NOTE
Game server builds are immutable once created. Therefore, developers cannot toggle between OS image preview and
OS image core.
A game server operating in production will be auto-updated to the latest OS core image version if the version that the
build was made is older than the latest. This will be applied automatically for any new multiplayer server allocation
request only.
Managing a build alias and allocating to it
5/24/2022 • 4 minutes to read • Edit Online
A build alias is a management layer on top of builds, which allows calls to RequestMultiplayerServer to be
distributed over multiple builds in a controlled fashion. This can improve the simplicity and reliability of build to
build upgrades and several other scenarios listed below. Aliases achieve this by specifying a list of build ids
along with the weight of each one. The weight represents the ratio of allocation calls that should be forwarded
to the corresponding build.
Safe deployment that is backwards compatible
This is the most common scenario for a build to build upgrade, where you are updating the game server and
retail clients are compatible with both servers.
Clients will reference Alias 1, which would have the following configuration:
Build 1: Weight = 1
Once Build 2 is created, Alias 1 will be changed to be:
Build 1: Weight = 8
Build 2: Weight = 2
You can gradually change the weights until all new server requests are fulfilled by Build 2. At this point the
weight for Build 1 is 0 and can be removed from the alias.
A typical use case for an alias is affinitizing them to a client compatibility version and game mode. For example
"DeathMatch client 2.2 RETAIL." Aliases allow you to manage this higher-level abstraction while continuously
updating the builds that power this experience. Aliases also make it easier for you to roll-back builds if
necessary.
Deployment that is not backwards compatible
In this case you want to update the game server at the same time you are updating game clients, as your current
game clients are not compatible with the old server build. Transitioning from one build to another would be
done as follows:
Old clients will reference Alias 1, which would have the following:
Build 1: Weight = 1
Once Build 2 is created, new clients will reference Alias 2, which would have the following:
Build 2: Weight = 1
In this scenario aliases are used similarly to builds, and their multiplexing functionality is not used.
Blast deployment that is backwards compatible
This is similar to the backwards compatible build to build upgrade scenario, but with a more sudden switch in
demand behavior. Transitioning from one build to another would be done as follows:
Clients will reference Alias 1, which would have the following:
Build 1: Weight = 1
Once Build 2 is created, Alias 1 will be changed to be:
Build 1: Weight = 0
Build 2: Weight = 1
Testing a deployment that is backwards compatible
When you want to update the game server, and the client version is compatible with both servers, but you wants
to test the second version before deploying it at scale for all players. Testing and transitioning from one build to
another could be done as follows:
Clients will reference Alias 1, which would have the following:
Build 1: Weight = 1
Once Build 2 is created. Testing clients would reference Alias 2, which would have the following:
Build 2: Weight = 1
Once Build 2 is verified. Alias 1 will be changed to be:
Build 1: Weight = 8
Build 2: Weight = 2
Gradually build 2 would be weighted more and absorb all traffic.
POST https://titleId.playfabapi.com/MultiplayerServer/CreateBuildAlias
Sample body:
{
"AliasName":"TestingAlias",
"BuildSelectionCriteria":
[{
"BuildWeightDistribution":{"9a8a4584-c81a-479c-9ef9-16d3743f7ca7":"1"}
}]
}
Sample response:
{
"AliasId":"97d2b0a5-7c04-4593-8451-66bbb97f94b6",
"AliasName":"TestingAlias",
"BuildSelectionCriteria":
[{
"BuildWeightDistribution":{"9a8a4584-c81a-479c-9ef9-16d3743f7ca7":"1"}
}]
}
POST https://titleId.playfabapi.com/MultiplayerServer/UpdateBuildAlias
Sample body:
{
"AliasId":"97d2b0a5-7c04-4593-8451-66bbb97f94b6",
"AliasName":"TestingAliasRenamed",
"BuildSelectionCriteria":
[{
"BuildWeightDistribution":{"9a8a4584-c81a-479c-9ef9-16d3743f7ca7":"1",
"7ac7f347-3d61-9fe9-c974-a18c4854a8a9":"1"}
}]
}
Sample response:
{
"AliasId":"97d2b0a5-7c04-4593-8451-66bbb97f94b6",
"AliasName":"TestingAliasRenamed",
"BuildSelectionCriteria":
[{
"BuildWeightDistribution":{"9a8a4584-c81a-479c-9ef9-16d3743f7ca7":"1",
"7ac7f347-3d61-9fe9-c974-a18c4854a8a9":"1"}
}]
}
POST https://titleId.playfabapi.com/MultiplayerServer/DeleteBuildAlias
Sample body:
{
"AliasId":"97d2b0a5-7c04-4593-8451-66bbb97f94b6"
}
GET https://titleId.playfabapi.com/MultiplayerServer/ListBuildAliases
Sample response:
[{
"AliasId":"97d2b0a5-7c04-4593-8451-66bbb97f94b6",
"AliasName":"TestingAliasRenamed",
"BuildSelectionCriteria":
[{
"BuildWeightDistribution":{"9a8a4584-c81a-479c-9ef9-16d3743f7ca7":"1",
"7ac7f347-3d61-9fe9-c974-a18c4854a8a9":"1"}
}]
}]
POST https://titleId.playfabapi.com/MultiplayerServer/RequestMultiplayerServer
Sample body:
{
"SessionId":"6a07440c-7bcc-4e23-8b81-4934543ff966",
"PreferredRegions":["SouthCentralUs"],
"BuildAliasParams":
{"AliasId":"97d2b0a5-7c04-4593-8451-66bbb97f94b6"}
}
Archiving and retrieving multiplayer server logs
5/24/2022 • 2 minutes to read • Edit Online
In several scenarios, you may want to keep logs or other arbitrary file content from your game servers for later
analysis.
There are two ways you can gather your logs either through the Game Server SDK or Game Manager. The SDK
provides an API that allows you to write to a log file or access a logging directory.
See Integrating game servers with the PlayFab game server SDK (GSDK) to learn more about these logging
mechanisms. To programmatically gather your logs, use the ListArchivedMultiplayerServers method. The result
will give you the information for the servers, next you'll need to call GetMultiplayerServerLogs method with the
Server ID as the input.
Archived Ser vers is the vehicle for retrieving these logs after the game server has terminated. These logs are
kept for 28 days after the termination of your game server.
To do this using Game Manager first, go to the Builds page in the Multiplayer tab , and select the build that is
associated to the server you're looking for.
Next, select the Ser vers tab located at the top and you'll see a list of VM's and servers, select the Archived
ser vers link at the bottom
Use the Search bar at the top of the page and use either the Host ID or VM ID to download logs for a specific
server.
VM Metrics (preview)
5/24/2022 • 4 minutes to read • Edit Online
Introduction
Game developers sometimes need access to system level metrics (CPU/RAM/etc.) for the Virtual Machines that
are created as part of their Builds. These metrics can provide unique insights to the game developer during the
development of their multiplayer game server. Given these metrics, a game developer can make informed
decision about utilizing VM resources.
Performance metrics can support various development scenarios:
1. Using CPU and memory utilization data to measure the resource needs of multiplayer servers, so game
developer can properly calculate the optimal number of game servers on a specific Virtual Machine SKU
(type)
2. Using network counters to detect an irregular network environment, such as attempted DDoS attacks or
other network congestion
PlayFab Multiplayer Servers service supports a limited number of system metrics via the VM Metrics (preview)
feature.
IMPORTANT
This feature is currently experimental and offered as a preview. This means that parts of it can change at any time. We are
significantly iterating on the experience and asking customers for feedback.
Usage
VM metrics for a Build can be enabled in two ways, depending on how a Build is created:
1. Using Game Manager, you can enable the "Virtual machine metrics preview" checkbox on the "New Build"
Game Manager page.
2. Using the PlayFab Multiplayer Servers API, you can set the property "IsEnabled" to true in the following API
objects:
InstrumentationConfiguration in the CreateBuildWithManagedContainer API call for a Windows Build with
containers
InstrumentationConfiguration in the CreateBuildWithProcessBasedServer API call for a process-based
Windows Build
LinuxInstrumentationConfiguration in the CreateBuildWithCustomContainer API call for a Linux Build
When VM metrics feature is enabled for a Build, it will remain enabled for the entire lifetime of the Build. You
can't enable/disable VM metrics for a Build after it has been created.
Windows
On Windows, VM metrics collection is a feature of the existing PlayFab container/process orchestrator called
VmAgent . VmAgent periodically (every 10 seconds) runs a task that will query the following system performance
counters:
1. Available MBytes
2. % Processor Time
3. % User Time
4. Disk Reads/sec (for drive D:)
5. Disk Writes/sec (for drive D:)
6. Bytes Received/sec
7. Bytes Sent/sec
Collected counter values are sent to our internal metrics collector running on the VM. The collector aggregates
and sends them to our internal backend so they can be presented to the user on Game Manager.
Linux
On Linux, we're using the open-source telegraf agent for collecting and processing metrics. Telegraf collects
metrics every 10 seconds and emits them to our internal collector agent every 60 seconds. For reference, below
you can see the contents of the telegraf.conf configuration file we're using, feel free to consult the official telegraf
docs for further details.
We're also using an internal utility called telegraf-geneva-processor that emits the diff value for counter level
metrics (like net_bytes_recv) metric. Emitting the diff value instead of the actual counter value results in better
visualization in the provided Game Manager graphs.
[agent]
interval = "10s"
round_interval = true
metric_batch_size = 1000
metric_buffer_limit = 10000
collection_jitter = "0s"
flush_interval = "60s"
flush_jitter = "0s"
precision = ""
debug = false
omit_hostname = true
[global_tags]
titleID = "TITLE_ID"
buildID = "BUILD_ID"
vmID = "VM_ID"
[[inputs.mem]] # https://www.linuxatemyram.com/
fieldpass = ["available_percent"]
name_prefix = "telegraf_"
[[inputs.net]] # /proc/net/dev
fieldpass = ["bytes_sent", "bytes_recv"]
name_prefix = "telegraf_"
interfaces = ["eth0"]
tagexclude = ["interface"]
# https://github.com/influxdata/telegraf/tree/master/plugins/inputs/diskio
[[inputs.diskio]] # /proc/diskstats
fieldpass = ["reads", "writes"] # number of reads and writes on sdb device
devices = ["sdb"] # sdb device contains everything (including container storage) apart from /mnt
name_prefix = "telegraf_" # which is the place where some of our shared folders are
# grab the allocated percentage from VmAgent. Be aware that this must be in influx format
[[inputs.http]]
urls = ["http://localhost:56001/v1/metrics/allocatedpercentage"]
name_prefix = "telegraf_"
data_format = "influx"
tagexclude = ["url"]
[[processors.execd]]
command = [
"/usr/bin/telegraf-geneva-processor",
"-configFile=/etc/telegraf/telegraf.geneva.processor.conf"
]
This telegraf.conf configuration enables the telegraf agent to collect the below metrics:
1. cpu_usage_system
2. cpu_usage_user
3. memory_available_percent
4. net_bytes_recv_diff (network bytes received for eth0)
5. net_bytes_sent_diff (network bytes sent for eth0)
6. diskio_reads_diff (number of reads for sdb)
7. diskio_writes_diff (number of writes for sdb)
Similar to Windows, telegraf sends the collected counter values to our internal metrics collector. The collector
aggregates and sends these values to our internal backend so they can be presented to the user on Game
Manager.
Allocation Percentage
In both Windows and Linux VMs, we're emitting a metric called Allocation Percentage. The value of this metric is
calculated by dividing the number of Active servers with the Total number of servers on the VM. This metric is
meant to be used when evaluating and interpreting the reported system metric values. This is because the value
of the system metrics will probably be different on a VM with lots of Active servers compared to a VM with lots
of StandingBy servers.
Viewing VM metrics
When you enable the VM metrics feature for a new Build, metrics will be emitted as soon as the Build is
successfully deployed. You can use the "Virtual Machines" (https://developer.playfab.com/en-
US/<YOUR_TITLE_ID>/multiplayer/server/virtual-machines) page on Game Manager to get a link to display VM
metrics for a specified VM.
You can also access the VM metrics by selecting your build, going to the servers tab, and hitting the menu inline
with the VM you would like to see the metrics on, and select "View Metrics"
Prerequisites
1. Game Server integrated with GSDK.
GSDK facilitates two-way communication between your game server process and the MPS service. To
learn how to integrate game servers with GSDK, see this article. The tutorial uses the Wrapper sample on
GitHub. The Wrapper sample includes a fake game and GSDK. To download the sample, see PlayFab
Wrapper Sample.
2. LocalMultiplayerAgent (LMA) toolset.
Download the latest release and extract it to the desired folder. (such as C:\PlayFabVmAgent)
3. [Optional] Install Docker Desktop on Windows.
LMA can debug Linux/Windows container game servers using Docker for Windows. You can skip this
part if you want to run your game server as a process (run executable game server) instead of a
container.
Next steps
Run LocalMultiplayerAgent in Process Mode
In Process mode, LMA will run an executable game server and directly communicate with it without the
need to set up Docker.
Container knowledge isn't required - you don't need to create any program that runs in a container.
Run LocalMultiplayerAgent in Container Mode
In Container mode, LMA will run and test a game server running in a [Windows/Linux]container.
How to run a game server using
LocalMultiplayerAgent in Process mode
5/24/2022 • 4 minutes to read • Edit Online
Configure MultiplayerSettings.json
Navigate to the folder where you extracted the LMA toolset and open the MultiplayerSettings.json file. This file is
a build configuration mock file that simulates the build on MPS.
You can populate json using LMA MultiplayerSettings.json Generator. The Generator is a simple web page that
creates json based on your options. You can find the Generator under extracted folder of LMA.
Here's the example of MultiplayerSettings.json for Wrapper sample to run LMA in Process mode.
{
"RunContainer": false, // Set RunContainer to false if you are running LMA in Process mode.
"OutputFolder": "C:\\output\\WindowProcess", // Path where config files and logs will be generated from
LMA at each run
"NumHeartBeatsForActivateResponse": 10, // default value
"NumHeartBeatsForTerminateResponse": 60, // default value
//the server will run in stand-by mode for 10 heartbeats and stay in active state for 35 heartbeats.
"TitleId": "59F84", // default value
"BuildId": "8624d52e-87a1-4a12-b7f6-b92720ef8919", // default value
"Region": "EastUs", // default value
"AgentListeningPort": 56001, // default value
"AssetDetails": [
{
"MountPath": "", // Mount Path is only required for Container mode. leave it as blank.
"SasTokens": null,
"LocalFilePath": "D:\\gameassets.zip" // where your game server is located as an archive format.
}
],
"ProcessStartParameters": {
"StartGameCommand": "wrapper.exe -g fakegame.exe arg1 arg2"
// shell command to run Wrapper. Command will be executed where game asset is extracted.
// Make sure the StartGameCommand provided above is an example of the Wrapper sample.
},
"PortMappingsList": [
[
{
"NodePort": 56100, // default value
"GamePort": {
"Name": "game_port",
// Port name is already defined in the Wrapper sample. Wrapper will grab the port information
using game_port via GSDK while it's running.
"Protocol": "TCP"
}
}
]
],
}
Make sure to update the following fields correctly in the MultiplayerSettings.json to run LMA in Process mode.
LocalFilePath- Full Local Path (on your workstation) to the game server asset zip file created earlier, for
example: D:\MyAmazingGame\asset.zip (note that backslashes need to be escaped for JSON formatting).
StartGameCommand - The StartGameCommand path for a process is a relative path. The working directory
will be where your game asset is extracted.
PortMappingsList - These are the ports that are available to your game while running.
NodePort is the port that is opened on your workstation
GamePort.Number isn't required for Process mode. Port number will be bound to Node Port via
GSDK when your game server is running. In the real scenario, MPS will bind the port dynamically
for each Process-based game session.
Set the GamePort.Name to the same value as defined in your game server. You can check the GSDK
config at runtime for the value with the key GamePort.Name. If you're using the Wrapper Sample,
port name is already defined to "game_port", so you should set the same value here.
GamePort.Protocol - Specify protocol type: TCP or UDP
OutputFolder - Path to a drive or folder where the outputs and config files are generated. Ensure that
there's sufficient space available since the game server will be extracted under this path. If not specified,
the agent folder is used.
AgentListeningPort - This is the port for the LMA to communicate with the game server. Any open port
will work, 56001 is a default value. If you have another process binding to 56001, you must change this
value or kill the other process on port 56001.
ResourceLimits - not required for Process mode.
MountPath - not required for Process mode.
SessionCookie (optional) - Any session cookie that is passed to your game server as part of the
RequestMultiplayerServer API call. In the real scenario on MPS, after the connection is established, server
will notify the client to load corresponding resources from SessionCookie.
Run LocalMultiplayerAgent
Now you're ready to run LocalMultiplayerAgent.
In a PowerShell window :
Navigate to directory under LMA that contains LocalMultiplayerAgent.exe.
Run LocalMultiplayerAgent.exe . At this point, LMA sets up the http listener, unzips the game asset, and
starts the game server in a separate process.
If you are running your game server as a Process, the Windows Firewall may pop-up and ask if you
want to allow traffic to the NodePort you specified. If you want to avoid that, you can either run the
LocalMultiplayerAgent in admin mode or enable the port in the firewall.
LMA will wait for heartbeats from the GSDK integrated with your game server. If the GSDK is integrated
correctly, LMA prints the outputs as following order:
1. CurrentGameState - Initializing
(This may not show up if your game server directly calls GSDK::ReadyForPlayers and doesn't call GSDK::Start)
2. CurrentGameState - StandingBy
3. CurrentGameState - Active
4. CurrentGameState - Terminating
To learn more about states of a game server, see What is Game Server Lifecycle of PlayFab Multiplayer Server.
If the shutdown callbacks are set up correctly, your game server exits soon after the state is set to terminating.
It's important to verify that the game server exits to avoid ungraceful shutdowns on the PlayFab platform.
The LMA should also terminate along with the game.
Configure MultiplayerSettings.json
Navigate to the folder where you extracted the LMA toolset and open the MultiplayerSettings.json file. This file is
a build configuration mock file that simulates the build on MPS.
You can also populate a json using LMA MultiplayerSettings.json Generator. The Generator is a simple web page
that creates a json based on your options. You can find the Generator under
LocalMultiplayerAgent/SettingsJsonGenerator.
Here's the example of MultiplayerSettings.Json to run the Wrapper sample as Linux Container .
{
"RunContainer": true, // Set RunContainer to true if you are running LMA in Container mode.
"OutputFolder": "C:\\output\\LMAContainer", // Path where config files and logs will be generated from
LMA at each run
"NumHeartBeatsForActivateResponse": 10,
"NumHeartBeatsForTerminateResponse": 60,
"TitleId": "", // default value
"BuildId": "00000000-0000-0000-0000-000000000000", // default value
"Region": "59F84", // default value
"AgentListeningPort": 56001, // default value
"ContainerStartParameters": {
/// replace ImageDetails fields to your own images saved on ACR.
"ImageDetails": {
"Registry": "mydockerregistry.io",
"ImageName": "wrapper",
"ImageTag": "0.1",
"Username": "",
"Password": ""
}
},
"PortMappingsList": [
[
{
"NodePort": 56100,
"GamePort": {
"Name": "game_port",
// The same value of GamePort Name should be also defined in the Wrapper so Wrapper can
get a port information while it's running.
"Number": 80,
"Protocol": "TCP"
}
}
]
],
}
For Windows Container , you don't need to build your container. LMA will package your game server as Windows
Container. You just need to specify the Windows container base image in ImageDetails field and set
LocalFilePath to where your game asset is located on your work station.
"AssetDetails": [
{
"MountPath": "C:\\Assets",
// Mount Path should be "C:\\Assets" for Windows Container.
"LocalFilePath": "D:\\gameassets.zip"
// where your game server is located as an archive format.
}
]
"ContainerStartParameters": {
"StartGameCommand": "C:\\Assets\\wrapper.exe -g C:\\Assets\\fakegame.exe arg1 arg2",
// Your game assets will be extracted under C:\\Assets (default mount path for Windows Container) and
LMA will run your game server with StartGameCommand argument.
// Make sure the StartGameCommand provided above is an example of the Wrapper sample.
"ImageDetails": {
"Registry": "mcr.microsoft.com",
"ImageName": "playfab/multiplayer",
"ImageTag": "wsc-10.0.17763.973.1",
"Username": "",
"Password": ""
// username and password are not required to use MCR image.
}
// LMA will package an existing game sample (path defined in LocalFilePath) as a Windows container.
}
Make sure to update the following fields correctly in the MultiplayerSettings.json to run LMA in Container mode.
LocalFilePath - Full Local Path (on your workstation) to the game server asset zip file created earlier, for
example: D:\gameassets.zip (note that backslashes need to be escaped for JSON formatting). This field is
required for Windows Container as LMA needs to locate your game asset and then package it into a
container.
PortMappingsList - These are the ports that are available to your game while running.
NodePort is the port that is opened on your workstation and will be mapped to the GamePort.
GamePort.Number is the port that your game server needs to bind to when running in a container. For
example, here we set port number as 80 which fakegame.exe will be listening to.
Set the GamePort.Name to the same value as defined in your game server. You can check the GSDK
config at runtime for the value with the key GamePort.Name.
GamePort.Protocol - Specify protocol type: TCP or UDP
Update the GamePort section to match the protocol and port at which your game server is listening for
clients. You can add multiple ports.
ForcePullFromAcrOnLinuxContainersOnWindows- Set true when you want to pull Linux Container Image
from Docker Registry and avoid pulling from the local registry. In most cases, you'd want this set to false.
ContainerStartParameters.ImageDetails - Your game server image can be published on a container
registry or can be locally built. If you want to pull Linux Container image from Docker Registry (For
example, Azure Registry), you need to set value for username and password and set
ForcePullFromAcrOnLinuxContainersOnWindows as true. For Windows Container, username and password
aren't required.
OutputFolder - Path to a drive or folder where the outputs and config files are generated. Ensure that
there's sufficient space available since the game server will be extracted under this path. If not specified,
the agent folder is used.
AgentListeningPort - This is the port for the LMA to communicate with the game server. Any open port
will work, 56001 is a default value. If you have another process binding to 56001, you must change this
value or kill the other process on port 56001.
ResourceLimits (optional) - If specified, docker limits CPU/memory usage. Warning: If your server goes
over the allowed memory, it's killed. ResourceLimits can only be specified in container mode.
SessionCookie (optional) - Any session cookie that is passed to your game server as part of the
RequestMultiplayerServer API call. In the real scenario on MPS, after the connection is established, server
will notify the client to load corresponding resources from SessionCookie.
Docker set up
Run PowerShell scripts to set up the docker networks called "PlayFab" and add firewall rules to communicate
with LocalMultiplayerAgent.
For Linux Container, Run SetupLinuxContainersOnWindows.ps1 .
For Windows Container, Run Setup.ps1 . It will pull down the PlayFab docker image from Microsoft/PlayFab-
Multiplayer.
Note that the first time the script runs, it can take a few minutes to download the container image.
To run this setup successfully, you may have to configure the firewall of any 3rd party antivirus
program that you have installed.
To learn how target the correct docker daemon between Windows and Linux containers, see How to switch
Docker to use Windows/Linux Container
Run LocalMultiplayerAgent
In a PowerShell window :
Navigate to directory under LMA that contains LocalMultiplayerAgent.exe.
Run LocalMultiplayerAgent.exe for Windows Container.
Run LocalMultiplayerAgent.exe -lcow for Linux Container.
(lcow stands for Linux Containers On Windows)
At this point, LMA sets up the http listener and run a container. You can run docker ps command to see
running containers on your machine.
LMA will wait for heartbeats from the GSDK integrated with your game server. If the GSDK is integrated
correctly, LMA prints the outputs as following order:
1. CurrentGameState - Initializing
(This may not show up if your game server directly calls GSDK::ReadyForPlayers and doesn't call GSDK::Start)
2. CurrentGameState - StandingBy
3. CurrentGameState - Active
4. CurrentGameState - Terminating
To learn more about states of a game server, see What is Game Server Lifecycle of PlayFab Multiplayer Server.
If the shutdown callbacks are set up correctly, your game server exits soon after the state is set to terminating.
It's important to verify that the game server exits to avoid ungraceful shutdowns on the PlayFab platform.
The LMA should also terminate along with the game.
Many debugging tasks of PlayFab Multiplayer Servers can be done locally using LocalMultiplayerAgent.
However, sometimes the behavior of the game server can differ between the local environment and the actual
service so you would like to connect directly to debug a running server because it is marked as unhealthy or not
performing as expected.
In order to connect to the VM hosting your game server (either Windows or Linux), you can get Remote Desktop
(RDP)/SSH credentials using the "Connect" button on playfab.com web application. You can see this button on
the "Virtual Machines" page on your Multiplayer Build) or using CreateRemoteUser API call.
As soon as you connect to the VM, you can use the console of the operating system to monitor your game
servers. MPS service uses Docker containers to spin up game server processes. To run Docker CLI commands,
you'll need an admin powershell on Windows and sudo su - on Linux.
IMPORTANT
These are advanced Docker container debugging instructions. Using these instructions may break your game servers. We
do not recommend using these commands on containers running your production game servers.
We strongly advise you not to take any dependency on behavior or information you see while debugging the containers.
Only publicly documented APIs and behavior are supported, other things can change without notice.
In this case, port 30000 on the VM is mapped onto 3600 on the container for TCP whereas 30001 on the VM is
mapped on 3601 on the container for UDP. For more information, see Docker networking.
NOTE
In both Windows and Linux, Docker containers are part of the "playfab" Docker network. You can do docker inspect
network playfab to see information about the network.
How can I see runtime details for a container?
Once you do docker ps you can grab the container name or hash and do docker inspect <nameOrHash> .
You will see lots of information, like the state of the container, the volume binding on the host VM, port bindings,
environment variables passed into the container and more.
How can I get the logs of my game server?
You can use the command docker logs <nameOrHash>. These logs contain everything your app sends to
standard output/standard error streams. Bear in mind that these logs exist only for existing containers. If your
game server crashes, our monitoring process in the VM will delete this container and create a new one.
Consequently, it's a better practice to use GSDK to log from inside your game server. To learn more, see Logging
with GSDK and Archiving and retrieving multiplayer server logs to access the logs from terminated game
servers.
Can I connect "inside" a running container to see what's going on?
Yup! You can do docker exec -it <nameOrHash> powershell on Windows and docker exec -it <nameOrHash>
bash on Linux. There, you get access to a command line process in the container where you can issue native
commands to debug/diagnose issues.
For this command to work on Linux, Bash shell must be installed in your base container. If it isn't, you can use
Bourne shell by running docker exec -it <nameOrHash> sh .
How can I see the ports that are open on my container?
Once you are connected "inside" the container, you can use netstat -ano on Windows and netstat -tulpn on
Linux when you have a command line process inside your container (check the previous instruction).
If this command doesn't work on Linux, try installing netstat by apt update && apt install net-tools . On
Linux, you can use nestatst -tulpn inside the VM to see that the ports are indeed open. Recall that VM ports
will be different than container ports, you can see this port mapping with docker ps for your containers.
Debugging steps
Check PF_ConsoleLogs.txt for any useful error message
Check if your .zip asset package contains all the required DLLs for your game. For instructions, see
Determining required DLLs.
Check the Windows Event log to see if there's any useful information about Docker failures
On LocalMultiplayerAgent, I am not getting any heartbeats
There might be some leftover containers from previous attempts. You can use docker ps -a to see all
containers and docker rm -f <containerNameOrTag> to delete them.
On Windows, how can I monitor TCP and UDP packets?
Consider using a tool like Wireshark (external link) utility.
How can I debug a deployed multiplayer server using Visual Studio?
For instructions, see Using Visual Studio to debug servers
See also
Locally debugging game servers
Locally debugging game servers and integration
with PlayFab
5/24/2022 • 9 minutes to read • Edit Online
Overview
PlayFab multiplayer game servers require integration with PlayFab Game Server SDK (GSDK). In addition, game
servers are run as containerized applications on the PlayFab Multiplayer platform.
Running them as containerized applications enables running and debugging the server locally, in an
environment that matches that of the PlayFab platform in Azure. This facilitates faster development iterations.
This article helps you verify that your PlayFab game server conforms to the platform requirements.
The PlayFab local debugging toolset includes LocalMultiplayerAgent that provides mock responses to the GSDK
and verifies whether your game server is integrated with the GSDK correctly. With the mock responses, the
VmAgent cycles the game server through various states in its lifecycle on the PlayFab Multiplayer platform.
You can configure the agent to run the game server as a containerized application and verify that your game
server is packaged with all the required dependencies and will run without issues on the PlayFab Multiplayer
platform. LocalMultiplayerAgent can work with either Windows or Linux game servers.
NOTE
Avoid this common mistake - do not accidentally zip a folder within a folder in the zip. After zipping, browse the
zip folder and double-check that your compression software did not add an extra layer of file hierarchy.
Download the local debugging toolset and extract it to a folder of your choice (such as
C:\PlayFabVmAgent).
While inspecting the: LocalMultiplayerAgent MultiplayerSettings.json Generator json file, read more
about the following options below.
Navigate to the location of the extracted folder and open the MultiplayerSettings.json file in a text editor
(such as Visual Studio Code). Update the following properties:
LocalFilePath - Full Local Path (on your workstation) to the game server asset zip file created earlier,
for example: D:\\MyAmazingGame\\asset.zip (note that backslashes need to be escaped for JSON
formatting).
StartGameCommand - The full path to the game server executable within the container. For example, if
the name of the executable is mygame.exe, a sample path would be C:\\Assets\\mygame.exe. The
paths for the StartGameCommand are different for a Process and a Container. The
StartGameCommand path for a container is an absolute path to a resource in the container or asset
folder. The StartGameCommand path for a process is a relative path where the working directory will
be the first asset specified.
PortMappingsList - These are the ports that are available to your game while running. NodePort is the
port that is opened on your workstation, GamePort.Number is the port that your game server needs to
bind to when running in a container. Update the GamePort section to match the protocol and port at
which your game server is listening for clients. If your game server needs multiple ports, copy/paste
the existing port configuration and increment NodePort then update GamePort.Number and
GamePort.Name to the required port. When running as a process, GamePort.Number is ignored, your
process should bind to NodePort. To handle both cases, do one of the following:
Set the ports to the same value
Check the GSDK config at runtime for the value with the key GamePort.Name which always
returns the correct port to bind against.
There are additional fields in the MultiplayerSettings.json file you might want to edit:
ResourceLimits (optional) - If specified, docker limits CPU/memory usage. Warning: If your server
goes over the allowed memory, it is killed. ResourceLimits can only be specified in container mode.
SessionCookie (optional) - Any session cookie that is passed to your game server as part of the
RequestMultiplayerServer API call.
OutputFolder (optional) - Path to a drive or folder where the outputs and config files are generated.
Ensure that there is sufficient space available since the game server will be extracted under this path. If
not specified, the agent folder is used.
MountPath - The path within the container at which to mount the asset. This field does not need to be
specified when running in process mode. We recommend using the sample value - C:\\Assets (note
that backslashes need to be escaped for JSON formatting).
AgentListeningPort - Specifies the port to which the agent binds to communicate with the game
server. Any open port will work, if you have another process binding to 56001 you must change this
value (or kill the other process).
Verifying containerization
If you are new to the container world, you can check an intro here.
Prerequisites
Windows 10 Pro (or above) with April 2018 (1803) update.
Download Docker. Alternately, you can download it from the main page of the Docker website.
Setup
Ensure that Docker is set to use Windows Containers
In a Powershell window (as Administrator):
Navigate to the folder where the toolset was extracted.
Run Setup.ps1 which sets up the docker networks, add firewall rules to communicate with
LocalMultiplayerAgent , and pull down the PlayFab docker image from Microsoft/PlayFab-
Multiplayer. Note that the first time the script runs, it can take a few minutes to download the
container image.
NOTE
To run this setup successfully, you may have to configure the firewall of any 3rd party antivirus program
(such as McAfee, Norton, or Avira) that you have installed.
{
"RunContainer": true,
"OutputFolder": "C:\\output\\UnityServerLinux",
"NumHeartBeatsForActivateResponse": 10,
"NumHeartBeatsForTerminateResponse": 60,
"TitleId": "",
"BuildId": "00000000-0000-0000-0000-000000000000",
"Region": "WestUs",
"AgentListeningPort": 56001,
"ContainerStartParameters": {
"ImageDetails": {
"Registry": "mydockerregistry.io",
"ImageName": "mygame",
"ImageTag": "0.1",
"Username": "",
"Password": ""
}
},
"PortMappingsList": [
[
{
"NodePort": 56100,
"GamePort": {
"Name": "game_port",
"Number": 7777,
"Protocol": "TCP"
}
}
]
],
"SessionConfig": {
"SessionId": "ba67d671-512a-4e7d-a38c-2329ce181946",
"SessionCookie": null,
"InitialPlayers": [ "Player1", "Player2" ]
}
}
Some notes:
1. You must set RunContainer to true. This is required for Linux game servers.
2. Modify imageDetails with your game server docker image details. Image may be built locally (using
docker build command) or be hosted in a remote container registry.
3. StartGameCommand and AssetDetails are optional. You don't normally use them when you use a Docker
container since all game assets + start game server command can be packaged in the corresponding
Dockerfile
4. Last, but definitely not least, pay attention to the casing on your OutputFolder variable, since Linux
containers are case sensitive. If casing is wrong, you might see a Docker exception similar to error while
creating mount source path '/host_mnt/c/output/UnityServerLinux/PlayFabVmAgentOutput/2020-01-
30T12-47-09/GameLogs/a94cfbb5-95a4-480f-a4af-749c2d9cf04b': mkdir /host_mnt/c/output: file exists
After you perform all the previous steps, you can then run the LocalMultiPlayerAgent with the command
LocalMultiplayerAgent.exe -lcow (lcow stands for Linux Containers On Windows)
Troubleshooting
In container mode, if your game server exits immediately with an error similar to "Container ... exited with
exit code 1", but it works fine in process mode, make sure that you have included all required system DLLs in
your asset package.
All logs are located under OutputFolder that is specified in the MultiplayerSettings.json file.
LocalMultiplayerAgent creates a new folder each time it is started, with the timestamp as folder name. All
game server logs emitted via GSDK are located within the GameLogs folder.
If the game server is running in a container, there might be an additional level of directory hierarchy to sift
through.
The GSDK writes debug logs to the GameLogs folder. These logs are located within the GameLogs folder
along with the logs output by the game server.
Ensure firewalls (windows and other anti-virus) are configured to allow the traffic over the ports.
If you get an error similar to:
Docker API responded with status code=InternalServerError, response={"message":"failed to create endpoint
<container_name> on network playfab: hnsCall failed in Win32: The specified port already exists". It is
likely there is already a container running on the specified port.
This can happen if LocalMultiplayerAgent exits prematurely. Use the command docker ps to find the
container that is running, and then kill it using docker kill <container_name> .
If you get an error that contains Failed to find network 'playfab' . Try rerunning Setup.ps1
Known Limitations
1. Containers might not terminate at the end of the debugging. If this occurs, run the following PowerShell
commands as Administrator. These commands stop and remove all containers, including those were not
started by LocalMultiplayerAgent .
This article will cover how to enable automatic crash dump collection for servers. We currently don't support
this feature in the UI or through PowerShell.
NOTE
This functionality is only available for windows container servers. We do not currently have a way for linux or Windows
process based servers.
To enable automatic crash dump collection, you can use CreateBuildWithManagedContainer api as shown below.
To learn more about the CreateBuildwithManagedContainer see Multiplayer Server - CreateBuild With Managed
Container In the JSON, you can add in a new field called "WindowsCrashDumpConfiguration" to the request
body that will enable crash dumps.
"BuildName": "crashDumpTest",
"ContainerFlavor": "ManagedWindowsServerCore",
"MultiplayerServerCountPerVm": 1,
"Ports": [
{
"Name": "PortName",
"Num": 1243,
"Protocol": "TCP"
}
],
"RegionConfigurations": [
{
"Region": "EastUs",
"MaxServers": 1,
"StandbyServers": 1
}
],
"StartMultiplayerServerCommand": "C:\\Assets\\CrashingServerExample.exe sizeMiB:10",
"UseStreamingForAssetDownloads": false,
"GameAssetReferences": [
{
"FileName": "CrashingServerExample_v1_0.zip",
"MountPath": "C:\\Assets"
}
],
"VmSize": "Standard_D2_v2",
"WindowsCrashDumpConfiguration": {
"IsEnabled": true,
"DumpType": 0,
"CustomDumpFlags": 6693
}
}
NOTE
Once you enable this your DumpType and CustomDumpFlag values will get put into the registry keys. To learn more read
Collecting User mode dumps
Once a server has crashed and logs have been created a PlayStream notification will give you a server ID. After
you get the server ID, you can search for it under the archived servers page. Navigate to the Archived servers
page and paste into the search bar the server ID you were given. Download the logs for the affected server and
you'll see your crash dump files. To learn more, read Archiving and retrieving multiplayer server logs
Attaching a Profiler
5/24/2022 • 2 minutes to read • Edit Online
This article goes over attaching a profiler and how you can get the output files. A profiler is used to help debug
issues around graphics and performance of your game servers. To use tools such as dotnet trace or PIX you'll
need to first upload your profiler of choice. Then you'll associate it to a build, and the output files will be put into
your logs folder.
It isn't recommended to attach a profiler to production builds as it can affect performance. Set up for attaching a
profiler will need to be done at build creation. We currently don't support attaching a profiler through Game
Manager so you'll need to create a build using our APIs. For more information, see Walkthrough: Deploy builds
using PowerShell/API.
When creating a build, there's a field for asset reference under the monitoring configuration. Include the asset
reference in the monitoring configuration. Ensure your asset is uploaded in Game Manager. To learn more, see
Manage assets in Build Overview.
For a Linux server, below is a sample of an execution script for the profiler.
sighdl()
{
#This is the folder the monitoring output should be written to.
monitoring_folder_path = "${PF_MONITORING_LOG_FOLDER}"
exit 0
}
#set up the trap function to catch the signals and exit gracefully
trap sighdl SIGKILL SIGINT SIGTERM
sleep 3600
For a windows server below is a sample of an execution script for the profiler.
#Sample function that checks for the sentinel file's existence in order to end.
function Check_Sentinel_File()
{
$fullPath = $Env:PF_SENTINEL_FILE
while(!(Test-Path $fullPath)) { Start-Sleep 10}
#PF_MONITORING_LOG_FOLDER contains the log folder where the monitoring output should be saved
Check_Sentinel_File
Make sure you save your output inside the folder set on the PF_MONITORING_LOG_FOLDER
environment variable as it will ensure your output is saved.
Once the server has been archived, you can download the logs and inside you'll find a folder called
PlayfabProfilingOutput . This will have what you have written in your execution script along with any
standard outputs and errors.
Scaling Standby
5/24/2022 • 4 minutes to read • Edit Online
PlayFab’s scaling capabilities enable developers to adjust game server hosting capacity to meet actual player
demand. These controls help developers efficiently keep game server hosting costs low while maintaining
enough capacity to quickly add new players to join multiplayer games with minimal to no waiting.
Scaling game servers is something developers think about after their game is successfully deployed and
operating. The controls demonstrated in this section helps developers define the elasticity of resource scaling
while maintaining enough capacity to add new players with minimal to no waiting.
Servers in the propping and standing-by states are billed to your title, and you'll want to optimize these
processes to reduce cost. Before we get to how you can calculate the standing by target here are some helpful
terms to understand.
Terminology
Terms you should understand about scaling standby servers.
Target Standby – Also commonly known as Standby Target and Standing by target, it is a value set by the
platform that specifies the target number of standby servers to have available to avoid standby pool
starvation.
Target Standby Floor – A game developer configurable measure representing the minimum floor quantity
of servers kept idle to fulfill demand for new game servers.
Actual Standby – The quantity of standby servers reported by the Multiplayer Servers platform where its
values are distinct between when Dynamic Standby is enabled versus when Dynamic Standby is disabled.
Pre-propping - Azure and PlayFab must create the virtual machine, initialize its operating system, and
configure its environment. PlayFab drives this pre-propping activity before the virtual machine is assigned to
a customer and billed.
Propping - The game servers assets must be loaded, and the game server application itself often needs
some time to prepare for players.
Standing by In order to immediately fulfill demand for a multiplayer server, some servers are kept idle
ready for players constantly.
Scaling benefits
A summary of scaling benefits includes:
B EN EF IT DESC RIP T IO N
Increase application availability Ensures that your game server pool always has the right
number of VMs by proactively provisioning capacity
Lower compute costs Adds instances only when needed to optimize costs
Scale instances across purchase options Scaling options optimize performance across instance type,
region, size and game server build configurations
Scaling methods
PlayFab offers multiple mechanisms to scale when and how to scale your servers. Game developers have the
flexibility of:
1. Configuring minimum & maximum thresholds
2. Customizing scale configurations per server build profiles such as (a) instance types, (b) VM size, or (c)
regions
3. Managing change effortlessly from the developers’ portal or from the Multiplayer Servers RESTful API
4. Monitor scaling metrics in server & usage charts
The three methods to configure scaling of game servers are:
Default
Scheduled
Dynamic
Each has a unique approach but trigger from a known or unknown state of player demand. The default method
scales up to the max servers configured and scales down on sessions completed. In this mechanism, there’s no
extra steps required by the developer. This is the simplest method where developers set a max server and
standby limit so that PlayFab automatically shrinks and grows VMs by way of player demand.
To fully embrace the breadth of scaling options, the following key concepts and terminology must be
understood first.
Key Concepts
Scaling mechanisms control the number of standby server availability
Standby servers are VM allocated servers with no active connected players. These will transition in accepting
for player connections in response to RequestMultiplayerServer API call; they transition to a termination state
when the game server process exits
Scaling mechanisms are uniquely applied at each region of a build
Each scaling configuration is represented as a region override
Dynamic Standby is an auto scaling enhancement that monitors standby server threshold levels and
dynamically activates increased provisioning of game servers to meet demand at scale.
Dynamic Scaling enables you to follow the demand curve for your player traffic, reducing the need to manually
provision multiplayer server capacity in advance. For example, you can set thresholds to multiply standby
servers by amounts when standby servers deplete to percentage of “standby available”.
Terminology
Dynamic Standby Settings – A game developer configurable programmatic object representing Dynamic
Standby settings to avoid standby pool starvation.
Dynamic Standby Activated – The point in time when the Multiplayer Servers platform starts allocating
standby servers at a rate aligned with the dynamic Standby settings, overriding that target standby floor
settings.
Dynamic Standby Deactivated – The point in time when the Multiplayer Servers platform stops allocating
standby servers at a rate aligned with the dynamic Standby settings, restoring the target standby floor
settings.
How it works
Game developers specify a target standby floor value for the minimum number of standby servers. If the rate at
which active servers are allocated grows rapidly, the actual standby servers may hit zero. If Dynamic Standby is
enabled, an auto scaling heuristic will trigger and adjust the target standby value used by the platform to
compensate for the rate of active server allocations.
To state this another way, if the number of available standby servers decreases at a rate that could lead to
standby pool starvation, dynamic standby will increase the target number standby servers.
The following graphs show the difference of availability of servers when Dynamic Standby is enabled and when
it is disabled.
C H A RT L EGEN D
At time T2, even though the target standby floor setting is 10, the actual standby value reported by the platform
is near zero because the rate at which active servers are allocated is too large for the number of standby servers.
With Dynamic Standby enabled, the target standby is set to 20. This allows the standby pool to handle the
request rate and rebuild to handle the additional growth in active servers.
Calculating Dynamic Standby Targets
With Dynamic Standby enabled, the target standby is calculated for each threshold configured:
IF (Active Servers > 1X Target Standby) AND ((Actual Standby / Target Standby Floor) < 0.50) THEN Target
Standby = 1.5 * Target Standby
IF (Active Servers > 1X Target Standby) AND ((Actual Standby / Target Standby Floor) < 0.25) THEN Target
Standby = 3.0 * Target Standby
IF (Active Servers > 1X Target Standby) AND ((Actual Standby / Target Standby Floor) < 0.005) THEN Target
Standby = 4.0 * Target Standby
Revisiting figure #1 above, the following table illustrates the target standby calculation inputs and its values:
A C T IVE SERVER
A C T IVE SERVER A L LO C AT IO N TA RGET A C T UA L TA RGET
T IM E C O UN T RAT E STA N DB Y F LO O R STA N DB Y STA N DB Y
T0 40 >+40 servers 10 10 10
per time T
When Dynamic Standby is deactivated, there is a gradual ramp down of standby servers until the original
standby floor is reached.
When the dynamic standby button is toggled in the on position, the dynamic overrides dialog expands to with
configuration options. The options control how Dynamic Standby responds when it ramps up or down due to
player demand. Each dialog input is described in the table below:
Ramp down time The amount of time after a threshold is no longer triggered
before the target standby will be reduced to the normal level
Percent Standby The threshold triggered when current standby drops to this
percentage of the base target standby
Scheduled Standby is an auto scaling enhancement that adjusts standby server levels at a single or recurring
scheduled date & time. Scheduled standby enables server scaling based on a schedule. It allows you to scale
your game server ahead of predicted load changes. For example, every weekend, traffic to your game server
increases on Friday 2 PM PST and starts to decrease by Sunday 11 PM PST. You can plan your scaling activities
based on the known player demand patterns of your game.
How it works
Game developers specify a target standby floor value for the minimum number of standby servers. If player
demand is predicted to grow during a specific date & time window where active servers grows rapidly, the
actual standby servers may hit zero triggering standby pool starvation. If Scheduled Standby is enabled, standby
pools can auto scale and adjust the target standby value used by the platform at a specific date and time.
To enable Scheduled Standby, create a region overrides by selecting Edit overrides to configure scaling settings
for a specific region.
Configuring a regions override will surface options to enable server scaling settings for both dynamic standby
and scheduled standby. Scheduled standby is disabled by default. To enable scheduled standby, select New
override in the Scheduled overrides page section.
When the scheduled new override is selected, , the scheduled overrides dialog expands to surface options that
control how Scheduled Standby behaves when it ramps up to support player demand or when it ramps down
when players disconnect from active servers. Each dialog input is described below:
Day of the week Scheduled day of the week to scale standby settings
After making changes to the scheduled overrides of a region, select Save and close to save the changes made
and return to the build regions summary page. The builds region summary page indicate that Scheduled
standby is enabled and tabulates the scheduled settings.
Scaling Programmatically
5/24/2022 • 2 minutes to read • Edit Online
Configuring Dynamic Standby requires editing the settings properties of the Dynamic Standby object. Modifying
the default values of the properties is an advanced game server feature and must be done with caution.
Configuring Schedule Standby requires editing the settings properties of the Schedule Standby object.
Modifying the default values of the properties is an advanced game server feature and must be done with
caution.
You can deploy PlayFab multiplayer servers to more than a dozen Azure regions. There are two reasons to do
this:
1. Additional regions provide redundancy. If a single Azure region fails, players can access servers in other
regions.
2. Additional regions allow players to access servers that are "nearby" and deliver low-latency connectivity.
When you call RequestMultiplayerServer, you specify a ranked list of Azure regions that PlayFab uses to fulfill
the request. PlayFab will attempt to fulfill the request using the #1 ranked region, but if there aren't servers
standing by in that region, or the region has some other fault, a sub-optimal region further down the list will be
attempted.
Whenever possible, you should use player latency data to inform the ranking of Azure regions used while
requesting a multiplayer server. PlayFab provides services and tools to help with this task.
Quality-of-service beacons
PlayFab operates beacons in every Azure region in use by PlayFab multiplayer servers. These beacons will reflect
UDP traffic and can be used to measure latency with UDP transport.
The usage of UDP is important, because most multiplayer games use UDP transport for their most
performance-critical game traffic. Internet service providers and other elements of the Internet ecosystem may
deliver differentiated performance for UDP vs. TCP vs. ICMP flows.
This is the typical flow for using these beacons in the context of a player device:
1. Login the player to PlayFab. This is typically done with a LoginWithCustomID or another login API.
2. Call ListQoSServersForTitle. This provides hostnames to PlayFab's QoS beacons. A typical implementation
might have this procedure occur on the Multiplayer Menu page for the game.
3. Create a UDP socket.
4. Send a single UDP datagram to port 3075 on the QoS server. The message content must start with 0xFFFF
(1111 1111 1111 1111).
5. The server will reply with a single datagram, with the message contents having the first 2 bytes "flipped" to
0x0000 (0000 0000 0000 0000). The rest of the datagram contents will be copied from the initial ping.
6. Measure the time between sending the UDP message and receiving a response.
C++
There are the two QoS APIs available in the PlayFab cross-platform (CPP) SDK.
The code is located in PlayFabQosApi.cpp.
Parameters:
numThreads - The maximum number of pings to make in parallel. Increasing this number will reduce
execution time, but network contention can cause inaccurate results if this number is too big.
timeoutMs - The timeout (in milliseconds) applied to each ping attempt (Default: 250ms).
// Runs a QoS operation asynchronously. The operation pings a set of datacenters and returns a result with
average response times.
std::future<QoSResult> GetQoSResultAsync(unsigned int numThreads, unsigned int timeoutMs =
DEFAULT_TIMEOUT_MS);
// Runs a QoS operation synchronously. The operation pings a set of datacenters and returns a result with
average response times.
QoSResult GetQoSResult(unsigned int numThreads, unsigned int timeoutMs = DEFAULT_TIMEOUT_MS);
Allocating game servers and connecting Visual
Studio debugging tools
5/24/2022 • 3 minutes to read • Edit Online
NOTE
You can use the MpsAllocatorSample (found here) for an easy way to allocate game servers during development of your
game
Client allocation
Multiplayer servers are expensive and powerful. By default, you can only request a multiplayer server from your
own trusted service using a PlayFab developer secret key.
However, allocating servers directly from player devices can save you the cost of implementing service-to-
service calls and be useful in some circumstances.
To enable client allocation:
Select Settings from the menu on the left.
Select the API Features tab.
Then activate the Allow Client to star t games option.
When this setting is activated, you can call RequestMultiplayerServer using the entity token for any player
associated with the title.
NOTE
The procedure that follows will enable insecure, unauthenticated debugging.
The following procedure should only be applied to server builds that are for development and testing, and
generally avoided in a player-facing environment.
1. Get the VS2017 Remote Debugging tools:
/prepcomputer /quiet
NOTE
We recommend specifically listing the port so your program can handle the process exit code if the port is already in use,
rather than binding to a random port which isn't open.
PlayFab game servers are containerized applications. When game servers are deployed to Azure, their
networking environment is virtualized, and the game server will not have direct access to its Internet accessible
IP addresses.
Instead, game servers using GetAdaptersInfo (Windows) or GetIfAddrs (Linux) will observe a single network
adapter with non-unique IP addresses that have been configured through Network Address Translation (NAT44).
This usage of network virtualization and NAT allows game servers to maintain connections even as underlying
Azure infrastructure may be changing. All game servers have IPv4 connectivity, but IPv6 connectivity will be
added in the future.
NOTE
All Game Servers have IPv4 connectivity - IPv6 connectivity will be added in the future.
You may configure a Server deployment to pack multiple Game Server instances on a single virtual machine.
For the most part, this does not modify the network environment, as each containerization allows each Game
Server instance to have independent IP addresses and TCP/UDP port spaces.
However, all instances on a single virtual machine share the physical network infrastructure, and can create
network contention.
While testing high-density configurations, it is important to test that typical contention does not cause
unacceptable game play issues.
Different virtual machine sizes and operating systems are provisioned with differing levels of bandwidth. To see
the bandwidth provisioned for a specific SKU, please see Azure’s throughput documentation.
Game servers are allocated through service-to-service calls through the PlayFab server API. The connection
information required for client connectivity is passed through these services and clients, which typically use TCP
or UDP sockets to drive a direct connection to the game server. Typically, game servers will listen on well-known
UDP and TCP ports selected by the game developer.
Game clients need the Internet-facing IP address of your game servers to connect to them. Clients also need
port-forwarding information to allow well-known ports to which the server is listening, to be addressable
through the Azure network virtualization apparatus.
Multiplayer Servers includes a free and limited capacity of simultaneous cores to evaluate the building of
multiplayer server games. Game developers enrolled in paid pricing plans, however, may request additional
server cores for their game title(s). Requesting additional quota will increase the maximum number of cores that
your multiplayer service has access to if the request is approved. The Multiplayer Ser vers | Quota
Summar y page presents a self-serve mechanism in Game Manager for game developers to:
Request additional quota
Review a histor y of quota requests provisioned or under review
7. After processing your request, if it is approved a notification will surface at the top of the Game Manager
indicating your request was approved. You may verify your changes were made by accessing the View Quota
page by selecting the View Quota button at the top of the Multiplayer Ser vers | Quota Summar y page.
8. If your request is too large to approve immediately, you will be prompted to provide additional details of
your quota change request as in (a) start date desired and (b) notes to help assess the change. Examples
include forecast title metrics (e.g. daily active users, concurrent game players per second, etc.). This
information will be manually reviewed by PlayFab who will be in contact with you regarding the status of
your quota change request.
NOTE
This topic frequently references available Azure compute series and regions. To review PlayFab's current selection and
pricing see Multiplayer Servers - detailed price sheet.
Usage of PlayFab multiplayer servers has limits that are applied on a per-title basis. A key limit is the aggregate
number of Azure compute cores.
By default, indie, pro, and enterprise customers have limits set to 16 Av2 cores and 8 Dv2 cores split in East
US and West US.
Contact PlayFab Support to gain access to additional compute series, regions, or limit increases.
It is important to review title limits well in advance of any major game event, so you can be assured that PlayFab
will support peak player demand.
NOTE
For requests of 1,000 cores or more, it can take several days for PlayFab to secure the desired limit increases for you.
NOTE
In the future, this will be integrated with the PlayFab limits page.
When you attempt to edit a build's regional configuration, PlayFab enforces that the maximum server
configuration you specify does not cause your title to exceed configured limits in aggregate.
The following screenshot of the Edit Build page shows these safeguards in action, as shown below.
You can use this page to specify the maximum number of multiplayer servers that a build can support in each
region. Depending on your virtual machine and density selections, a single server might require 1/4 of a Av2
core, or 4 Av2 cores.
In the above example there are 8 Av2 cores allocated to this title in West US. This build is configured to pack 3
servers on an single-core A1v2 virtual machine, so the configured "6 servers" maximum will consume 25% (2
cores) of the available 8 Av2 core quota in West US.
Azure Enterprise Agreement (EA) billing for PlayFab
services
5/24/2022 • 2 minutes to read • Edit Online
If you are interested in very high usage of PlayFab services ($500,000.00+ per year) including PlayFab
Essentials, Multiplayer Servers, Insights, Party, User Generated Content and Pub Sub, we may be able to bill you
through an Azure Enterprise Agreement (EA) . If you are an existing EA customer this requires Microsoft to
amend the terms of your EA to include PlayFab pricing details. If you are not an existing EA customer please
contact us at helloplayfab@microsoft.com to learn more about this billing option.
To start the EA billing process, contact your Azure solutions specialist and work with them to provide PlayFab
Sales:
Azure enterprise agreement (enrollment id) to govern PlayFab usage
Mapping of PlayFab Title IDs to Azure subscriptions for billing
PlayFab will emit multiplayer server consumption via an Azure SKU called PlayFab Multiplayer Servers. Each
PlayFab title will emit to the Azure subscription provided, and you will get a monthly bill through the EA portal.
This single Azure SKU for PlayFab Multiplayer Servers will be measured in dollars, without a break-down of cost
by resource (e.g. Fv2 compute, Zone 2 network egress, etc.). Use Game Manager to see a break-down of costs by
resource.
Billing for PlayFab Multiplayer Servers 2.0
5/24/2022 • 5 minutes to read • Edit Online
Most PlayFab services, including PlayFab Multiplayer Matchmaking, are included with every paid PlayFab pricing
mode, as part of our core offering. However, PlayFab Multiplayer Servers is billed on a consumption basis. This
document describes that billing plan.
The free evaluation mode also includes limit imposed on simultaneous cores activated in game servers. The paid
modes, however, allow game developers to request additional server cores for their title.
The maximum simultaneous core quota in the free evaluation modes are:
This is typically not enough to launch a live game, but it can help you evaluate the service and get started.
To learn more about these different virtual machine please see Azure VM Sizes.
NOTE
The amount of free evaluation capacity provided per month is based on your PlayFab billing mode and is also calculated
based on core hours. This means that if you use a **single core ** Av2 series VM (like A1v2), you have 750 free hours. But
if you use a **dual core ** Av2 series VM (like A2v2), you have 375 free hours instead — 750 divided by 2 equals 375.
Total $1,124.90
IN P UT DEF IN IT IO N
At 100,000 users, each averaging 12 user minutes per month, this comes out to 1.2 million user minutes.
Dividing this number by the average users per session (4) results in 300,000 total session minutes used.
In this example we are packing 3 servers on a 2-core D2_v3 virtual machine:
IN P UT DEF IN IT IO N
Since we are running 3 servers on our D2_v3 VM , we can divide the total session minutes used (300,000) by
the number of servers (3) to figure out approximately how many D2_v3 VM minutes (100,000) have been used
this month.
Traditional multiplayer server hosting may require you to pay for significant overhead capacity, to handle
natural variation in player activity.
It is common for games to have higher levels of concurrency during the weekends and holidays that require you
to "pre-pay" for more servers than necessary, as shown below.
PlayFab Multiplayer Server builds automatically scale with your player base. Servers are transitioned to the
active state by calling RequestMultiplayerServer, and are later recycled when your game server terminates
(typically the end of a "multiplayer round").
However, delivering this dynamic scaling with minimal allocation latency requires some overhead, which
originates from 2 key sources:
1. Standing-by ser vers - Players do not want to wait for servers, and PlayFab targets a 3 second response
time for fulfilling a server request. PlayFab will maintain a set of standing-by servers to ensure that
servers are immediately available. As this standing-by pool is consumed by new allocations, PlayFab
initializes new standing-by sessions. The amount of standing-by sessions required is dependent on how
fast new sessions are requested during peak utilization, and how quickly they can be created and
initialized.
2. Vir tual machine fragmentation - If you host multiple sessions on a single virtual machine, there can
sometimes be extra stand-by capacity due to fragmentation. In our example of 3 sessions per virtual
machine, a virtual machine might have only 1 active session, and the remaining two "spaces" are added
to the stand-by pool. Until the active session is terminated, the virtual machine must stay online - even if
the additional stand-by capacity is not needed.
NOTE
Typically, these sources of overhead increase the required compute-hours by 20%.
Calculating networking
Network egress can be a substantial expense, especially for large multiplayer sessions with many simultaneous
connected players (32+). During development and testing, run your server locally to get an estimate of its
network utilization during play.
IN P UT DEF IN IT IO N
In this example, assume that testing shows that a multiplayer session sends 1 MB of data per second of active
play.
Since we earlier calculated 300,000 server minutes used in a month, we can estimate that 300,000 users x 60
MB per minute equals 18,000,000 MB of data sent per month.
How to pay
PlayFab offers three pathways for billing.
1. Billing through credit card.
2. Billing through PlayFab invoicing. This is ideal for many professional projects, but requires you to
contact our customer services group to get set up.
3. Billing through Azure & Microsoft Enterprise Agreements. This is ideal for organizations that may
have a volume deal with Azure or another Microsoft product line. Please contact our customer services
group or your Azure solutions specialist to learn more.
In all three options you will receive a detailed analysis of your multiplayer server activity in Game Manager.
However - for Azure/EA customers - the final invoicing through Azure is simplified, and will show these high
level line-items denominated in dollars:
PlayFab Essential Services
PlayFab Multiplayer Servers
Multiplayer servers - detailed price sheet
5/24/2022 • 56 minutes to read • Edit Online
PlayFab multiplayer servers operate on most generally available Azure virtual machine sizes and regions. These
are the most popular series for game developers providing progressively faster processors.
Recommended VMs
The Dav4 and Dasv4 series feature the AMD 2.35Ghz EPYCTM 7452 2nd Generation processor in a multi-
threaded configuration with up to 256 MB L3 cache, and each 8 cores have 8 MB of dedicated L3 cache. The
Dav4-series sizes offer a combination of vCPU, memory and temporary storage that is suitable for most
gaming workloads. The Dasv4 Azure VMs expose up to 96 vCPUs, 384 GBs of RAM, and 768 GBs of SSD-
based storage. Furthermore, the Azure Performance Improvement team has tuned Dasv4 VMs to be the most
stable, delivering the best price/performance ratio on Azure with no code changes needed.
The Eav4 and Easv4-series utilize AMD's 2.35Ghz EPYCTM7452 processor in a multi-threaded configuration
with up to 256MB L3 cache, increasing options for running most memory optimized workloads. The Eav4-
series and Easv4-series have the same memory and disk configurations as the Ev3 & Esv3-series, and are
ideal for memory-intensive applications.
The Dasv4 is now the recommended SKU for running game servers in Azure. For customers currently on the
Dv2, Fsv2 and Dv3 VMs, we highly recommend switching to Dasv4 as it offers the best ratio of price to CPU
performance and more memory than the Fsv2. Below is a comparison of the PlayFab Multiplayer Servers 2 core
SKUs. Prices are approximate as they vary based on the region selected.
VM Comparison Summary
A P P RO X. P RIC E
P ER A C U VS
SK U CPU RA M ( GB ) STO RA GE ( GB ) ACU D2V2
Alternative VMs
The Fsv2-series is based on the Intel® Xeon® Platinum 8168 processor. It features a sustained all core
Turbo clock speed of 3.4 GHz and a maximum single-core turbo frequency of 3.7 GHz. Intel® AVX-512
instructions are new on Intel Scalable Processors. These instructions provide up to a 2X performance boost to
vector processing workloads on both single and double precision floating point operations. In other words,
they're really fast for any computational workload. At a lower per-hour list price, the Fsv2-series is the best
value in price-performance in the Azure portfolio based on the Azure Compute Unit (ACU) per vCPU.
The Dv2-series VMs features a powerful CPU and optimal CPU-to-memory configuration making them
suitable for most production workloads. The Dv2-series is about 35% faster than the D-series. Dv2-series
runs on the Intel® Xeon® 8171M 2.1GHz (Skylake), Intel® Xeon® E5-2673 v4 2.3 GHz (Broadwell), or
the Intel® Xeon® E5-2673 v3 2.4 GHz (Haswell) processors with the Intel Turbo Boost Technology 2.0.
The Av2-series VMs can be deployed on a variety of hardware types and processors. The size is throttled,
based upon the hardware, to offer consistent processor performance for the running instance, regardless of
the hardware it is deployed on.
NOTE
The following prices are per virtual machine compute hour.
VM Hourly Rates
REC O M M EN DED A LT ERN AT IVE
Dasv4, Dav4, Easv4, Eav4 Fsv2, Fv1, Dsv3, Dv3, Dsv2 ,Dv2, Av2
Av2
Av2 Standard is the latest generation of A-series virtual machines with similar CPU performance and faster disk.
These virtual machines are suitable for development workloads, build servers, code repositories, low-traffic
websites and web applications, micro services, early product experiments, and small databases. Like the prior A
Standard generation, Av2 virtual machines will include load balancing and auto-scaling at no additional charge.
back to top
US East
IN STA N C E VC P U RA M STO RA GE L IN UX W IN DO W S
back to top
US East 2
IN STA N C E VC P U RA M STO RA GE L IN UX W IN DO W S
back to top
US West
IN STA N C E VC P U RA M STO RA GE L IN UX W IN DO W S
back to top
US West 2
IN STA N C E VC P U RA M STO RA GE L IN UX W IN DO W S
back to top
US Central
IN STA N C E VC P U RA M STO RA GE L IN UX W IN DO W S
back to top
US North Central
IN STA N C E VC P U RA M STO RA GE L IN UX W IN DO W S
back to top
US South Central
IN STA N C E VC P U RA M STO RA GE L IN UX W IN DO W S
back to top
US West Central
IN STA N C E VC P U RA M STO RA GE L IN UX W IN DO W S
back to top
North Europe
IN STA N C E VC P U RA M STO RA GE L IN UX W IN DO W S
back to top
West Europe
IN STA N C E VC P U RA M STO RA GE L IN UX W IN DO W S
back to top
France Central
IN STA N C E VC P U RA M STO RA GE L IN UX W IN DO W S
back to top
India Central
IN STA N C E VC P U RA M STO RA GE L IN UX W IN DO W S
back to top
UAE North
IN STA N C E VC P U RA M STO RA GE L IN UX W IN DO W S
back to top
Brazil South
IN STA N C E VC P U RA M STO RA GE L IN UX W IN DO W S
back to top
South Africa North
IN STA N C E VC P U RA M STO RA GE L IN UX W IN DO W S
back to top
Australia East
IN STA N C E VC P U RA M STO RA GE L IN UX W IN DO W S
back to top
Australia South East
IN STA N C E VC P U RA M STO RA GE L IN UX W IN DO W S
back to top
Korea Central
IN STA N C E VC P U RA M STO RA GE L IN UX W IN DO W S
back to top
Japan East
IN STA N C E VC P U RA M STO RA GE L IN UX W IN DO W S
back to top
Japan West
IN STA N C E VC P U RA M STO RA GE L IN UX W IN DO W S
back to top
East Asia
IN STA N C E VC P U RA M STO RA GE L IN UX W IN DO W S
back to top
South East Asia
IN STA N C E VC P U RA M STO RA GE L IN UX W IN DO W S
Dv2
The Dv2-series virtual machines run on the Intel® Xeon® Platinum 8272CL processor (second generation
Intel® Xeon® Scalable processors), Intel® Xeon® 8171M 2.1GHz (Skylake), Intel® Xeon® E5-2673 v4
2.3 GHz (Broadwell), or the Intel® Xeon® E5-2673 v3 2.4 GHz (Haswell) processors with the Intel Turbo Boost
Technology 2.0. The D1-5 v2 sizes offer a balanced combination of vCPU(s), memory, and local disk for most
production workloads.
back to top
US East
IN STA N C E VC P U RA M STO RA GE L IN UX W IN DO W S
back to top
US East 2
IN STA N C E VC P U RA M STO RA GE L IN UX W IN DO W S
back to top
US West
IN STA N C E VC P U RA M STO RA GE L IN UX W IN DO W S
back to top
US West 2
IN STA N C E VC P U RA M STO RA GE L IN UX W IN DO W S
back to top
US Central
IN STA N C E VC P U RA M STO RA GE L IN UX W IN DO W S
back to top
US North Central
IN STA N C E VC P U RA M STO RA GE L IN UX W IN DO W S
back to top
US South Central
IN STA N C E VC P U RA M STO RA GE L IN UX W IN DO W S
back to top
US West Central
IN STA N C E VC P U RA M STO RA GE L IN UX W IN DO W S
back to top
North Europe
IN STA N C E VC P U RA M STO RA GE L IN UX W IN DO W S
back to top
West Europe
IN STA N C E VC P U RA M STO RA GE L IN UX W IN DO W S
back to top
France Central
IN STA N C E VC P U RA M STO RA GE L IN UX W IN DO W S
back to top
India Central
IN STA N C E VC P U RA M STO RA GE L IN UX W IN DO W S
back to top
UAE North
IN STA N C E VC P U RA M STO RA GE L IN UX W IN DO W S
back to top
Brazil South
IN STA N C E VC P U RA M STO RA GE L IN UX W IN DO W S
back to top
South Africa North
IN STA N C E VC P U RA M STO RA GE L IN UX W IN DO W S
back to top
Australia East
IN STA N C E VC P U RA M STO RA GE L IN UX W IN DO W S
back to top
Australia South East
IN STA N C E VC P U RA M STO RA GE L IN UX W IN DO W S
back to top
Korea Central
IN STA N C E VC P U RA M STO RA GE L IN UX W IN DO W S
back to top
Japan East
IN STA N C E VC P U RA M STO RA GE L IN UX W IN DO W S
back to top
Japan West
IN STA N C E VC P U RA M STO RA GE L IN UX W IN DO W S
back to top
East Asia
IN STA N C E VC P U RA M STO RA GE L IN UX W IN DO W S
back to top
South East Asia
IN STA N C E VC P U RA M STO RA GE L IN UX W IN DO W S
IN STA N C E VC P U RA M STO RA GE L IN UX W IN DO W S
back to top
US East 2
IN STA N C E VC P U RA M STO RA GE L IN UX W IN DO W S
back to top
US West
IN STA N C E VC P U RA M STO RA GE L IN UX W IN DO W S
back to top
US West 2
IN STA N C E VC P U RA M STO RA GE L IN UX W IN DO W S
back to top
US Central
IN STA N C E VC P U RA M STO RA GE L IN UX W IN DO W S
back to top
US North Central
IN STA N C E VC P U RA M STO RA GE L IN UX W IN DO W S
back to top
US South Central
IN STA N C E VC P U RA M STO RA GE L IN UX W IN DO W S
back to top
US West Central
IN STA N C E VC P U RA M STO RA GE L IN UX W IN DO W S
back to top
North Europe
IN STA N C E VC P U RA M STO RA GE L IN UX W IN DO W S
back to top
West Europe
IN STA N C E VC P U RA M STO RA GE L IN UX W IN DO W S
IN STA N C E VC P U RA M STO RA GE L IN UX W IN DO W S
back to top
India Central
IN STA N C E VC P U RA M STO RA GE L IN UX W IN DO W S
back to top
UAE North
IN STA N C E VC P U RA M STO RA GE L IN UX W IN DO W S
back to top
Brazil South
IN STA N C E VC P U RA M STO RA GE L IN UX W IN DO W S
back to top
South Africa North
IN STA N C E VC P U RA M STO RA GE L IN UX W IN DO W S
back to top
Australia East
IN STA N C E VC P U RA M STO RA GE L IN UX W IN DO W S
back to top
Australia South East
IN STA N C E VC P U RA M STO RA GE L IN UX W IN DO W S
back to top
Korea Central
IN STA N C E VC P U RA M STO RA GE L IN UX W IN DO W S
back to top
Japan East
IN STA N C E VC P U RA M STO RA GE L IN UX W IN DO W S
back to top
Japan West
IN STA N C E VC P U RA M STO RA GE L IN UX W IN DO W S
back to top
East Asia
IN STA N C E VC P U RA M STO RA GE L IN UX W IN DO W S
back to top
South East Asia
IN STA N C E VC P U RA M STO RA GE L IN UX W IN DO W S
Dv3
The Dv3-series virtual machines run on the Intel® Xeon® Platinum 8272CL processor (second generation
Intel® Xeon® Scalable processors), Intel® Xeon® 8171M 2.1GHz (Skylake), Intel® Xeon® E5-2673 v4
2.3 GHz (Broadwell), or the Intel® Xeon® E5-2673 v3 2.4 GHz (Haswell) processors in a hyper-threaded
configuration. The Dv3-series sizes offer a combination of vCPU(s), memory, and local disk well suited for most
production workloads.
back to top
US East
IN STA N C E VC P U RA M STO RA GE L IN UX W IN DO W S
back to top
US East 2
IN STA N C E VC P U RA M STO RA GE L IN UX W IN DO W S
back to top
US West
IN STA N C E VC P U RA M STO RA GE L IN UX W IN DO W S
back to top
US West 2
IN STA N C E VC P U RA M STO RA GE L IN UX W IN DO W S
back to top
US Central
IN STA N C E VC P U RA M STO RA GE L IN UX W IN DO W S
back to top
US North Central
IN STA N C E VC P U RA M STO RA GE L IN UX W IN DO W S
back to top
US South Central
IN STA N C E VC P U RA M STO RA GE L IN UX W IN DO W S
back to top
US West Central
IN STA N C E VC P U RA M STO RA GE L IN UX W IN DO W S
back to top
North Europe
IN STA N C E VC P U RA M STO RA GE L IN UX W IN DO W S
back to top
West Europe
IN STA N C E VC P U RA M STO RA GE L IN UX W IN DO W S
back to top
France Central
IN STA N C E VC P U RA M STO RA GE L IN UX W IN DO W S
back to top
India Central
IN STA N C E VC P U RA M STO RA GE L IN UX W IN DO W S
back to top
UAE North
IN STA N C E VC P U RA M STO RA GE L IN UX W IN DO W S
back to top
Brazil South
IN STA N C E VC P U RA M STO RA GE L IN UX W IN DO W S
back to top
South Africa North
IN STA N C E VC P U RA M STO RA GE L IN UX W IN DO W S
back to top
Australia East
IN STA N C E VC P U RA M STO RA GE L IN UX W IN DO W S
back to top
Australia South East
IN STA N C E VC P U RA M STO RA GE L IN UX W IN DO W S
back to top
Korea Central
IN STA N C E VC P U RA M STO RA GE L IN UX W IN DO W S
back to top
Japan East
IN STA N C E VC P U RA M STO RA GE L IN UX W IN DO W S
back to top
Japan West
IN STA N C E VC P U RA M STO RA GE L IN UX W IN DO W S
back to top
East Asia
IN STA N C E VC P U RA M STO RA GE L IN UX W IN DO W S
back to top
South East Asia
IN STA N C E VC P U RA M STO RA GE L IN UX W IN DO W S
Dsv3
The Dsv3-series support premium storage and run on the Intel® Xeon® Platinum 8272CL processor (second
generation Intel® Xeon® Scalable processors), Intel® Xeon® 8171M 2.1GHz (Skylake), Intel® Xeon®
E5-2673 v4 2.3 GHz (Broadwell), or the Intel® Xeon® E5-2673 v3 2.4 GHz (Haswell) processors with Intel
Turbo Boost Technology 2.0 and feature Intel® Hyper-Threading Technology. The Dsv3-series sizes offer a
combination of vCPU(s), memory, and temporary storage well suited for most production workloads.
back to top
US East
IN STA N C E VC P U RA M STO RA GE L IN UX W IN DO W S
back to top
US East 2
IN STA N C E VC P U RA M STO RA GE L IN UX W IN DO W S
back to top
US West
IN STA N C E VC P U RA M STO RA GE L IN UX W IN DO W S
back to top
US West 2
IN STA N C E VC P U RA M STO RA GE L IN UX W IN DO W S
back to top
US Central
IN STA N C E VC P U RA M STO RA GE L IN UX W IN DO W S
back to top
US North Central
IN STA N C E VC P U RA M STO RA GE L IN UX W IN DO W S
back to top
US South Central
IN STA N C E VC P U RA M STO RA GE L IN UX W IN DO W S
back to top
US West Central
IN STA N C E VC P U RA M STO RA GE L IN UX W IN DO W S
back to top
North Europe
IN STA N C E VC P U RA M STO RA GE L IN UX W IN DO W S
back to top
West Europe
IN STA N C E VC P U RA M STO RA GE L IN UX W IN DO W S
back to top
France Central
IN STA N C E VC P U RA M STO RA GE L IN UX W IN DO W S
back to top
India Central
IN STA N C E VC P U RA M STO RA GE L IN UX W IN DO W S
back to top
UAE North
IN STA N C E VC P U RA M STO RA GE L IN UX W IN DO W S
back to top
Brazil South
IN STA N C E VC P U RA M STO RA GE L IN UX W IN DO W S
back to top
South Africa North
IN STA N C E VC P U RA M STO RA GE L IN UX W IN DO W S
back to top
Australia East
IN STA N C E VC P U RA M STO RA GE L IN UX W IN DO W S
back to top
Australia South East
IN STA N C E VC P U RA M STO RA GE L IN UX W IN DO W S
back to top
Korea Central
IN STA N C E VC P U RA M STO RA GE L IN UX W IN DO W S
back to top
Japan East
IN STA N C E VC P U RA M STO RA GE L IN UX W IN DO W S
back to top
Japan West
IN STA N C E VC P U RA M STO RA GE L IN UX W IN DO W S
back to top
East Asia
IN STA N C E VC P U RA M STO RA GE L IN UX W IN DO W S
back to top
South East Asia
IN STA N C E VC P U RA M STO RA GE L IN UX W IN DO W S
Fv1
The F-series virtual machines feature 2-GiB RAM and 16 GiB of local SSD temporary storage per CPU core and
are optimized for compute intensive workloads. The F-series sizes are based Intel® Xeon® Platinum 8272CL
processor (second generation Intel® Xeon® Scalable processors), Intel® Xeon® 8171M 2.1GHz (Skylake),
Intel® Xeon® E5-2673 v4 2.3 GHz (Broadwell), or the Intel® Xeon® E5-2673 v3 2.4 GHz (Haswell)
processor. These virtual machines are suitable for scenarios like batch processing, web servers, analytics, and
gaming.
back to top
US East
IN STA N C E VC P U RA M STO RA GE L IN UX W IN DO W S
back to top
US East 2
IN STA N C E VC P U RA M STO RA GE L IN UX W IN DO W S
back to top
US West
IN STA N C E VC P U RA M STO RA GE L IN UX W IN DO W S
back to top
US West 2
IN STA N C E VC P U RA M STO RA GE L IN UX W IN DO W S
back to top
US Central
IN STA N C E VC P U RA M STO RA GE L IN UX W IN DO W S
back to top
US North Central
IN STA N C E VC P U RA M STO RA GE L IN UX W IN DO W S
back to top
US South Central
IN STA N C E VC P U RA M STO RA GE L IN UX W IN DO W S
back to top
US West Central
IN STA N C E VC P U RA M STO RA GE L IN UX W IN DO W S
back to top
North Europe
IN STA N C E VC P U RA M STO RA GE L IN UX W IN DO W S
back to top
West Europe
IN STA N C E VC P U RA M STO RA GE L IN UX W IN DO W S
back to top
France Central
IN STA N C E VC P U RA M STO RA GE L IN UX W IN DO W S
back to top
India Central
IN STA N C E VC P U RA M STO RA GE L IN UX W IN DO W S
back to top
UAE North
IN STA N C E VC P U RA M STO RA GE L IN UX W IN DO W S
back to top
Brazil South
IN STA N C E VC P U RA M STO RA GE L IN UX W IN DO W S
back to top
South Africa North
IN STA N C E VC P U RA M STO RA GE L IN UX W IN DO W S
back to top
Australia East
IN STA N C E VC P U RA M STO RA GE L IN UX W IN DO W S
back to top
Australia South East
IN STA N C E VC P U RA M STO RA GE L IN UX W IN DO W S
back to top
Korea Central
IN STA N C E VC P U RA M STO RA GE L IN UX W IN DO W S
back to top
Japan East
IN STA N C E VC P U RA M STO RA GE L IN UX W IN DO W S
back to top
Japan West
IN STA N C E VC P U RA M STO RA GE L IN UX W IN DO W S
back to top
East Asia
IN STA N C E VC P U RA M STO RA GE L IN UX W IN DO W S
back to top
South East Asia
IN STA N C E VC P U RA M STO RA GE L IN UX W IN DO W S
Fsv2
The Fsv2-series virtual machines provide 2-GiB of RAM and 8 GB of local temporary storage (SSD) per vCPU(s)
and are optimized for compute intensive workloads. The Fsv2-series VMs are hyper-threaded and based on the
Intel® Xeon® Platinum 8272CL (second generation Intel® Xeon® Scalable processors), or the Intel
Xeon® Platinum 8168 (Skylake) processor. These virtual machines are ideal for scenarios like batch processing,
web servers, analytics, and gaming.
back to top
US East
IN STA N C E VC P U RA M STO RA GE L IN UX W IN DO W S
back to top
US East 2
IN STA N C E VC P U RA M STO RA GE L IN UX W IN DO W S
back to top
US West
IN STA N C E VC P U RA M STO RA GE L IN UX W IN DO W S
back to top
US West 2
IN STA N C E VC P U RA M STO RA GE L IN UX W IN DO W S
back to top
US Central
IN STA N C E VC P U RA M STO RA GE L IN UX W IN DO W S
back to top
US North Central
IN STA N C E VC P U RA M STO RA GE L IN UX W IN DO W S
back to top
US South Central
IN STA N C E VC P U RA M STO RA GE L IN UX W IN DO W S
back to top
US West Central
IN STA N C E VC P U RA M STO RA GE L IN UX W IN DO W S
back to top
North Europe
IN STA N C E VC P U RA M STO RA GE L IN UX W IN DO W S
back to top
West Europe
IN STA N C E VC P U RA M STO RA GE L IN UX W IN DO W S
back to top
France Central
IN STA N C E VC P U RA M STO RA GE L IN UX W IN DO W S
back to top
India Central
IN STA N C E VC P U RA M STO RA GE L IN UX W IN DO W S
back to top
UAE North
IN STA N C E VC P U RA M STO RA GE L IN UX W IN DO W S
back to top
Brazil South
IN STA N C E VC P U RA M STO RA GE L IN UX W IN DO W S
back to top
South Africa North
IN STA N C E VC P U RA M STO RA GE L IN UX W IN DO W S
back to top
Australia East
IN STA N C E VC P U RA M STO RA GE L IN UX W IN DO W S
back to top
Australia South East
IN STA N C E VC P U RA M STO RA GE L IN UX W IN DO W S
back to top
Korea Central
IN STA N C E VC P U RA M STO RA GE L IN UX W IN DO W S
back to top
Japan East
IN STA N C E VC P U RA M STO RA GE L IN UX W IN DO W S
back to top
Japan West
IN STA N C E VC P U RA M STO RA GE L IN UX W IN DO W S
back to top
East Asia
IN STA N C E VC P U RA M STO RA GE L IN UX W IN DO W S
back to top
South East Asia
IN STA N C E VC P U RA M STO RA GE L IN UX W IN DO W S
Dav4
The Das v4-series VMs support Premium SSD disk storage and are based on the 2.35Ghz AMD EPYCTM 7452
processor, which can achieve up to 3.35GHz. The Das v4 VM sizes offer a combination of vCPUs, memory and
temporary storage able to meet the requirements associated with most production workloads.
back to top
US East
IN STA N C E VC P U RA M STO RA GE L IN UX W IN DO W S
back to top
US East 2
IN STA N C E VC P U RA M STO RA GE L IN UX W IN DO W S
back to top
US West
IN STA N C E VC P U RA M STO RA GE L IN UX W IN DO W S
back to top
US West 2
IN STA N C E VC P U RA M STO RA GE L IN UX W IN DO W S
back to top
US Central
IN STA N C E VC P U RA M STO RA GE L IN UX W IN DO W S
back to top
US North Central
IN STA N C E VC P U RA M STO RA GE L IN UX W IN DO W S
back to top
US South Central
IN STA N C E VC P U RA M STO RA GE L IN UX W IN DO W S
back to top
US West Central
IN STA N C E VC P U RA M STO RA GE L IN UX W IN DO W S
back to top
North Europe
IN STA N C E VC P U RA M STO RA GE L IN UX W IN DO W S
back to top
West Europe
IN STA N C E VC P U RA M STO RA GE L IN UX W IN DO W S
back to top
France Central
IN STA N C E VC P U RA M STO RA GE L IN UX W IN DO W S
back to top
India Central
IN STA N C E VC P U RA M STO RA GE L IN UX W IN DO W S
back to top
UAE North
IN STA N C E VC P U RA M STO RA GE L IN UX W IN DO W S
back to top
Brazil South
IN STA N C E VC P U RA M STO RA GE L IN UX W IN DO W S
back to top
South Africa North
IN STA N C E VC P U RA M STO RA GE L IN UX W IN DO W S
back to top
Australia East
IN STA N C E VC P U RA M STO RA GE L IN UX W IN DO W S
back to top
Australia South East
IN STA N C E VC P U RA M STO RA GE L IN UX W IN DO W S
back to top
Korea Central
IN STA N C E VC P U RA M STO RA GE L IN UX W IN DO W S
back to top
Japan East
IN STA N C E VC P U RA M STO RA GE L IN UX W IN DO W S
back to top
Japan West
IN STA N C E VC P U RA M STO RA GE L IN UX W IN DO W S
back to top
East Asia
IN STA N C E VC P U RA M STO RA GE L IN UX W IN DO W S
back to top
South East Asia
IN STA N C E VC P U RA M STO RA GE L IN UX W IN DO W S
Dasv4
The Da v4-series VMs are based on the 2.35Ghz AMD EPYCTM 7452 processor, which can achieve up to
3.35GHz. The Dav4 VM sizes offer a combination of vCPU(s), memory and temporary storage able to meet the
requirements associated with most production workloads. Data disk storage is billed separately from virtual
machines. To use Premium SSD disk storage, select the Das v4 VMs.
back to top
US East
IN STA N C E VC P U RA M STO RA GE L IN UX W IN DO W S
back to top
US East 2
IN STA N C E VC P U RA M STO RA GE L IN UX W IN DO W S
back to top
US West
IN STA N C E VC P U RA M STO RA GE L IN UX W IN DO W S
back to top
US West 2
IN STA N C E VC P U RA M STO RA GE L IN UX W IN DO W S
back to top
US Central
IN STA N C E VC P U RA M STO RA GE L IN UX W IN DO W S
back to top
US North Central
IN STA N C E VC P U RA M STO RA GE L IN UX W IN DO W S
back to top
US South Central
IN STA N C E VC P U RA M STO RA GE L IN UX W IN DO W S
back to top
US West Central
IN STA N C E VC P U RA M STO RA GE L IN UX W IN DO W S
back to top
North Europe
IN STA N C E VC P U RA M STO RA GE L IN UX W IN DO W S
back to top
West Europe
IN STA N C E VC P U RA M STO RA GE L IN UX W IN DO W S
back to top
France Central
IN STA N C E VC P U RA M STO RA GE L IN UX W IN DO W S
back to top
India Central
IN STA N C E VC P U RA M STO RA GE L IN UX W IN DO W S
back to top
UAE North
IN STA N C E VC P U RA M STO RA GE L IN UX W IN DO W S
back to top
Brazil South
IN STA N C E VC P U RA M STO RA GE L IN UX W IN DO W S
back to top
South Africa North
IN STA N C E VC P U RA M STO RA GE L IN UX W IN DO W S
back to top
Australia East
IN STA N C E VC P U RA M STO RA GE L IN UX W IN DO W S
back to top
Australia South East
IN STA N C E VC P U RA M STO RA GE L IN UX W IN DO W S
back to top
Korea Central
IN STA N C E VC P U RA M STO RA GE L IN UX W IN DO W S
back to top
Japan East
IN STA N C E VC P U RA M STO RA GE L IN UX W IN DO W S
back to top
Japan West
IN STA N C E VC P U RA M STO RA GE L IN UX W IN DO W S
back to top
East Asia
IN STA N C E VC P U RA M STO RA GE L IN UX W IN DO W S
back to top
South East Asia
IN STA N C E VC P U RA M STO RA GE L IN UX W IN DO W S
IN STA N C E VC P U RA M STO RA GE L IN UX W IN DO W S
back to top
US East 2
IN STA N C E VC P U RA M STO RA GE L IN UX W IN DO W S
back to top
US West
IN STA N C E VC P U RA M STO RA GE L IN UX W IN DO W S
back to top
US West 2
IN STA N C E VC P U RA M STO RA GE L IN UX W IN DO W S
back to top
US Central
IN STA N C E VC P U RA M STO RA GE L IN UX W IN DO W S
back to top
US North Central
IN STA N C E VC P U RA M STO RA GE L IN UX W IN DO W S
back to top
US South Central
IN STA N C E VC P U RA M STO RA GE L IN UX W IN DO W S
back to top
US West Central
IN STA N C E VC P U RA M STO RA GE L IN UX W IN DO W S
back to top
North Europe
IN STA N C E VC P U RA M STO RA GE L IN UX W IN DO W S
back to top
West Europe
IN STA N C E VC P U RA M STO RA GE L IN UX W IN DO W S
back to top
France Central
IN STA N C E VC P U RA M STO RA GE L IN UX W IN DO W S
back to top
India Central
IN STA N C E VC P U RA M STO RA GE L IN UX W IN DO W S
back to top
UAE North
IN STA N C E VC P U RA M STO RA GE L IN UX W IN DO W S
back to top
Brazil South
IN STA N C E VC P U RA M STO RA GE L IN UX W IN DO W S
back to top
South Africa North
IN STA N C E VC P U RA M STO RA GE L IN UX W IN DO W S
back to top
Australia East
IN STA N C E VC P U RA M STO RA GE L IN UX W IN DO W S
back to top
Australia South East
IN STA N C E VC P U RA M STO RA GE L IN UX W IN DO W S
back to top
Korea Central
IN STA N C E VC P U RA M STO RA GE L IN UX W IN DO W S
back to top
Japan East
IN STA N C E VC P U RA M STO RA GE L IN UX W IN DO W S
back to top
Japan West
IN STA N C E VC P U RA M STO RA GE L IN UX W IN DO W S
back to top
East Asia
IN STA N C E VC P U RA M STO RA GE L IN UX W IN DO W S
back to top
South East Asia
IN STA N C E VC P U RA M STO RA GE L IN UX W IN DO W S
Easv4
The Eas v4-series VMs support Premium SSD disk storage and are based on the 2.35Ghz AMD EPYCTM 7452
processor, which can achieve up to 3.35GHz. The Eas v4-series VMs are ideal for memory-intensive enterprise
applications.
back to top
US East
IN STA N C E VC P U RA M STO RA GE L IN UX W IN DO W S
back to top
US East 2
IN STA N C E VC P U RA M STO RA GE L IN UX W IN DO W S
back to top
US West
IN STA N C E VC P U RA M STO RA GE L IN UX W IN DO W S
back to top
US West 2
IN STA N C E VC P U RA M STO RA GE L IN UX W IN DO W S
back to top
US Central
IN STA N C E VC P U RA M STO RA GE L IN UX W IN DO W S
back to top
US North Central
IN STA N C E VC P U RA M STO RA GE L IN UX W IN DO W S
back to top
US South Central
IN STA N C E VC P U RA M STO RA GE L IN UX W IN DO W S
back to top
US West Central
IN STA N C E VC P U RA M STO RA GE L IN UX W IN DO W S
back to top
North Europe
IN STA N C E VC P U RA M STO RA GE L IN UX W IN DO W S
back to top
West Europe
IN STA N C E VC P U RA M STO RA GE L IN UX W IN DO W S
back to top
France Central
IN STA N C E VC P U RA M STO RA GE L IN UX W IN DO W S
back to top
India Central
IN STA N C E VC P U RA M STO RA GE L IN UX W IN DO W S
back to top
UAE North
IN STA N C E VC P U RA M STO RA GE L IN UX W IN DO W S
back to top
Brazil South
IN STA N C E VC P U RA M STO RA GE L IN UX W IN DO W S
back to top
South Africa North
IN STA N C E VC P U RA M STO RA GE L IN UX W IN DO W S
back to top
Australia East
IN STA N C E VC P U RA M STO RA GE L IN UX W IN DO W S
back to top
Australia South East
IN STA N C E VC P U RA M STO RA GE L IN UX W IN DO W S
back to top
Korea Central
IN STA N C E VC P U RA M STO RA GE L IN UX W IN DO W S
back to top
Japan East
IN STA N C E VC P U RA M STO RA GE L IN UX W IN DO W S
back to top
Japan West
IN STA N C E VC P U RA M STO RA GE L IN UX W IN DO W S
back to top
East Asia
IN STA N C E VC P U RA M STO RA GE L IN UX W IN DO W S
back to top
South East Asia
IN STA N C E VC P U RA M STO RA GE L IN UX W IN DO W S
PlayFab is committed to the reliable operation of our services 24/7. However, incidents do occur. This page
describes how you can raise incidents to our attention and how PlayFab communicates our status during
incident mitigation.
Paging PlayFab
If you are a PlayFab enterprise customer, you will have been provided a confidential email address to alert us to
any urgent issues. This email inbox pages our engineering team 24/7, and you will be provided an
acknowledgement within 30 minutes of email receipt.
NOTE
The Status Labels listed in the table are the ones used on our System Status site status.playfab.com.
Severity 1 and 2 outages will be reported as a Major Outage on status.playfab.com. On-going updates will be
provided every 30 minutes through status.playfab.com, Slack, and Teams.
Severity 3 outages will be reported as a Degradation on status.playfab.com, with on-going updates every 60
minutes. These incidents are not communicated through Slack or Teams.
In some cases, PlayFab may detect that a Severity 2 or Severity 3 outage is occurring but only impacting one or
two titles. In these situations, we will not post to status.playfab.com. Instead, we will post to your specific Slack or
Teams channel and provide updates every 30-60 minutes.
Managing server capacity
5/24/2022 • 4 minutes to read • Edit Online
A game servers' ability to scale in response to player demand is dependent on the number of simultaneous
virtual machine cores consumed by a multiplayer server game. If a game server runs out of VM cores,
subsequent requests to allocate VMs will fail. Monitoring server capacity is essential to prevent capacity errors
or diagnosing scaling problems due to player demand. This article describes the Quota Usage page and how to
manage your game server for capacity issues.
To access the quota usage page, navigate to the Multiplayer | Servers | Quota menu. The Quota Usage page
surfaces peak core usage both in visualized charts and a tabulated format. The data powering these metrics is
sampled every 60 minutes.
Detail CSV
The detail CSV contains the data that also produces the peak core usage table but with additional data sampled
at 1 minute intervals. Therefore a detailed export of a peak core usage table filtered for the last hour containing
a single build deployed in 1 region will produce approximately 60 rows (i.e. 1 build & region row per minute).
The schema of the CSV are:
Timestamp GMT timestamp of core reading Fri Nov 20 2020 05:23:32 GMT+0000
NOTE : Like the core usage table, export data is also dependent on the time series selected at the top of the
quota summary page.
In the Multiplayer section of the Game Manager, there is an "Analytics" page on the Servers tab that you can use
to track server consumption. For multiplayer-focused games, server spend can be significant and these tools
help you monitor your estimated bill.
The time-series data available to you via this monitoring experience is a graph showing compute-hours (y-axis)
over time (x-axis). You can adjust the time range.
Multiplayer Servers samples and resources
5/24/2022 • 2 minutes to read • Edit Online
This topic lists samples and resources for PlayFab Multiplayer Game Servers.
Samples
Main repo for all the samples
Wrapper (Windows and Linux)—Using the sample
MpsAllocator—Learn to call frequently used APIs
Windows Runner C#—Using the sample
OpenArena (Linux)
Matchmaking with Server (Using a C# game title)
UnityMirror—Use Unity game engine with PlayFab Multiplayer Servers
Resources
PlayFabMultiplayerAPI module
PlayFab LocalMultiplayerAgent
See also
SDKs overview
Wrapper sample
5/24/2022 • 6 minutes to read • Edit Online
The Wrapper sample, also known as wrappingGsdk, wraps an existing game so it can be used in the deployment
of builds for game servers that use Windows OS and Linux OS .
Using the wrapper application, you would also be able to use your game server build on PlayFab Multiplayer
Servers.
IMPORTANT
A wrapper is a workaround by processing the standard output and error streams to call GSDK methods and it's not
meant for production use.
Sample content
This sample consists of two .NET Core console applications.
Wrapper—integrates the latest Nuget package for the PlayFab Game Server SDK (GSDK) with your game
server. Note that this wrapper application is not meant for production usage
Fakegame—a basic game server that has no knowledge of GSDK. It is like a typical game server that you
would have prior to using PlayFab Multiplayer Servers. It starts the ASP.NET Core Web Server Kestrel that
listens to TCP port 80. It's meant to simulate a game server that has absolutely zero knowledge of GSDK. You
can use it if you don't have a game server of your own. It has two GET routes we can use, /hello for getting a
simple response and /hello/terminate that can terminate the server.
Requirements
.NET Core 3.1 x64 SDK
NOTE
In order to use and view the PlayFab Multiplayer Servers, you need to enable the feature from Game Manager. For
instructions, see Enable the PlayFab Server feature.
Detailed steps
Build Wrapper executable
Open Command Prompt
Use the cd command to change directory path to the wrapper.csproj file location. Example: cd
C:/ReplaceWithYourFilePath/wrappingGsdk/wrapper
Then run the following .NET Core CLI command:
TIP
To cross-check, follow the instructions at Use fakegame project to build the gameassets.zip and use it as a reference.
TAG="0.1"
ACR="customer5555555.azurecr.io"
docker login ${ACR}
TIP
To check that ACR and TAG variables are properly defined, run echo $ACR and echo $TAG .
5. Enter your username and password obtained from the earlier step.
6. Build and upload the Linux container image.
Run the commands below to build and upload the Dockerfile. Note that there is a "." at the end of docker build
command. You have to be in the same folder/directory as the Dockerfile. For details, see Build and upload Linux
container image.
NOTE
During the allocation when using RequestMultiplayerServer API, the port you connect to will be different than 80. This is
because the PlayFab Multiplayer Server service will create a mapping between the Azure Load Balancer (that exposes your
ports to the Public internet) to the game servers running on the Azure Virtual Machines.
// if you are using fakegameserver you should also configure port mapping for port 80
"PortMappingsList": [
[
{
"NodePort": 56100,
"GamePort": {
"Name": "game_port",
"Number": 80,
"Protocol": "TCP"
}
}
]
]
You are now ready to test with LocalMultiplayerAgent. If you have configured it correctly, as soon as
LocalMultiplayerAgent launches your game server, you can connect to it via curl at
http://localhost:56100/Hello .
See also
Create your first server
Resources and samples
PlayFab Multiplayer Server SDKs
API Reference
MpsAllocator sample
5/24/2022 • 2 minutes to read • Edit Online
MpsAllocatorSample can be found here along with the rest of the MPS samples.
This sample is a simple .NET Core application that allows you to easily call some frequently used MPS APIs, like
the ones that list VMs/servers and allocate game servers (RequestMultiplayerServer). To easily and quickly
request a multiplayer server from Game Manager, select the button located at the top of our servers page that
can help you do that. To learn more check out our Servers overview. In order to use it, you need to have installed
.NET Core 3.1 (download here). You can then use either dotnet build command to build an executable for your
platform or just run dotnet run to run the application.
You can find more information about dotnet build command here
In order to authenticate with PlayFab APIs, the app needs your PlayFab TitleID and a developer secret key. To
create a secret key for your title, visit the Settings/Secret-Keys page on the PlayFab developer portal here:
https://developer.playfab.com/en-US/r/t/<Your_TitleID>/settings/secret-keys. You can provide these keys via
environment variables PF_TITLEID and PF_SECRET , or as command line arguments.
The app uses the PlayFab SDK via the corresponding Nuget package
Once you run the application, you can choose which API to call. Each API will ask you to provide necessary
parameters. Here's the list of the available options:
RequestMultiplayerServer: This option will allocate a game server and return its details (IP, FQDN, Port).
Successful invocation of this API call will result in a game server's transition from "StandingBy" state to
"Active" (more here)
ListBuildSummaries: This option will return summaries about your title's Builds
GetBuild: This option will return details about the specified Build
ListMultiplayerServers: This option will return summaries about game servers in a specified Build
ListVirtualMachineSummaries: This option will return summaries about virtual machines in a specified Build
GetMultiplayerServerDetails: This option will return details about a specified game server
See also
Create your first server
Resources and samples
PlayFab Multiplayer Server SDKs
API Reference
Windows Runner C# sample
5/24/2022 • 3 minutes to read • Edit Online
This tutorial lists the steps to get the sample set up ready for use with the PlayFab Multiplayer Servers.
NOTE
In order to use and view the PlayFab Multiplayer Servers, you need to enable the feature from Game Manager. For
instructions, see Enable the PlayFab Server feature.
Log into your developer account on PlayFab.com to use the Game Manager portal
Select your game title
Select the settings icon > API features as shown in the image below.
Under Options , select Allow client to star t games as shown in the image below.
Server set up
Describes how to get the PlayFab Multiplayer Game Server Build.
Download the compiled version of the PlayFab Multiplayer Server Build for the Windows Runner sample.
If you prefer to build this on your own:
Get the Windows Runner C# sample using standard Git methods or downloading this as a zip file.
Open the project using Visual Studio 2017 or later. This should automatically trigger dependencies like
the latest PlayFab Game Server SDK (GSDK) nuget package to be downloaded.
Compile and build the WindowsRunnerCSharp.csproj in release x64 configuration. You would get a
game server build that is integrated with the GSDK, making this a valid PlayFab Multiplayer Game
Server Build.
Go to the bin folder and zip up all the x64 release binaries. There should be no internal folder
structure, the zip file should be a simple flat collection of files, as shown in the image below.
TIP
To cross-check, you can compare your build output with the compiled version provided in the link above.
When you have the zip file, you are ready to start deploying a build.
Client set up
Describes how to get the Windows Runner client application to connect to the game servers you've created
using PlayFab Multiplayer Servers. This can only be set up after you have servers in standby.
After deploying a build, wait for standby servers to be available
Get the titleId and buildId of the build
Using Game Manager:
Go to My Studios and Titles page and look for your game title. Copy the ID value listed there
and paste it somewhere convenient that you can access later. This is the titleId
Select the game title to view the dashboard
Go to Multiplayer > Ser vers > Builds
Copy the ID for the build you want to use and paste it somewhere convenient. This is the
buildId
Using PowerShell, this information is in the output after the build is deployed successfully.
Copy the titleId and buildId and paste it somewhere convenient
Get the Windows Runner C# sample using standard Git methods or downloading this as a zip file. Skip if
you have done this earlier.
Open the project using Visual Studio 2017 or later. This should automatically trigger dependencies like
the latest Game Server SDK nuget package to be downloaded.
Compile and build the WindowsRunnerCSharpClient.csproj in release x64 configuration
Open Command Prompt and navigate to the output folder of this project
Run the WindowsRunnerCSharpClient using this command line, replacing <TitleId> and <BuildID> with
the values above: dotnet WindowsRunnerCSharpClient.dll --titleId <TitleId> --buildId
<BuildId>
Example:
cd
C:\Users\UserName\Documents\GitHub\MpsSamples\WindowsRunnerCSharp\WindowsRunnerCSharpClient\bin\Release\netc
oreapp3.1
When the client successfully connects to the server, the Command Prompt would display a log message
informing you that a server is allocated with an IP address.
See also
Create your first server
Resources and samples
PlayFab Multiplayer Server SDKs
API Reference
Walkthrough: Deploy builds using Game Manager
5/24/2022 • 2 minutes to read • Edit Online
This topic describes how to deploy builds for VMs using Windows OS in Game Manager based on the Windows
Runner C# sample.
NOTE
In order to use and view the PlayFab Multiplayer Servers, you need to enable the feature from Game Manager. For
instructions, see Enable the PlayFab Server feature.
Deploying a build is one of the processes in creating a game server using the Windows Runner C# sample.
Prerequisites
Make sure you have completed the following steps.
Configure API feature option
Server set up.
Steps
1. Log into your developer account on PlayFab.com
2. Go to My Studios and Titles page and select your game title to display the dashboard
3. Go to Multiplayer > Ser vers page, select New Build at the top right to create a new build
4. Use "My build" as the Build Name
5. Select a server with limited free usage, such as Av2 (until July 2021) and Dasv4 (from July 2021)
6. Set 1 for Servers per machine
Image below shows values used in the info section section.
7. Under Virtual Machine OS, select Windows as the platform, Windows Ser ver Core as the Container
image
Image below shows values used in the OS section.
8. Under Assets, select Upload then navigate to folder with the compiled PlayFab Multiplayer Server Build for
the WindowsRunnerSample. To get the Build, see Server side set up
Set C:\Assets as the mount path
Image below shows values used in the assets section.
9. Set C:\Assets\WindowsRunnerCSharp.exe as the Start Command.
10. For network, use port 3600 using game_por t as the name. Use TCP as the protocol as shown in the
image below.
11. Under Regions, select "East US", 1 standby server and 1 maximum server.
12. Select Save to start the deployment process. You will be taken to the build home page. The build will
display the Deploying status as show in the image below. In 10 to 20 minutes, your build should be in
the Deployed state.
After servers are deployed, set up the client and connect to the servers.
See also
Walkthrough: Deploying builds using PowerShell/API
Windows Runner C# sample
Samples and resources
Walkthrough: Deploy builds using PowerShell/API
5/24/2022 • 2 minutes to read • Edit Online
This topic describes how to deploy/create builds for Windows OS VMs in PowerShell on a Windows 10
development device based on the Windows Runner C# sample.
NOTE
In order to use and view the PlayFab Multiplayer Servers, you need to enable the feature. We recommend that you use
the Game Manager method to enable this feature. For instructions, see Enable the PlayFab Server feature.
Prerequisites
Make sure you have completed the following steps.
Configure API feature option
Server set up.
Uninstall-Package PlayFabMultiplayer
Both the commands and arguments are different in this new module. For detailed documentation about each
command, see Cmdlet documentation.
4. Upload assets
When you deploy Windows servers, you would use the managed Windows Container. All you have to do is to
upload the PlayFab Multiplayer Game Server Build as an asset.
Update the value of the FilePath flag with the local file location of winrunnerSample.zip . If you don't know
where this file is, follow the instructions here to get the file.
5. Create a build
Now that the asset is uploaded, we can create a build. Run the following commands.
The code below uses the Standard_D2as_v4 VM in the EastUS region. Replace strings according to the VM
and region you want to use.
$vmSize = "Standard_D2as_v4"
# All PlayFabMultiplayerApi cmdlets return objects, so we can pass the returned object to ConvertTo-Json for
human readability.
$buildResponse | ConvertTo-Json -depth 5
This topic lists the different flavors of Azure PlayFab Multiplayer Game Server SDKs (GSDKs) we have today.
Download links
Note that these SDKs are for the servers.
Game Server SDK GitHub repo for all libraries
Unity Game Server SDK (GSDK)
C++ Game Server SDK (GSDK) for Windows servers via NuGet
C# Game Server SDK (GSDK) for Windows servers via NuGet
Java Game Server SDK (GSDK) for Windows and Linux servers via Maven
TIP
Unsure if this is the SDK you need? See SDKs overview - PlayFab SDK, Party SDK, Multiplayer Game Server SDK.
See also
SDKs overview
How to use PlayFab GSDK Unreal plugin
5/24/2022 • 3 minutes to read • Edit Online
This article describes how to integrate PlayFab Multiplayer Server SDK (GSDK) Unreal Online Subsystem (OSS)
plugin with your Unreal project.
This plugin offers both a Blueprint API and a C++ API. The Blueprint API still requires your Unreal Project to be a
C++ project, and will not work on a Blueprint only project. If it is currently a Blueprint only project, then you
need to convert to a C++ project beforehand, before adding the plugin.
It has been originally tested with Unreal Engine 4.26, 4.27, 5.0 early access, and 5.0 official release . This plugin
will be actively maintained to work with the latest 3 - 4 versions of Unreal. If something fails using these
versions, please open an issue here: Unreal Engine GSDK Repo.
To use these guides, replace all instances of ThirdPersonMP with your project name, if different.
Requirements
Download Visual Studio. The community version is free.
Required workloads: .NET desktop development and Desktop development with C++
Download Unreal Engine Source Code. For instructions, see Downloading Unreal Engine Source code
(external).
If you haven't already, perform a git clone this repo to your local machine
git clone https://github.com/PlayFab/gsdk.git
Later steps will involve integrating files from this repo to your project
[Optional] Download the LocalMultiplayerAgent
[Optional] Alternatively, download LocalMultiplayerAgent source.
[Optional] PlayFab Marketplace plugin or the source version on GitHub. This plugin is not required for GSDK
but is required for many PlayFab services, including login.
Project creation
The Unreal server project needs to be a network-enabled multiplayer Unreal project with a dedicated-server
mode. If you don't have a project that meets these prerequisites, follow our Unreal prerequisite set up guide to
set one up. Once you have a network-enabled, multiplayer project, with a dedicated server, return to this step
and continue.
When ready, open your network-enabled multiplayer Unreal server project, and continue to the next step to
install the Unreal GSDK.
Deploy to PlayFab
You're now ready to create game-servers in the cloud using PlayFab Multiplayer Services. PlayFab MPS supports
Windows servers and Linux servers.
Acknowledgments
Thank you to Stefan Krismann for creating and submitting this plugin.
Thank you to Nick Arthur for his amazing Dockerfile.
Thank you to Adam Rehn for all his work with Unreal and Docker, including code, samples, examples, and
tutorials.
Example Project Setup
5/24/2022 • 2 minutes to read • Edit Online
This guide covers the construction of an example project which can operate as a game-client and dedicated
game-server. This will set up the minimum requirements for an Unreal project, before the GSDK can be
integrated.
This guide is an excellent starting point if you are starting from scratch.
Goals
The project needs to have the following capabilities and features:
Networking
Multiplayer
Dedicated Game-Server
To accomplish this, we will construct a project from scratch using Unreal tutorials.
Requirements
Download Visual Studio. The community version is free.
Required workloads: .NET desktop development and Desktop development with C++
Download Unreal Engine Source Code. For instructions, see Downloading Unreal Engine Source code
(external).
Instructions
All of the necessary instructions are in the Unreal Tutorials. First, download Unreal Engine Source Build by
following these instructions from the Unreal Engine website.
Next, you should follow the Unreal Third Person Template tutorial. This covers the creation of a basic project we
will use for the rest of this document.
Then, you should proceed to the Unreal Multiplayer Programming Quick Start tutorial. Note, the first step of this
tutorial is an abbreviated version of the one above. This guide upgrades the ThirdPersonMP template to a
multiplayer project.
Once finished with the above guides, you will have a working multiplayer game-client. Next, you need a
dedicated server. At this point, you should proceed to the Unreal Setting Up Dedicated Servers tutorial. This will
set up a dedicated server for your project, and concludes our list of requirements.
Once finished with all guides, you will have a network-enabled multiplayer project with a dedicated game-
server.
Next steps
You are now ready to install the PlayFab Unreal GSDK into this project.
Alternately, you can return to the main Unreal GSDK Plugin guide.
Add GSDK to Project
5/24/2022 • 8 minutes to read • Edit Online
This article describes how to upgrade an existing project so it can be hosted on PlayFab Multiplayer Servers
(MPS). The process involves adding and configuring PlayFab GSDK into an Unreal project. The instructions here
are written using the Unreal ThirdPersonMP template project.
Note, your Unreal project must have the following capabilities:
Networking
Multiplayer
Dedicated Game-Server
If not, you will need to return to the Example Project Setup guide to configure your project as a network-enabled
multiplayer game, with dedicated server capabilities.
Goals
We will add and configure the PlayFab Unreal GSDK to your project, and test it locally to verify it is expected to
work on PlayFab Multiplayer Services.
Requirements
Download Visual Studio. The community version is free.
Required workloads: .NET desktop development and Desktop development with C++
Download Unreal Engine Source Code. For instructions, see Downloading Unreal Engine Source code
(external).
A completed ThirdPersonMP Example Project, or a project with similar capabilities
PlayFab Unreal GSDK plugin
[Optional] PlayFab Marketplace plugin or the source version on GitHub. This plugin is not required for GSDK
but is required for many PlayFab services, including login.
C++ Implementation
Add the plugin to the project
Follow these steps to add the Unreal GSDK to your project:
Go to your Unreal project
Open File Explorer and create a Plugins folder in your games' root directory. In the Plugins folder, create a
folder called PlayFabGSDK.
Go to {depot}\GSDK\gsdk\UnrealPlugin . Drag all the files from the UnrealPlugin folder into the
Plugins/PlayFabGSDK folder.
Lastly, open the {ProjectName}.uproject file in a text editor of your choice. In the plugins array, add the
"PlayFabGSDK" plugin.
See the example below:
{
"FileVersion": 3,
"EngineAssociation": "{YourEngineVersion}",
"Category": "",
"Description": "",
"Modules": [
{
"Name": "{ProjectName}",
"Type": "Runtime",
"LoadingPhase": "Default",
"AdditionalDependencies": [
"Engine"
]
}
],
"Plugins": [ // Add this if it doesn't exist
{ // Add this
"Name": "PlayFabGSDK", // Add this
"Enabled": true // Add this
} // Add this
] // Add this if it doesn't exist
}
Right-click on the {ProjectName}.uproject file and select the option to Switch Unreal Engine version ,
which is how you can quickly check which Unreal Engine version you are currently using. The popup seen
below should appear. If you already see that the Unreal Engine version is source build, you don’t need to
change anything, so click Cancel. If the Unreal version is not currently the source build, select it from the
dropdown list and then click OK.
Right-click on the {ProjectName}.uproject file again and select "Generate Visual Studio Project Files".
Finally, build the project in Visual Studio and start the Editor by selecting the Development Editor
configuration.
Project set up
Once your project has enabled server mode, you will have a {ProjectName}Server.Target.cs file.
Result should look similar to:
For Windows builds, you may need to add these optional configurations:
DisablePlugins.Add("WMFMediaPlayer");
DisablePlugins.Add("AsyncLoadingScreen"); //if you are using this plugin
DisablePlugins.Add("WindowsMoviePlayer");
DisablePlugins.Add("MediaFoundationMediaPlayer");
First, check the include statements and ensure that the following are included in the header file for your
GameInstance class ([YourGameInstanceClassName].h):
#include "CoreMinimal.h"
#include "Engine/GameInstance.h"
#include "MyGameInstance.generated.h"
[Optional] With the following code, the user can introduce a log channel specifically for the GameInstance.
Alternatively, logging with LogTemp is sufficient.
Then, add the following declarations to the public section: (If you already have an Init() function, there is no need
to include another declaration)
public:
protected:
UFUNCTION()
void OnGSDKShutdown();
UFUNCTION()
bool OnGSDKHealthCheck();
UFUNCTION()
void OnGSDKServerActive();
UFUNCTION()
void OnGSDKReadyForPlayers();
};
M o d i fy t h e G a m e I n st a n c e C P P fi l e
#include "[YourGameInstanceClassName].h"
#include "PlayfabGSDK.h"
#include "GSDKUtils.h"
If the custom log channel has been introduced in the header file, then the following code is necessary:
DEFINE_LOG_CATEGORY(LogPlayFabGSDKGameInstance);
Then locate your Init() function. If you don't have an Init() function yet, then add in the function as such:
C re a t e I n i t ( ) f u n c t i o n
void U[YourGameInstanceClassName]::Init()
{
FOnGSDKShutdown_Dyn OnGSDKShutdown;
OnGSDKShutdown.BindDynamic(this, &UMyGameInstance::OnGSDKShutdown);
FOnGSDKHealthCheck_Dyn OnGSDKHealthCheck;
OnGSDKHealthCheck.BindDynamic(this, &UMyGameInstance::OnGSDKHealthCheck);
FOnGSDKServerActive_Dyn OnGSDKServerActive;
OnGSDKServerActive.BindDynamic(this, &UThirdPersonGameInstance::OnGSDKServerActive);
FOnGSDKReadyForPlayers_Dyn OnGSDKReadyForPlayers;
OnGSDKReadyForPlayers.BindDynamic(this, &UThirdPersonGameInstance::OnGSDKReadyForPlayers);
UGSDKUtils::RegisterGSDKShutdownDelegate(OnGSDKShutdown);
UGSDKUtils::RegisterGSDKHealthCheckDelegate(OnGSDKHealthCheck);
UGSDKUtils::RegisterGSDKServerActiveDelegate(OnGSDKServerActive);
UGSDKUtils::RegisterGSDKReadyForPlayersDelegate(OnGSDKReadyForPlayers);
}
If you already had an Init() function, go to check in [YourGameInstanceClassName].cpp file to see if you have a
variable that indicates whether the instance is for a dedicated server. If you can find this variable , then add
the following to the end of your Init() function:
M o d i fy exi s ti n g I n i t() fu n c ti o n
if (IsDedicatedServerInstance() == true)
{
FOnGSDKShutdown_Dyn OnGsdkShutdown;
OnGsdkShutdown.BindDynamic(this, &UShooterGameInstance::OnGSDKShutdown);
FOnGSDKHealthCheck_Dyn OnGsdkHealthCheck;
OnGsdkHealthCheck.BindDynamic(this, &UShooterGameInstance::OnGSDKHealthCheck);
FOnGSDKServerActive_Dyn OnGSDKServerActive;
OnGSDKServerActive.BindDynamic(this, &UShooterGameInstance::OnGSDKServerActive);
FOnGSDKReadyForPlayers_Dyn OnGSDKReadyForPlayers;
OnGSDKReadyForPlayers.BindDynamic(this, &UShooterGameInstance::OnGSDKReadyForPlayers);
UGSDKUtils::RegisterGSDKShutdownDelegate(OnGsdkShutdown);
UGSDKUtils::RegisterGSDKHealthCheckDelegate(OnGsdkHealthCheck);
UGSDKUtils::RegisterGSDKServerActiveDelegate(OnGSDKServerActive);
UGSDKUtils::RegisterGSDKReadyForPlayers(OnGSDKReadyForPlayers);
}
Complete the Init() function by calling the following function that sets up the default port for MPS.
#if UE_SERVER
UGSDKUtils::SetDefaultServerHostPort();
#endif
void UMyGameInstance::OnGSDKShutdown()
{
UE_LOG(LogPlayFabGSDKGameInstance, Warning, TEXT("Shutdown!"));
FPlatformMisc::RequestExit(false);
}
bool UMyGameInstance::OnGSDKHealthCheck()
{
UE_LOG(LogPlayFabGSDKGameInstance, Warning, TEXT("Healthy!"));
return true;
}
void UThirdPersonGameInstance::OnGSDKServerActive()
{
/**
* Server is transitioning to an active state.
* Optional: Add in the implementation any code that is needed for the game server when
* this transition occurs.
*/
UE_LOG(LogPlayFabGSDKGameInstance, Warning, TEXT("Active!"));
}
void UThirdPersonGameInstance::OnGSDKReadyForPlayers()
{
/**
* Server is transitioning to a StandBy state. Game initialization is complete and the game
* is ready to accept players.
* Optional: Add in the implementation any code that is needed for the game server before
* initialization completes.
*/
UE_LOG(LogPlayFabGSDKGameInstance, Warning, TEXT("Finished Initialization - Moving to StandBy!"));
}
Blueprint implementation
This part is only needed if you have decided to proceed with the Blueprint implementation and not with the pure
C++ implementation. Some of the nodes presented below are outdated. We advise users who prefer the
Blueprint implementation to consult the C++ implementation for the nodes that will be required.
Observe the Content Browser window in the Unreal Editor
Pick or create a folder to contain new Blueprints
Right-Click and create a Blueprint class
In the All classes dropdown menu, find your GameInstance class
In this example, the blueprint is named "MyGameInstance"
Double-click the blueprint
On the left side, hover over the function field and select the Override dropdown
Select the Init function
Right-click in the graph and add in all register GSDK function
For GSDK Shutdown and Maintenance Delegate drag out a line from the red square, and select "Add Custom
Event"
For "Register GSDK Health Check Delegate", select the "Create Event" in the "Event Dispatchers".
In the dropdown of the new node "Create matching function". This is impor tant, as the GSDK Health
Check Delegate has a return value.
Don't forget to connect all the nodes to the Event Init node.
Add "Ready for Players" to be able to react to the ready signal of PlayFab.
Set the GameInstance class
After creating a custom GameInstance class that integrates with the gsdk, you have to configure your project to
actually use this newly created GameInstance class. There are two ways to do this - either through the Unreal
Engine editor or by editing DefaultEngine.ini directly.
In the Unreal Editor
In the editor, the default GameInstance can be set through the UI in the editor. In the editor, go to Edit -> Project
Settings . From that opened window, navigate to Maps&Modes on the left side. Scroll to the bottom, and then
you can set the option GameInstanceClass to your new GameInstance class directly (avoid typos, it must be an
exact match).
In DefaultEngine.ini
Or you can update DefaultEngine.ini file and add the following lines:
[/Script/EngineSettings.GameMapsSettings]
GameInstanceClass=/Script/{ProjectName}.MyGameInstance
[/Script/UnrealEd.ProjectPackagingSettings]
IncludeAppLocalPrerequisites=True
If the category already exists in your DefaultGame.ini, then just add the second line to it. This configuration
ensures that all app local dependencies ship with the project as well.
If you are using Continuous Integration (CI), then you could add it to your setup to only turn on this flag when
building a dedicated server, so the prerequisite dlls only get added if it is a dedicated server build.
Next steps
You are now ready to build your project on your local machine.
Alternately, you can return to the main Unreal GSDK Plugin guide.
Build the ThirdPersonMP Example Project
5/24/2022 • 3 minutes to read • Edit Online
This article describes how to successfully build a PlayFab Multiplayer compatible Unreal project using the Unreal
ThirdPersonMP sample as a template project. In this guide you will find all the build configurations needed by
later steps to test and verify your Unreal project. There are no special GSDK steps on this page, this only covers a
specific set of Unreal build instructions useful for this example.
Goals
Build the "Development Editor"
Build a game-client
Build the "Development Server"
Build a release Server
Requirements
Download Visual Studio. The community version is free.
Required workloads: .NET desktop development and Desktop development with C++
Download Unreal Engine Source Code. For instructions, see Downloading Unreal Engine Source code
(external).
Completed Unreal Project with PlayFab Unreal GSDK installed and configured
Knowledge about Unreal Build Configuration options
Instructions
The GSDK setup guide previously described the steps to "Switch Unreal Engine Version" and "Generate Visual
Studio project files". There is also an Unreal guide about the various compilation options, which you should
review.
Development Editor
The development editor should be the first thing you build. To do this, find your {ProjectName}.uproject file,
right-click, and "Generate Visual Studio project files" (You may have already done this in the previous guide, in
which case, you can skip this step. Once complete, you can open {ProjectName}.sln in Visual Studio.
Once Visual Studio loads, change your configuration to "Development Server". The Solution Configuration
dropdown is sometimes hard to read, but can be resized in the toolbar customization options. Now, build. The
first time you do this, it can take several hours, but you likely did this in the previous guide. Repeated builds
should be fairly fast for a small project. Once finished, you can run/debug the project
Solution/Games/ThirdPersonMP. This will start the Development Editor.
Build Shipping Client
Run the Development Editor. From the development editor window, pick these options in this order:
File -> Package Project -> Build Target -> ThirdPersonMP (Or the name of your project)
File -> Package Project -> Build Configuration -> Development
File -> Package Project -> Windows (64-bit)
(This opens a popup window asking you to pick a location - make sure you remember this location)
The first time packaging occurs in this configuration, it may take a while
The first shipping client build will take upto multiple hours, even if you've already built Development
Editor
Repeat builds will be much faster for a simple project like ThirdPersonMP
Open the client location you picked and find ThirdPersonMP.exe
Build Development Server
Close the Development Editor (Unreal is no longer running, only Visual Studio should be open now)
Toolbars -> Configuration -> "Development Server"
Build/Rebuild Solution
The first time packaging occurs in this configuration, it may take a while
The first development server build will take upto multiple hours, even if you've already built
Development Editor
Repeat builds will be much faster for a simple project like ThirdPersonMP
Use Explorer to find {projectLocation}\Binaries\Win64\ThirdPersonMPServer.exe
Build Shipping Server
Run the Development Editor. From the development editor window, pick these options in this order:
File -> Package Project -> Build Target -> ThirdPersonMPServer (Or the name of your project)+Server
File -> Package Project -> Build Configuration -> Development
File -> Package Project -> Windows (64-bit)
(This opens a popup window asking you to pick a location - make sure you remember this location)
The first time packaging occurs in this configuration, it may take a while
The first shipping server build will take upto multiple hours, even if you've already built Development
Editor
Repeat builds will be much faster for a simple project like ThirdPersonMP
Open the server location you picked and find ThirdPersonMPServer.exe
Next steps
You are now ready to deploy your game server on your local machine.
Alternately, you can return to the main Unreal GSDK Plugin guide.
ThirdPersonMP Example Project Local Deployment
and Debugging
5/24/2022 • 6 minutes to read • Edit Online
The purpose of this guide is to demonstrate running your game-server on your local machine, in a MPS-
compliant way, so you can test and debug your server before uploading it to PlayFab.
Goals
Test the local deployment options for the ThirdPersonMP+GSDK project.
Verify your server executes properly when run using LocalMultiplayerAgent
Verify you can attach a debugger to your server instance
Requirements
Download Visual Studio. The community version is free.
Required workloads: .NET desktop development and Desktop development with C++
Download Unreal Engine Source Code. For instructions, see Downloading Unreal Engine Source code
(external).
Completed Unreal Project with PlayFab Unreal GSDK installed and configured
"Development Server" configuration of your project built from Visual Studio
[Optional] Download the LocalMultiplayerAgent
[Optional] Alternatively, download LocalMultiplayerAgent source.
"Debug" or "Release" configuration of LocalMultiplayerAgent built from this repo with Visual Studio
Using Visual Studio, Open MpsAgent.sln, Select either Debug or Release configuration, and then build
the LocalMultiplayerAgent.
[Optional] Install Docker for Windows
Notation
{depot} will refer to the full windows path for the location where you download your Git projects. These can be
anywhere you like, such as: C:\depot, S:\depot, Z:\gitrepos or whichever drive and path are convenient for you. It
is typically recommended (especially for Unreal), that your {depot} path be very short, if possible. For the author,
{depot} resolves to: M:\depot\GSDK . For example, with the requirements list above, you will likely have some or
all of the following:
{depot}/ThirdPersonMP
{depot}/MpsAgent
[Optional] {depot}/gsdk [This contains the PlayFab Unreal GSDK plugin previously installed into
ThirdPersonMP]
[Optional] {depot}/UnrealMarketplacePlugin [This contains the PlayFab Unreal Marketplace plugin, which is
not required for this guide, but almost certainly required for other PlayFab features]
It is not required that you have all of these in the same location, but it is likely useful to do so, and for
organization, this guide encourages you to do so.
Instructions
Local execution, no containers
First, you will need to configure your LocalMultiplayerAgent to execute your server project. The first iteration
will run the process directly on your local PC without any isolation.
In Explorer, find and open the file: {depot}\MpsAgent\LocalMultiplayerAgent\MultiplayerSettings.json . An
abbreviated version of this file with the parts important to this guide are as follows [NOTE the escaped \'s for
paths in the json - this is a json file, and thus it's required to escape all \'s as \\]:
{
"RunContainer": false,
...
"AssetDetails": [
{
"MountPath": "C:\\Assets",
"LocalFilePath": "{PATH-TO-ZIP}"
}
],
...
"PortMappingsList": [
[
{
"NodePort": 30000,
"GamePort": {
"Name": "UnrealServerGsdkHostPort",
"Number": 8888,
"Protocol": "UDP"
}
}
]
],
"ProcessStartParameters": {
"StartGameCommand": "{PATH-TO-EXE} -log"
},
"ContainerStartParameters": {
"StartGameCommand": "C:\\Assets\\ThirdPersonMPServer.exe -log",
...
}
}
For the purposes of this guide, the parts of the json file obscured by ... above, just utilize the project defaults.
The purpose and values for the important fields are as follows:
RunContainer: For this guide, this will always be false. Setting this to true requires Docker.
When true, the ProcessStartParameters/StartGameCommand is ignored, and
ContainerStartParameters/StartGameCommand is used instead
When true, everything is built and run in a docker container, rather than on the local machine context
This guide covers the scenario when RunContainer is false, so that we can more easily debug the
server process
Setting this to true requires a Shipping Server build, additional Windows DLLs or Linux dependencies,
and Docker for Windows
AssetDetails/LocalFilePath: {PATH-TO-ZIP}
This location must be fully defined, and a valid zip file must exist at this location
This zip file should contain a fully constructed "Shipping Server" build
PortMappingsList:
This is the LocalMultiplayerAgent equivalent of defining the port in Game Manager
The GSDK plugin is hard-coded to look for a port with the name: UnrealServerGsdkHostPort
The GSDK plugin SetDefaultServerHostPort method will internally override the internal Unreal server-
hosting port to match this port
The GSDK plugin will only use the port named UnrealSer verGsdkHostPor t , which is configured in
Por tMappingsList when using LocalMultiplayerAgent.
This json lets you locally test driving this port number from MPS, and ensures your GSDK plugin will
receive it properly
ContainerStartParameters/StartGameCommand: While RunContainer is false, this is unused.
When RunContainer==true, it supersedes the ProcessStartParameters/StartGameCommand
This path is the internal path within the docker container, and will be the sum of
AssetDetails/MountPath, plus the internal path-to-exe in your zip file defined by
AssetDetails/LocalFilePath
For this example, this could be: C:\\Assets\\ThirdPersonMPServer.exe -log
ProcessStartParameters/StartGameCommand: This command will effectively be the path to your exe, and any
command-line parameters used to start your game server
-log is an Unreal command to instruct the game-server to save an execution log
{PATH-TO-EXE} can be one of two choices:
Any absolute path to an exe for your game server (even development game server), plus any
command-line parameters for your server
This choice will ignore the contents of the zip file, and instead execute any arbitrary exe
in any location
This is a local debug option that only works on your local machine to debug
development builds: It does not help you verify your zip file is ready to upload to MPS
This choice should be used when testing a development server, suitable for attaching a
VS debugger
For this example, this could be:
{depot}\\ThirdPersonMP\\Binaries\\Win64\\ThirdPersonMPServer.exe -log
For the author, this is:
M:\\depot\\GSDK\\ThirdPersonMPGSDK\\Binaries\\Win64\\ThirdPersonMPServer.exe -log
A relative path, which should indicate the relative path into your zip file, to run your server
This is the standard workflow that mirrors how it works on an MPS cloud instance
This choice should be used when testing a shipping server, and helps verify your zip is
ready to upload to MPS
For this example, this could be: ThirdPersonMPServer.exe -log
Once you have created your zip file and set all of these lines to appropriate values, you can rebuild your
LocalMultiplayerAgent, and prepare to debug your server.
Debug your server
You can run LocalMultiplayerAgent from Visual Studio with the "Start New Instance" command, sometimes
bound to F5, or you can navigate to {depot}\LocalMultiplayerAgent\bin\{configuration}\netcoreapp3.1 and
double-click "LocalMultiplayerAgent.exe". You can also run this from within a cmd window to observe or capture
debug log information.
Running LocalMultiplayerAgent.exe should start your game server. You will usually want to have Task Manager
open for this. You can find your game server process ID in the Details tab of Task Manager.
Once you see your ThirdPersonMPServer process running in Task Manager, you can return to Visual Studio,
select the Debug dropdown -> Attach to Process. From the popup window, you can search your process name:
ThirdPersonMPServer, and then select the proper process ID, identified from Task Manager.
At this point, you should be able to perform typical debugging into your game server.
NOTE: Unreal provides multiple build configurations and multiple ways to build your server. For best results, use
the "Development Server" configuration, and output, built directly from Visual Studio. Shipping builds, or builds
from the Development Editor may work better for other situations, but the "Development Server" configuration
built directly from Visual Studio will be easier to attach and debug in Visual Studio.
Troubleshooting
Many instances of ThirdPersonMPServer in Task Manager
If there are multiple instances listed (usually 3 or more), you may need to use Task Manager to force-close
instances that are lingering from previous attempts.
LocalMultiplayerAgent launches 2 instances of ThirdPersonMPServer
If your LocalMultiplayerAgent starts multiple instances, look for the process ID with a comparatively high
memory use. Some configurations of the game server generate two executables, which run as a pair. You will
want to attach to the one with a much higher memory use.
Next steps
You are now ready to deploy your server to the cloud.
Alternately, you can return to the main Unreal GSDK Plugin guide.
Deploy and Run Windows Server in the Cloud
5/24/2022 • 5 minutes to read • Edit Online
This guide explains how to deploy your Windows server build to PlayFab Multiplayer Server (MPS) cloud. This is
great for testing and rapid iteration of your game server while in development. Many users will use Linux
servers for a production release after testing with Windows.
Goals
Deploy a project to the cloud.
Connect to it from a local game-client
Requirements
Download Visual Studio. The community version is free.
Required workloads: .NET desktop development and Desktop development with C++
Download Unreal Engine Source Code. For instructions, see Downloading Unreal Engine Source code
(external).
Completed Unreal Project with PlayFab Unreal GSDK installed and configured
Release Server configuration of your project built from Visual Studio or Development Editor
Client configuration of your project built from Visual Studio or Development Editor
MPS is enabled for your title, and billing is set up
[Optional] Install Docker for Windows
Instructions
Package the game -server
[OPTIONAL] This section can be done to refresh the files which Unreal builds into your project. This is useful
if you've recently created or deleted files.
If you have not recently built your project in "development editor" configuration, do so now
Close Visual Studio
Navigate to the {ProjectName}.uproject file for your project
Right-click on the {ProjectName}.uproject file in your file editor and select "Generate Visual Studio
Project Files"
Re-open the {ProjectName}.sln file in Visual Studio
Select Development Editor configuration
Run your project
Observe the Unreal Editor, which should have loaded your project
In the top left of the Unreal editor menu, Select File -> Package -> Build Target -> {ProjectName}Ser ver
Select File -> Package -> Build Configuration -> Shipping
Select File -> Package -> Windowsx64
Select and remember an output location {ShippingServerFolder}
You can now use this packaged version of your game-server to test with LocalMultiplayerAgent
Once verified with LocalMultiplayerAgent, see creating a build guide
Testing on MPS at this point will require an intermediate tool from PlayFab MpsAllocatorSample
This tool bypasses some client work for now, and allows us to allocate a server without a direct
request from the game-client
The proper way to do this on a client is a separate topic covered in the allocation guide.
Zip your Shipping Server build from {ShippingServerFolder} above
Your zip should contain everything in {ShippingServerFolder}, optionally at the root of the zip file
[Optional] IE, the root of your zip should contain {ProjectName}Server.exe (It's suggested the exe
should not be in a subfolder such as "WindowsServer". Rebuild your zip if desired)
Get familiar with the build creation process guide
Specific details for specific configurations are detailed below:
Set up a Windows Dedicated Server on PlayFab
This section will cover creating a build in PlayFab MPS, uploading your game-server, and connecting to it for the
first time. You can also follow the core MPS server creation guide for less Unreal specific instructions.
Navigate to Game Manager -> Multiplayer
Select New Build
Give the build a name
Select a Virtual Machine (For the samples described in these guides, the recommended option with the
fewest cores is sufficient)
Servers per machine can be approximately 1~10
Improving/Raising this number is based on the performance of your game-server
You can use VM metrics to measure performance of your game server, and optimize to raise this
number
Skip Ser ver details for now (covered in the next step)
In the Assets block, drag your zip file from the previous section into the upload box
If you're re-launching, you can select Use existing assets
Wait for the upload to complete
Skip Star t Command for now (covered in the next step)
In the Network block, set the Port Name field to UnrealServerGsdkHostPort
It's mandatory to define the port that will be used to connect to your game-server
Unreal GSDK contains code to read this port automatically, and internally override the Unreal Server
host port according to this value
The name of this port is required to be UnrealServerGsdkHostPort
Continue to the next step that matches the "Server Details" that you want to configure
Option 1: Windows Process Mode
This option runs your game-server(s) as a process directly on the VM. Your processes will share access to the full
machine, including ports, drives, etc. This option unzips your asset upload, and executes the "Start Command"
from the location of your unzipped files as the working directory.
In Ser ver Details , select Process and Windows
In Assets , set the start command to:
{ProjectName}Server.exe or {ProjectName}Server.exe -log if you want to generate log files
The start command is executed from the command-line, using your unzipped asset files as the
working directory
If you chose to pack your zip file with sub-folders, you can specify a relative path such as:
WindowsServer/{ProjectName}Server.exe to access your project with a relative sub-path
Select Add Build
Skip ahead to the Configure Regions section below
Option 2: Windows Container Mode
This option runs your game-server(s) in docker containers, isolating them from each other. Each server process
will have a separate virtual drive, virtual network ports, etc. This option unzips your asset to a Mount Path you
will define, and expects your start command to be a full path, based on the Mount Path.
Prerequisite requirement: Configure Docker to run Windows containers
In Ser ver Details , select Process and Windows
In Assets
Set the Mount Path for your gameServer zip file to C:\assets (or something similar, denoted as
{MountPath})
Set the start command to: {MountPath}\{ProjectName}Server.exe or
{MountPath}\{ProjectName}Server.exe -log if you want to generate log files
The start command should represent a full path in the container, to your -Server.exe file
If you chose to pack your zip file with sub-folders, you can specify an absolute path such as:
{MountPath}\WindowsServer\{ProjectName}Server.exe to access your project with an absolute sub-path
Select Add Build
Skip ahead to the Configure Regions section below
Next steps
Many users will want to test their server by connecting a game client.
Other users may optionally continue on to rebuild and redeploy their servers using Linux containers. Linux
reduces the server-hosting costs for large-scale deployment.
Otherwise, you can return to the main Unreal GSDK Plugin guide.
Set up a Linux Dedicated Server on PlayFab
5/24/2022 • 4 minutes to read • Edit Online
The purpose of this guide is to describe all the steps needed to build and verify a Linux dedicated server. The
following steps are specific to Unreal Engine 5 (both early access and official release). The same set of steps have
been tested and apply also to UE 4.26 and UE 4.27, with some minor differences related to the location of the
packaging option on the Unreal Engine UI, which is different in UE 4.27 and UE5 early access.
More Linux deployment information can be found here
Requirements
Install Unreal Linux prerequisites
Install Docker for Windows
Instructions
From Unreal Linux prerequisites , download the toolchain for your installed Unreal Engine and run the
executable. Note, like many parts of these guides, these steps will work only if your Unreal Engine built from
source.
After the installation is complete, examine your Windows environment variables and confirm the
following system variable exists: LINUX_MULTIARCH_ROOT .
In your Unreal Engine source directory:
Rerun: Setup.bat
Rerun: GenerateProjectFiles.bat
Return to your own project:
Right-click your {ProjectName}.uproject file, and Generate Visual Studio project files
Open the {ProjectName}.sln file in Visual Studio
Set the configuration to Development Editor
Build and run the Unreal Editor
At this point, you should be able to package your project for Linux server in a directory of your choice.
For Unreal Engine 5, in the Editor, click packaging on the top right of the screen and the Linux option
should now be available to be selected. For UE 4.26 and UE 4.27, the packaging option lies under the
file tab.
Confirm your configurations for Server & Shipping, select Linux to build, and then select the output
directory.
EXPOSE 7777/udp
WORKDIR /server
NOTE: The chown command fixes the $PF_SERVER_LOG_DIRECTORY to be accessible by your server process,
and then && chains the command to execute your server
Using a terminal of your choice, navigate to the Linux server directory
Windows users typically use cmd or powershell, though bash via third party tools or WSL are also
available
Mac and Linux users typically use bash
Run: docker build -t "[imageName]:[tag]" . , where imageName and tag are options of your choice.
Remember these names, you will use them again
Examples could be: YourProjectNameSer ver and 01 respectively
The tag element is typically used to version your server instance
These tags will be used in a later step
You can type docker images on the terminal to retrieve imageName and tag if you forget
Type docker images on the terminal to inspect the successful creation of the docker image.
Keep this terminal window open and set it aside as we will have more commands for it later
(Denoted as [Docker terminal] in later steps)
Next steps
Many users will want to test their server by connecting a game-client.
Otherwise, you can return to the main Unreal GSDK Plugin guide.
Connect to MPS hosted build
5/24/2022 • 3 minutes to read • Edit Online
This article describes how you can connect clients to PlayFab Multiplayer Servers (MPS) hosted servers using a
utility tool. This tool is used during development to bypass typical steps to provision and activate servers. Earlier
steps in this example sequence covered adding the Unreal GSDK to a standard ThirdPersonMP tutorial project. In
doing so, we set up the server connection side, but we ignored a proper client connection sequence. PlayFab
requires servers to be provisioned and activated before clients can connect to them. We will not cover that
process here, but more details are available in the MPS Documentation. Instead, for this example, we will bypass
those complicated steps and instead use a manual utility to rapidly test connections between the client and
server.
Prerequisites
Clone or download the MpsSamples repo
A fully deployed ThirdPersonMP server in "Deployed" status, with at least 1 server fully propped and in
"Standby" mode
ThirdPersonMP is the sample project built and deployed in earlier pages of this guide.
A build's status becomes "Deployed" when it contains servers that are ready for connections. These
servers are considered in "Standby"
A built game-client, ready to connect
Visual Studio with .Net Core 3.1 (available as an optional checkbox in the Visual Studio Installer)
{
"ConnectedPlayers": [],
"FQDN": "...",
"IPV4Address": "52.180.68.101",
"LastStateTransitionTime": "2021-12-06T22:12:46.212Z",
"Ports": [
{
"Name": "UnrealServerGsdkHostPort",
"Num": 30000,
"Protocol": "UDP"
}
],
"Region": "WestUs",
"ServerId": "...",
"SessionId": "...",
"State": "Active",
"VmId": "..."
}
NOTE: Values unimportant to this example have been replaced with ...
Look for IPV4Address and Por ts.Num in your response
In the example above, these values are: 52.180.68.101 and 30000 respectively
Your values can/will be different
Return to your RunCloud.bat file, and fill in these values for IP-ADDRESS and PORT. Example:
From windows explorer, double click this .bat file, to run the game-client, wait a moment, and then double
click it again
This should start two instances of your game-client, both connected to your cloud hosted game server
From here, you can run around in both games, and you should see that both users' movements and actions
are reflected in both game clients, for both players
SUCCESS! If you see that, you've completed the full Setup/Build/Deploy/Connect process
Navigation
For some users, this guide sequence is now finished. You can return to the main Unreal GSDK Plugin guide.
If your test was run on Windows servers, then you can try the more advanced Linux Server deployment guide.
Matchmaking
5/24/2022 • 4 minutes to read • Edit Online
IMPORTANT
This feature is currently in public preview. It is provided to give you an early look at an upcoming feature, and to allow you
to provide feedback while it is still in development.
Overview
The new PlayFab Matchmaking feature provides a great way to build matchmaking into your game and offers a
simple, yet powerful system to help your users find each other. This feature is an upgrade to PlayFab's existing
matchmaker and uses the proven capabilities of Xbox Live's SmartMatch.
This marks the first time the firmly established technology of Xbox Live matchmaking has been available outside
of the Xbox Live ecosystem, and it will be available to you everywhere via PlayFab.
When an individual or group wants to enter a match, your title submits a request to the matchmaking service.
Once the request is made, the service will hold on to the request and try to match it with other requests. The
service then creates matches that contain players who are most compatible.
Terminology
There are a few common terms used throughout the matchmaking system that we'll need to define. They are:
Ticket - A ticket is the resource at the core of the matchmaking process. A ticket consists of a player or a
list of players that want to play together, along with their attributes (such as in-game levels, favorite
maps, or skill).
Queue - A queue is a collection of tickets to be matched together and a set of rules that controls how
tickets are matched.
Rule - A rule is a constraint on which tickets are eligible to match. The matchmaking algorithm searches
for a set of tickets that satisfy all the rules defined by a queue to create a match.
Attribute - An attribute is a value associated with a player that can have Rules applied to it. Attributes
can be specified in either the ticket or the player's Entity Objects.
Match - A match is the output of the matchmaking process. It is a collection of tickets that satisfy all the
rules for the queue the tickets were submitted to.
Basics
When a player or group of players want to play together, one player creates a ticket for themselves or the entire
group, and submits it to matchmaking through your title. The join flow ensures that all players in the group
consent to match together. Once the player or players have joined, the matchmaking process begins
automatically. When matchmaking finds a suitable match, the title must group those matched players together
into a game.
A ticket is submitted to a matchmaking queue. A title can have multiple queues. For example, a title might create
one queue for a ranked game mode and another for a social game mode. Tickets can only match with other
tickets in the same queue, and a player may only be in one ticket at a time.
To define a queue, you must create a queue configuration. The simplest configuration consists of the queue
name and the match size (a minimum and maximum number of players). The matchmaking service will attempt
to fill the match to the max size provided, but if insufficient tickets are available a match of the minimum size
can be generated.
If you have different game modes with different match size requirements, it is best to create multiple queue
configurations. For more advanced matchmaking scenarios, queue rules can be configured.
We currently support these rule types:
String equality rule : ensures that a string attribute is the same across all tickets in a match.
Difference rule : ensures that the absolute difference for a number attribute between any two tickets in a
match is less than a configured maximum difference.
Set intersection rule : ensures that for a given attribute that is a list of strings, all tickets in a match share at
least as many values as is configured.
Match total rule : ensures that the sum of a number attribute across all players in a match is within a
configured range.
Region selection rule : ensures that the latency to a common data center for all users of the match is less
than a configured max value.
Team size balance rule : ensures that teams included in a match contain similar member counts.
Team difference rule : ensures that teams included in a match are within a configured difference for a
specific attribute (such as skill).
Team ticket size similarity rule : enforces that the number of large parties is equal to the number of
teams, or is zero.
Rules can be defined to enforce basic functionality, such as matching players with the same map, game mode or
game version. More advanced uses allow constraints to relax over time or become disabled after some time.
Such rules are useful for skill-based matchmaking. Visit Game Manager for more in-depth documentation on
these options.
For more information on specific flows from either your game client or service, see the following
documentation.
Quickstart guide
Quickstart - Client SDK
Quickstart - REST API
Configuration
Configuring matchmaking queues
Matchmaking scenario and configuration examples
Tutorials
Specifying attributes with your tickets
Displaying queue statistics in your title
Integrating with PlayFab Multiplayer Servers
Handling common error cases
Workaround for peer-to-peer connection
Using server backfill tickets
Analyzing Your Matchmaking Queue Usage
SDKs and Tools
Matchmaking API Reference (Public Preview)
PlayStream Events
matchmaking_match_found
matchmaking_ticket_completed
matchmaking_user_ticket_completed
matchmaking_user_ticket_invite
Public preview release notes
While PlayStream events are enabled, there is no currently integrated push notification system. As such, polling
is still the preferred method for checking the status of matchmaking a ticket.
Matchmaking Client SDK quickstart
5/24/2022 • 7 minutes to read • Edit Online
IMPORTANT
This feature is currently in public preview. It is provided to give you an early look at an upcoming feature, and to allow you
to provide feedback while it is still in development.
This quickstart guide walks you through the entire process for integrating the matchmaking feature in your title
code.
This tutorial illustrates how to submit a ticket to a specific queue in order to find a game. A queue likely maps to
a game mode or multiple game modes (ex.: a capture the flag mode and a king of the hill mode in the same
queue).
The matchmaking service handles finding a match amongst tickets in a queue. When a match is found, your title
must handle connecting the players together for gameplay.
Prerequisites
You need a PlayFab account to access Lobby and Matchmaking features.
Create/sign in to your PlayFab account. For instructions, see Quickstart: Game Manager.
const char* yourQueueName = ...; // This is the name of the queue you configured in Game Manager.
PFMatchmakingTicketConfiguration configuration{};
configuration.timeoutInSeconds = 120;
configuration.queueName = yourQueueName;
std::vector<PFEntityKey> remoteMatchMemberEntityKeys;
remoteMatchMemberEntityKeys.push_back({ remoteMemberEntityId1, "title_player_account" });
remoteMatchMemberEntityKeys.push_back({ remoteMemberEntityId2, "title_player_account" });
const char* yourQueueName = ...; // This is the name of the queue you configured in Game Manager.
PFMatchmakingTicketConfiguration configuration{};
configuration.timeoutInSeconds = 120;
configuration.queueName = yourQueueName;
configuration.membersToMatchWithCount = 2; // number of remote members to match with
configuration.membersToMatchWith = remoteMatchMemberEntityKeys.data();
PCSTR ticketId;
hr = PFMatchmakingTicketGetTicketId(ticket, &ticketId);
RETURN_IF_FAILED(hr);
PFMatchmakingTicketConfiguration configuration{};
configuration.timeoutInSeconds = 120;
configuration.queueName = queueName;
uint32_t stateChangeCount;
const PFMatchmakingStateChange * const * stateChanges;
hr = PFMultiplayerStartProcessingMatchmakingStateChanges(g_pfmHandle, &stateChangeCount, &stateChanges);
RETURN_IF_FAILED(hr);
switch (stateChange.stateChangeType)
{
case PFMatchmakingStateChangeType::TicketStatusChanged:
{
const auto& ticketStatusChanged = static_cast<const
PFMatchmakingTicketStatusChangedStateChange&>(stateChange);
PFMatchmakingTicketStatus status;
if (SUCCEEDED(PFMatchmakingTicketGetStatus(ticketStatusChanged.ticket, &status)))
{
printf("Ticket status is now: %i.\n", status);
}
break;
}
case PFMatchmakingStateChangeType::TicketCompleted:
{
const auto& ticketCompleted = static_cast<const PFMatchmakingTicketCompletedStateChange&>
(stateChange);
if (FAILED(ticketCompleted.result))
{
// On failure, we must record the HRESULT so we can return the state change(s) and then bail
// out of this function.
hrTicketError = ticketCompleted.result;
}
break;
}
}
}
// Now that we've returned the state change(s), bail out if we detected ticket failure.
RETURN_IF_FAILED(hrTicketError);
PFMultiplayerDestroyMatchmakingTicket(g_pfmHandle, ticket);
Calling this doesn't guarantee the ticket will be canceled. The ticket could still complete before the cancelation
can be processed, or the cancelation request may fail due to networking or service errors. You should still
process matchmaking state changes to get the result of the ticket.
Example using the Matchmaking client SDK
HRESULT hr = PFMatchmakingTicketCancel(ticket);
PFMultiplayerDestroyMatchmakingTicket(g_pfmHandle, ticket);
PFLobbyHandle lobby;
RETURN_IF_FAILED_HR(PFMultiplayerJoinArrangedLobby(
m_pfmHandle,
&joiningUser,
lobbyArrangementString,
&joinConfig,
nullptr, // optional asyncContext
&lobby));
Conclusion
Using this quickstart, you should now have a successful matchmaking flow in your game. In addition, you
should consider the following:
How your title handles group formation.
What your title displays while users are waiting for a match.
How to handle failures and retries.
Matchmaking REST API quickstart
5/24/2022 • 5 minutes to read • Edit Online
IMPORTANT
This feature is currently in public preview. It is provided to give you an early look at an upcoming feature, and to allow you
to provide feedback while it is still in development.
This quickstart guide walks you through the entire process for integrating the matchmaking feature. All code
examples within this quickstart are for Unity - however, the concepts and flow apply (in general) to other
platforms as well.
Depending on your game design, consider the single user and multiple user matchmaking section.
NOTE
This guide assumes that you have already configured a matchmaking queue in Game Manager.
This tutorial illustrates how to submit a ticket to a specific queue in order to find a game. A queue likely maps to
a game mode or multiple game modes (ex.: a capture the flag mode and a king of the hill mode in the same
queue).
The matchmaking service handles finding a match amongst tickets in a queue. When a match is found, your title
must handle connecting the players together for gameplay.
PlayFabMultiplayerAPI.CreateMatchmakingTicket(
new CreateMatchmakingTicketRequest
{
// The ticket creator specifies their own player attributes.
Creator = new MatchmakingPlayer
{
Entity = new EntityKey
{
Id = "<Entity ID goes here>",
Type = "<Entity type goes here>",
},
PlayFabMultiplayerAPI.GetMatch(
new GetMatchRequest
{
MatchId = "<match ID goes here>",
QueueName = "myqueue",
},
this.OnGetMatch,
this.OnMatchmakingError);
PlayFabMultiplayerAPI.CancelMatchmakingTicket(
new CancelMatchmakingTicketRequest
{
QueueName = "myqueue",
TicketId = "<ticket ID goes here>",
},
this.OnTicketCanceled,
this.OnMatchmakingError);
The Creator field must contain the user attributes required by the queue configuration matching the
QueueName . A good value for GiveUpAfterSeconds time is 120 seconds, to prevent users from giving up on their
own.
Group members join the match ticket
Once the match ticket has been created, the other members of the group have to join it to move along the
matchmaking process. At this time, the ticket is in the WaitingForPlayers status. It will not begin matching with
other tickets until all MembersToMatchWith have joined the ticket.
To have members join, the Creator must share the TicketId to the other members through your title. Each
member then calls JoinMatchmakingTicket, providing their own required attributes. Once all members have
joined the ticket, the ticket status becomes WaitingForMatch .
PlayFabMultiplayerAPI.JoinMatchmakingTicket(
new JoinMatchmakingTicketRequest
{
TicketId = "<ticket ID>",
QueueName = "myqueue",
Member = new MatchmakingPlayer
{
Entity = new EntityKey
{
Id = "<Entity ID goes here>",
Type = "<Entity type goes here>",
},
Attributes = new MatchmakingPlayerAttributes
{
DataObject = new
{
Skill = 19.3
},
},
}
},
this.OnJoinMatchmakingTicket,
this.OnMatchmakingError);
The rest of the process is the same as that of single user ticket matchmaking
Connecting your players together
Once your players have matched, you will want to have them join each other - either through a server, or by
peer-to-peer connections.
If you are using a dedicated server, you can rely on the Match ID to uniquely identify the group of players they
should be in. If you are using PlayFab's multiplayer servers, GetMatch will provide a server and port for your
players to connect to.
Please refer to Integrating with PlayFab Multiplayer Servers for more information.
As of this release, peer-to-peer connection is currently not officially supported by matchmaking. If peer-to-peer
is required, consider using Playfab Party, or an interim workaround. Contact us for more support on this.
Conclusion
Using this quickstart, you should now have a successful matchmaking flow in your game. In addition, you
should consider the following:
How your title handles group formation.
What your title displays while users are waiting for a match.
How to handle failures and retries.
Known issues and limitations
In Public Preview, polling of tickets is required to obtain the match status and match ID. In the near future, we
will have a push mechanism for the clients to be updated on state changes.
The multi-user ticket flow will also be improved by the push mechanism. Follow the PlayFab blog for future
updates on improvements to matchmaking.
Matchmaking tutorials
5/24/2022 • 2 minutes to read • Edit Online
The tutorials in this section will guide you through a variety matchmaking topics.
Configuring matchmaking queues
Matchmaking scenario and configuration examples
Specifying attributes with your tickets
Displaying queue statistics in your title
Integrating with PlayFab Multiplayer Servers
Handling common error cases
Using server backfill tickets
Analyzing Your Matchmaking Queue Usage
Workaround for peer-to-peer connection
Configuring matchmaking queues
5/24/2022 • 8 minutes to read • Edit Online
Overview
Match configuration centers around queues, which represent a place where tickets wait to be matched with each
other. Each queue has some general configuration about what is required for a match. In addition, it can contain
a set of rules which provide further restrictions on how tickets are matched together.
Queue configuration
At the queue level, the configuration describes basic requirements regarding how tickets are matched inside a
queue, as well as how you obtain statistics information about the queue.
Queue name
The name for a specific queue. It is between 1 and 64 characters long (inclusive) and is case-sensitive. It is alpha-
numeric, plus underscores and hyphens, and starts with a letter or number. Generally a queue name represents
a way to play a game, such as "4v4CaptureTheFlag" or "UnrankedRace". When creating a matchmaking ticket,
the queue name must be specified to identify which queue it should enter.
Match size
The range of players allowed in a match. The minimum match size must be greater than or equal to 2, and the
maximum match size must be less than or equal to 100 (this limit is 32, if using teams).
In addition, even if a ticket alone already meets the minimum requirements for a match, it won't return a match
found until it matches at least one other ticket. If a ticket already meets the maximum requirement for a match,
however, it will be rejected.
Statistics available to players
This determines which queue statistics are exposed to players through the GetQueueStatistics API. Servers
always have access to all statistics. See the Displaying queue statistics in your title tutorial for more information.
There are two options you can control within this:
1. Show the number of players matching - Whether the number of players waiting for a match is exposed
to players. Titles may use this to hide the relative popularity of the mode, or to keep player counts hidden for
business reasons.
2. Show the time to match statistics - Whether the time to match statistics (average and percentiles) are
exposed to players.
Teams
A queue can include team configuration to have the match service assign players to teams. Additional team-
specific rules can be used to control how team assignment is done. Furthermore, the match service will ensure
that players matching together in the same ticket are not assigned to different teams.
You can have 2 or more teams defined in a queue.
Team name - The name used for this team. Team names are between 1 and 64 characters long (inclusive)
and are case-sensitive. They are alphanumeric, plus underscores and hyphens, and start with a letter or
number. In addition they must be unique within a queue.
Team size - Minimum and maximum number of players that can be on the team. Matchmaking will try to
form teams with as many players as possible up to the maximum.
Besides defining the teams and their sizes, additional rules can be enabled to help with how to handle teams in
matchmaking. See below for information on team-specific rules.
Rule configuration
Rules may be optionally defined for a queue. When configured, they help the matchmaking algorithm determine
which tickets should match together. Each rule applies to a single attribute in the player metadata. You can have
a maximum of 20 rules defined for a single queue.
There are many types of rules. Each contains some common configurable elements, as well as elements that are
specific to that particular type of rule. In addition, many rules allow an expansion, in which the rules become less
restrictive over time.
Common rule elements
The elements below are often used by all rules.
Rule Name - The name must be between 1 and 255 characters long (inclusive), is alpha-numeric plus
underscores and hyphens, and must start with a letter or number. Rule names must be unique within a
queue.
Weight - A way to modify the importance of a rule. Rules in general provide both a restriction as well as
a way to sort the remaining tickets that are eligible. The weight is a multiplier, modifying how important
the rule is for sorting purposes.
Attribute Source - Rules often act upon information that is provided to them. This field describes two
options for the source of this information:
1. User - Attributes are submitted alongside players in the create or join ticket request.
2. Player Entity - Attributes are retrieved from the player's associated Player Entity. These can be set via
the SetObjects API
Attribute Path - The path to reach the attribute. When using a User Attribute Source, it is simply the
name of the attribute. When using a Player Entity Attribute Source, it is a JSONPath that retrieves a
particular item from the entity, such as $.playerSkill.Mean .
Behavior when attribute is not specified - If a rule requires an attribute, but none is specified, the
rule may be configured with one of two behaviors:
1. It may supply a default value for the attribute.
2. It may use this as a signal to indicate the ticket meets any restriction supplied by the rule. This may be
useful if for instance, some players express a preference, and another player is willing to match
anyone. The player with no preference can neglect to supply an attribute, and match with any other
players.
Standard rule types
Each of the rule types is listed below, along with its purpose, some common uses, and any specific configuration
the rule may require.
Difference Ensures that the absolute Groups players by skill, Merge function - Select
difference for a number experience, or other how multiple player values
attribute between any two numeric comparisons are merged into one value
tickets in a match is less representing the ticket.
than a configured maximum Choices are min, max, and
difference. average. Defaults to
average.
Set Intersection Ensures that for a given DLC or map selection Min intersection size -
attribute that is a list of Minimum number of shared
strings, all tickets in a match items for a match.
share at least as many
values as is configured.
Match Total Ensures that the sum of a Role selection, emulating Min/Max total - Sum of
number attribute across all host/server matchmaking, attribute must be within
players in a match is within adjusting player count these inclusive bounds.
a configured range. restrictions over time
Region Selection Ensures that the latency to Required for multiplayer Max Latency - Only
a common data center for server integration datacenters within this max
all users of the match is less latency are eligible for a
than a configured max match.
value.
Team Difference Ensures that teams included Balancing skills across none
in a match are within a teams
configured difference for a
specific attribute (such as
skills). This is very similar to
a standard Difference Rule,
except that the values
compared are each team's
average value.
Team Size Balance Ensures the difference in Player count balance across Allowed Team Size
player count between the teams Difference - How uneven
largest and smallest team the teams can be, as
does not exceed a measured by the difference
threshold. For instance, this in the number of players
rule could be used to create assigned to each one.
a queue where 3v3 and 4v4
matches are allowed, but a
3v4 is not.
Team Ticket Size Similarity Ensures that all teams Prevents parties (pre-made none
either have a large party, or teams) from matching with
do not have a large party. A a group of solo players.
large party is defined as at
least half of the maximum
team's size.
Expansions and becoming optional
Rules may become optional or less restrictive over time, allowing tickets that have waited for some time to
search wider for a potential match. There are two methods for controlling this behavior:
1. Seconds until optional - Simply indicates a length of time that the rule is active. The rule no longer
restricts matches among tickets that have waited this time.
2. Expansion process - Rules gradually adjust their configured thresholds over time. For instance, a
Difference Rule may require matches within a particular maximum difference. As a ticket waits, the rule
may expand the maximum difference, permitting expansion to a larger and larger range for the ticket,
and allowing it to be matched even if perfect opponents are unavailable.
Expansions can be either linear or custom . In a linear expansion, a value grows over time, using a fixed change
after each time interval. The items customized in a linear expansion are:
Seconds between expansions - How long in between each instance of the rule changing its restrictions.
Delta - The change of the value.
Limit - The end value. The rule never expands beyond this point.
In a custom expansion, the rule can use an arbitrary value each time the rule changes its restrictions. The
following fields are used:
Seconds between expansions - How long in between each instance of the rule changing its restrictions
One or more custom fields that modifies a rule during the expansion. Each field is semicolon delimited to
represent a different value which is used in each expansion's interval. The word "null" may be used in place of
a value to indicate the rule is not active during this interval.
The exact field modified depends on the rule. The following chart describes which rules have which kinds of
expansions, and what fields are modified by the expansion.
For more details on configuration use cases and examples, see Matchmaking scenario and configuration
examples.
Displaying queue statistics in your title
5/24/2022 • 2 minutes to read • Edit Online
Titles may sometimes wish to show how active their queues are, in an effort to set user expectations for wait
times. They may retrieve these statistics and display them directly to the user, or perhaps retrieve these statistics
from a server to display or collect approximated telemetry as they wish. This tutorial shows the steps for
retrieving these statistics from matchmaking.
Retrieving statistics
Call the GetQueueStatistics API to retrieve the statistics. These values are aggregated and updated over time. For
this reason, the GetQueueStatistics API should only be called intermittently. It is not intended to provide real-
time tracking of a queue's statistics.
Handling common error cases
5/24/2022 • 4 minutes to read • Edit Online
PlayFab matchmaking provides a simple interface for entering and leaving matchmaking. Despite this, there are
still multiple points where things may not go according to plan. Some of the more common error cases are
shown below, along with the ways a title should handle them.
This page assumes you are familiar with the general flow of PlayFab matchmaking. See our Matchmaking
quickstart for more information on the common use of matchmaking.
NOTE
The errors MatchmakingAttributeInvalid and MatchmakingPlayerAttributesInvalid indicate an issue with the
formatting of attributes. See the section on Specifying Ticket Attributes for the details on how to pass attributes in a
ticket.
Other error codes indicate the request is valid, but circumstances outside the request prevent the ticket from
being accepted. In particular, these are:
1. - This indicates you have been submitting tickets too frequently. See the
MatchmakingRateLimitExceeded
section below for more details.
2. MatchmakingTicketMembershipLimitExceeded - This indicates the user is already in another active ticket. Users
are restricted from being in more than one ticket within a queue at a time, as they cannot play two games at
once. See the more detailed section below for more information on correcting this situation.
If you receive an HTTP error code of 503, simply retry your request after a brief delay.
NOTE
Although the response will have an HTTP status code of 429, the request itself is valid and can still be retried.
Matchmaking includes an option that can automatically create a game server for the resulting match. The
allocated server will run a build, which is configured in the queue's config. On startup, the server is passed in the
members of the match as the list of initial players.
A matchmaking queue is tied to a single multiplayer server build.
"MatchmakingQueue": {
"Name": "ServerEnabledQueue",
"MinMatchSize": 2,
"MaxMatchSize": 2,
"ServerAllocationEnabled": true,
"BuildId": "88b3e315-829c-4b6d-9872-74f427ad5331",
"Rules": [
{
"Type": "RegionSelectionRule",
"MaxLatency": 1000,
"Path": "Latencies",
"Weight": 1,
"Name": "RegionRule",
"SecondsUntilOptional": 60
}
]
}
The flow of calls to matchmaking remains the same with the server allocation enabled. Once matchmaking
allocates a server for the match, the resulting server details can be read from the Match object itself by calling
GetMatch.
A sample response is provided below for a GetMatch call for a queue with server allocation enabled.
{
"MatchId": "7c36330d-46b5-443f-8d8f-10390bce09d5",
"Members": [{
"TeamId": "",
"Entity": {
"Id": "67282A13A1A58910",
"Type": "title_player_account",
"TypeString": "title_player_account"
},
"Attributes": {
"DataObject": null,
"EscapedDataObject": "{\"StringEqualityRulePath\":\"0bc42969-76b1-4dcb-871d-d6e19cee741b\"}"
}
},
{
"TeamId": "",
"Entity": {
"Id": "6DB2B17FD21CC230",
"Type": "title_player_account",
"TypeString": "title_player_account"
},
"Attributes": {
"DataObject": null,
"EscapedDataObject": "{\"StringEqualityRulePath\":\"0bc42969-76b1-4dcb-871d-d6e19cee741b\"}"
}
}],
"RegionPreferences": ["WestUs", " EastUs"],
"ServerDetails": {
"IPV4Address": "40.76.31.170",
"Ports": [{
"Name": "game_port",
"Num": 30003
}]
}
}
The clients can use the IP and port from the server details section of the response to connect to the server. For
further information on how to connect clients to multiplayer servers, please refer to Connecting clients to
servers
NOTE
When a region of your build runs out of capacity, matchmaking will not be able to allocate matches for the queue in that
region. Matchmaking will keep retrying the allocation until the ticket expires. To increase multiplayer capacity, please refer
to Accessing increased core limits and additional Azure regions
Overview
The system of queues and rules provides the flexibility to handle a large number of scenarios. Below are
examples of some of the more common matchmaking use cases, and their associated queues. Each of these can
be submitted directly via PlayFab APIs. These options can also be set via the Game Manager UI.
"MatchmakingQueue": {
"Name": "MyFirstQueue",
"MinMatchSize": 2,
"MaxMatchSize": 2,
"ServerAllocationEnabled": false,
"Rules": [
{
"Type": "StringEqualityRule",
"Attribute": {
"Path": "Build",
"Source": "User"
},
"AttributeNotSpecifiedBehavior": "MatchAny",
"Weight": 1,
"Name": "BuildVersionRule"
}
]
}
{
"MatchmakingQueue": {
"Name": "FreeForAllQueue",
"MinMatchSize": 4,
"MaxMatchSize": 4,
"ServerAllocationEnabled": false,
"Rules": [
]
}
}
{
"MatchmakingQueue": {
"Name": "CaptureTheFlagQueue",
"MinMatchSize": 4,
"MaxMatchSize": 4,
"ServerAllocationEnabled": false,
"Rules": [
]
}
}
NOTE
The number of players required to play must be the same across modes for this to function correctly.
{
"MatchmakingQueue": {
"Name": "MultiGameModeSearchQueue",
"MinMatchSize": 4,
"MaxMatchSize": 4,
"ServerAllocationEnabled": false,
"Rules": [
{
"Type": "SetIntersectionRule",
"MinIntersectionSize": 1,
"Attribute": {
"Path": "GameMode",
"Source": "User"
},
"AttributeNotSpecifiedBehavior": "MatchAny",
"Weight": 1,
"Name": "GameModeRule"
}
]
}
}
Customizing expansions
Expansions can be customized to use arbitrary values in each time interval. For instance, you may want the
allowed skill to grow slowly to start, and later grow increasingly quickly over time.
"MatchmakingQueue": {
"Name": "SkillBasedFreeForAllCustomExpansionQueue",
"MinMatchSize": 4,
"MaxMatchSize": 4,
"ServerAllocationEnabled": false,
"Rules": [
{
"Type": "DifferenceRule",
"Difference": 0.2,
"MergeFunction": "Average",
"DefaultAttributeValue": 0.5,
"Expansion": {
"DifferenceOverrides": [
0.025,
0.05,
0.1,
0.2,
0.3,
0.5
],
"Type": "Custom",
"SecondsBetweenExpansions": 5
},
"Attribute": {
"Path": "Skill",
"Source": "User"
},
"AttributeNotSpecifiedBehavior": "UseDefault",
"Weight": 1,
"Name": "SkillRule",
"SecondsUntilOptional": 30
}
]
}
NOTE
Note that if a MaxOverrides or MinOverrides array is not specified, the rule's original Max or Min value will be used
in its place.
"MatchmakingQueue": {
"Name": "PlayerExpansionOverTime",
"MinMatchSize": 8,
"MaxMatchSize": 50,
"ServerAllocationEnabled": false,
"Rules": [
{
"Type": "MatchTotalRule",
"Attribute": {
"Path": "PlayerCount",
"Source": "User"
},
"Min": 8,
"Max": 50,
"Weight": 1,
"Expansion": {
"MinOverrides": [
50,
45,
40,
35,
25,
16,
8
],
"Type": "Custom",
"SecondsBetweenExpansions": 10
},
"Name": "PlayersRequiredRule",
"SecondsUntilOptional": 60
}
],
}
Multiplayer servers
A queue can automatically feed into PlayFab's multiplayer servers feature, allocating a server and feeding it a list
of matched players. This queue provides the smallest example of such a config, which is the
ServerAllocationEnabled flag, along with the BuildId representing what build of the server should be started.
When the ServerAllocationEnabled flag is set to true ,a RegionSelectionRule is also required to indicate where
a server should be allocated for each match.
"MatchmakingQueue": {
"Name": "MultiplayerServersQueue",
"MinMatchSize": 24,
"MaxMatchSize": 24,
"ServerAllocationEnabled": true,
"BuildId": "6a4d2760-4295-417e-b149-0a12e3570d94",
"Rules": [
{
"Type": "RegionSelectionRule",
"MaxLatency": 200,
"Path": "Latency",
"Weight": 1,
"Name": "RegionSelectionRule"
}
]
}
Battle Royale
Battle Royale games place many people into an arena. In this example, the game is set up with teams of four.
Currently there is a limit of 32 players allowed in a team scenario such as this one - This limitation will be
improved in the future.
This example also contains multiplayer server setup information for dedicated servers, which is often necessary
for games with large numbers of players. This is similar to the example shown above.
"MatchmakingQueue": {
"Name": "BattleRoyaleStyleQueueWithTeams",
"MinMatchSize": 32,
"MaxMatchSize": 32,
"ServerAllocationEnabled": true,
"BuildId": "6a4d2760-4295-417e-b149-0a12e3570d94",
"Teams": [
{
"Name": "team1",
"MinTeamSize": 4,
"MaxTeamSize": 4
},
{
"Name": "team2",
"MinTeamSize": 4,
"MaxTeamSize": 4
},
{
"Name": "team3",
"MinTeamSize": 4,
"MaxTeamSize": 4
},
{
"Name": "team4",
"MinTeamSize": 4,
"MaxTeamSize": 4
},
{
"Name": "team5",
"MinTeamSize": 4,
"MaxTeamSize": 4
},
{
"Name": "team6",
"MinTeamSize": 4,
"MaxTeamSize": 4
},
{
"Name": "team7",
"MinTeamSize": 4,
"MaxTeamSize": 4
},
{
"Name": "team8",
"MinTeamSize": 4,
"MaxTeamSize": 4
}
],
"Rules": [
{
"Type": "RegionSelectionRule",
"MaxLatency": 200,
"Path": "Latency",
"Weight": 1,
"Name": "RegionSelectionRule"
}
]
}
"MatchmakingQueue": {
"Name": "CrossDeviceQueue",
"MinMatchSize": 32,
"MaxMatchSize": 32,
"ServerAllocationEnabled": false,
"BuildId": "6a4d2760-4295-417e-b149-0a12e3570d94",
"Rules": [
{
"Type": "StringEqualityRule",
"Attribute": {
"Path": "DeviceType",
"Source": "User"
},
"AttributeNotSpecifiedBehavior": "MatchAny",
"Weight": 1,
"Name": "CrossDeviceRule"
}
]
}
NOTE
If the number of hosts vastly outnumbers the searchers or vice-versa, this may cause slow matchmaking times for all
players. Consider the implications of your matchmaking design to ensure there are enough players in any given
subpopulation to satisfy your matchmaking rules and the desired average time to match.
"MatchmakingQueue": {
"Name": "HostSearcherQueue",
"MinMatchSize": 8,
"MaxMatchSize": 8,
"ServerAllocationEnabled": false,
"BuildId": "6a4d2760-4295-417e-b149-0a12e3570d94",
"Rules": [
{
"Type": "MatchTotalRule",
"Attribute": {
"Path": "IsHost",
"Source": "User"
},
"Min": 1,
"Max": 1,
"Weight": 1,
"Name": "OneHostRule"
}
]
}
Games may have role requirements - for instance, a game may require one drummer, two guitarists, and one
vocalist. Or one tank, two DPS, and one support. Games may use the MatchTotalRule to require these roles as
shown below.
"MatchmakingQueue": {
"Name": "RoleBasedQueue",
"MinMatchSize": 4,
"MaxMatchSize": 4,
"ServerAllocationEnabled": false,
"BuildId": "6a4d2760-4295-417e-b149-0a12e3570d94",
"Rules": [
{
"Type": "MatchTotalRule",
"Attribute": {
"Path": "TankSelected",
"Source": "User"
},
"Min": 1,
"Max": 1,
"Weight": 1,
"Name": "TankRule"
},
{
"Type": "MatchTotalRule",
"Attribute": {
"Path": "DPSSelected",
"Source": "User"
},
"Min": 2,
"Max": 2,
"Weight": 1,
"Name": "DPSRule"
},
{
"Type": "MatchTotalRule",
"Attribute": {
"Path": "SupportSelected",
"Source": "User"
},
"Min": 1,
"Max": 1,
"Weight": 1,
"Name": "SupportRule"
}
]
}
DLC packs
With various DLC packs, players may opt to only find other players that have a matching DLC, using a
SetIntersectionRule . Each player passes in the DLC packs they own, and a match requires a group to share at
least one DLC pack.
NOTE
After 30 seconds, the rule becomes optional, allowing players to match without sharing DLC.
"MatchmakingQueue": {
"Name": "DlcQueue",
"MinMatchSize": 4,
"MaxMatchSize": 4,
"ServerAllocationEnabled": false,
"BuildId": "6a4d2760-4295-417e-b149-0a12e3570d94",
"Rules": [
{
"Type": "SetIntersectionRule",
"MinIntersectionSize": 1,
"Attribute": {
"Path": "DlcPacks",
"Source": "User"
},
"AttributeNotSpecifiedBehavior": "MatchAny",
"Weight": 1,
"Name": "DlcRule",
"SecondsUntilOptional": 30
}
]
}
Enabling Statistics
Enabling statistics allows your title to display information about a queue. This information can be useful for
setting player expectations as they choose a game mode they would like to play.
Conversely, titles may wish to hide this information - either for business intelligence purposes, or to avoid
directing players into high-traffic queues.
The queue below enables both the ability to see the number of players present in a queue and an estimated time
a ticket takes to match.
NOTE
A server may always retrieve this information - the configuration shown below only controls whether users are allowed to
make this call as well.
"MatchmakingQueue": {
"Name": "StatisticsEnabledQueue",
"MinMatchSize": 8,
"MaxMatchSize": 8,
"ServerAllocationEnabled": false,
"Rules": [],
"StatisticsVisibilityToPlayers": {
"ShowNumberOfPlayersMatching": true,
"ShowTimeToMatch": true
}
}
Specifying attributes with your tickets
5/24/2022 • 2 minutes to read • Edit Online
Rules determine which tickets are matched, based on the attributes specified by players. These attributes can be
specified in two ways, either:
1. Within the create ticket request
2. In the player's entity
This tutorial describes how to specify those attributes.
POST https://{{TitleId}}.playfabapi.com/Match/CreateMatchmakingTicket
{
"Creator": {
"Entity": {
"Id": "A8140AB9109712B",
"Type": "title_player_account",
"TypeString": "title_player_account"
},
"Attributes": {
"DataObject": {
"mu": 16.0,
"sigma": 1.8,
"nestExample": {
"exp": 1500
}
}
}
},
"MembersToMatchWith": [],
"GiveUpAfterSeconds": 2,
"QueueName": "SkillRuleQueue"
}
Below is an example queue configuration with a DifferenceRule . This rule contains an attribute path and source
that will pick up the value 16.0, specified by the CreateMatchmakingTicket request above.
"MatchmakingQueue": {
"Name": "SkillRuleQueue",
"MinMatchSize": 2,
"MaxMatchSize": 2,
"ServerAllocationEnabled": false,
"Rules": [
{
"Type": "DifferenceRule",
"Difference": 3,
"MergeFunction": "Average",
"Attribute": {
"Path": "mu",
"Source": "User"
},
"AttributeNotSpecifiedBehavior": "MatchAny",
"Weight": 1,
"Name": "SkillRule",
"SecondsUntilOptional": 10
}
]
}
NOTE
Rules can navigate through the DataObject with a JSON Path. Replacing the Path field with "nestExample.exp" would
cause the rule to use the value 1500 for the ticket created above.
This allows data to be stored for a user, rather than the title needing to specify it on each create ticket call. This
may make more sense for values that persist for a user, or that users cannot be trusted to submit. An example of
this SetObjects call is shown below.
POST https://{{TitleID}}.playfabapi.com/Object/SetObjects
{
"Objects": [
{
"ObjectName": "playerSkill",
"DataObject": {
"skillDetail": {
"mu": 16.0,
"sigma": 2.0
}
}
}
],
"Entity": {
"Id": "A8140AB9109712B",
"Type": "title_player_account",
"TypeString": "title_player_account"
}
}
A queue with the following configuration would retrieve the value 16.0 for use in its DifferenceRule rule, when
a ticket is created with this player.
NOTE
In the Path field, the first item after the root is the ObjectName , allowing you to choose which stored object to
reference.
"MatchmakingQueue": {
"Name": "PlayerEntityRuleQueue",
"MinMatchSize": 2,
"MaxMatchSize": 2,
"ServerAllocationEnabled": false,
"Rules": [
{
"Type": "DifferenceRule",
"Difference": 1,
"MergeFunction": "Average",
"Attribute": {
"Path": "$.playerSkill.skillDetail.mu",
"Source": "PlayerEntity"
},
"AttributeNotSpecifiedBehavior": "MatchAny",
"Weight": 1,
"Name": "SkillRule",
"SecondsUntilOptional": 10
}
]
}
Special formats
Most rules use attributes that are either strings or numeric, and are simply those values in JSON format. Rules
that require more complex attributes to be passed in are listed below.
Region Selection rule
A Region Selection rule requires an array of latency measurements with the specified schema. The following
example is the expected attribute format for a region selection rule, shown alongside the two attributes used in
the CreateMatchmakingTicket request example for comparison.
POST https://{{TitleId}}.playfabapi.com/Match/CreateMatchmakingTicket
{
"Creator": {
"Entity": {
"Id": "A8140AB9109712B",
"Type": "title_player_account",
"TypeString": "title_player_account"
},
"Attributes": {
"DataObject": {
"mu": 16.0,
"sigma": 1.8,
"Latencies": [
{
"region": "EastUs",
"latency": 150
},
{
"region": "WestUs",
"latency": 400
}
]
}
}
},
"MembersToMatchWith": [],
"GiveUpAfterSeconds": 2,
"QueueName": "ServerEnabledQueue"
}
In this example, Latencies must match the field referenced by the Path field in the rule. An example of a rule
which would use the Latencies field is included in the queue below.
"MatchmakingQueue": {
"Name": "ServerEnabledQueue",
"MinMatchSize": 2,
"MaxMatchSize": 2,
"ServerAllocationEnabled": true,
"BuildId": "88b3e315-829c-4b6d-9872-74f427ad5331",
"Rules": [
{
"Type": "RegionSelectionRule",
"MaxLatency": 1000,
"Path": "Latencies",
"Weight": 1,
"Name": "RegionRule",
"SecondsUntilOptional": 60
}
]
}
NOTE
When using the region selection rule for a queue that has server allocation enabled, the regions must be valid Azure
Regions. You can find the list of valid Azure Regions here.
Using server backfill tickets
5/24/2022 • 4 minutes to read • Edit Online
Games hosted on a server sometimes find they need to search for additional players. Most often this occurs
when one or more players disconnect while the game is in progress. Server backfill tickets allow a game server
to search for additional players which will fit into the game currently being played.
Server backfill tickets differ from regular matchmaking tickets in multiple ways:
1. Matching
Backfill tickets cannot match with each other.
Backfill tickets are given priority during searching. This reduces fragmentation of the player base.
2. Contract
Backfill tickets may be created with a ServerDetails field. This allows the server to indicate how
matched players should connect to it.
Backfill tickets may be created with team assignments. This allows games with teams to maintain their
team information.
3. Queue properties
Backfill tickets do not trigger Multiplayer Server allocation.
Backfill tickets are not reflected in queue statistics, as their players are already playing a game and
would inaccurately skew wait time.
4. Ownership
Backfill tickets are owned by a game server, not a user. Users cannot view or interact with backfill
tickets in any way.
In addition to the members, the game server may specify two additional pieces of information.
ServerDetails
This structure is identical to the structure returned in a GetMatch call, and allows the server to specify any
information required to connect to it. When the backfill ticket is matched, its ServerDetails structure will be
returned to any players who call GetMatch on the resulting match. All fields in this structure are optional. Titles
may only need a subset of these in order to provide enough information for clients to connect to the game
server.
NOTE
The IPV4Address field is not validated and may be used to supply arbitrary connection string information to clients.
{
"ServerDetails": {
"IPV4Address": "123.234.123.234",
"Ports": [
{
"Port": {
"Name": "portname",
"Num": 12345,
"Protocol": "UDP"
}
}
],
"Region": "EastUS"
}
}
Team Assignments
If the backfill ticket is submitted to a queue with teams, each member may also be specified with a TeamId,
indicating the team they are currently on. This membership will be preserved when a Match is returned. If a
TeamId is not specified for a user, it may be placed on any team.
{
"Members": [
{
"TeamId": "red",
"Entity": {
"Id": "6570DE3537DC9DF6",
"Type": "title_player_account",
"TypeString": "title_player_account"
},
"Attributes": {
"DataObject": {
"Skill": 25
}
}
}
]
}
NOTE
Clients are not allowed to cancel a backfill ticket they are in. Suppose a client was in a 4v4 match, and a player on the
opposing team dropped. The client could maintain its advantage by continously canceling any backfill tickets it was in. To
prevent this, only game servers may cancel backfill tickets.
{
"code": 400,
"status": "BadRequest",
"error": "MatchmakingTicketMembershipLimitExceeded",
"errorCode": 2055,
"errorMessage": "User is a member of too many backfill tickets.",
"errorDetails": {
"UsersExceedingMembershipLimit": [
"title_player_account!562D72A5B184F612"
]
}
}
The game server can recover a user from this situation by calling CancelAllServerBackfillTicketsForPlayer, which
removes all backfill tickets the user is in. ListServerBackfillTicketsForPlayer is also provided as a method to
discover which backfill tickets a player may be in.
PlayFab matchmaking provides charts that help developers understand their customer's matchmaking usage
patterns. The Matchmaking Usage view can be accessed within the GameManager portal under the Muliplayer-
>Matchmaking tab. Once a specific queue is selected, there will appear a "Usage" sub tab adjacent to the "Edit
Queue" sub tab. As long as matchmaking activity is occuring in that queue, selecting the Usage tab will render
various charts that depict matchmaking activity (or possibly lack thereof) within it.
Charts
Each of the charts described below can render data over the past hour, 4 hours, day, 3 days, week, or month (4
weeks). To change the time window, click the time duration dropdown and select a different time window. All
graphs will render using the same time window.
Average Matchmaking Time
This chart shows how long it takes for a match to be found in this matchmaking queue. If the time seems to take
longer than expected, it's worth re-examining the rules for this queue to see if those rules are overly restrictive
resulting in longer matchmaking times. It also is worth looking at the other charts to see how active this queue
is and if other issues may be preventing timely matches.
Y-Axis: seconds
Y-Axis: seconds
Zero or erratic match completion rate Queue configured incorrectly, queue doesn't match with title
Low match completion rate, long matchmaking times Queue rules are too restrictive
High match completion rate, high ticket cancellation rate Quitters, unsatisfactory matches
Workaround for peer-to-peer connection
5/24/2022 • 2 minutes to read • Edit Online
The end result of matchmaking is a Match - a collection of tickets that satisfy the rules for the queue. For titles
with a dedicated server, the match ID is unique, and can be used to identify groups of players that should play
together.
In the peer-to-peer case however, the title needs to pass connection information to each other. This tutorial
describes a workaround to perform this.
NOTE
Peer-to-peer connection in matchmaking is currently not officially supported. Consider PlayFab Party, or contact us for
more information.
POST https://{{TitleId}}.playfabapi.com/Match/CreateMatchmakingTicket
{
"Creator": {
"Entity": {
"Id": "A8140AB9109712B",
"Type": "title_player_account",
"TypeString": "title_player_account"
},
"Attributes": {
"DataObject": {
"IP": "123.234.123.12"
}
}
},
"MembersToMatchWith": [],
"GiveUpAfterSeconds": 2,
"QueueName": "IPExampleQueue"
}
NOTE
While this can be used to exchange IPs, it does not guarantee connectivity between the clients.
Lobby and Matchmaking real-time notifications
5/24/2022 • 2 minutes to read • Edit Online
Overview
The Matchmaking and Lobby features have built in support for real-time notifications. Notifying players of
changes to Matchmaking or Lobby has never been easier, as the work to handle notifications is done for you.
New APIs will allow connected clients to subscribe for notifications of Lobby and Matchmaking changes. With
this addition, you'll no longer need to poll for changes to matches or lobbies.
The client SDK has been designed to simplify your work. The client SDK manages calls between clients and
Lobby and Matchmaking services. It handles the delivery of notifications from those services to connected
clients in real time. Real-time notifications have cross-platform support, and will work anywhere PlayFab
supplies a client SDK. Matchmaking and Lobby can be used separately or together, and real-time notifications
will work in either case. There's no support for real-time notifications without the client SDK at this time. Real-
time notifications aren't available as a solution for stand-alone or general use.
IMPORTANT
This feature is currently in public preview. It is provided to give you an early look at an upcoming feature, and to allow you
to provide feedback while it is still in development.
Azure PlayFab Lobby is a service to create a temporary grouping mechanism for players to play games together.
It's frequently used with matchmaking after finding people to play with.
Benefits
Cross-platform scalable lobby service
Highly customizable to support a wide variety of gameplay needs
Use seamlessly with PlayFab LiveOps and backend services. This includes PlayFab Matchmaking, PlayFab
Multiplayer Servers, and PlayFab Party
Client SDK support for real-time push notifications with PlayFab Matchmaking and PlayFab Lobby.
See also
Lobby and matchmaking
Lobby properties
Owner requirements and privileges
Create a lobby
Lobby ownership changes
Find lobbies
Create searchable lobbies
Getting started with Azure PlayFab Lobby
5/24/2022 • 2 minutes to read • Edit Online
IMPORTANT
This feature is currently in public preview. It is provided to give you an early look at an upcoming feature, and to allow you
to provide feedback while it is still in development.
This article describes how to set up the development environment for Azure PlayFab Lobby and start using it.
Prerequisites
You need a PlayFab account to access Lobby and Matchmaking features.
Create/sign in to your PlayFab account. For instructions, see Quickstart: Game Manager.
Initialize Lobby
Initialize the PlayFab Multiplayer Client SDK by following these basic steps.
static PFMultiplayerHandle g_pfmHandle = nullptr;
...
...
HRESULT hr = S_OK;
// Set an entity token for a local user. The token will be used for operations on behalf of this user.
If using
// the PF Core SDK, this should be called each time the PF Core SDK provides a refreshed token.
hr = PFMultiplayerSetEntityToken(g_pfmHandle, localUserEntity, entityToken);
RETURN_IF_FAILED(hr);
return S_OK;
Next steps
Create a Lobby
Find and join a lobby
Invite another player to a lobby
Use lobby properties to coordinate a game session
See also
Create searchable lobbies
Lobby properties
Lobby Client SDK reference
Lobby SDKs
Create a lobby
5/24/2022 • 2 minutes to read • Edit Online
IMPORTANT
This feature is currently in public preview. It is provided to give you an early look at an upcoming feature, and to allow you
to provide feedback while it is still in development.
PFLobbyCreateConfiguration lobbyConfiguration{};
lobbyConfiguration.maxMemberCount = 16;
lobbyConfiguration.ownerMigrationPolicy = PFLobbyOwnerMigrationPolicy::Automatic;
lobbyConfiguration.accessPolicy = PFLobbyAccessPolicy::Private;
lobbyConfiguration.lobbyPropertyCount = 1;
lobbyConfiguration.lobbyPropertyKeys = &gameModePropertyKey;
lobbyConfiguration.lobbyPropertyValues = &gameModePropertyValue;
PFLobbyJoinConfiguration creatorMemberConfiguration{};
creatorMemberConfiguration.memberPropertyCount = 1;
creatorMemberConfiguration.memberPropertyKeys = &playerColorPropertyKey;
creatorMemberConfiguration.memberPropertyValues = &playerColorPropertyValue;
See also
Lobby Client SDK reference
Create searchable lobbies
Lobby properties
Lobby and matchmaking
Lobby invites
5/24/2022 • 2 minutes to read • Edit Online
IMPORTANT
This feature is currently in public preview. It is provided to give you an early look at an upcoming feature, and to allow you
to provide feedback while it is still in development.
This article provides an overview about Lobby invites and explains how to manage state changes for lobbies
that allow invites.
Invite types
There are two types of invites your game is likely to make use of.
1. In-game invites
2. Platform invites
Joining a lobby by in-game invites
A member of a lobby may invite another player to that lobby directly via the lobby service.
This will share the lobby's connection string with the invited player.
The invited player will receive the invitation via PFLobbyInviteReceivedStateChange and can use the
attached connection string to join the lobby.
These invites work cross-platform but only work in-game.
Joining a lobby by platform invites
Members of the lobby can directly share the lobby's connection string with other players over platform-
specific invite mechanisms.
These invites will not work cross-platform but can be received without the recipient already running the
game.
Once the invited player receives the connection string via the platform mechanism, they can use the attached
connection string to join the lobby.
void HandleInvitationListenerStatusChange(
const PFLobbyInvitationListenerStatusChangedStateChange& invitationListenerStateChange)
{
PFLobbyInvitationListenerStatus status;
HRESULT hr = PFMultiplayerGetLobbyInvitationListenerStatus(
g_pfmHandle,
&invitationListenerStateChange.listeningEntity,
&status);
assert(SUCCEEDED(hr));
switch (status)
{
case PFLobbyInvitationListenerStatus::Listening:
{
Log("%s is listening for invitations", invitationListenerStateChange.listeningEntity.id);
break;
}
case PFLobbyInvitationListenerStatus::NotAuthorized:
{
Log("Invitation listener not authorized!"); // this is likely an issue with the listener's
entity token.
break;
}
default:
}
}
Use PFLobbySendInvite to send an invite to another PlayFab user via the lobby service.
The recipient will receive a PFLobbyInviteReceivedStateChange .
See also
Lobby and matchmaking
Find lobbies
Join lobbies
Lobby properties
Joining lobbies and connection strings
5/24/2022 • 2 minutes to read • Edit Online
IMPORTANT
This feature is currently in public preview. It is provided to give you an early look at an upcoming feature, and to allow you
to provide feedback while it is still in development.
Players join lobbies by providing the lobby service with a lobby's "connection string", an opaque identifier which
grants membership to the lobby.
Players can discover connection strings and join lobbies in the following ways.
1. By using in-game invites—A member of a lobby may invite another player to that lobby directly via the lobby
service. This will share the lobby's connection string with the invited player. These invites work cross-
platform but only work in-game. For more information, see Lobby invites
2. By using platform-provided invites—Members of the lobby can directly share the lobby's connection string
with other players over platform-specific invite mechanisms. These invites will not work cross-platform but
can be received without the recipient already running the game.
3. By searching for available lobbies with FindLobbies and joining an available lobby
4. By sharing the lobby's connection string via any out-of-band, custom discovery mechanism
PFLobbyJoinConfiguration joinConfig;
joinConfig.memberPropertyCount = 1;
joinConfig.memberPropertyKeys = &playerColorPropertyKey;
joinConfig.memberPropertyValues = &playerColorPropertyValue;
//
// Join the lobby using the connection string
//
HRESULT hr = PFMultiplayerJoinLobby(
g_pfmHandle,
&localUser,
connectionString,
&joinConfig,
nullptr,
nullptr);
See also
Find lobbies
Create searchable lobbies
Lobby and matchmaking
Lobby properties
Create a lobby
Lobby properties
5/24/2022 • 2 minutes to read • Edit Online
IMPORTANT
This feature is currently in public preview. It is provided to give you an early look at an upcoming feature, and to allow you
to provide feedback while it is still in development.
This article describes custom properties stored on the lobby. Use this functionality to store metadata about the
game sessions that your lobby's represent.
Pre-defined properties
Each lobby has a set of pre-defined properties commonly needed for most game scenarios.
P RO P ERT Y DEF IN IT IO N
owner The entity that owns the lobby. Some lobbies may
temporarily be ownerless in some circumstances. To learn
more, see Ownership changes.
membershipLock This value indicates whether new members may join the
lobby or not. When Locked , new members may not join.
When Unlocked new members may join. This property can
only be changed by the owner.
Custom Properties
There are 3 types of custom properties that titles can define.
1. Custom lobby properties
These properties apply to the whole lobby.
Only members of the lobby can see these properties.
Only the owner of the lobby can change these properties.
2. Custom member properties
There is a unique map of member properties for each member in the lobby
Only members of the lobby can see these properties.
All members of the lobby can see every other members' properties.
Each member may modify their own member properties but cannot modify another member's
properties.
Once a member leaves the lobby, their member properties are deleted from the lobby.
3. Custom search properties.
These are special properties which can be used by all players in your title to search for lobbies
matching a specific criteria.
These properties apply to the whole lobby.
Only the owner of the lobby can change these properties.
There are restrictions on what keys you can use for these properties.
To learn more, see Create searchable lobbies.
All properties are maps of key-value pairs.
See also
Create a lobby
Owner requirements and privileges
Lobby and matchmaking
Find lobbies
Create searchable lobbies
Create searchable lobbies
5/24/2022 • 2 minutes to read • Edit Online
IMPORTANT
This feature is currently in public preview. It is provided to give you an early look at an upcoming feature, and to allow you
to provide feedback while it is still in development.
Example code
In this example, the lobby created has the following custom search properties defined.
Game mode = "DeathMatch"
Competition style = "Ranked"
Skill level = Skill level of the person who created the lobby
static PFMultiplayerHandle g_pfmHandle; // initialized elsewhere
PFEntityKey m_localUser;
namespace MyGame {
uint32_t GetPlayerSkill(); // defined elsewhere
}
void CreateLobbyWithSearchProperties()
{
std::string playerSkill = std::to_string(MyGame::GetPlayerSkill());
PFLobbyCreateConfiguration lobbyConfiguration{};
lobbyConfiguration.maxMemberCount = 16;
lobbyConfiguration.searchPropertyCount = _countof(searchPropertyKeys);
lobbyConfiguration.searchPropertyKeys = searchPropertyKeys;
lobbyConfiguration.searchPropertyValues = searchPropertyValues;
PFLobbyHandle lobby;
HRESULT hr = PFMultiplayerCreateAndJoinLobby(
g_pfmHandle,
&m_localUser,
&lobbyConfiguration,
nullptr,
nullptr,
&lobby);
}
See also
Find lobbies
Lobby properties
Owner requirements and privileges
Create a lobby
Find lobbies
5/24/2022 • 4 minutes to read • Edit Online
IMPORTANT
This feature is currently in public preview. It is provided to give you an early look at an upcoming feature, and to allow you
to provide feedback while it is still in development.
It's often useful for titles to let players find lobbies that meet a particular set of criteria like map and difficulty
level among other in-game qualities. This enables players to find the game sessions they want with the people
they want.
This article explains how to use FindLobbies to enable players to find lobbies. To see how to find lobbies can be
used in game titles, see Common Scenarios.
NOTE : When comparing string properties, be sure to wrap the compared value in single quotes. e.g.
"string_key1 eq 'SOME STRING VALUE' ". Numeric properties do not require this.
#define SUPPORT_XBL_CROSSPLAY
searchConfiguration.filterString = filterString.c_str();
searchConfiguration.sortString = sortString.c_str();
void ProcessStateChanges()
{
while (true)
{
uint32_t stateChangeCount;
const PFLobbyStateChange* const* stateChanges;
RETURN_VOID_IF_FAILED(PFMultiplayerStartProcessingLobbyStateChanges(
g_pfmHandle,
&stateChangeCount,
&stateChanges));
RETURN_VOID_IF_FAILED(PFMultiplayerFinishProcessingLobbyStateChanges(
g_pfmHandle,
stateChangeCount,
stateChanges));
}
}
// Update game UI to display search results when a list of matching lobbies is returned.
void GuiPostCurrentLobbySearchResults(
const PFLobbyFindLobbiesCompletedStateChange& stateChange)
{
if (FAILED(stateChange.result))
{
GuiToastErrorAndExitScreen();
return;
}
for (uint32_t i = 0; i < stateChange.searchResultCount; ++i)
{
const PFLobbySearchResult& searchResult = stateChange.searchResults[i];
GuiPostLobbySearchResultRow(searchResult); // defined elsewhere
}
}
See also
Create searchable lobbies
Join lobbies
Lobby and matchmaking
Lobby properties
Create a lobby
Owner requirements and privileges
5/24/2022 • 2 minutes to read • Edit Online
IMPORTANT
This feature is currently in public preview. It is provided to give you an early look at an upcoming feature, and to allow you
to provide feedback while it is still in development.
Owner requirements
The owner of a lobby can be either a client or a server. Both must have access to the title. Client owners must
also be a member of the lobby.
In other words, there are two main types of lobbies available—Server-owned and client-owned.
Server-owned lobbies can be lobbies owned by your title and waits for players to join. These lobbies have your
title game server listed as the owner. Client-owned lobbies are those that are created on behalf on players. These
lobbies have a client listed as the owner. It's important to note that PlayFab Lobby is a service so all lobbies are
created on PlayFab servers.
To learn how to create lobbies, see Create a lobby and Lobby and matchmaking walkthrough.
Privileges
The owner of a lobby has special privileges.
1. The owner can set lobby level items.
Server owners are allowed to modify everything that can be modified, except member data.
Client owners are allowed to modify everything a server owner can and their own member data. They
can't modify other members' data.
2. The owner can remove members from the lobby.
3. The owner may appoint another owner. This occurs by sending an update with the owner field specified.
The server owner can only specify another server to be the new owner.
The client owner can only specify another client, who is a member of the lobby, to be the new owner.
Privileges for server owners only
Server owner can query for lobbies they own.
Lobby is hidden during ownership migration. After a lobby owner change, the new server owner needs to re-
establish notification subscription and get a new subscribe connection. This turns the lobby visibility back on
for search.
Server owner can control notifications to its members
See also
Lobby properties
Create a lobby
Lobby ownership changes
Ownership changes
5/24/2022 • 3 minutes to read • Edit Online
IMPORTANT
This feature is currently in public preview. It is provided to give you an early look at an upcoming feature, and to allow you
to provide feedback while it is still in development.
Most game scenarios benefit from having a specially selected "owner" of the lobby. So it's important to define
policies to determine how ownership of the lobby migrates when the owner of the lobby leaves or is
disconnected.
See also
Lobby properties
Owner requirements and privileges
Create searchable lobbies
Create a lobby
Use Lobby and Matchmaking Together
5/24/2022 • 5 minutes to read • Edit Online
IMPORTANT
This feature is currently in public preview. It is provided to give you an early look at an upcoming feature, and to allow you
to provide feedback while it is still in development.
When designing multiplayer games, matchmaking and lobbies are often used together to help people form
groups to play together.
PlayFab Lobby and PlayFab Matchmaking helps you implement a wide variety of multiplayer scenarios.
This article describes the relationship between these two services and illustrates how they can be used together
to implement a game scenario specified below.
Example Scenario
A player wants to play with other people. The player starts a multiplayer game, invites friends, and waits for
others to join.
Design specifications
The game is open for everyone to join.
The initial set of players is populated via matchmaking.
The lobby owner is able to invite friends to join.
When the required number of players are met, all players in the lobby receive a message asking if they're
ready to start the game. They have one minute to respond. The game starts after all the players confirmed
that they're ready to start game.
If players in the lobby did not confirm their ready-to-play status, the lobby owner can remove them as
inactive players and use matchmaking to find new players to quickly replace them.
When any player gets disconnected unexpectedly during the game, the title should find a new replacement
for the dropped player through matchmaking using server backfill.
When the game ends, all players return to the lobby. Players are awarded team achievements equally. They
have the option to either stay to start another game together or leave the lobby.
Implementation
This section describes how to use Matchmaking and Lobby to implement the above design specifications.
Create a matchmade lobby
Send invites to friends
Allow people to find and join game
Notify players to start game
Remove and replace inactive players
Handle a finished game
Create a matchmade lobby
Create a public lobby for a group of matchmade players.
Each player creates a matchmaking ticket with their specified matchmaking attributes.
To learn more, see Specify ticket attributes.
All created tickets are added to a matchmaking queue be matched with one another.
Tickets are matched based on rules.
Rules can be defined in the matchmaking queue configuration.
To learn more, see Configure matchmaking queues.
After matchmaking, each player joins the matchmade lobby via the matchmaking ticket's
lobbyArrangementString .
When joining the arranged lobby, specify that the lobby's accessPolicy is Public to make the lobby
open.
See Arranged lobbies for more information.
The first player to join the arranged lobby becomes the owner for the lobby.
The lobby properties can be used to specify which game map a game session intends to use.
For more information, see Lobby properties.
Use search properties to enable players to find this lobby and game session among all of the active lobbies
in your title.
For more information, see Search properties.
Send invites to friends
Allow the lobby owner to select friends and send invites.
Get lobby owner's friends list
Display game UI to allow lobby owner to select friends to invite
Send in-game invites to selected friends.
For more information, see Lobby invites.
Allow people to find and join game
Setup the lobby's search properties to allow other players to find it
Display all lobbies in your game UI. Your title should also provide a way to accept player's search terms.
Use PFMultiplayerFindLobbies using the player's search parameters to return a list of lobbies that match
the criteria.
After a player selects to join a game, use PFMultiplayerJoinLobby to add the player to the game.
Notify players to start game
Inform all players in the lobby that game is ready to start
When the required number of players are in the lobby, display game UI to get players to confirm that they're
ready to start play.
Allow the lobby owner to view these confirmation responses.
Remove and replace inactive players
Lobby owner has the ability to remove inactive or disconnected players and initiate matchmaking to fill up the
remaining spots
If a player has discoonected or did not respond within the given set duration (one minute), use
PFLobbyForceRemoveMember to remove the player.
The lobby owner will use CreateSer verBackfillTicket to create a matchmaking ticket. Tickets created using
this API are given priority during searching. This is to minimize gameplay disruption. To learn more, see
Using server backfill tickets.
After joining the backfill lobby, the game's lobby owner can share the original lobby's connection string with
the new backfill players and they can join the original lobby.
Extend the game start time when appropriate.
Handle a finished game
After the game has finished, all players return to the lobby screen to complete the game session.
Lobbies are transient so any data from the lobby which should be persisted should be retained by each
player at this point.
For example, some game scenarios may benefit from processing data stored in the member
properties and turning that data into player achievements.
Players who want to continue playing with the same group will stay in the lobby.
Players who want to stop playing with the same group will leave the lobby with PFLobbyLeave and restart
the process with a new matchmaking group.
See also
Create a lobby
Lobby invites
Search properties
Lobby properties
Using server backfill tickets in Matchmaking
Lobby and Matchmaking real-time notifications
5/24/2022 • 2 minutes to read • Edit Online
Overview
The Matchmaking and Lobby features have built in support for real-time notifications. Notifying players of
changes to Matchmaking or Lobby has never been easier, as the work to handle notifications is done for you.
New APIs will allow connected clients to subscribe for notifications of Lobby and Matchmaking changes. With
this addition, you'll no longer need to poll for changes to matches or lobbies.
The client SDK has been designed to simplify your work. The client SDK manages calls between clients and
Lobby and Matchmaking services. It handles the delivery of notifications from those services to connected
clients in real time. Real-time notifications have cross-platform support, and will work anywhere PlayFab
supplies a client SDK. Matchmaking and Lobby can be used separately or together, and real-time notifications
will work in either case. There's no support for real-time notifications without the client SDK at this time. Real-
time notifications aren't available as a solution for stand-alone or general use.
IMPORTANT
This feature is currently in public preview. It is provided to give you an early look at an upcoming feature, and to allow you
to provide feedback while it is still in development.
Functions
F UN C T IO N DESC RIP T IO N
PFLobbyGetConnectionString Gets the default connection string associated with the lobby.
PFLobbyGetMembers Gets the list of PlayFab entities currently joined to the lobby
as members.
PFLobbySendInvite Send an invite to this lobby from the local user to the invited
entity.
PFMultiplayerCreateAndJoinLobby Create a new lobby and add the creating PlayFab entity to it.
Structures
ST RUC T URE DESC RIP T IO N
PFLobbySearchFriendsFilter The filter structure used to limit lobby search results to only
those lobbies owned by the player's friends.
State changes
STAT E C H A N GE DESC RIP T IO N
Enumerations
EN UM ERAT IO N DESC RIP T IO N
PFLobbyOwnerMigrationPolicy The available policies the lobby service can use to migrate
lobby ownership between members.
1.1.1
April 13, 2022
Bug fixes
Switch: Provides a new PAL header required to build against PlayFab Multiplayer.
1.1.0
March 4, 2022
API changes
PFMultiplayerGetErrorMessage's API signature has changed. Previously this function returned an HRESULT
and used an output paramter to return the error message string. Now the function returns the string directly.
New features
GDK: Added support for automatically handling suspend and resume on Xbox.
Bug fixes
Fixed a bug where using initial member data passed to PFMultiplayerJoinLobby would be ignored if the
player was rejoining a lobby.
1.0.0
November 23, 2021
PlayFab Multiplayer is now available in private preview. For an overview of Matchmaking and Lobby features,
check out:
PlayFab Lobby Overview
PlayFab Multiplayer Lobby Quickstart
PlayFab Matchmaking Overview
PlayFab Multiplayer Matchmaking Quickstart
Azure PlayFab Party overview
5/24/2022 • 2 minutes to read • Edit Online
Azure PlayFab Party is a low-latency chat and data communication solution for cross-platform and cross-device
multiplayer games. The voice and text features in Party can be used as a standalone chat solution.
For multiplayer games that use a server-client authoritative architecture to curtail competitive cheating concerns
or support devices with limited resources, consider multiplayer servers like PlayFab multiplayer servers to host
custom, dedicated game logic in a dynamically scaling cloud environment and use Party for chat
communication.
This topic provides a high-level overview of Party features. For details, see Party features.
Features
Party is designed for use on many platforms like Android, iOS, Nintendo Switch, Google Stadia, PlayStation, PC,
and Xbox. Party also provides C/C++ SDKs and SDKs for use with game engines like Unity and Unreal. For a
complete list, see Party SDKs.
Interoperable multiplayer infrastructure
Cross-network/cross-platform multiplayer game experiences.
Low-latency secure data communication
Industry-standard encryption and authentication.
Cross-platform mesh: automatic low-latency cloud relay or select regions yourself, choosing from
Azure regions distributed across the globe
Direct peer-to-peer functionality.
Background Quality of Service (QoS) measurements.
Flexible topology design possibilities
Everyone-to-everyone.
Constrained to "teams" or game-defined "channels" and more.
Accessible voice and text chat
Real-time speech-to-text and text-to-speech.
Real-time translation for text and voice by using Azure Cognitive Services.
Ability to add real-time custom voice effects like spatial sound.
Capabilities designed for multiplayer games
Efficient game states and logic delivery.
Integrates with custom discovery systems—players finding other players.
Policy enforcement for connectivity and communication.
Party is a managed game service. Discounts are available when you use Party with Xbox Live. For pricing
information, see PlayFab pricing. To learn about the meters that drive billing, see Party pricing.
If you are interested, here is a video of our presentation at Microsoft Game Dev 2021. The presentation explains
the above Party features in greater detail with demos and includes a quickstart tutorial.
See also
Party features
Getting started with Party
Multiplayer servers
Multiplayer
Matchmaking
Party and direct peer-to-peer connections
Azure PlayFab Party features
5/24/2022 • 5 minutes to read • Edit Online
This topic provides details about Azure PlayFab Party features and how you can use them in your game.
For a high-level summary of Party features, see Party overview. If you're ready to start developing, see Getting
started with Party.
NOTE
You're responsible for the compliance of your multiplayer and cross-network implementation.
NOTE
Using data transmission in Party is entirely optional. Some games use only the chat features.
See also
Party overview
Getting started with Party
Multiplayer servers
Multiplayer
Matchmaking
Party and direct peer-to-peer connections
Getting started with Azure PlayFab Party
5/24/2022 • 3 minutes to read • Edit Online
This topic describes how to set up the development environment for Azure PlayFab Party and start using it.
Prerequisites
You need a PlayFab account, and you must enable the Party feature to start using Party.
1. Create/sign in to your PlayFab account. For instructions, see Quickstart: Game Manager.
2. Enable Party feature via Game Manager from your PlayFab account.
Useful resources
Run a sample
Running a sample is a helpful way to learn how Party works. To download a sample, go to Party samples. If you
have questions or need help, go to PlayFab forums.
Install the PlayFab SDK
You can use the PlayFab SDK to get the PlayFab Entity Token. The PlayFab SDK is needed when you want to use
other PlayFab functionalities such as economy and leaderboards.
1. Install the version of the PlayFab SDK that you need—select by languages, game engines, or frameworks.
2. Associate your game's PlayFab title ID with the PlayFab SDK. If you need to find out what title IDs are or
where to find them, see Your studios and titles.
Key concepts
To help you design and harness the full power of Party, following are some concepts that cover different key
areas.
Party objects and their relationships
Know what the key objects are and how they relate to each another. This information provides you with a
basic understanding of the overall data communication architecture.
Party chat basics
Understand how chat works. Learn which key objects need to be created and defined to implement chat.
Party invitations and the security model
Learn how to limit access to a network as a way to protect the integrity of your own network. Understand
how you can effectively use invites as part of your security design.
Party interacts with your discovery flows
Party can be used with other PlayFab multiplayer features. These features enable players to find other
players so that they can play together. Learn how matchmaking, lobby, and other features can help in this
discovery process.
Party API reference documentation
Get more details about parameters, return values, and behaviors when invoking the C/C++ libraries.
Party UX guidelines for Text-to-speech and Speech-to-text
Understand the best practices for designing user experiences. Be informed about our recommendations
around chat and data communication user interfaces.
See also
Party overview
Party features
Party SDKs
Party samples
Multiplayer servers
Multiplayer
Matchmaking
Party samples
5/24/2022 • 2 minutes to read • Edit Online
This topic lists all the Azure PlayFab Party samples that are currently available.
If there's a specific sample that you'd like to have, let us know by writing a post on our forums.
Access to samples for Nintendo Switch, PlayStation®4, PlayStation®5, Google Stadia, PC (GDK), and Xbox
(GDK) requires special approval and adherence to platform policies. For more information, see Request access
for SDKs and samples.
List of samples
SA M P L E DESC RIP T IO N P L AT F O RM / O P ERAT IN G SY ST EM
Chat app Demonstrates Party chat usage with Windows 10, Windows 8.1, Windows
full speech-to-text and text-to-speech 7, Android, iOS, Stadia, Switch,
capabilities. PlayStation 4, PlayStation 5
Bumble Rumble Demonstrates usage of Party Windows 10, Windows 8.1, Xbox (XDK)
networking, matchmaking, and
accessible voice chat—full speech-to-
text and text-to-speech capabilities. It
doesn't include Xbox Live requirements
and game invites.
See also
Party SDKs
Party overview
Getting started with Party
Enabling PlayFab Party
5/24/2022 • 2 minutes to read • Edit Online
This tutorial will get you up and running quickly by showing you in a few steps how to enable the use of PlayFab
Party with the PlayFab Party demo app.
For more on the PlayFab Game Manager, see the Game Manager quickstart.
NOTE
You must launch your title on Game Manager before shipping your title to avoid Dev Mode limits. Failing to do so can
cause your title to not function as more players engage in your game.
This quickstart is intended to be a high-level overview of PlayFab Party's core features. PlayFab Party was
designed to be cross-platform from the ground up. We've structured these quickstarts in the same way, where
most of the information applies to all platforms, and platform-specific prerequisites and steps are described in
the linked documents.
In this quickstart, critical pieces of functionality are highlighted via explanatory text and code snippets. However,
note that this is not a step-by-step walk-through.
For a deeper understanding, consult the linked reference and conceptual documentation, and per-platform
sample applications.
Platform Prerequisites
Before you start this quickstart, perform any necessary platform-specific setup as specified in the following
topics:
1. Android prerequisites
2. iOS prerequisites
3. Nintendo Switch prerequisites
4. Xbox XDK prerequisites
When you finish the platform-specific steps, continue with the rest of the steps in this topic to set up PlayFab
Party.
IMPORTANT
Follow these steps to Enable PlayFab Party.
Log into your PlayFab title and obtain an entity token and entity ID
To initialize and use Party, you must log in to PlayFab. You can use PlayFabClientAPI::LoginWithCustomID or a
platform-specific login method to do this.
Once you execute login, PlayFab returns an entity ID and entity token as part of the LoginResult. These two key
pieces of information are used to initialize a Local user instance for PlayFab Party.
An example code snippet for logging in with a custom ID as implemented in PlayFabManager.cpp is shown
below:
PlayFabClientAPI::LoginWithCustomID(
loginRequest,
[this, callback, userId](const LoginResult& loginResult, void*)
{
// Sign in was successful.
DEBUGLOG("PlayFab::signin -- Login with custom id callback\n");
After successfully obtaining the entity ID and entity token from PlayFab, you can proceed with enabling and then
initializing Party.
m_partyInitialized = true;
}
if (PARTY_FAILED(err))
{
DEBUGLOG("CreateLocalUser failed: %s\n", GetErrorMessage(err));
return;
}
}
3. Create a chat control and set the audio input and output channel where Party will receive or forward data.
The chat control object manages the chat operations for the user on the specific device.
// Only create local chat controls if they don't exist.
if (m_localChatControl == nullptr)
{
PartyLocalDevice* localDevice = nullptr;
if (PARTY_FAILED(err))
{
DEBUGLOG("GetLocalDevice failed: %s\n", GetErrorMessage(err));
return;
}
// Create a chat control for the local user on the local device
err = localDevice->CreateChatControl(
m_localUser, // Local user object
m_languageCode, // Language id
nullptr, // Async identifier
&m_localChatControl // OUT local chat control
);
if (PARTY_FAILED(err))
{
DEBUGLOG("CreateChatControl failed: %s\n", GetErrorMessage(err));
return;
}
if (PARTY_FAILED(err))
{
DEBUGLOG("SetAudioInput failed: %s\n", GetErrorMessage(err));
return;
}
if (PARTY_FAILED(err))
{
DEBUGLOG("SetAudioOutput failed: %s\n", GetErrorMessage(err));
}
if (PARTY_FAILED(err))
{
DEBUGLOG("Populating available TextToSpeechProfiles failed: %s \n", GetErrorMessage(err));
}
// Set transcription options for transcribing other users regardless of language, and ourselves.
PartyVoiceChatTranscriptionOptions transcriptionOptions =
PartyVoiceChatTranscriptionOptions::TranscribeOtherChatControlsWithMatchingLanguages |
PartyVoiceChatTranscriptionOptions::TranscribeOtherChatControlsWithNonMatchingLanguages |
PartyVoiceChatTranscriptionOptions::TranslateToLocalLanguage |
PartyVoiceChatTranscriptionOptions::TranscribeSelf;
if (PARTY_FAILED(err))
{
DEBUGLOG("SetTranscriptionOptions failed: %s\n", GetErrorMessage(err));
}
At this point, you have the PlayFab Party initialized in your application or game.
Refer to the NetworkManager::Initialize() code in NetworkManager.cpp in the demo app for a complete
sample.
The next step is to Create and Connect to a Party Network.
// Initialize an empty network descriptor to hold the result of the following call.
PartyNetworkDescriptor networkDescriptor = {};
The full code of the CloudScript functions are given below for reference:
try {
server.CreateSharedGroup({ SharedGroupId: roomId });
} catch(err) {
log.info("Shared group " + roomId + " could not be created.");
log.error(err);
}
var updateRequest = {
SharedGroupId: roomId,
Data: {
Data: {
"network": networkDescriptor
}
};
server.UpdateSharedGroupData(updateRequest);
};
//
// Used to retrieve a previously stored network descriptor by roomId.
// Inputs:
// roomId - The hash key used to store and retrieve the network descriptor.
//
handlers.get_network_descriptor = function (args, context)
{
if (args && args.hasOwnProperty("roomId"))
{
var roomId = args.roomId;
}
else
{
return;
}
try
{
var getRes = server.GetSharedGroupData({ SharedGroupId: roomId });
return getRes.Data;
}
catch(err)
{
return;
}
};
Once each player has a way to retrieve the network descriptors by selecting a room and calling the CloudScript
functions, they can use the network descriptor thus retrieved to join the Party Network.
The following steps are required to successfully join a PlayFab Party Network:
1. Retrieve the network descriptor as a string by executing the above-mentioned PlayFab CloudScript
function.
2. Deserialize the network descriptor from the network descriptor string.
3. Connect to the Party Network.
4. Authenticate the local user for the network.
5. Connect the local chat control to the network so that we can use VOIP.
6. Establish a Party Network endpoint for game message traffic.
if (PARTY_FAILED(err))
{
DEBUGLOG("ConnectToNetwork failed to deserialize descriptor: %s\n", GetErrorMessage(err));
errorCallback(err);
return;
}
if (PARTY_FAILED(err))
{
DEBUGLOG("ConnectToNetwork failed: %s\n", GetErrorMessage(err));
errorCallback(err);
return false;
}
if (PARTY_FAILED(err))
{
DEBUGLOG("AuthenticateLocalUser failed: %s\n", GetErrorMessage(err));
errorCallback(err);
return false;
}
// Connect the local user chat control to the network so we can use VOIP
err = m_network->ConnectChatControl(
m_localChatControl, // Local chat control
nullptr // Async identifier
);
if (PARTY_FAILED(err))
{
DEBUGLOG("ConnectChatControl failed: %s\n", GetErrorMessage(err));
errorCallback(err);
return false;
}
if (PARTY_FAILED(err))
{
DEBUGLOG("Failed to CreateEndpoint: %s\n", GetErrorMessage(err));
errorCallback(err);
return false;
}
if (PARTY_FAILED(err))
{
DEBUGLOG("Failed to SendMessage: %s\n", GetErrorMessage(err));
}
}
IMPORTANT
While creating the chat control in one of the previous steps, you've already set up the audio input and output devices
which will be used by Party to send, receive and render audio data. To receive the audio messages, you'll also need to set
the appropriate chat permission between each chat control if you want audio to flow. By default, the chat permissions are
set to NONE. For more information, refer to the Chat Permissions article.
The processing of other messages from the Party layer is best accomplished in a dedicated update thread or a
high-frequency game loop. The game loop should be set up to run every frame and receive messages from the
Party Manager via the StartProcessingStateChanges() function.
For a complete description of all the state changes refer to the Party Reference Documentation. Alternatively,
you can refer to the NetworkManager.cpp for an example of how to process each state change.
Conclusion
In this quickstart, we walked through the key pieces of PlayFab Party and saw how to interact with them.
We encourage you to take a look at the complete Reference and Conceptual documentation as well as samples
for a deeper understanding of the systems.
Next steps
For additional platform-specific guidance for application, see:
Xbox and Xbox Live
Xbox Requirements
Using MPSD
PlayFab Party objects and their relationships
5/24/2022 • 13 minutes to read • Edit Online
Successfully using the power and flexibility of the PlayFab Party API begins with understanding the following
crucial objects defined in its scope:
Device - A distinct instance of the game executing on a physical device. A local device exists whenever the
API is being used.
User - An individual logged-on player, or more precisely, a PlayFab title_player_account Entity that the
game has actively provided to PlayFab Party for authentication and identification purposes. One or more
users are associated with a given device.
Network - A secured collection of one or more devices and their authorized users that the game creates for
the purpose of exchanging chat or data communication. This typically aligns with a game's multiplayer
session or chat party concept.
Endpoint - An abstraction for sending and receiving data within a network. An endpoint may represent a
device, a user, or any desired game-specific concept.
Chat control - A representation of a user specifically for configuring, originating, and targeting voice and
text chat in one or more networks.
Object relationships
As a simplified conceptual hierarchy, networks contain devices, which in turn contain users, optional endpoints,
and optional chat controls. For example:
While simple enough to understand, the preceding relationship diagram is actually an incomplete depiction of
PlayFab Party's capabilities and can be misleading if taken on its own. In reality, the Party API supports devices
connecting to multiple networks at once. For example, one might desire to maintain communication with a
group of friends over time as that same group also joins and leaves separate larger game sessions with
strangers. Considering this broader scenario allows us to better grasp the relationships between these objects.
It might feel intuitive to conceptualize a device as belonging to networks, but this is not the case. It is more
correct to realize that devices participate in networks. As such, only a single device API object, whether remote
or local, is ever created by the Party library when a particular instance is encountered, regardless of the number
of networks it shares with your local device.
As an example, the following diagram shows two networks and three devices with users, chat controls and
endpoints. Device A and its two chat controls (with associated users) are participating in Network 1, while
Devices B and C have connected both to that network and to Network 2 with a single chat control (and
associated user) each. All devices have created one or two endpoints in each network where they're connected:
In the above diagram, every device sees a single instance of all three devices and their chat controls, since they
have at least one network in common with each other. Device A only knows about Endpoints 1-4 in Network 1,
but Devices B and C can see the Endpoints 5-7 they created in Network 2 as well.
If Device C were instead only participating in Network 2 in the above diagram and not both networks, then:
Device C obviously would not have been able to create Endpoint 4 in Network 1, nor see Endpoints 1-3 that
the others had created within it.
Device C would not know about Device A or its two chat controls only in Network 1.
Device A would similarly not see Device C or its chat control only in Network 2.
Device B however would still see all devices and their chat controls since it's still in both networks.
So, despite devices and chat controls being "outside" a strict hierarchical tree relationship with networks, it's
important to note that a game instance will never actually encounter a remote device or chat control without the
context of an accompanying network. If the local and remote device or chat control have at least one network in
common, the remote object may be visible. But if there are no common networks, then the remote object will
never be created.
NOTE
Games are not required to connect to more than one network simultaneously in order to use PlayFab Party successfully.
You can learn more about whether and how to use multiple networks in a subsequent advanced topic.
NOTE
The network descriptor for a network can change in rare circumstances. Games should be prepared for notifications of
such changes, and then update or re-advertise the new network descriptor for an existing network in order to avoid
problems with additional devices connecting.
Even with a network descriptor available, gaining access to a network is restricted to users that the game
authorizes to join the particular network in advance (or perhaps "just-in-time" when the user has been added to
a corresponding externally-managed gameplay session, for example). This user authorization is done during
network creation and through subsequent creation and revocation of invitations as described in more detail in
the topic Invitations and the security model.
Games can choose to use invitations to restrict entry to only users' friends, or to prevent malicious players from
joining the network.
Devices can connect to more than one network at a time. You can learn more about whether and how to use
multiple networks in a later topic.
The kinds of actions that can be taken on PartyNetwork objects include authenticating local users into it,
connecting and enumerating chat controls, creating and enumerating endpoints, or getting network-wide
performance information.
Device
The PartyDevice object represents a distinct instance of the game and its PlayFab Party library code executing
on a physical device. Most operations aren't performed on PartyDevice objects themselves; rather they're an
organizational mechanism for defining which endpoints or chat controls belong to that game instance,
particularly for platforms and games that support more than one local user simultaneously. PlayFab Party uses
this relationship knowledge to optimize transmission of game data and chat by only sending one copy of a
message even if multiple targets on the device need to receive it, for example.
Remote PartyDevice objects are "byproducts" of connecting to a network and authenticating a user into that
network. They're only created when valid, authenticated remote users associated with the device are
participating in a network to which the local device is also connected. Correspondingly, they are also destroyed
once that is no longer true.
On the other hand, the PartyLocalDevice specialized sub-object is always available for the local game instance
to reference as long as PlayFab Party is initialized. It is never explicitly created or destroyed.
User
A PlayFab Party user is a unique human player for whom the game has performed PlayFab Player Login in order
to acquire a title_player_account Entity ID and token.
Remote users are identified within the PlayFab Party API solely by their Entity ID string associated with chat
controls and optionally with endpoints. They are not represented using a dedicated object. This is because
PlayFab Party doesn't have functionality that meaningfully interacts with arbitrary users, other than for raw
identification and as a label associated with those other objects.
Conversely, for local users there are explicit PartyLocalUser objects, since games own the management of their
lifetimes within PlayFab Party. The game will typically create a PartyLocalUser when the game has successfully
logged that PlayFab player in using the applicable login method, and destroy the PartyLocalUser as appropriate
when that user logs off. For platforms and games that support multiple local players logged in, additional
PartyLocalUser objects should be created for each player.
PartyLocalUser objects are also important because they are the basis of all authentication. A valid local user
must exist in order to either create a new network or to authentication into one.
Authorizing users is described in more detail in the topic covering Invitations and the security model.
Almost every operation requires a PartyLocalUser to be provided or present, even though very few operations
are performed on PartyLocalUser objects themselves.
PartyLocalUser objects are created using the PartyManager object. They can only be explicitly destroyed by their
creators. While they have no direct object representation on remote devices, chat controls and endpoints
associated with them will be destroyed if the owning device removes the PartyLocalUser or disconnects from
the network, gracefully or otherwise.
Endpoint
PartyEndpoint objects are optional but are the core of PlayFab Party data communication for games that
leverage them. Like typical networking sockets, endpoints are an abstracted addressing mechanism for
originating or targeting data messages within a network. They could represent a device, an individual user, or
any arbitrary game-defined concept (e.g., a tank unit) that you'd like to uniquely identify for sending and
receiving messages.
The specialized PartyLocalEndpoint sub-object is for endpoints created in the network by the local game
instance. This is where most endpoint functionality resides. Its PartyLocalEndpoint::SendMessage() transmits
game data payloads from the PartyLocalEndpoint to one or more other PartyEndpoint objects in the same
network. It provides various options for selecting how best to handle Internet packet loss (e.g., guarantee
delivery and/or ordering), to control the tradeoff between low latency versus coalescing multiple messages
from the same or other local endpoints for lower bandwidth usage, and to react when the connection quality
isn't sufficient to support the rate at which the game is sending. You can learn more about transmitting game
data using endpoints in a later topic.
In addition to being a source or destination for data messages itself, each PartyEndpoint object is also assigned
a 16-bit endpoint unique identifier by PlayFab Party that allows you to reference the specific endpoint in
message payloads sent to or from separate PartyEndpoint objects within the network. This provides a
convenient way to avoid the overhead of sending a full, larger user Entity ID string or other identifier it might
represent, for example, without having to build your own peer-to-peer identity agreement negotiation.
PartyLocalEndpoint objects are created using their containing PartyNetwork object. Doing so results in
corresponding PartyEndpoint objects being created on remote devices. An endpoint can be destroyed explicitly
by its creator, or will be destroyed implicitly when the owning device disconnects from the network or the
associated PartyLocalUser object (if one had been specified) is removed from the network.
Chat control
PartyChatControl objects are the mechanism for using PlayFab Party's optional chat communication features.
They represent a particular user's associated audio input/output devices, preferences, and communication
policies.
The specialized PartyLocalChatControl sub-object is also available for chat controls created by the local game
instance. This is where you configure the permissions allowing chat communication to or from remote
PartyChatControl objects, for example, to choose network-wide vs. team-only chat, or to apply platform policy
restrictions. Local chat controls are used for sending chat text, synthesizing text to speech, requesting
transcriptions and translations of voice streams, muting, and more.
PartyLocalChatControl objects must be connected to a network before they will be created as PartyChatControl
objects on remote devices in that same network. A device will always only see a single representative
PartyChatControl object created, even when that device and chat control have connected to more than one
network in common. This helps avoid unnecessary duplication or interruption of audio and text chat messages.
PartyLocalChatControl objects are created using the containing PartyLocalDevice object. A chat control can be
destroyed explicitly by its creator, or will be destroyed implicitly when the owning device disconnects from the
network or the associated PartyLocalUser object is removed from the network.
State Change
PartyStateChange structures are used to inform the game of all asynchronous operation completions, incoming
messages, update notifications, and other API-related events.
To simplify how you work with complex multi-machine interactions over the Internet with unpredictable timing,
PlayFab Party guarantees it won't modify any state it reports from the API except as a result of an explicit call by
the game. But since you do still need a way to learn about remotely initiated operations or unplanned
occurrences that modify local state, PlayFab Party and the game cooperate through a special pair of methods,
PartyManager::StartProcessingStateChanges() and PartyManager::FinishProcessingStateChanges() . These are
called at a point in the game's work loop where it's convenient to handle such updates. The new events are
reported from PartyManager::StartProcessingStateChanges() as an array of zero or more PartyStateChange
structures. Once the game has handled the state changes, the array is returned using
PartyManager::FinishProcessingStateChanges() .
The PartyStateChange structure is not a full object by itself. It's a base header to be cast to a more detailed
structure containing information on the specific type of completion or notification, pointers to the relevant
objects, and any error information.
Working with state changes is described in full detail in a later topic.
Next steps
Learn about PlayFab Party invitations and the security model
Learn how PlayFab Party interacts with your discovery flows
Find out more about PlayFab Party chat communication
See how to work with asynchronous operations and notifications in PlayFab Party
Understanding how PlayFab Party chat works
5/24/2022 • 3 minutes to read • Edit Online
With PlayFab Party you can easily add voice and text communication to your game.
PlayFab Party chat is:
Flexible : Gives you full control of how you want your player to communicate.
Powerful : Uses hardware codec acceleration on supported platforms.
Accessible : Powered by Azure Cognitive Services, speech-to-text, text-to-speech and translation features are
built-in and easy to enable.
Efficient : Having your chat system tightly integrated with your networking layer means voice data get sent
where it needs to go in the most efficient way possible.
Chat basics
To add voice and text communication to your game you will first need to create a PartyLocalChatControl object.
This PartyLocalChatControl object will act as the management object for chat operations related to a specific
local user, allowing you to choose the input and output device, mute state, and accessibility preferences. Each
local user can have no more than one chat control. For a local chat control to communicate with another chat
control, the following requirements must be met:
1. The two chat controls must be in the same network.
2. The chat permissions between the two chat controls must allow audio and/or text communication to flow.
With your local chat control in-hand you are now ready to have it connect to a network by calling
PartyNetwork::ConnectChatControl() . Upon connection, other devices in the network will be notified that your
chat control has joined the network with a PartyChatControlJoinedNetworkStateChange state change. You will also
receive a PartyChatControlJoinedNetworkStateChange for every other chat control already in the network and will
immediately be able to communicate with them.
PartyAudioDeviceSelectionType::None
When this audio device selection type is chosen, the chat control won't use any audio device. This is the default.
PartyAudioDeviceSelectionType::SystemDefault
When this audio device selection type is chosen, the chat control will attempt to use the system's default
communication device. On Windows, the player can change this device at any time through the Windows Sound
Control Panel and Party will respond to those changes automatically. This selection type is not supported on
Xbox One and generally not recommended if you have more than one local user participating in chat
simultaneously.
PartyAudioDeviceSelectionType::PlatformUserDefault
P L AT F O RM W H AT TO USE
Windows 7 IMMDevice
NOTE
We strongly recommend using PartyAudioDeviceSelectionType::PlatformUserDefault on Xbox One and
PartyAudioDeviceSelectionType::SystemDefault on Windows platforms.
Text chat translation can also be enabled by calling PartyLocalChatControl::SetTextChatOptions() . By setting the
PartyTextChatOptions::TranslateToLocalLanguage option Party will translate incoming text message to the local
chat control's language. The chat control's language can optionally be configured during chat control creation
and can be accessed by calling PartyLocalChatControl::GetLanguage() . Translation will also be applied to
incoming speech-to-text transcription.
Text moderation is also available for text chat. To learn more about this feature, please refer to the Using text
moderation page.
Accessible chat
Powered by Azure Speech Services, Party can transcribe player voice chat and synthesize speech from text. This
functionality has several uses but was primarily designed as an accessibility aide. We recommend tying
activation of this capability to an ease-of-access player setting. For more guidance on how to use the
accessibility features provided by Party, see text-to-speech guidelines and the speech-to-text guidelines.
Next steps
Find out more about PlayFab Party chat permissions and muting
PlayFab Party text-to-speech and text input UX
guidelines
5/24/2022 • 11 minutes to read • Edit Online
The PlayFab Party library gives game creators the power to engage more players through accessible game chat
options. It provides a means for voice chat to be transcribed to text and for text input to be converted to
synthesized voice. You can implement a custom UI solution for these features in your title. On Xbox and
Windows, you can use platform APIs to implement the relevant UI.
This topic is part one of a two-part series covering UX solutions for speech-to-text and text-to-speech
implementation. Part one focuses on text-to-speech implementation, requirements, and console and PC UI
solutions, while part two focuses on speech-to-text implementation, requirements, and console and PC UI
solutions.
UI Narration (in- User is guided by the For text messaging For text messaging
game) Xbox OS synthesized systems: Games use systems: Games use
voice to launch game the Speech synthesis the Speech Synthesis
Alternative for API to guide the user API to narrate replies
reading in-game Game uses the to launch the Xbox
menus and text Speech Synthesis API OS keyboard
replies to narrate menu
options leading the
user to the MP lobby
EXP ERIEN C E STA GE SET UP P L AY C H AT M ESSA GE
Narrator (Xbox OS) User is guided by the For text messaging N/A
Xbox OS synthesized systems: A virtual
Alternative for voice to launch game Keyboard is narrated
reading Xbox menus as the user types a
message
Synthesizing text-to-speech
Once the title has configured a text-to-speech voice profile, text can be synthesized to speech audio via
PartyLocalChatControl::SynthesizeTextToSpeech() . For the Voice Chat scenario, the audio data will appear as
though it was captured "naturally" by the microphone associated with the user starting the text-to-speech
operation. This is akin to the user holding the microphone to a computer that is talking on their behalf. For the
Narration scenario, the audio data will be played to the user's audio output.
Synthesizing text-to-speech is an asynchronous operation; the completion of the operation is indicated by
PartyManager::StartProcessingStateChanges() providing a PartySynthesizeTextToSpeechCompletedStateChange .
Although a voice profile must be configured before synthesizing text-to-speech, it isn't necessary to wait for the
asynchronous operation started by PartyLocalChatControl::SetTextToSpeechProfile() to complete before calling
PartyLocalChatControl::SynthesizeTextToSpeech() . If a profile operation is in progress, the text-to-speech
operation will be queued and start after the profile operation completes.
Text messaging
In addition to text-to-speech, Party supports traditional text messaging. Although many titles tie text-to-speech
to text messaging, that isn't a requirement - Party supports text-to-speech and text messaging as independent
features. For more information, see Understanding chat.
Text-to-speech UX
Text-to-speech enables a person to use the platform to send a synthesized voice stream to the active game chat
participants. This is great for enabling the person to participate when there is no text chat-based system
available, and all communication is active through the in-game voice chat.
Discovery
For Xbox and Windows, users can find text-to-speech and speech-to-text settings in the Accessibility section
under Settings in Xbox Home (Xbox console) or Xbox App (Windows 10). The settings are controlled via toggle
buttons that enable or disable the features for all Xbox games specific to the user profile that integrate with the
platform settings. For all other platforms, refer to their accessibility guidelines for text-to-speech and speech-to-
text setting locations.
NOTE
If your game chooses to add additional settings that are game specific only, then they should be placed inside your game.
In general, accessibility options belong under the game’s settings/options menu. Ideally, settings should be available as a
dedicated button press and accessible from any screen or, at least, the Pause menu.
NOTE
The keyboard will still appear when a gamepad is installed. It will not appear when a hardware keyboard is
installed.
2. PC OS vir tual keyboard (Windows 10 example)
The PlayFab Party API supports receiving input across all platforms. However, text input components are
not provided consistently across those platforms.
On the Xbox console, games can rely on the virtual keyboard. It has its own input box, which accepts
text that is then provided to the title.
On Windows, games can rely on the virtual keyboard with a caveat - it doesn't have an input box. This
means that the game must provide a text input box to accept the keystrokes generated by the virtual
keyboard. Even if the game does not support traditional text chat, text input may be required for text-
to-speech support.
UX recommendation (Windows )
Cross-platform games that do not support traditional text messaging must provide a text input box to
accept keystrokes to support text-to-speech.
NOTE
The phrases used here specific to the sample game being shown.
In the second image, a pop-up display offers a list of ten replies. A user can select up to four, each mapped to a
D-pad direction based on the order of selection.
Conclusion
PlayFab Party text-to-speech and speech-to-text APIs are highly effective features for including a wider range of
users in a game and gaming conversations. The more gamers engage and develop relationships, the more likely
they are to continue playing. This guidance will help ensure the best possible user experience.
Resources
Design templates
QuickChat_AI_Template.zip Contains:
QuickChat_ConsolePC_Templates.ai
Text-to -speech narration menu guidelines
Speech interactions
Speech synthesis API (Windows)
PlayFab Party text-to -speech and speech-to -text UX series
Part 1: PlayFab Party text-to-speech and text input UX Guidance
Part 2: PlayFab Party speech-to-text and text display UX Guidance
SDK documentation
"Accessible in-game chat overview" in the PlayFab SDK (see SDK Downloads)
Accessibility guidance
Griffiths, Gareth. Subtitles: Increasing Game Accessibility, Comprehension Gamasutra
Game Accessibility Guidelines A straightforward reference for inclusive game design
Straub, Josh. Game Accessibility: What It Is And Why It Matters Game Informer
Inclusive design
Xbox's Gaming for Everyone Initiative
Inclusive Design Microsoft Design Toolkit and education
Kojouharov, Stefan. 10 Tips on Creating an Addictive ChatBot Referenced in this document for conversational
UI tips.
PlayFab Party speech-to-text and text display UX
guidelines
5/24/2022 • 13 minutes to read • Edit Online
The PlayFab Party library gives game creators the power to engage more players through accessible game chat
options. It provides a means for voice chat to be transcribed to text and for text input to be converted to
synthesized voice. You can implement a custom UI solution for these features in your title. On Xbox and
Windows, you can use platform APIs to implement the relevant UI.
This document is part two of a two-part series covering UX solutions for speech-to-text and text-to-speech
implementation. Part one focuses on text-to-speech implementation, requirements, and console and PC UI
solutions, while this topic focuses on speech-to-text implementation, requirements, and console and PC UI
solutions.
UI Narration (in- User is guided by the For text messaging For text messaging
game) Xbox OS synthesized systems: Games use systems: Games use
voice to launch game the Speech synthesis the Speech Synthesis
Alternative for API to guide the user API to narrate replies
reading in-game Game uses the to launch the Xbox
menus and text Speech Synthesis API OS keyboard
replies to narrate menu
options leading the
user to the MP lobby
EXP ERIEN C E STA GE SET UP P L AY C H AT M ESSA GE
Narrator (Xbox OS) User is guided by the For text messaging N/A
Xbox OS synthesized systems: A virtual
Alternative for voice to launch game Keyboard is narrated
reading Xbox menus as the user types a
message
Receiving transcriptions
When audio is sent to a chat control associated with a local user that has enabled transcription, the audio will be
transcribed. Each transcription will be indicated by a PartyVoiceChatTranscriptionReceivedStateChange provided
by PartyManager::StartProcessingStateChanges() . The speaker, receiver(s), and transcription text will be specified
in the state change. Additionally, the state change will specify whether the transcription text is a Hypothesis or
Final phrase. A Hypothesis phrase is a snapshot in the transcription process that indicates an iterative
refinement of the transcription text. These can optionally be used to improve the perceived responsiveness of
the transcription process. A Final phrase represents the end of the transcription process after a user has
completed a sentence or phrase.
Displaying transcriptions
When transcription text is received, it should be displayed according to the following UX design guidelines. The
Windows::Gaming::UI::GameChatOverlay or Windows::Xbox::UI::Accessibility API can be used on Windows or
Xbox, respectively, to use the default system text chat UI that has been designed to comply with these guidelines.
Discovery
For Xbox and Windows, users can find text-to-speech and speech-to-text settings in the Accessibility section
under Settings in Xbox Home (Xbox console) or Xbox App (Windows 10). The settings are controlled via toggle
buttons that enable or disable the features for all Xbox games specific to the user profile that integrate with the
platform settings. For all other platforms, refer to their accessibility guidelines for text-to-speech and speech-to-
text setting locations.
NOTE
If your game chooses to add additional settings that are game specific only, then they should be placed inside your game.
In general, accessibility options belong under the game’s settings/options menu. Ideally, settings should be available as a
dedicated button press and accessible from any screen or, at least, the Pause menu.
NOTE
Verdana is the most legible font that Microsoft ships. Even better than Verdana by itself is to present the font with high
contrast (full black on full white or vice-versa) and at large sizes. Size, contrast, and letterform are the three biggest factors
in legibility (in that priority order).
Start testing your design by using the ConversationWindow_Template.ai . Go to Resources for the native
Adobe Illustrator (.ai) file.
Position and proportion
Now that you have minimum text requirements for the conversation window, you can begin testing positioning
and size ratio.
Positioning: relative vs. fixed
Aligning the conversation window to a grid format provides a very straightforward set of inputs that can scale
regardless of the screen resolution. For example, the Xbox OS speech-to-text UI references nine quadrants
(Left/Top, Left/Center, Left/Bottom, Middle/Top, and so on) for positioning.
If your game outputs to multiple screen resolutions (4K, PC), you won't have to worry about scaling 1080p X,Y
pixel values to a different screen size.
By having a predetermined number of relative positions, you won't have to fight with legacy code to maintain
pixel-perfect positioning of design elements, fonts or safe areas. Your design guarantees a relative position
instead.
Consider referencing multiple positions to accommodate varying screen complexity:
Identify screens where game chat activity is critical.
Avoid inhibiting interaction. (See Note)
Avoid hiding critical details. (See Note)
NOTE
Take care to position the conversation window so that it doesn't inhibit game activity. This will ensure speech-to-text users
can enjoy a comparable experience as other users.
User-controlled customization
There may be screens where there simply isn't room to accommodate a conversation window of any size.
Example: The end-of-game results UI fills the entire screen. A conversation window risks covering critical stats.
PC example: A button is mapped to toggle the display ON/OFF and is annotated in the legend.
Functional requirements
Conversation continues to be tracked while the window is minimized.
The user can expand and see the latest replies. (The user does not see a history of missed replies.)
This option appears when a user profile's speech-to-text setting is detected as enabled.
This setting would not override the OS Profile's speech-to-text setting.
Display frequency
Chat activity will fluctuate between players during game sessions. There is no value to keeping an empty chat
window open when players aren't chatting.
Automatically close the window when chat has been inactive for a set period.
Example: The speech-to-text window closes after 15s of inactivity. This number is based on the time it would
take a user to read one message of 280 characters.
NOTE
It's worth testing various settings to ensure that opening and closing a window isn't too distracting on a game screen
with a lot of activity.
Scrolling
During ongoing conversations, the window must facilitate a view of most recent replies. Most recent replies are
displayed at the bottom of the replies and scroll up.
NOTE
Auto-scrolling is a solution that makes managing conversations easier for both developers and users. It comes closest to
mimicking fluid conversation. The less effort a user has to make to manage the view, the more time they have to focus on
gameplay. A manual scrollbar would require shifting controller focus, which can be disruptive during active gameplay.
Visual disparity
It may be tempting to design this chat window to match your UI style. However, the chat window has a specific
function, unique from other game components. It is presenting information that originates outside of game
instruction.
It is game information that also uses text and frames. A user could confuse the intention of the chat window with
actual in-game components, if they look too similar. Therefore, the Chat overlay must possess unique attributes
that clearly separate it from the game UI. Degree of disparity is up to the designer’s discretion.
Closing or destroying the conversation window
A game must determine when the conversation window remains active (while a user is multi-tasking) or when it
should close (for example, when a user exits a chat session). Keep in mind that this window represents a live chat
conversation and is not to be confused with instant messaging (IM). For example, if a user walks away from their
console or pauses a game, the conversation will continue but they'll have missed replies that occurred before
they return.
NOTE
UX recommendation: Keep the window active when a game is constrained or paused. Close the window when the game
exits.
Title-callable UI (TCUI)
Console example: The Xbox One Guide is TCUI and has a transparent overlay that dims the screen.
It's common for a platform’s system UI to be the ‘top’ visible layer of any game or app UI. For example, the Xbox
One operating system-initiated UI (error messaging, a virtual keyboard, toasts, the Xbox One Guide, people
picker, and other elements) applies a full screen, semi-transparent, black overlay with their content window.
UX impact : Visibility of the conversation window will be obscured.
Conclusion
PlayFab Party text-to-speech and speech-to-text APIs are highly effective features for including a wider range of
users in a game and gaming conversations. The more gamers engage and develop relationships, the more likely
they are to continue playing. This guidance will help ensure the best possible user experience.
Resources
Design templates
PlayFab Parties_AI_Templates.zip Contains:
PlayFab Parties_9GridTemplate.ai
ConversationWindow_Template.ai
Text-to -speech narration menu guidelines
Speech interactions
Speech synthesis API (Windows)
PlayFab Party text-to -speech and speech-to -text UX series
Part 1: PlayFab Party text-to-speech and text input UX guidance
Part 2: PlayFab Party speech-to-text and text display UX guidance
SDK documentation
"Accessible in-game chat overview" in the PlayFab SDK (see SDK Downloads)
Accessibility guidance
Griffiths, Gareth. Subtitles: Increasing Game Accessibility, Comprehension Gamasutra
Game Accessibility Guidelines A straightforward reference for inclusive game design
Straub, Josh. Game Accessibility: What It Is And Why It Matters Game Informer
Inclusive design
Xbox's Gaming for Everyone Initiative
Inclusive Design Microsoft Design Toolkit and education
Kojouharov, Stefan. 10 Tips on Creating an Addictive ChatBot Referenced in this document for conversational
UI tips.
PlayFab Party chat permissions and muting
5/24/2022 • 2 minutes to read • Edit Online
Overview
PlayFab Party gives you fine-grained control over how your players can communicate with each other's. Rather
than specifying teams or channels, PlayFab Party requires that explicit permissions between each pair of chat
controls be defined. The chat permissions system allows you to control incoming and outgoing voice
communication as well as incoming text communication between any pair of chat controls.
Chat permissions
Communication between chat controls is disabled by default and it is up to the Game to set the right
PartyChatPermissionOptions between each pair of chat controls. Chat permissions should reflect the relationship
between each chat control as determined by the scenario you are trying to achieve. For example, in a team
versus team scenario, you might want to set the chat permissions to allow all types of communication between
members of the same team, block audio communication between members of opposing team, and allow
receiving text between everyone in the session.
The following example shows how to enable all communication between a local and a remote chat control. The
variable localChatControlA is pointing to a valid PartyLocalChatControl object while remoteChatControlB is
pointing to a valid PartyChatControl object representing a chat control on a remote device.
NOTE
Please note that chat permissions only apply locally. In the previous example, full bi-directional communication will only
happen if remoteChatControlB is remotely configured to allow all communication with localChatControlA
Muting
Games also have the ability to mute outgoing audio ( PartyLocalChatControl::SetAudioInputMuted() ) as well as
incoming audio from remote chat control ( PartyLocalChatControl::SetIncomingAudioInputMuted() ). The states of
these mutes can be accessed through their respective getters and are also reflected through the chat indicators
returned by PartyLocalChatControl::GetChatIndicator() and PartyLocalChatControl::GetLocalChatIndicator() .
Mutes are particularly useful to give some form of temporary control to the player without having to change
any of the chat permissions you might have set at the beginning of the gaming session.
Broadcast
Suppose that User A is the leader giving orders and User B, C, and D can only listen.
On User A's device:
localChatControlA->SetPermissions(chatControlB, PartyChatPermissionOptions::SendAudio);
localChatControlA->SetPermissions(chatControlC, PartyChatPermissionOptions::SendAudio);
localChatControlA->SetPermissions(chatControlD, PartyChatPermissionOptions::SendAudio);
localChatControlB->SetPermissions(chatControlA, PartyChatPermissionOptions::ReceiveAudio |
PartyChatPermissionOptions::ReceiveText);
localChatControlB->SetPermissions(chatControlC, PartyChatPermissionOptions::None);
localChatControlB->SetPermissions(chatControlD, PartyChatPermissionOptions::None);
localChatControlC->SetPermissions(chatControlA, PartyChatPermissionOptions::ReceiveAudio |
PartyChatPermissionOptions::ReceiveText);
localChatControlC->SetPermissions(chatControlB, PartyChatPermissionOptions::None);
localChatControlC->SetPermissions(chatControlD, PartyChatPermissionOptions::None);
localChatControlD->SetPermissions(chatControlA, PartyChatPermissionOptions::ReceiveAudio |
PartyChatPermissionOptions::ReceiveText);
localChatControlD->SetPermissions(chatControlB, PartyChatPermissionOptions::None);
localChatControlD->SetPermissions(chatControlC, PartyChatPermissionOptions::None);
Using real-time audio manipulation to apply custom
voice effects
5/24/2022 • 8 minutes to read • Edit Online
PlayFab Party is a real-time networking and voice chat solution. When configured for voice chat, PlayFab Party
transmits microphone audio and plays it back unmodified. Some games need access to the voice chat audio
buffers to implement custom audio effects, such as spatial audio or voice filters. This document provides a
walkthrough of how to use the real-time audio manipulation feature to intercept and modify voice chat audio in
PlayFab Party.
Prerequisites
This walkthrough assumes you have basic familiarity with voice chat in PlayFab Party.
Platform support
Real-time audio manipulation isn't available on all platforms. While the methods associated with real-time audio
manipulation are present in the unified, cross-platform header, they're currently only implemented for Windows
and Xbox. The methods will return errors on other platforms.
Audio streams
Real-time audio manipulation introduces the concept of audio streams for retrieving audio from or submitting
audio to the library. There are two types of audio streams. The first is the source stream . A source stream is
used to retrieve audio from a chat control. Each chat control can only have a single source stream, called the
voice stream . For a local chat control, this is used to retrieve the microphone input; for a remote chat control,
this is used to retrieve incoming voice audio. If the voice stream exists for a chat control, the library will redirect
source audio for that chat control to its voice stream rather than handling the audio automatically. For a local
chat control, this means redirecting microphone audio to the voice stream instead of automatically encoding
and transmitting it; for a remote chat control, this means redirecting incoming voice audio to the voice stream
instead of automatically submitting it to each local chat control to be played back. Source streams are
represented by the PartyAudioManipulationSourceStream .
The second type of stream is the sink stream . A sink stream is used to submit audio to a chat control. Only
local chat controls can have sink streams, and they each can have two. They're called the capture stream and
render stream . If the capture stream exists for a chat control, the library will pull audio from the capture
stream to encode and transmit to other chat controls instead of the microphone. If the render stream exists for a
chat control, the library will pull audio from the render stream and play it back in addition to the voice chat
audio that is automatically played back from remote chat controls. Audio submitted to the capture stream is
used as the local chat control's microphone input; audio submitted to the render stream is played back or
"rendered" to the local chat control's audio output device. Sink streams are represented by the
PartyAudioManipulationSinkStream .
Each stream configuration method allows you to specify the format of the audio that you will retrieve from or
submit to the stream. For more information about supported formats, see the reference documentation for each
stream configuration method.
Retrieving audio from a source stream
You can retrieve audio from a source stream via PartyAudioManipulationSourceStream::GetNextBuffer() . When
voice activity is detected, a new buffer will be available approximately every 40 ms. If no buffers are available,
the call will succeed and provide a zero length buffer. The total number of buffers instantaneously available can
be retrieved via PartyAudioManipulationSourceStream::GetAvailableBufferCount() .
For efficiency, GetNextBuffer() provides a buffer that points to the library's memory instead of copying the
entire buffer. It can optionally be modified in place. Once you're done processing a buffer, you should release it
via PartyAudioManipulationSourceStream::ReturnBuffer() so that the library can reclaim its memory. Multiple
buffers can be retrieved before any are returned, and buffers don't need to be returned in the order they were
retrieved.
Submit audio to a sink stream
You can submit audio to a sink stream via PartyAudioManipulationSinkStream::SubmitBuffer() . The buffer is
copied by the library and can be immediately freed after the call completes.
Every 40 ms, the library consumes 40 ms of audio that has been submitted to the sink stream. To prevent audio
hiccups, audio should be submitted at a constant rate.
Scenarios
Microphone audio manipulation a.k.a. pre -encode buffer manipulation
Microphone audio manipulation is the act of intercepting and changing the microphone audio before it's
transmitted to other chat controls. This is sometimes called "pre-encode buffer manipulation" because the
microphone audio is modified before it's encoded and transmitted to other chat controls. If you wish to
implement this scenario for a local chat control, first configure a voice stream and capture stream for the local
chat control. Once configured, a function called by each tick of a dedicated audio thread to process the
microphone audio of that single chat control might look like the following.
// An app-defined function that takes a microphone buffer and generates a new
// buffer that should be transmitted to other chat controls.
std::vector<uint8_t>
ProcessLocalVoiceBuffer(
PartyMutableDataBuffer* inputBuffer
);
void
ProcessLocalMicrophoneAudioForSingleChatControl(
PartyLocalChatControl* chatControl
)
{
// Get the voice stream from which we want to retrieve audio. This provides
// the audio generated by the chat control's input device.
PartyAudioManipulationSourceStream* voiceStream;
RETURN_VOID_IF_FAILED(chatControl->GetAudioManipulationVoiceStream(&voiceStream));
// Get the capture stream to which we want to submit audio. This is used to
// submit audio that will be transmitted to other chat controls.
PartyAudioManipulationSinkStream* captureStream;
RETURN_VOID_IF_FAILED(chatControl->GetAudioManipulationCaptureStream(&captureStream));
void
ProcessRemoteVoiceAudio(
const std::vector<PartyChatControl*>& remoteChatControls,
const std::vector<PartyLocalChatControl*>& localChatControls
)
{
std::map<PartyAudioManipulationSourceStream*, PartyMutableDataBuffer> remoteVoiceBuffers;
//Acquirevoicebuffersfromeachremotechatcontrol.
for (auto remoteChatControl : remoteChatControls)
{
// Get the voice stream for this chat control from which we will retrieve audio.
PartyAudioManipulationSourceStream* voiceStream;
PartyError error = remoteChatControl->GetAudioManipulationVoiceStream(&voiceStream);
if (PARTY_FAILED(error))
{
printf("Failedtogetvoicestream!error=0x%08x", error);
continue;
}
// Mixthevoicebuffersandsubmittoeachrenderstream.
for (auto localChatControl : localChatControls)
{
// Get the render stream for this chat control to which we will submit audio.
PartyAudioManipulationSinkStream* renderStream;
PartyError error = localChatControl->GetAudioManipulationRenderStream(&renderStream);
if (PARTY_FAILED(error))
{
printf("Failedtogetrenderstream!error=0x%08x", error);
continue;
}
//Releasethevoicebuffers.
for (auto voiceBuffer : remoteVoiceBuffers)
{
// Return the voice buffer that we had cached from this voice stream.
PartyError error = voiceBuffer.first->ReturnBuffer(voiceBuffer.second.buffer);
if (PARTY_FAILED(error))
{
printf("Failedtoreturnbuffer!error=0x%08x", error);
}
}
}
If two players are trying to chat together and one or both of them can't hear each other, try these
troubleshooting steps.
NOTE
By default, chat controls will not be associated with any audio device. Be sure to call
PartyLocalChatControl::SetAudioInput() and PartyLocalChatControl::SetAudioOutput() on all of your chat
controls.
Verify that the chat controls have the right chat permissions
Use PartyLocalChatControl::GetPermissions() to look up the PartyChatPermissionOptions between two chat
controls. For example, if a user Alice is unable to hear another user Bob, you will want to make sure that Alice
has the permission to receive audio from Bob and that Bob has the permission to send audio to Alice.
On Alice's device:
PartyChatPermissionOptions chatPermissions;
PartyError error = localChatControlAlice->GetPermissions(remoteChatControlBob, &chatPermissions);
if (PARTY_SUCCEEDED(error))
{
if (static_cast<bool>(chatPermissions & PartyChatPermissionOptions::ReceiveAudio))
{
printf("Alice can receive audio from Bob!");
}
}
On Bob's device:
PartyChatPermissionOptions chatPermissions;
PartyError error = localChatControlBob->GetPermissions(remoteChatControlAlice, &chatPermissions);
if (PARTY_SUCCEEDED(error))
{
if (static_cast<bool>(chatPermissions & PartyChatPermissionOptions::SendAudio))
{
printf("Bob can send audio to Alice!");
}
}
PlayFab Party offers a text moderation solution that is integrated with text chat. Text chat can be moderated in
real-time to filter out offensive language. This feature is backed by Azure's Content Moderator. For more
information, see Azure Content Moderator.
Language support
Text moderation is supported for more than 30 languages. However, you don't need to do anything to configure
a language selection for text moderation; the language of each text message is automatically detected by Azure.
For a complete list of supported languages which support auto-detection and profanity filtering, refer to Azure
Content Moderator's list of supported languages.
Additional fields are present on the PartyChatTextReceivedStateChange to enable more complex scenarios, such
as giving users an option to view an unfiltered version of the text. Refer to the
PartyChatTextReceivedStateChange reference page for more information.
If moderating a text message fails, either due to a service error or because the text was deemed offensive by the
service without being able to identify specific terms, then the entire text message will be masked with asterisks.
You can determine if this has happened by looking at PartyChatTextReceivedOptions enum provided in the
options field of PartyChatTextReceivedStateChange .
See also
Understanding how PlayFab Party chat works
PartyLocalChatControl::SetTextChatOptions
PartyChatTextReceivedOptions
PlayFab Party invitations and the security model
5/24/2022 • 10 minutes to read • Edit Online
PlayFab Party is designed to provide a secure communication environment by default. This helps protect games
and players, but security restrictions can raise API usage questions for developers. This page introduces the
security features of PlayFab Party, primarily focusing on invitations and effective patterns for using them.
PlayFab Party uses industry-standard encryption and authentication for all communication (management data,
game data, and real-time communication). This includes all peer-to-peer transmissions and all transactions to
Azure services, whether they're web services (which use HTTPS) or the transparent cloud relay service (which
uses DTLS).
Limiting access to a network is a core part of protecting the integrity of the network. The ability to join a
network is gated by four things:
Knowledge of the network descriptor
Possession of a valid PlayFab title_player_account entity token
Knowledge of an invitation identifier
Presence of the PlayFab entity ID for the above token in the specified invitation, or the specified invitation
being an open invitation
Note that a given PlayFab Party network can have a maximum of 32 players.
Invitations
An invitation ( PartyInvitation ) is an object within a network that grants user access to the network. Invitations
can be created and revoked throughout the lifetime of a network. An invitation has a creator, a unique identifier,
a revocability setting, and an optional set of users specified as entity IDs. A network can have any number of
active invitations, including none. A network is always created with an initial invitation.
Invitation lifetime
An invitation is active from the time it is created until it is revoked.
Creation
There are two ways to create an invitation. The first way is by calling PartyManager::CreateNewNetwork() . Since an
invitation is required to join a network, one must exist when a network is created. This invitation is known as the
initial invitation, and it has some special properties described below. The second way is by calling
PartyNetwork::CreateInvitation() .
The creator of an invitation is the user which was specified when calling PartyNetwork::CreateInvitation() . The
initial invitation has no creator.
When an invitation is created (or when joining a network with an active initial invitation), a
PartyInvitationCreatedStateChange is generated.
IMPORTANT
The initial invitation does not implicitly allow the creator of a network to join. Unless an open invitation is being used, be
sure to include the creator's entity ID in the user list.
Enumeration
Enumerating active invitations is done using PartyNetwork::GetInvitations() . Only the invitations created on
the local device, along with the initial invitation if it is still active, can be enumerated.
Revocation
An invitation is revoked by calling PartyNetwork::RevokeInvitation() . Only the creator of an invitation may
revoke it, except for the initial invitation, which may be revoked by any user. Additionally, an invitation is
automatically revoked when the user that created it is removed from the network.
When an invitation is revoked, a PartyInvitationRevokedStateChange is generated on all devices that could see
the invitation.
Once the initial invitation is revoked, it cannot be created again. Its identifier may be reused for a new invitation,
but that new invitation will not have the special properties of the initial invitation.
IMPORTANT
Revoking an invitation has no effect on the devices and users that have already joined the network. To remove a user or
device from the network, use PartyNetwork::KickUser() or PartyNetwork::KickDevice() . Note that these methods
are not yet implemented.
Invitation configuration
The configuration of an invitation is specified during creation using the PartyInvitationConfiguration struct.
Identifiers
Each invitation has an identifier which uniquely identifies it within the network. If an identifier is not specified
when creating an invitation, Party will assign one. For calls to PartyManager::CreateNewNetwork() , the assigned
identifier is returned in an out parameter and also reported in PartyCreateNewNetworkCompletedStateChange when
network creation completes. For calls to PartyManager::CreateInvitation() , the assigned identifier can be
retrieved from the invitation out parameter or the invitation field in
PartyCreateInvitationCompletedStateChange when the invitation creation completes.
Although an invitation identifier must be unique, after an invitation is revoked, its identifier may be reused when
creating a new invitation.
Initial invitation and other invitations
Although there is only one type of invitation, the initial invitation created by the call to
PartyManager::CreateNewNetwork() is a bit different from invitations created later via
PartyNetwork::CreateInvitation() . The differences are summarized in the table below.
Visibility All devices can see the initial invitation. Only the device that created the
As long as the initial invitation has not invitation will be able to see it. A non-
been revoked, it will be returned by initial invitation will only be returned
calls to by
PartyNetwork::GetInvitations() . PartyNetwork::GetInvitations() if
Upon joining a network, each device it was created on that device, and a
will receive a PartyInvitationCreatedStateChange
PartyInvitationCreatedStateChange will only be generated for it on the
for the initial invitation if it has not creating device.
been previously revoked.
P RO P ERT Y IN IT IA L IN VITAT IO N OT H ER IN VITAT IO N S
Revocability Anyone may revoke the initial Only the creator may revoke the
invitation. When explicitly specifying invitation. When creating the
the invitation configuration, invitation, revocability must be set to
revocability must be set to PartyInvitationRevocability::Creator
PartyInvitationRevocability::Anyone .
.
Lifetime The initial invitation is active until it is A non-initial invitation is active until it
explicitly revoked. are explicitly revoked, or until the user
which created it is removed from the
network. When the user is removed
from the network, all the invitations
they created are automatically
revoked.
Creator The initial invitation has no creator. The user specified when calling
PartyInvitation::GetCreatorEntityId() PartyNetwork::CreateInvitation is
will return null. the creator.
PartyInvitation::GetCreatorEntityId()
will return that user's entity ID.
Invitations (other than the initial invitation) are hidden from other devices for privacy reasons. See the friends
list usage pattern for an example of why this is important.
Users and open invitations
An invitation contains 0 or more users specified as title_player_account entity IDs. If an invitation contains
users, that invitation only grants access to join the network to those users. However, if an invitation contains no
users, this is an open invitation. Any user may join the network with the identifier of an open invitation.
NOTE
On a multi-user device, such as a game console, be sure to use the correct invitation with the correct user. Depending on
which users are specified in each invitation, it is possible that different users on the device might need to use different
invitations when authenticating a user into the network via PartyNetwork::AuthenticateLocalUser().
Immutability
Once an invitation is created, its configuration cannot be changed. However, after an invitation has been
revoked, another can be created with the same identifier but a different configuration. See the dynamic single
invitation usage pattern.
Usage patterns
PlayFab Party invitations are simple but flexible. There are many effective ways to use them to achieve different
access models for a network. Below are a few common patterns.
Open network
An open network is the simplest to understand and implement. It allows anyone with the network descriptor
and invitation identifier to join.
Create an open network by passing null for the initialInvitationConfiguration parameter when calling
PartyManager::CreateNewNetwork() . The identifier for the open invitation is returned as an out parameter. After
the network creation completes, share the network descriptor and invitation identifier to allow users to join.
Optionally, you may close the network at any point in the future by revoking the initial invitation.
WARNING
Because a network is only as secure as the devices and users that join it, exercise caution when sharing the network
descriptor and invitation identifier of an open network.
IMPORTANT
When revoking an invitation and creating a new one with the same identifier, there will be a small window of time where
the invitation identifier is invalid. If you are using this approach, it will be necessary to retry the call to
PartyNetwork::AuthenticateLocalUser() if it fails after a reasonable waiting period.
Next steps
Learn how PlayFab Party interacts with your discovery flows
Integrating discovery with PlayFab Party
5/24/2022 • 4 minutes to read • Edit Online
Discovery is the process by which users find each other to play together. PlayFab Party does not provide a
discovery mechanism, but can be used with any existing mechanism which provides communication between
users.
NOTE
When specifying users in an invitation, the users' title_player_account Entity IDs are used. These Entity IDs will need
to be obtained out-of-band of PlayFab Party.
Lobby
If your game provides a lobby which allows data to be sent between clients, it can be used as a communication
medium for exchanging network connection information. The flow might look something like this:
A set of users is selected to play a game together.
One of those users is selected as the creator.
Each user in the set sends their title_player_account Entity ID to the creator.
The creator creates the network, specifying the users' Entity IDs in the initial invitation configuration.
Once network creation completes, the creator sends the network descriptor and the initial invitation identifier
to the set of users that should join.
Each user uses the network descriptor and the invitation identifier to connect to the network.
Matchmaking
A matchmaking service, such as PlayFab Matchmaking, can be used to find a list of users to play with. The flow
might look something like this:
Users initiate a match request with the service. The title_player_account Entity ID must be part of the
request, because the match result must contain each user's Entity ID.
Users receive a match result containing the set of users that should be part of the network.
A predetermined algorithm is used to select which user will be the creator.
The creator creates the network, specifying the other matched users' Entity IDs in the initial invitation
configuration.
Once network creation completes, the creator uses an out-of-band communication medium to send the
network descriptor and the initial invitation identifier to other matched users.
Each matched user uses the network descriptor and the invitation identifier to connect to the network.
NOTE
An out-of-band communication medium is required to send the connection information from the creator to the other
matched users.
Configuring transport behavior
5/24/2022 • 2 minutes to read • Edit Online
PlayFab Party's networking capabilities expand on the User Datagram Protocol (UDP) features of the native
platform to provide datagram transport facilities that are ideal for real-time multiplayer games.
While Transmission Control Protocol (TCP) provides reliable streams, and UDP provides unreliable datagrams,
Party’s networking behavior can be configured on a per datagram basis. When using
PartyLocalEndpoint::SendMessage to transmit a datagram from a local Party endpoint to a remote endpoint you
can specify PartySendMessageOptions to fine-tune the desired transport behavior.
Capabilities include:
Guaranteed Deliver y - The GuaranteedDelivery flag ensures the message arrives at all targets, implicitly
retransmitting data if necessary to mitigate environmental packet loss. This option flag works well when
sending important state information that must always reach the destination or else the target should be
removed from the network. The default option is BestEffortDelivery which provides UDP-like fire and
forget behavior.
Sequential Deliver y - Orders the delivery of the message relative to other messages that were sent
sequentially from this local endpoint to the target endpoint. Use this option flag to send state information
that must reach the destination in a particular sequence. This may result in a slightly lower network efficiency
and possibly longer wait to receive all the packets when there is packet loss or reordering by the
environment. Using SequentialDelivery with GuaranteedDelivery may result in messages being queued on
the target endpoint while waiting for previously sent sequential messages to arrive. This may result in a
perceived increase in latency when experiencing environmental packet loss or reordering, but the target
endpoint will always see every message, in the same order in which they were sent. This performance trade-
off is common to TCP-like protocols and sometimes called head-of-line blocking.
Coalescing - The Party library automatically fragments and reassembles large messages that exceed the
maximum size supported by the environment so that callers are not required to manage this. But if you're
sending many small datagrams, coalescing multiple messages together in a single packet allows maximizing
bandwidth efficiency (reducing per-packet overhead) at the potential expense of perceived latency for a
message if you delay its transmission in order to coalesce. Sending with the CoalesceOpportunistically flag
(the default coalescence option) causes the Party library to coalesce the message with other queued
messages, if any are available, but not to wait for more messages if this message can be transmitted
immediately. Sending with the AlwaysCoalesceUntilFlushed flag causes the Party library to delay
transmission until PartyLocalEndpoint::FlushMessages is called, at which point the queued messages will be
coalesced and transmitted.
Network statistics and local queueing
Depending on the message sending options and network state, Party might locally queue messages before
transmission. This local queueing is carefully managed to avoid introducing latency. This is necessary to ensure
that Party does not flood the player's network and that features like coalescing can be applied.
PartyNetwork::GetNetworkStatistics allows you to collect data on aggregate network performance, including
latency to Party relay service. PartyLocalEndpoint::GetEndpointStatistics allows for visibility into queuing and
packet loss statistics for a specific remote endpoint.
PlayFab Party and direct peer-to-peer connections
5/24/2022 • 7 minutes to read • Edit Online
This page explains how you can enable and use direct peer-to-peer connections in PlayFab Party using example
game code. It also includes considerations to help you evaluate when to use direct peer-to-peer connections in
your games.
As part of successfully authenticating an initial user into a network, a device may attempt to establish direct
peer-to-peer connections with other devices already participating in the network when permitted by the
network configuration. For attempts that are successful, endpoint messages and chat data between the devices
will be transmitted using those direct connections. For attempts that fail due to environmental incompatibilities
between the devices, all communication between those devices will be transmitted via transparent cloud relay
servers instead. If the devices aren't permitted to attempt direct peer connections by the network configuration,
then they never exchange IP address information and will always transmit endpoint messages and chat data via
transparent cloud relay servers.
NOTE
Establishing direct peer connectivity is best effort and may not be possible due to environmental factors, per-device
connectivity options, or platform policy. For more information about evaluating whether a direct peer-to-peer connection
was established to a particular device, see Evaluating the connection type and latency.
Billing meters
The same billing meters are applied in networks that use direct peer-to-peer connections as in networks that use
the cloud relay service. However, only game or voice data that goes through the cloud relay service count
toward the Network egress and Par ty voice meters.
PlayFab Party port usage, firewall and packet size
requirements
5/24/2022 • 5 minutes to read • Edit Online
This topic provides details about Azure PlayFab Party port usage, firewall and packet size requirements that are
needed to enable chat and data communication.
Communication Patterns
Azure PlayFab Party has two communication patterns that must be permitted by the local device and
environmental infrastructure in order for API operation to succeed:
1. HTTPS communication, which is initiated from the API caller to multiple cloud web services, including
playfabapi.com.
2. UDP socket-based secure communication with transparent cloud relay servers, and other peer devices (if
supported).
If either pattern is blocked, early PlayFab Party API operations or automatic notifications such as the initial
PartyRegionsChangedStateChange will report PartyStateChangeResult::InternetConnectivityError .
For web service request issues, other necessary PlayFab and platform operations outside of Party such as the
user login functions would also likely fail. These failures are often caused by local firewall restrictions or proxy
requirements for HTTPS connections. Most issues can be resolved by enabling direct, outbound HTTPS
communication to cloud web services from the local device or network.
See also
PlayFab Party and direct peer-to-peer connections
Multiple networks
5/24/2022 • 3 minutes to read • Edit Online
PlayFab Party supports using multiple PlayFab Party networks simultaneously. The following diagram provides
an example representation of how different objects might relate to each other in a multi-network scenario.
For a more complete explanation of how these relationships work, check out the documentation covering
PlayFab Party objects and their relationships.
This page will cover when using multiple networks is appropriate, when it isn't, and common pitfalls to avoid.
WARNING
Using multiple, simultaneous PlayFab Party networks is an advanced scenario that may require more complex game logic
to manage. Often, a game scenario which uses multiple networks can be redesigned or simplified to only require a single
network, and care should be taken to evaluate whether this is possible before designing your game's network architecture
around multiple Party networks. More information on when multiple networks is or is not appropriate can be found in the
next section, When to use multiple networks.
Cost
PlayFab Party's usage measurement is impacted by the number of networks a player is connected to. The Party
Connectivity billing meter is calculated per-network, so using multiple networks simultaneously costs more than
using a single network. Be sure to consider the cost-impact when planning your game architecture.
You can view more information about PlayFab Party costs on the PlayFab Party Pricing page.
PlayFab Party Pricing
5/24/2022 • 2 minutes to read • Edit Online
PlayFab Party performs background Quality of Service (QoS) measurements to provide titles low-latency access
to remote Azure resources. Here we'll outline the core scenarios where titles should expect to encounter Party's
QoS features.
uint32_t regionCount = 0;
const PartyRegion* regionList = nullptr;
Alternatively, titles can inspect the Party library's QoS measurement results and select a list of preferred regions
based on title-specific criteria.
To inspect QoS measurement results, wait to receive a successful PartyRegionsChangedStateChange from
PartyManager::StartProcessingStateChanges.
switch (stateChange->stateChangeType)
{
case PartyStateChangeType::RegionsChanged:
{
auto regionsChanged = static_cast<PartyRegionsChangedStateChange*>(stateChange);
if (regionsChanged.result == PartyStateChangeResult::Succeeded)
{
m_qosResultsReady = true;
}
}
// ...
}
Then call PartyManager::GetRegions to inspect and evaluate the current list of regions and latencies.
if (m_qosResultsReady)
{
uint32_t regionCount;
const PartyRegion* regionList;
// Prevent Party from using Azure regions above some latency threshold.
// The game is unplayable in those scenarios.
std::vector<PartyRegion> filteredRegionList = OmitRegionsAboveMaxLatency(regionCount, regionList,
maxLatency);
error = PartyManager::GetSingleton().CreateNewNetwork(
localUser,
&networkConfiguration,
filteredRegionList.size(),
filteredRegionList.data(),
nullptr,
nullptr,
nullptr,
nullptr);
if (PARTY_FAILED(error))
{
DEBUGLOG("PartyManager::CreateNewNetwork failed: %s\n", PartyManager::GetErrorMessage(error));
return;
}
ZONE REGIO N S
Zone 1 West US, East US, North Central US, South Central US, East
US 2, Central US, West Europe, North Europe
Zone 2 East Asia, Southeast Asia, Japan East, Japan West, Australia
East, Australia Southeast
For more information about region selection, see Selecting regions for Party networks.
You can view the current Party rates on the PlayFab pricing page.
For more information about Azure regions, see the Azure documentation.
PlayFab Party release notes
5/24/2022 • 9 minutes to read • Edit Online
PlayFab Party had a significant (up to 90%) price drop on 10/13/2020. You can view the updated Party rates on
the Pricing page. For more information about the price drop, see our blog post.
1.7.8
April 21, 2022
Bug fixes
Fixed an issue where memory wasn't fully cleaned up when PartyManager::Cleanup() was called.
Fixed an issue where calling PartyLocalChatControl::SetAudioInput() or
PartyLocalChatControl::SetAudioOutput() with the same audio device selection would unnecessarily result in
the library reinitializing the audio device.
1.7.7
Mar 16, 2022
Bug fixes
Playstation4, Playstation5: Fixed a crash that occurred when there was no audio device after the audio
devices were removed.
Switch: Fixed an issue that caused web requests to fail when multiple PlayFab transactions were triggered.
1.7.6
Feb 8, 2022
Performance improvements
Windows, XDK, Nintendo Switch, Playstation4, Playstation5: Removed two worker threads and perform
relevant work on a preexisting, lower frequency work thread. The Microsoft Game Development Kit (GDK)
version of the library already had this coalesced work behavior.
Bug fixes
iOS, Android, Switch, Playstation4, Playstation5, and Stadia: Fixed a small amount of memory allocated
during initialization not being properly freed during cleanup.
Avoid reporting PartyChatTextReceivedOptions::FilteredDueToError flag in PartyChatTextReceivedStateChange
when text moderation is not enabled.
1.7.5
Sep 30, 2021
Bug fixes
Fixed an issue where some 16kHz microphones were not working.
Fixed an issue where microphone permission changes were not handled on Windows.
Fixed a memory leak in some PartyManager::CreateNewNetwork() failure conditions.
Fixed an occasional crash in PartyLocalEndpoint::GetEndpointStatistics() .
1.7.0
Jun 29, 2021
New profiling hooks and chat control indicators
Developers interested in where time is spent in internal library functions can now install optional method
entrance and exit callbacks to hook into their preferred high-performance instrumentation method. For more
information, see PartyManager::SetProfilingCallbacksForMethodEntryExit . In this release the callbacks are only
supported for Windows, Xbox One XDK, and Microsoft Game Core platforms.
New NoRemoteInput and RemoteAudioInputMuted chat control indicators provide more granularity on
currently silent audio state. For more information, see PartyChatControlChatIndicator .
Endpoint message behavior improvements
The 'PartySendMessageQueuingConfiguration' timeoutInMilliseconds field is now also evaluated by the
transparent cloud relay if forced to queue messages before forwarding because of differing network
conditions or responsiveness of the remote targets.
When fully authenticated into a network, sending to a 0-entry array will correctly target the exact set of all
remote endpoints the library currently reports in the network at that time. Endpoints being created while the
message is in the process of transmitting are no longer potentially included.
1.6.1
Bug fixes
Fixed a bug where a crash may occur when a chat control is connected to a network while that same chat
control is disconnecting from another network.
1.6.0
Apr 12, 2021
New thread control and text moderation features
The library's work can now be run manually on game-controlled threads. For more information, see
PartyManager::SetWorkMode .
Offensive text chat can now optionally be filtered. For more information, see Using text moderation.
Explicit enum numbering in the header
Enum values in the header now have explicit numbering.
1.5.13
Mar 26, 2021
Bug fixes
Fixed a bug where audio is cutting out on iOS devices using Bluetooth headsets.
Fixed a bug where an incorrect error code is generated when the app doesn't have permission to activate a
microphone on Windows platforms.
Fixed a bug where an unhealthy device is never refreshed unless something else forces a refresh.
Fixed a bug where a crash may occur when dereferencing a send channel's user data after the source
endpoint associated with that channel has become invalid.
Fixed a bug where clients experience silent failures if a remote chat control doesn't have a language code.
1.5.10
Bug fixes
Fixed a bug where the library may fail to initialize on some Windows devices due to a mismatch between the
processor affinity of the process and the library's default thread affinity.
Fixed a bug where the library may not provide errors when an operation fails due to an internal web request
failure.
Fixed a bug where a crash may occur when direct peer connectivity is enabled and the library attempts to
establish direct peer connectivity to another device.
Fixed a bug that may result in crackly or distorted audio.
1.5.1
Sep 05, 2020
Bug fix
Fixed a bug where the library may fail to activate the microphone on iOS.
1.5.0
New direct peer-to -peer connectivity, latency, and speech-to -text features
Direct peer-to-peer connectivity is now supported in the Windows 10 and Microsoft Game Core versions of
the library. For more information, see Using direct peer-to-peer connectivity.
The round trip latency between the local device and a remote device can now be queried through the library.
For more information, see PartyEndpointStatistic::AverageDeviceRoundTripLatencyInMilliseconds
Speech-to-text profanity masking can now be disabled. For more information, see
PartyVoiceChatTranscriptionOptions::DisableProfanityMasking .
1.4.13
Windows 8.1 dependency issue
This release removes an unnecessary dependency on api-ms-win-core-version-l1-1-1.dll which prevented
previous versions from working on Windows 8.1
1.4.8
Apr 30, 2020
TLS1.2
The transcription stack has been updated to use TLS1.2 on Windows 7, Android, and iOS. Please upgrade if
you make use of any of these platforms as TLS1.1 support will be deprecated by Azure Speech Services
beginning in September 2020. All other platforms already support TLS1.2 and no upgrade is necessary.
Bug fixes
Fixed a bug where the languageCode field in the PartyCreateChatControlCompletedStateChange struct was not
being populated.
Fixed a bug which was artificially inflating the latency measurements reported by
PartyManager::GetRegions() .
Fixed a bug which allowed PartyManager::SetMemoryCallbacks() to be called at unsafe times.
Fixed a bug where calling PartyManager::DestroyLocalUser() with a PartyLocalUser in a PartyNetwork would
generate a PartyLocalUserRemovedStateChange with an incorrect value in the removedReason field,
PartyLocalUserRemovedReason::RemoveLocalUser , instead of the correct value,
PartyLocalUserRemovedReason::DestroyLocalUser .
Misc changes
The bandwidth used by chat data has been reduced.
More descriptive error codes and error messages are now provided when sandbox issues are encountered
on Xbox.
PartyManager::Initialize() will now fail if an empty PlayFab Title ID is provided.
Passing invalid PlayFab Entity Tokens to PartyManager::CreateLocalUser() will now result in more descriptive
error messages in the state change results for operations which rely on a valid token.
Typos in the header documentation have been fixed.
A more descriptive error code and error message is now provided when an invalid region is passed to
PartyManager::CreateNewNetwork() .
The documentation for the lifetimes of PartyString values has been clarified for the structures and
interfaces in Party.h.
The documentation for PartyManager::Cleanup() was clarified to explain it is not a thread-safe call.
A more descriptive error code and error message are provided when PartyManager::ConnectToNetwork()
asynchronously fails with internet connectivity errors.
1.3.0
Chat API Changes
The real-time audio manipulation functions, which can be used to modify outgoing or incoming voice chat
audio, are implemented for Windows and Xbox. For more information, see Using real-time audio
manipulation to apply custom voice effects.
The chat permission options have more options for optionally configuring text-to-speech and microphone
audio permissions independently. For more information, see PartyChatPermissionOptions .
This breaks compatibility with previous releases of the Xbox Live Helper library. This release is compatible
with version 1.2.0 of the Xbox Live Helper library. For more information, see the Xbox Live Helper Library
release notes.
Each transcription state change now indicates whether it represents text-to-speech or microphone audio. For
more information, see PartyVoiceChatTranscriptionReceivedStateChange .
1.2.2
iOS Changes
Adds support for the volume control API.
1.2.0
Android Changes
Adds support for the volume control API.
Removes audio focus handling from the library. Host applications are now expected to implement their own
focus handling logic.
1.0.2
Fixed crash in background telemetry
1.0.1
Party API Changes
PartyManager::SetMemoryCallbacks Changes
This release of Party adds fixes for PartyManager::SetMemoryCallbacks() and also restrictions about when this API
is safe to call. Check the reference documentation of the API in Party.h for details.
Removal of PartyStateChangeResult::TitleCreateNetworkThrottled
The PartyStateChangeResult value TitleCreateNetworkThrottled has been removed from the API, since the Party
library will never generate it.
0.7.0-prerelease
Windows Packaging Changes
This release of Party introduces a new NuGet package, Microsoft.PlayFab.PlayFabParty.Cpp.Windows, which
replaces and deprecates the NuGet packages specific to Windows 10 and Windows 7
(Microsoft.PlayFab.PlayFabParty.Cpp.Win10 and Microsoft.PlayFab.PlayFabParty.Cpp.Win7, respectively). The new
unified Windows NuGet package contains two new DLLs, PartyWin.dll (supports Windows 8.1 and up) and
PartyWin7.dll (only for use on Windows 7). With the new Windows unified NuGet package, the correct Party DLL
is loaded based on runtime detection of the OS version, so both PartyWin.dll and PartyWin7.dll should be
included in the game distribution package.
Android Changes
The Android flavor now uses a shared object for Party (libparty.so) instead of a static library (libparty.a).
This release also contains Android-specific bug fixes for audio device selection.
iOS Changes
The iOS flavor of Party now has the framework package included for dynamically loading libparty instead of the
statically built libparty.a.
API Changes
UpdateEntityToken API
This release of Party makes a change related to the handling of PlayFab entity tokens. In the previous version,
the game provided Party with a user's entity token in the PartyManager::CreateLocalUser() API. Thereafter, Party
internally refreshed the entity token and kept it up to date.
In this version, the internal token refreshing behavior has been removed and is replaced by a new API,
PartyLocalUser::UpdateEntityToken() . The caller is now responsible for monitoring the expiration of the entity
token provided to PartyManager::CreateLocalUser() and PartyLocalUser::UpdateEntityToken() . When the token
is nearing or past the expiration time a new token should be obtained by performing a PlayFab login operation
and provided to the Party library by calling PartyLocalUser::UpdateEntityToken() . It is recommended to acquire
a new token when the previously supplied token is halfway through its validity period. On platforms that may
enter a low power state or otherwise cause the application to pause execution for a long time, preventing the
token from being refreshed before it expires, the token should be checked for expiration once execution
resumes.
The rough flow is as follows:
1. The game calls a LoginWith* PlayFab API
2. The response from PlayFab contains the entity token and also the expiration time
3. Provide the token information to Party with the PartyManager::CreateLocalUser() API, as before
4. [New] Make note of the expiration time in order to know when to refresh it
5. [New] At halfway through the token's expiration time (or soonest opportunity after that time), acquire a fresh
token by calling LoginWith* again and track the new token's expiration time
6. [New] Call PartyLocalUser::UpdateEntityToken() to pass in the new token to Party
Additional notes:
The act of acquiring an entity token does not invalidate any previously obtained entity tokens. They remain
valid until they expire.
The internal refreshing functionality was removed because most games are expected to make their own
PlayFab calls and so having both the game and the Party library fetching entity tokens causes unnecessary
service load to basically manage two sets of tokens.
Chat API Changes
The PartyVoiceChatTranscriptionReceivedStateChange now includes a languageCode field, which indicates the
language of the transcription.
The PartyChatTextReceivedStateChange now includes a languageCode field, which may indicate the language of
the chat text. The languageCode field will be populated when chat text translation has been enabled via
PartyLocalChatControl::SetTextChatOptions() .
0.6.0-prerelease
Added support for iOS, Android, and Nintendo Switch platforms.
For more information, see the following links:
iOS/Android
Nintendo Switch
0.5.0-prerelease
API Changes
Accessible Chat
Added support for text-to-speech narration. (see PartyLocalChatControl::SetTextToSpeechProfile() )
Added more options for controlling when speech-to-text occurs. (see
PartyLocalChatControl::SetTranscriptionOptions() )
Added text-to-text translation to the API, although it is not yet supported. ( see
PartyLocalChatControl::SetTextChatOptions() )
Reduced text-to-speech bandwidth and memory usage.
Network access control
PartyNetwork::SetAccessControlList() and related methods have been removed from the API. Use the new
PartyInvitation class and related methods to create open invitations or grant access to specific PlayFab
users to your Party networks.
0.4.6-prerelease
API Changes
Added new public API PartyLocalUser::UpdateEntityToken() .
0.2.0-prerelease
API Changes
PartyManager::Initialize now requires a valid PlayFab Title ID to be passed in.
What is PlayFab Insights?
5/24/2022 • 2 minutes to read • Edit Online
NOTE
The PlayFab Insights feature is in public preview. We anticipate ongoing changes to it as we continue gathering feedback
and optimizing for customer use.
PlayFab Insights is a completely managed data environment, giving you instant access to your games data
without the need for additional engineering. Unlike other hosted data solutions Insights requires no setup, no
GDPR work, and no extra engineering. Simply use PlayFab services and your data is available. Automatically
ingest and scale, connect external visualization tools, and query freely.
Key Features
Insights key features revolve around data cluster management, data retention, ingestion options and
connectivity to outside tools.
Automatic Ingestion
PlayFab services automatically fire Playstream events. Any events fired by PlayFab services or created through
our SDK are automatically routed to your Insights cluster. There is no need to worry about defining schema or
DDL from automatic events. However, the option for sending your own custom events is available. For more
information about sending custom events, see the Custom event overview of Generating PlayStream events.
Change Your Performance Level To Meet Your Needs
Match your cluster performance to your needs minute by minute. Slide your performance level up or down or
alternatively schedule your cluster to have different performance levels automatically using scheduled tasks. See
Performance Level & Retention for details.
Schedule Your Performance Level
Use standard cron expressions to automically scale your cluster up and down during known times. See
Scheduled Scaling for details.
Keep Your Data as Long as You Need
Never delete your data or clear your data out every 30 days, whatever is needed for your studio. See
Performance Level & Retention for details.
Connect Outside Tools
Connect PowerBI or Grafana for visualization, automate data jobs with Python or Azure Data Factory, explore
your data with Azure Data Explorer. See Connectivity for details.
Export Original or Cleaned Data
Use the automated export service to export all your data to Azure Blob or AWS S3. See Exporting Data for
details.
Bring Your Own Datasets
Ingest your own custom datasets with Management Commands. Merge your custom Playstream events,
standard Playstream events, and custom uploaded data to create more robust datasets.
GDPR Compliant
Standard reporting is tracked and GDPR compliant. Simply call the playfab GDPR delete request and well do the
rest. Have custom data you need to delete? No problem, use the Management Commands to maintain your
custom data.
PlayFab Insights offers an unprecedented look into your game's data and the trends created by your users. Part
of Insights' power is the flexibility to be paired with many other data and analytics tools. This section contains
tutorials that show you how to connect Insights to other tools.
Currently, you can connect the following external tools to Insights:
Connect to Power BI
Connect to Kusto Explorer
Connect to Azure Data Explorer (ADX)
Connect to Azure Data Factory (ADF)
Connect to Grafana
Connect to Python
Connect to Kusto C# SDK
Power BI
Pairing Power BI with Insights allows you to easily create visualizations of your game data.
To get started, go to the tutorial Connecting Power BI to Insights.
Kusto Explorer
Kusto Explorer is a rich desktop application that allows you to explore your game data using Kusto query
language.
To get started, go to the tutorial Connecting Kusto Explorer to Insights.
Grafana
Grafana is an open-source tool for running analytics and monitoring systems. It pulls data from Insights to
maintain dashboards with a wide variety of visualization options.
To get started, go to the tutorial Connecting Grafana to Insights.
Python
You have the option to connect Python to Insights and query your game data with it, including using the library
from Jupyter Notebooks.
To get started, go to the tutorial Connecting Python to Insights.
Kusto C# SDK
The Kusto C# SDK offers all the capabilities of Kusto, with the additional ability to query Insights from Azure
functions.
To get started, go to the tutorial Connecting Kusto C# SDK to Insights.
Tutorial: Create an Azure Active Directory (AAD)
Application to use with Insights
5/24/2022 • 2 minutes to read • Edit Online
This tutorial covers creating an Azure Active Directory (AAD) application to use with Insights, which is one of the
prerequisites for connecting the following tools with Insights:
Azure Data Factory (ADF)
Grafana
Python
Prerequisites
An Azure account with an active subscription. Create an account for free
3. In the Register an application window enter a name for your registration, then select which account
types you would like this registration to support. (If you need help deciding, select the Help me choose
link which will open a window with more information.)
4. Select Register . You will be directed to a page with an overview of your newly-registered applcation.
Save the Application (client) ID and Director y (tenant) ID somewhere (you will need these later).
5. In the navigation panel on the left-hand side select Cer tificates & secrets -> New client secret .
6. Enter a description for the secret and select how long you would like it to be valid.
7. Select Add , and the new secret will appear below Client secrets . Now make sure to copy the secret key
and save it somewhere secure. It's essential that you do this now, since you won't be able to access the
secret key once you leave this page.
You can verify that this command was successful by going to the Users page in GameManager. There
should be an entry that matches the Client/Tenant ID.
Note that this will make the Azure app an Admin on your game in PlayFab. If you would like the Azure
app to have lesser permissions, assign the Azure app a custom role in PlayFab that only has permissions
for the Kusto database. The necessary permissions are:
Explorer data & tab .
Analytics data read access , to run queries and simple management commands.
Analytics data write access , to create/drop tables, alter retention policy, ingest data, purge.
Next steps
Now that you have created an Azure app and linked it to your title database, follow the steps to connect
your tool of choice with Insights:
Connect with Azure Data Factory (ADF)
Connect with Grafana
Connect with Python
Tutorial: Connecting Power BI to Insights
5/24/2022 • 2 minutes to read • Edit Online
This guide helps you get started using Power BI along with Insights. After connecting, you can use Power BI to
create visualizations of your game data and more. To learn more about other tools you can connect Insights
with, see Connecting external tools to Insights.
Prerequisites
PlayFab account authenticated with AAD
You need a PlayFab account or user for which the authentication provider is set to Microsoft. The
Microsoft authentication provider uses Azure Active Directory (AAD) for authentication which is required
to use the Azure services. See Azure Active Directory Authentication for Game Manager for instructions
on creating an AAD-authenticated account or user.
To verify that the account, or user, is set to use the Microsoft authentication provider:
Visit the PlayFab log in page.
Use the the Sign in with Microsoft link to access your PlayFab account.
If you can sign in, then the account is set to use the Microsoft authentication provider.
Game Manager permissions for Insights
You need to assign your account a user role with the following Game Manager permissions enabled:
Admin status.
Access to the Explorer tab and associated data.
Read and write access to Analytics data.
You can either create a new user role or add these permissions to an existing role.
Other prerequisites
Power BI for desktop
Note that running Power BI for Desktop is required, this scenario is not supported in the PowerBI Web
Portal.
Additional resources
Power BI documentation
To learn about other tools to connect to Insights, see Connecting external tools to Insights
Tutorial: Connecting Kusto Explorer to Insights
5/24/2022 • 2 minutes to read • Edit Online
This guide helps you get started using Kusto Explorer along with Insights. After connecting, you can use Kusto
Explorer to query and explore your game data. To learn more about other tools you can connect Insights with,
see Connecting external tools to Insights.
Prerequisites
PlayFab account authenticated with AAD
You need a PlayFab account or user for which the authentication provider is set to Microsoft. The
Microsoft authentication provider uses Azure Active Directory (AAD) for authentication which is required
to use the Azure services. See Azure Active Directory Authentication for Game Manager for instructions
on creating an AAD-authenticated account or user.
To verify that the account, or user, is set to use the Microsoft authentication provider:
Visit the PlayFab log in page.
Use the the Sign in with Microsoft link to access your PlayFab account.
If you can sign in, then the account is set to use the Microsoft authentication provider.
Game Manager permissions for Insights
You need to assign your account a user role with the following Game Manager permissions enabled:
Admin status.
Access to the Explorer tab and associated data.
Read and write access to Analytics data.
You can either create a new user role or add these permissions to an existing role.
Other prerequisites
Kusto.Explorer
Additional resources
Kusto Explorer documentation
To learn about other tools to connect to Insights, see Connecting external tools to Insights
Tutorial: Connecting Azure Data Explorer to Insights
5/24/2022 • 2 minutes to read • Edit Online
This guide helps you get started using Azure Data Explorer (ADX) along with Insights. After connecting, you can
use Azure Data Explorer to query your game data and discover relevant insights. To learn more about other
tools you can connect Insights with, see Connecting external tools to Insights.
Prerequisites
PlayFab account authenticated with AAD
You need a PlayFab account or user for which the authentication provider is set to Microsoft. The
Microsoft authentication provider uses Azure Active Directory (AAD) for authentication which is required
to use the Azure services. See Azure Active Directory Authentication for Game Manager for instructions
on creating an AAD-authenticated account or user.
To verify that the account, or user, is set to use the Microsoft authentication provider:
Visit the PlayFab log in page.
Use the the Sign in with Microsoft link to access your PlayFab account.
If you can sign in, then the account is set to use the Microsoft authentication provider.
Game Manager permissions for Insights
You need to assign your account a user role with the following Game Manager permissions enabled:
Admin status.
Access to the Explorer tab and associated data.
Read and write access to Analytics data.
You can either create a new user role or add these permissions to an existing role.
Additional resources
Azure Data Explorer documentation
To learn about other tools to connect to Insights, see Connecting external tools to Insights
Tutorial: Connecting Azure Data Factory (ADF) to
Insights
5/24/2022 • 3 minutes to read • Edit Online
This guide helps you get started using Azure Data Factory (ADF) along with Insights. After connecting, you can
use Azure Data Factory to create workflows for orchestrating data movement and transforming game data at
scale. To learn more about other tools you can connect Insights with, see Connecting external tools to Insights.
In this tutorial you learn how to:
Create a data factory in Azure
Create a pipeline
Prerequisites
PlayFab account authenticated with AAD
You need a PlayFab account or user for which the authentication provider is set to Microsoft. The
Microsoft authentication provider uses Azure Active Directory (AAD) for authentication which is required
to use the Azure services. See Azure Active Directory Authentication for Game Manager for instructions
on creating an AAD-authenticated account or user.
To verify that the account, or user, is set to use the Microsoft authentication provider:
Visit the PlayFab log in page.
Use the the Sign in with Microsoft link to access your PlayFab account.
If you can sign in, then the account is set to use the Microsoft authentication provider.
Game Manager permissions for Insights
You need to assign your account a user role with the following Game Manager permissions enabled:
Admin status.
Access to the Explorer tab and associated data.
Read and write access to Analytics data.
You can either create a new user role or add these permissions to an existing role.
Other prerequisites
Create an Azure Active Directory (AAD) application and connect it to your title database
3. Select Create . After the deployment completes, under Next steps select Go to resource .
4. To open the Data Factory UI in a separate tab, select Author & Monitor .
Create a pipeline
We are now going to create a new pipeline to get data from Insights. To create a pipeline:
1. On the Let's get star ted page, select Create pipeline .
2. In the Activities panel under Azure Data Explorer , drag and drop an Azure Data Explorer
Command into the blank workspace. In the bottom panel under General , fill out the name and
description.
4. In the New linked ser vice (Azure Data Explorer (Kusto)) window, fill out the fields:
For Name , use the Title ID.
For Account selection method , select Enter manually .
For the Endpoint , use the PlayFab API endpoint, which is https://insights.playfab.com .
For Ser vice Principal ID , enter your Client ID from your Azure app.
For Ser vice Principal Key , enter your Client secret from your Azure app.
In the Database box, type the Title ID in all upper case.
Select Create . Now the pipeline is ready. You can go back to the main pipeline view by clicking the
pipeline name.
5. To verify that all of the information is correct, select Test connection . If everything is set up correctly, it
returns a Connection successful response.
3. To validate and debug the pipeline, in the toolbar above the workspace, select Validate and then select
Debug .
Additional resources
Azure Data Factory (ADF) documentation
To learn about other tools to connect to Insights, see Connecting external tools to Insights
Tutorial: Connecting Grafana to Insights
5/24/2022 • 3 minutes to read • Edit Online
This guide helps you get started using Grafana along with Insights. After connecting, you can use Grafana to run
analytics and monitoring systems on your game data from Insights. To learn more about other tools you can
connect Insights with, see Connecting external tools to Insights.
In this tutorial you learn how to:
Set up Grafana for Insights
Create a data source in Grafana
Create a dashboard in Grafana
Run Kusto queries and commands using the dashboard
Prerequisites
PlayFab account authenticated with AAD
You need a PlayFab account or user for which the authentication provider is set to Microsoft. The
Microsoft authentication provider uses Azure Active Directory (AAD) for authentication which is required
to use the Azure services. See Azure Active Directory Authentication for Game Manager for instructions
on creating an AAD-authenticated account or user.
To verify that the account, or user, is set to use the Microsoft authentication provider:
Visit the PlayFab log in page.
Use the the Sign in with Microsoft link to access your PlayFab account.
If you can sign in, then the account is set to use the Microsoft authentication provider.
Game Manager permissions for Insights
You need to assign your account a user role with the following Game Manager permissions enabled:
Admin status.
Access to the Explorer tab and associated data.
Read and write access to Analytics data.
You can either create a new user role or add these permissions to an existing role.
Other prerequisites
Create an Azure Active Directory (AAD) application and connect it to your title database
Create a dashboard
From the Grafana homepage we will create a new dashboard. To create a dashboard:
1. Select New dashboard .
2. In the New Panel dialog box, select Add Quer y .
3. In the Quer y panel next to Database select your database from the drop-down menu. In this example
the database name is Unicorn Battle .
3. Return to the Quer y tab. Enter a query and select Run . The results appear in the table above the Quer y
tab. In this example, we ran the query ['events.all'] | limit 100 .
Running a Kusto command follows the same process. Enter your command in the Quer y tab and select
Run . The results are displayed above. In this example, we ran the command .show tables .
Additional resources
Grafana documentation
To learn about other tools to connect to Insights, see Connecting external tools to Insights
Tutorial: Connecting Python to Insights
5/24/2022 • 2 minutes to read • Edit Online
This guide helps you get started using Python with Insights. It uses the Azure Kusto Python SDK. After
connecting, you can query your game data with Python and use the library from Jupyter Notebooks. To learn
more about other tools you can connect with Insights, see Connecting external tools to Insights.
Prerequisites
PlayFab account authenticated with AAD
You need a PlayFab account or user for which the authentication provider is set to Microsoft. The
Microsoft authentication provider uses Azure Active Directory (AAD) for authentication which is required
to use the Azure services. See Azure Active Directory Authentication for Game Manager for instructions
on creating an AAD-authenticated account or user.
To verify that the account, or user, is set to use the Microsoft authentication provider:
Visit the PlayFab log in page.
Use the the Sign in with Microsoft link to access your PlayFab account.
If you can sign in, then the account is set to use the Microsoft authentication provider.
Game Manager permissions for Insights
You need to assign your account a user role with the following Game Manager permissions enabled:
Admin status.
Access to the Explorer tab and associated data.
Read and write access to Analytics data.
You can either create a new user role or add these permissions to an existing role.
Other prerequisites
Create an Azure Active Directory (AAD) application and connect it to your title database
cluster = "https://insights.playfab.com"
token = None
if token_response:
if token_response['accessToken']:
token = token_response['accessToken']
db = "<title id>"
query = "['events.all'] | count"
crp = ClientRequestProperties()
crp.application = "KustoPythonSDK"
response = client.execute(db, query)
# Response processing
print(response)
Additional resources
Azure Kusto Python SDK documentation
To learn about other tools to connect to Insights, see Connecting external tools to Insights
Tutorial: Connecting Kusto C# SDK to Insights
5/24/2022 • 2 minutes to read • Edit Online
This guide helps you get started using the Kusto C# SDK along with Insights. After connecting, you can query
your Insights from Azure functions. To learn more about other tools you can connect Insights with, see
Connecting external tools to Insights.
Prerequisites
PlayFab account authenticated with AAD
You need a PlayFab account or user for which the authentication provider is set to Microsoft. The
Microsoft authentication provider uses Azure Active Directory (AAD) for authentication which is required
to use the Azure services. See Azure Active Directory Authentication for Game Manager for instructions
on creating an AAD-authenticated account or user.
To verify that the account, or user, is set to use the Microsoft authentication provider:
Visit the PlayFab log in page.
Use the the Sign in with Microsoft link to access your PlayFab account.
If you can sign in, then the account is set to use the Microsoft authentication provider.
Game Manager permissions for Insights
You need to assign your account a user role with the following Game Manager permissions enabled:
Admin status.
Access to the Explorer tab and associated data.
Read and write access to Analytics data.
You can either create a new user role or add these permissions to an existing role.
Other prerequisites
Create an Azure Active Directory (AAD) application and connect it to your title database
Install packages
1. Install the following NuGet packages:
Required: Microsoft.Azure.Kusto.Data
Optional: Microsoft.Azure.Kusto.Ingest
For more optional packages, see the Kusto .NET SDK documentation
2. Below is some sample code to get started with.
namespace HelloPlayFabInsights
{
using System;
using Kusto.Data;
using Kusto.Data.Common;
using Kusto.Data.Net.Client;
class Program
{
const string Cluster = "https://insights.playfab.com";
const string Database = "<title id>";
const string AzureAuthority = "microsoft.onmicrosoft.com";
const string AzureAuthority = "microsoft.onmicrosoft.com";
const string ClientId = "<app id>";
const string ClientSecret = "<app secret>";
Console.WriteLine("Run Query...");
RunQuery(kcsb);
Console.WriteLine("Run Command...");
RunCommand(kcsb);
/// <summary>
/// Run a query on your Insights database, and write the results to the console.
/// </summary>
/// <param name="kcsb"></param>
static void RunQuery(KustoConnectionStringBuilder kcsb)
{
using (var queryProvider = KustoClientFactory.CreateCslQueryProvider(kcsb))
{
var query = "['events.all'] | limit 10";
/// <summary>
/// Run the ".show tables" command on your Insights database, and write the results to the console.
/// </summary>
/// <param name="kcsb"></param>
static void RunCommand(KustoConnectionStringBuilder kcsb)
{
using (var commandProvider = KustoClientFactory.CreateCslAdminProvider(kcsb))
{
var command = ".show tables";
Additional resources
Azure Kusto .NET Samples
Kusto client library documentation
Data Explorer
5/24/2022 • 2 minutes to read • Edit Online
Overview
Data Explorer is the primary window into event data collected by your title and services. The data is stored in
PlayFab Insights, an in-development offering designed to provide a complete back-end solution for data and
analytics. For more information on the PlayFab Insights vision and strategy, see our webinar.
This feature provides fast indexing and querying on large, diverse data sets. For optimized queries, the engine
can query millions of records in a few seconds - a critical capability for games producing high throughput or
large volumes of gaming events.
Data Explorer has two different querying modes - basic and advanced. Basic mode is designed to let you quickly
discover insights in your event data without requiring query language knowledge. Advanced mode is designed
for more complex queries and deeper insights using the Kusto query language – a SQL-like language optimized
for ad hoc data exploration.
Explorer Advanced uses a simplified SQL-like language that's easy to pick up and learn. The intellisense
capabilities make it possible for users of all skill levels to author complex queries and render the results in-line.
Learn how to get started in the Quickstart section.
Data Explorer Quickstart
5/24/2022 • 2 minutes to read • Edit Online
[NOTE] The Explorer Feature is in public preview. We anticipate ongoing changes to it as we continue
gathering feedback and optimizing for customer use.
Basic mode
To query the data in basic mode:
1. Log in to the PlayFab Game Manager.
2. Select your Title.
3. In the left navigation column, select Data .
4. Select the Data Explorer (basic) tab at the top of the page.
To learn how to author custom Basic queries, see the Getting Started with Data Explorer basic mode tutorial.
Advanced mode
To query the data in advanced mode
1. Log in to the PlayFab Game Manager.
2. Select your Title.
3. In the left navigation column, select Data .
4. Select the Data Explorer (advanced) tab at the top of the page.
5. In the Data Explorer pane, select What’s This to display a set of sample queries.
6. Select Open Sample Quer y under Learning to Query to load the query into the Query pane.
7. Follow the directions in the query comments.
To learn how to author custom queries, see the Getting Started with Data Explorer advanced mode tutorial.
To learn about how to assign roles for read and write data access, see PlayFab User Roles.
Data Explorer Tutorials
5/24/2022 • 2 minutes to read • Edit Online
IMPORTANT
The Data Explorer feature is in public preview. We anticipate ongoing changes to it as we continue gathering feedback and
optimizing for customer use.
Data Explorer basic mode is designed to let you quickly discover insights in your event data without requiring
query language knowledge. This non-technical query building experience enables users to explore their data
quickly. To learn how to write more complex queries, see the Getting Started with Data Explorer (advanced)
tutorial.
Query Output
After running a query, you can see the output below in the Query Output panel. The output is in the format of a
bar graph as well as a table.
The graph shows the results for the largest 5 groups. You can see the other groups by clicking the dropdown at
the bottom of the graph.
The table shows the Event Name, Timestamp (UTC), Player ID, and Event Data (via JSON) for reach row.
Sample Queries
Single Condition Queries
What regions are players logging in from this week?
Example queries can be loaded into the Data Explorer basic by selecting “What’s This” and selecting a sample
query.
Limits
There are two limits which govern Data Explorer query usage:
1. Max query runtime: An individual query is not permitted to run longer than 30 seconds. If this limit is
exceeded, the query will be terminated and you will receive an error message.
2. Interval Usage: Each title is permitted a cumulative total runtime of three minutes per any given 10
minute interval. If this limit is exceeded, you will receive an error message and will need to wait before
running additional queries.
Data Retention
By default, Explorer queries run on hot storage, which can be configured in the Management tool. Queries that
search beyond the data stored in hot storage will have significantly longer run times and may time out.
Getting started with Data Explorer advanced mode
5/24/2022 • 5 minutes to read • Edit Online
IMPORTANT
The Data Explorer feature is in public preview. We anticipate ongoing changes to it as we continue gathering feedback and
optimizing for customer use.
Data Explorer advanced mode is designed for more complex queries and deeper insights using the Azure Data
Explorer query language – a SQL-like language optimized for ad hoc data exploration. To learn how to write
non-technical queries, see the Getting Started with Data Explorer basic mode tutorial.
As a matter of preference, a query can be expressed on a single line or using a line return before each pipe
delimiter. It makes no difference to the query itself.
The Query pane can contain more than one query. This makes it easy to start with a simple expression, validate
it runs, and build on it.
A blank line will separate one query from another. Your cursor position determines which query will run when
you press the “Run” button. You can also highlight a portion of the query to run only that expression.
Once you’ve located the events.all table, double click the table name. You’ll notice this expression has been
added to the Query pane.
NOTE
In Preview, you'll need to manually add the brackets and single quotes around the table name. A fix for this inconvenience
is in progress.
['events.all']
|
Note the brackets and single quotes around the name. Whenever the table or column name includes a “.” these
are required. Your cursor is now in the correct position to author your first operator. Let’s start using the take
operator.
['events.all']
| take 100
Run this query. Note that the Results pane now shows 100 rows of raw data.
In the Results pane, click the top row. Using the right arrow, navigate over to the FullName_Name column. This is
the name of the event. Arrow down until you find a player_logged_in event. Once you’ve found one, right arrow
over to the EventData column and double click. You should now see this:
Your query can reference any properties in the EventData JSON using the dot notation (.). You can try this now
by modifying your query to return only player_logged_in events from a single player. Double-click the EntityID
GUID and copy it to the clipboard.
Now update your query as follows and insert the GUID you copied:
['events.all']
| where FullName_Name == 'player_logged_in'
| where Entity_Id == 'paste from clipboard here'
TIP
Double equal signs are used to evaluate string equivalency. Single quotes at the beginning and end set apart a string.
Run the query and you’ll see the Results pane show player_logged_in events only for the selected player. You
can use dot notation to reference multiple nested layers of JSON hierarchy by simply adding a dot between each
layer.
Now let’s create a second query to group player logins by region. Without deleting what you’ve written, press
return twice. Let’s add a comment to our next query by using “//”. Comments will not be executed and are
helpful to keep track of the intent behind each query.
Once again, double-click the events.all table from the resources pane. This time, let’s add a time delimiter to our
expression to scope our query to just the past three days.
Run this query to get a full list of all log-in events over the past three days. However, we want to know how
many distinct players have logged in, not the count of events. To do this, we’ll use the distinct operator by Entity
ID.
['events.all']
| where Timestamp > ago(3d)
| where FullName_Name == 'player_logged_in'
| distinct Entity_Id
This query returns a list of Entity IDs who’ve logged in during the past three days. The Results pane shows the
number of records, so we can see the total count.
Now let’s get the count of players who’ve logged in from each platform. To do this, we’ll need the distinct count
of Entity IDs grouped by the platform property in the EventData JSON. This requires the summarize operator.
Because summarize does not support dynamic types, we’ll also need to cast platform to a string.
['events.all']
| where Timestamp > ago(3d)
| where FullName_Name == 'player_logged_in'
| summarize dcount(Entity_Id) by tostring(EventData.Platform)
Let’s finish this off with a flourish. By adding a single additional expression, we can render our results as a
column chart.
['events.all']
| where Timestamp > ago(3d)
| where FullName_Name == 'player_logged_in'
| summarize dcount(Entity_Id) by tostring(EventData.Platform)
| render columnchart
Sample Queries
We’ve only just scratched the surface of the types of queries that can be authored in Explorer. More example
queries can be loaded from the Explorer page by pressing “What’s This”. Each of these sample queries is chosen
to demonstrate some of the various operators available and how they can be applied to real world questions.
NOTE
Because the shape of your data might vary from our demo data set, you may need to modify the sample query to run for
your scenario.
Limits
There are two limits which govern Explorer query usage:
1. Max query runtime: An individual query is not permitted to run longer than 30 seconds. If this limit is
exceeded, the query will be terminated and you will receive an error message.
2. Interval Usage: Each title is permitted a cumulative total runtime of three minutes per any given 10
minute interval. If this limit is exceeded, you will receive an error message and will need to wait before
running additional queries.
Data Retention
By default, Data Explorer queries run on hot storage, which can be configured in the Management tool. Queries
that search beyond the data stored in hot storage will have significantly longer run times and may time out.
Schemas
5/24/2022 • 2 minutes to read • Edit Online
NOTE
The Explorer Feature is in public preview. We anticipate ongoing changes to it as we continue gathering feedback and
optimizing for customer use.
Overview
This section describes the data and data products stored in PlayFab Insights, an in-development offering
designed to provide a complete backend solution for data and analytics. For more information on the PlayFab
Insights vision and strategy, see our webinar.
Out of the box, PlayFab Insights offers a database for every title. This database contains tables with all the event
and processed data generated by your title. At a high level, data comes in two forms:
1. Event data streamed by the game and game services or the PlayFab APIs.
2. Processed data generated by PlayFab and its services on a scheduled basis.
Learn more about how to get started in the Quickstart section.
Schemas quickstart
5/24/2022 • 2 minutes to read • Edit Online
NOTE
The Schemas Features are in public preview. We anticipate ongoing changes to it as we continue gathering feedback and
optimizing for customer use.
Event Data
Event Data arrives in Insights through one of several pathways:
Many API calls log events which are automatically written to PlayFab Insights. For example, the
player_logged_in event is generated each time a log in API call is made.
The WriteEvents API allows developers to send descriptive events.
The WriteEvents.
Each of these events lands in a single table called events.all.
Processed Data
NOTE
No processed data sets are available in PlayFab Insights at this stage of our Public Preview. Please check back over time as
new features become available.
Processed data is copied into your title's database on a scheduled basis as transforms occur. Examples include
the Trends table, which is calculated nightly in order to power the Trends feature on Game Manager. This data is
copied to your Insights database for to enable custom analysis. Other planned data sets include the Player
Profile state table.
Schemas Tutorials
5/24/2022 • 2 minutes to read • Edit Online
The events.all table is the destination for all incoming events regardless of the ingestion pipeline they come
through. This table powers several features on Game Manager, including Event History and Explorer.
NOTE
Many columns present are written as an artifact of our ingestion process and are in the process of being deprecated. Only
those listed below are intended to remain. Other columns can and should be disregarded.
PlayFab Insights provides studios the ability to change the performance characteristics of their data system.
Controls are located in Management under the data section in Game Manager.
Performance Levels
Why are performance levels important?
Performance levels determine
the resources (cache size, compute power, memory) given to each query
the limits of concurrent queries, max number of concurrent queries, events per second, and active event
exports
Performance levels can also be used to increase the max number of events per second and the number of
allowed active event exports for a title.
How can I change my performance level?
The Performance Level slider is used to select a new performance level. The Performance Level Settings table
shows a comparison of your current settings versus new settings you've selected:
NOTE
Once paid insights features are enabled for a title, that title will also have access to customized data retention
values.
Cache Size
PlayFab Insights uses a specialized variation of Azure Data Explorer (Kusto). Insights separates storage into two
categories: Hot Cache and Storage. Hot Cache is memory and SSD storage and is extremely fast to query.
Complex queries and data functions are executed quickly when all data is readily accessible in the hot cache.
Data stored outside the hot cache in storage is still easily accessible and can be queried, but query times may
slow down with large datasets in storage. Data is separated by ingestion time, the most recent data stored first
in hot storage. Data storage is an entirely internal process to Insights and data is accessed in the same manner
no matter where its stored.
Example:
A studio has selected performance level 3 and therefor has 100GB of cache. They have also select 1200 days of
retention, so there is just over 3 years of data stored in their cluster. If the studio has a daily data footprint of 1
GB a day, then 100 Days of data is stored in the hot cache. A user can run a query over 90 days and query only
hot cache, they can run that same query over all 3 years and query from both sources, no change is needed in
query structure.
How is cache affected when I change my performance level?
When you change your performance down, data is loaded from hot cache into storage as the hardware
resources are reduced. Similarly, when increasing your performance level, hardware is instantly allocated to you
and data is transfered into your cache. This process is generally very fast, but terabyte level shifts in cache size
can take a short time to complete. For more information see Best Practices.
Compute Power
Compute power represents the maximum quantity of vCPUs allocated for each query. Based on the
parallelization of a given query plan, some queries cannot take full advantage of all vCPUs at once (order,
distinct). Additionally, to improve interactivity of the querying experience, priority is given to queries by start
time, meaning subsequent concurrent queries may see decreased vCPU allocation.
Compute power also increases the maximum query length before timeout. the following table represents
current numbers:
4 120s
8 180s
16 210s
32 240s
48 270s
64 300s
Retention
The retention setting allows a studio to set the total number of days data is kept. The default setting is 30 days,
which fulfills most GDPR compliance regulations. Retention can be set globally or by table using Management
Commands. Retention is charged at a rate of 50 credits per terabyte month, studios are only charged for what is
in use by day. For more information about Insights Credit Pricing, see Insights Credit Pricing.
Example A studio has 10 terabytes of data stored at the beginning of the month and does not increase that
storage. The total cost would be 500 (10 TB * 50 credits/TB) Credits.
Example A studio begins the month at 250 GB of data and increases to 750 GB of data throughout the month
linearly. The total charge would be 25 (average of each day of the month 0.5 TB * 50 credits/TB) Credits.
Insights Scheduled Scaling
5/24/2022 • 2 minutes to read • Edit Online
The Insights Performance Level can be set to scale up and down at specific times of the day. This allows a studio
to match their analytics resources demand to their supply and optimize costs. Scheduled Tasks can be found
under automation in Game Manager. It can also be reached by clicking the Add Insights scaling scheduled task
button in Insights Management.
Event Export is the primary mechanism for exporting data from your Insights data cluster without querying.
Event Export can be reached under the data section of PlayFab Game Manager. The amount of distinct export
commands you can run is tied to your performance level.
To create a new export:
1. Navigate to the Event Export page.
2. Select "New Event Export".
3. Fill out the required fields with your external storage account information.
4. There are several options for which data to export to choose from
a. You may select the checkbox for all events, this will export all data.
b. You may select one more more tables to export
c. You may select to use a custom query to define the output of the export. NOTE Using a custom query
for exporting all data will result in a slight addition of columns from the ETL process. NOTE When
using custom query, the output must have a timestamp column named timestamp.
5. You can choose between once an hour and once a day for export frequency
6. You can choose to have your data partitioned into individual files for more efficient storage and loading
Use Cases
1. Export all data to be ingested into a separate data system. Exporting all data allows for an efficient way to
create files to save for cold storage or for ingestion into another data processesing system. While this is
functional it is not the intended use case for Insights and Export. PlayFab Insights is excellent at data
modification and tranformation, the second case is recommended over this case.
2. Export custom query data. Using a custom query allows you to select custom datasets for export. This is ideal
for loading cleaned data models into machine learning systems like Spark and pandas (python), or into other
data systems and visualization platforms that provide specialized use cases.
Continuous Export
Continuous data export will begin exporting data only from the point of the export's creation.
Insights Management Commands
5/24/2022 • 4 minutes to read • Edit Online
Insights management commands allow users express more control over or to gather additional information on
their data system. The commands fall into two primary categories:
1. Management - These commands allow users to view more information about queries, commands and
retention as well as alter retention
2. Data Control - These commands allow users to create and drop custom tables, ingest local and cloud data
and purge data from their DB
Some commands are not available in evaluation mode.
C AT EGO RY C O M M A N DS
Management
.show queries
Returns a list of currently-executing queries by the user, or by another user, or by all users.
Usage: .show queries
Example: .show queries | where StartedOn > ago(1d)
This shows all queries that executed in the last day
.show running queries
Shows all currently executing queries
Usage: .show running queries
Example: .show running queries
This shows all currently running queries.
.show database policy caching
Shows the current caching policy on the database
Usage: .show database DatabaseName policy caching
Example: .show database myDatabase policy caching
This shows the current caching policy for the specified database.
.show table policy caching
Shows the current caching policy on the table
Usage: .show database DatabaseName.TableName policy caching
Example: .show database myDatabase.myTable policy caching
This shows the current cachingt policy for the specified table.
.show commands-and-queries
Returns a table with admin commands and queries which have reached a final state. These commands and
queries are available to query for 30 days.
Usage: .show commands-and-queries
Example: .show commands-and-queries | where StartedOn > ago(1d) | where State != "Completed"
This Shows all commands and queries that failed in the last day
.show table policy retention
Shows tables' effective retention policy taking cluster and database rules into account
Usage: .show table(s) (<table_name> [, ...]) policy retention
Example: .show table ['events.all'] policy retention
This shows the current retention policy for the "events.all" table.
.alter table policy retention (restricted to accounts on consumption pricing model)
Change the current retention policy on table(s) to <retention_policy>
Usage: .alter tables (<table_name> [, ...]) policy retention <retention_policy>
Example: .alter table ['events.all'] policy retention softdelete = 90d
This sets data in the "events.all" table to be removed from the table after 90 days.
Data Control
.create table (restricted to performance level 2 and above)
Creates a new empty table. The command must run in context of a specific database. If the table already exists
the command will return success.
Usage: .create table TableName ([columnName:columnType], ...)
Example: .create table ['custom.logs'] (Level:string, Timestamp:datetime, Id:string, Message:string)
This creates a new table called "custom.logs" with four columns. IMPORTANT Custom tables must begin
with "custom.".
.drop table (restricted to performance level 2 and above)
Drops the specified table. Note: This cannot be undone.
Usage: .drop table TableName [ifexists]
Example: .drop table ['custom.logs']
This drops the table named "custom.logs".
.set (restricted to performance level 2 and above)
Creates a table with results of Query Or Command
Usage: .set TableName [with (PropertyName = PropertyValue [, ...])] <| QueryOrCommand
Example: .set [‘custom.recentEvents’] <| [‘events.all’] | where Timestamp > now() – time(1h)
This creates a table "custom.recentEvents" containing the results of the above query
.append (restricted to performance level 2 and above)
Appends an existing table with results of QueryOrCommand
Usage: .append TableName [with (PropertyName = PropertyValue [, ...])] <| QueryOrCommand
Example: .append [‘custom.recentEvents’] <| [‘events.all’] | where Timestamp > now() – time(1h)
This adds to existing table "custom.recentEvents" with the results of the above query
.set-or-append (restricted to performance level 2 and above)
Create or appends to a table with results of QueryOrCommand
Usage: .set-or-append TableName [with (PropertyName = PropertyValue [, ...])] <| QueryOrCommand
Example: .set-or-append [‘custom.weekEvents’] <| [‘events.all’] | where Timestamp > now() – time(7d)
This appends data from the above query to table "custom.weekEvents". If the table does not exist, create it.
.set-or-replace (restricted to performance level 2 and above)
Replaces the data of the table if it exists (drops the existing data shards), or creates the target table if doesn't
already exist. The table schema will be preserved unless one of extend_schema or recreate_schema ingestion
property is set to true. If the schema is modified, this happens before the actual data ingestion in its own
transaction, so a failure to ingest the data doesn't mean the schema wasn't modified.
Usage: .set-or-replace TableName [with (PropertyName = PropertyValue [, ...])] <| QueryOrCommand
Example: .set-or-replace [‘custom.dayEvents’] <| [‘events.all’] | where Timestamp > now() – time(1d)
This replaces the data in table "custom.dayEvents" with the above query.
.ingest into (restricted to performance level 2 and above)
Ingests data into a table by "pulling" the data from one or more cloud storage artifacts.
Usage:
.ingest into table TableName SourceDataLocator [with ( IngestionPropertyName = IngestionPropertyValue [, ...]
)]
Example: .ingest into table [‘custom.myData’] (h’<your url here>’) with(ignoreFirstRecord=true)
This pushes data into table "custom.myData" from your cloud storage listed in the url.
.purge table (restricted to performance level 2 and above)
Permanently deletes data in table from the database
Usage: .purge table [TableName] in database [DatabaseName] allrecords with (noregrets='true')
Example: .purge table [‘custom.toPurge’] in database MyDatabase allrecords
This purges all data from table "custom.toPurge", permenantly deleting it from your data system.
Insights Pricing
5/24/2022 • 3 minutes to read • Edit Online
The total combined usage of Insights features are billed in a virtual currency called "Insights Credits". Insight
Credits are derived from conversion rates for usage of each Insight services.
The Standard and Premium pricing plans include a number of free monthly Insights credits. If usage exceeds the
number of free credits, any additional credits are billed at the rate specified on your plan. The Pay-as-you-go
pricing plan does not include free credits, so each credit is billed at the rate specified in the plan. For more
information on the number of free credits and additional credit rates included in each plan, see PlayFab Pricing.
Insights Performance
Each title is set to a chosen performance level that is billed to the minute (Insights Credits Per Hour / 60). The
cost in credits for each performance level is located at the bottom of the table on the Insights Management
page:
IMPORTANT
All MAU-based pricing plans will be converted to a usage-based pricing plan on 11/01/2020. As part of the transition, a
small number of titles will be placed on a paid Insights Performance level to maintain their current functionality. However,
if a title would like to reduce the performance level (and thus cost) while also accepting a decrease in performance, the
performance level can be adjusted on the Insights Management page in Game Manager using the above table.
Retention
Data retention is billed in Terabyte months. Every day the end of day storage size is recorded and averaged over
the month. Each terabyte is billed at 50 credits per terabyte month. For example, if a studio stored 1 terabyte of
data every day for a month, the total would be 1 TB/Month * 50 Credits = 50 Credits.
Pricing example
Below is an example scenario illustrating how one month of Insights billing is calculated for a studio:
In April, a studio used performance level 4 from 9AM to 5PM each weekday and scaled down to performance
level 2 at nights and on weekends. April has 21 weekdays and 9 weekend days, which works out to:
21 days at performance level 4, for 8 hours
21 days at performance level 2, for 16 hours
9 days at performance level 2, for 24 hours
The credit rate per hour for each of these levels is:
performance level 2 = 1 credits/hour
performance level 4 = 4 credits/hour
The total monthly charge for Insights Performance is calculated as:
21 (days) * 8 (hours) * 4 (credits per hour at performance level 4) + 21 (days) * 16 (hours) * 1 (credits per hour
at performance level 2) + 9 (days) * 24 (hours) * 1 (credits per hour at performance level 2) = 1,224 credits for
the month.
Starting the month with no stored data, the studio added 1 TB of data every other day for 30 days. At the end of
the month they averaged 15 TBs of data over the month. The total monthly charge for data retention is
calculated as:
15 TB * 50 Credits per TB/month = 750 Credits for the month.
Thus, the studio's total monthly cost for Insights performance and data retention is 1,974 credits.
Here we examine some best practices for using PlayFab Insights as well as address the most frequently asked
questions.
Best Practices
Each performance level comes with a certain quantity of cache. It is a good idea to calculate a daily data
footprint and decide how many days of data you would like in cache. A small buffer or very well known
data footprint will allow anyone performing queries to know when to expect optimal performance.
Running visualizations against that expected performance is also recommended for quick results.
For example, a studio has a 5 GB / day data footprint. Selecting a cache size of 450+ GB will allow 90
days of data in cache. Running all visualizations in 90 day running windows will be very efficient.
Joins, unions, and advanced queries will be very efficient. Another option would be to focus live
visualizations primarily on 30 day windows and set cache size up to 90 days during working hours
and 30 days during off hours, this will create large efficiencies in cost savings. Also keep in mind that
data is compressed in cache.
Data visualization platforms like PowerBI often run multiple queries for a single visualization. It's
recommended that the visualizations be updated serially. If under heavy load, or being used by many
users, it may make sense to increase performance level to a level that has higher concurrent queries
allowed to free up simultaneous queries for external tools and analysts.
The most common use case for scheduled scaling is to scale up during standard working hours and to
scale down after hours and weekends. If making large changes in performance level (e.g. level 3 to 8) it's
recommended that you intend to stay at the higher performance level for several hours. Loading
terrabytes of data in and out of cache quickly is an inefficient use of resources. All other limits are raised
instantly, so you may choose to make the scaling changes if needed.
Scheduled scaling is not mutually exclusive with manual scaling. If you find that you need more resources
in middle of the day, you can make a manual change, the scheduled scaling will continue as expected.
Reducing data storage can result in data loss. You will be warned with the message "Selected retention
setting is lower than current setting. Doing so may result in a loss of data." when attempting to reduce
storage. Due to the low cost of storage, long term retention is recommended.
Insights management commands allow the creation and updating of custom tables. For core reporting
and often used tables it's helpful to build custom aggregation tables. Aggregation tables generally have a
much smaller data footprint than the source data. This increases query performance and reduces the
need for a higher performance level.
For automating data aggregation we recommend using Azure Data Factory, a low-cost and scalable
automation option. For more information on using Azure Data Factory see the connectivity section.
Limit queries by timestamp, don't pull all data to explore the last several days (this is generally good
advice in any data system).
FAQ
How can I query data?
1. The simplest way is to use our built in data explorer.
2. The connectivity section has details on additional ways to access data.
I sent a Microsoft authentication link (AAD) and it didn't work, what happened?
If you already have a PlayFab account, you need to sign out before accepting an invite with a different
authentication method.
Why am I getting an error when trying to change my performance level or data retention?
1. If you have not signed up for a paid account, changing performance levels, retention, exports and some
management commands will be unavailable.
2. If your Insights cluster is currently changing performance levels you must wait until the change is completed.
Can I change between free and paid performance levels?
Sure! You can revert back to the free tier if you don't currently need any of the paid features.
How do I get data into my Insights cluster?
1. Most PlayFab services automatically generate data for you.
2. You can also implement your own telemetry through PlayStream, or our Telemetry system.
3. You can use Management Commands to ingest custom datasets.
What is the standard data schema for PlayFab events?
In PlayFab Insights we load all the data from all events into a single table. This table is named ['events.all].
Inside that table you will see a column called "EventData" that contains the payload of JSON information for
each event. For complete information about the events.all table, see About the events.all table for more
complete information.
Why can't I write SQL?
As of now, we only support KQL (Kusto Query Language) queries in most scenarios. We're actively exploring
adding SQL support. While KQL takes some getting used to, we think you'll like it once you do. For
information on converting SQL to Kusto queries, see SQL to Kusto query translation.
What's the difference between Events Per Second in my Insights performance level and the costs of sending
PlayStream events?
Events per second in your Insights performance level represents data ingestion to your cluster through any
means. PlayStream write events and write telemetry events are billed independently and represent the cost
of writing to the cloud.
Can I have a higher performance level than what I see on my management page?
File a support ticket with us and we'll contact you to arrange something that meets your needs.
What is the underlying technology behind PlayFab Insights?
PlayFab Insights uses a specialized variant of Azure Data Explorer (Kusto).
Why is my data schema different when exporting using custom queries?
The custom query output includes details from the ETL (Extract Transform Load) process. Some extra
columns will be included. Those columns are generally hidden in the query environment as they do not serve
a purpose.
What happens if I reduce my retention setting to a quantity of days that is less than the total number of days I
have data for?
You're warned that if you reduce your retention you might delete data. For example, if you have been
operating for 1 year and reduce the retention to 6 months, only the most recent 6 months of data is saved,
the rest is discarded.
How do I increase the timeout time on my queries?
The time out limits on queries is relative to your compute power which is defined in your performance level.
Refer to the compute power table in Performance and Retention under compute power.
Is there a limit to how much telemetry I can send?
The following limits exist for the WriteTelemetryEvents API call:
L IM IT N A M E L IM IT VA L UE N OT ES
Events per request 200 events per request Exceeding this limit will result in a
BadRequest error.
Events per entity 8,000 per second Exceeding this limit will result in a
PerEntityEventRateLimitExceeded
error. An entity most often
represents an individual player, but
can also be a player group or title.
If you run into any of these limits, please contact the Playfab Support team for assistance. In the upper
right-hand corner of Game Manager select the question mark icon, then select Contact Us .
I get an error “Query execution has exceeded the allowed limits” when I try to run a query.
This error occurs when the size of the result set or the number of rows in the result set exceeds the allowed
limit. Try limiting the amount of data returned by scoping the query to relevant data using the where, limit, or
summarize operators
To export all of your data, navigate to the Event Expor t Tab under Data on the Title Over view page in
PlayFab Game Manager.
If you want to pull only segments of data or if you are still hitting the query limit, you can partition the data
by time or unique id (ex. Player ID, Title ID) and run multiple, smaller queries. The follow is an example of how
to partition based on time:
Where
Limit
Summarize
How do I grant a user permissions to the Data > Explorer page for a
particular title?
Follow the PlayFab User Roles guide to access, create, and grant user permissions.
A user needs the following 3 permissions to access the Data Explorer:
Explorer data & tab (Read and Write permissions)
Analytics data read access (Read permissions)
Analytics data write access (Write permissions)
What are PlayFab Social Features?
5/24/2022 • 2 minutes to read • Edit Online
Adding social elements to a game helps keep players engaged and leverages your most valuable asset; your
community. No matter what form player interaction takes in your game, PlayFab can help you enable that
interaction with its suite of built-in common social gaming features.
Key Features
PlayFab Social features revolve around interactions between players, and includes friends lists, groups, clans and
guilds, tournaments, leaderboards, and support for player trading.
Friends
5/24/2022 • 2 minutes to read • Edit Online
Letting players connect with their friends is a great engagement tool for your game! PlayFab offers you the
ability to integrate with your players' existing social network (like Facebook, Steam, or Xbox Live) or to manage
your own custom friends lists within your game.
Any player in your title may be friends with any other player in your title. Notably, friendship on PlayFab is a
one-way street.
If Julie adds Bob as a friend, there is no approval process for Bob . In fact, Bob may be unaware.
Bob must separately add Julie for the friendship to be mutual.
If you wish to have reciprocity rules, it is your title's responsibility to enforce these conditions with a custom
game server or CloudScript logic, if necessary.
Friends lists
5/24/2022 • 3 minutes to read • Edit Online
Friends lists are a great feature for improving your players' ability to socialize. They're easy to work with, and
can make leaderboards more engaging for your users.
Prerequisites
SDK: Unity
The title ID is set in the PlayFabSharedSettings object.
The project can successfully log in a user.
The title has at least two registered users.
About friends
Any player in your title may be friends with any other player in your title. Notably, friendship on PlayFab is a
one-way street.
If Alber t adds Bob as a friend, there is no approval process for Bob . In fact, Bob may be unaware.
Bob must separately add Alber t for the friendship to be mutual. If you wish to have reciprocity rules, it is your
title's responsibility to enforce these conditions with a custom game server or CloudScript logic, if necessary.
In the event that a player has linked their Steam, Facebook, or Xbox Live account, their platform-specific friends
can also be displayed, if those friends also play your title.
Making friends
The example code uses the functions DisplayFriends() , and DisplayError(string error) as a proxy of your
app's UI. You paste these into your editor to get it to work without any extra effort - or replace the calls with your
own code.
1. Once a player logs in, they can access the UI for friends. The functionality usually includes adding, removing,
and displaying friends, at a minimum.
2. To get the player's current friends list, use the GetFriendsList API call.
List<FriendInfo> _friends = null;
void GetFriends() {
PlayFabClientAPI.GetFriendsList(new GetFriendsListRequest {
IncludeSteamFriends = false,
IncludeFacebookFriends = false,
XboxToken = null
}, result => {
_friends = result.Friends;
DisplayFriends(_friends); // triggers your UI
}, DisplayPlayFabError);
}
The GetFriendsList result contains a parameter friends which is a list of FriendInfo objects.
3. To add a friend to the player's friend list, use the AddFriend API call.
4. To remove a player from a player's friends list, use the RemoveFriend API call.
Going further
There are other things you can do with friends besides adding, removing, and displaying.
Tagging friends
The FriendInfo object, retrieved from GetFriendsList, includes a list of tags for the friend. When updating the list,
you would want to add and remove from this list, and include it in the API call (as shown below).
// this REPLACES the list of tags on the server
// for updates, make sure this includes the original tag list
void SetFriendTags(FriendInfo friend, List<string> newTags)
{
// update the tags with the edited list
PlayFabClientAPI.SetFriendTags(new SetFriendTagsRequest
{
FriendPlayFabId = friend.FriendPlayFabId,
Tags = newTags
}, tagresult => {
// Make sure to save new tags locally. That way you do not have to hard-update friendlist
friend.Tags = newTags;
}, DisplayPlayFabError);
}
You can use tags to inform matchmaking (for example, the player doesn't like playing with friends tagged 2tuff
at hard difficulty), implement friend groups - or just use them to store any metadata associated with a
relationship that you need.
An important note is that PlayFab currently does not index these tags in any way. GetFriendsList can't filter
based on them, so that must be done locally.
Keep this in mind when considering any performance implications resulting from this system.
Friends Tutorials
5/24/2022 • 2 minutes to read • Edit Online
Friends-specific APIs mirror the standard GetLeaderboard and GetLeaderboardAroundPlayer API calls, but
restrict the player pool to the player's friends list.
NOTE
The GetFriendLeaderboardAroundPlayer API does not base the center of the leaderboard around the currently logged in
player - it can be any PlayFab ID supplied with the request. You can use this to allow players to look up any friend's
location on the leaderboard, regardless of their distance from each other.
Groups, guilds and clans
5/24/2022 • 2 minutes to read • Edit Online
The Group entity type can be utilized by your game to create guild and clan interactions within your game. This
entity type gives you the ability to create different roles for members, invite members into the group, and
manage group membership.
The group that you create can utilize all of the base Entity programming model capabilities. For example, it can
use Objects and Files to store data that is specific to the Group.
To build a guild or clan system in your game, you will want to utilize the group functionality, and create a
customized experience within your game.
Entity groups
5/24/2022 • 7 minutes to read • Edit Online
Entity groups
Entity groups are the root concept that was inspired by the need for clans/guilds.
At its core, entity groups are any logical group of entities, which can serve any purpose. Entity groups can
simultaneously serve many purposes within your game.
Examples
Clans/Guilds - This was the starting point, and the main driving need. Entity groups can be used to
describe a set of players who are playing together on a regular basis, for whatever social glue that holds
them together on a long-term basis.
Par ties - Entity groups can be used for short-term groups created to allow individual players to
accomplish an immediate goal, and then easily disbanded afterward.
Chat Channels - Short or long term chat channels can be defined as an entity group.
In-Game subscription to information - Do you have a single-instance legendary item in your game?
Do players want constant updates about what is happening with that item? Create an entity group
focused on that item, with all player entities interested in the item as members.
In short, entity groups can be any collection of entities (whether NPC or player-controlled, real or abstract),
which need a persistent-state bound to that group.
A friends list is a group. A three person private chat is a group. Go nuts!
NOTE
We'd appreciate some warning in the forums if you are trying something we might not be expecting...
In addition, since entity groups are also entities themselves, they will contain all the initial features of entities:
Object data
File data
Profiles
They will be generally eligible for new entity features going forward, if those features are relevant to groups.
using PlayFab;
using PlayFab.GroupsModels;
using System;
using System.Collections.Generic;
using UnityEngine;
namespace TestGuildController
{
/// <summary>
/// Assumptions for this controller:
/// + Entities can be in multiple groups
/// - This is game specific, many games would only allow 1 group, meaning you'd have to perform some
additional checks to validate this.
/// </summary>
[Serializable]
public class GuildTestController
{
// A local cache of some bits of PlayFab data
// This cache pretty much only serves this example , and assumes that entities are uniquely
identifiable by EntityId alone, which isn't technically true. Your data cache will have to be better.
public readonly HashSet<KeyValuePair<string, string>> EntityGroupPairs = new
HashSet<KeyValuePair<string, string>>();
public readonly Dictionary<string, string> GroupNameById = new Dictionary<string, string>();
// Presumably, this would be part of a separate process where the recipient reviews and accepts
the request
var request = new AcceptGroupInvitationRequest { Group = EntityKeyMaker(prevRequest.Group.Id),
Entity = prevRequest.Entity };
PlayFabGroupsAPI.AcceptGroupInvitation(request, OnAcceptInvite, OnSharedError);
}
public void OnAcceptInvite(EmptyResponse response)
{
var prevRequest = (AcceptGroupInvitationRequest)response.Request;
Debug.Log("Entity Added to Group: " + prevRequest.Entity.Id + " to " + prevRequest.Group.Id);
EntityGroupPairs.Add(new KeyValuePair<string, string>(prevRequest.Entity.Id,
prevRequest.Group.Id));
}
// Presumably, this would be part of a separate process where the recipient reviews and accepts
the request
var request = new AcceptGroupApplicationRequest { Group = prevRequest.Group, Entity =
prevRequest.Entity };
prevRequest.Entity };
PlayFabGroupsAPI.AcceptGroupApplication(request, OnAcceptApplication, OnSharedError);
}
public void OnAcceptApplication(EmptyResponse response)
{
var prevRequest = (AcceptGroupApplicationRequest)response.Request;
Debug.Log("Entity Added to Group: " + prevRequest.Entity.Id + " to " + prevRequest.Group.Id);
}
public void KickMember(string groupId, EntityKey entityKey)
{
var request = new RemoveMembersRequest { Group = EntityKeyMaker(groupId), Members = new
List<EntityKey> { entityKey } };
PlayFabGroupsAPI.RemoveMembers(request, OnKickMembers, OnSharedError);
}
private void OnKickMembers(EmptyResponse response)
{
var prevRequest= (RemoveMembersRequest)response.Request;
Server vs client
Like all new entity API methods, there is no distinction between the server API and the client API.
The action is performed by the caller, according to how the process was authenticated. A client will be identified
as such, and will call these methods as a title player entity, and their roles and permissions within the group will
be evaluated with every call, ensuring they have permission to perform this action.
A server is authenticated with the same developerSecretKey , which identifies that process as a title entity. A title
will bypass the role checks, and API calls executed by a title will only fail if the action is impossible to perform, in
an instance such as if an entity cannot be removed if they are not a member.
Groups, guilds, and clans tutorials
5/24/2022 • 2 minutes to read • Edit Online
These tutorials teach you how to use groups functionality for your games, and how to build guilds and clans
within your game.
To store data for your groups, guilds or clans:
Objects
Files
For turn based games:
Using Shared Group Data
Using Shared Group Data
5/24/2022 • 3 minutes to read • Edit Online
Shared Group Data is a simple way for players to share some information with a tightly constrained list of other
players.
NOTE
Shared Group Data was originally designed to be driven by server-authoritative for most cases, and the previous advice
was to not add players directly to the Shared Group data, as that gave them read/write permissions (allowing for
cheating). However, our new API Access Policy allows a much greater variance in functionality and security over the
original design. More details are available in the advanced section of this document.
WARNING
Shared Group Data should not be used by groups larger than a dozen or so players, at most. One issue is that too many
players attempting to read the same data at the same time will result in delays reading the data (Shared Group Data is
not sharded or cached, the way that data meant to be read by many players at once, like Title Data is). And special care
should be taken to prevent players from over-writing each others data. In the instance that multiple players try to write
to the same Key at the same time, only one of those writes will "win", resulting in the loss of the other user's data.
At a high level, you can use Shared Group Data to implement Parties/Raids, or other semi-permanent groups of
players, as long as group size is relatively small, as stated.
While there's no strictly enforced limit currently, usage with many players is not supported, and in extreme cases
may result in throttling of the title feature to prevent impact to others in the service.
Key restrictions
Shared Group Data :
Only contains simple Key/Value Pair data (strings). For use as any other data type (such as Inventory
items, Statistics, Virtual Currency, etc.), the title must provide any necessary conversions.
Is neither sharded nor cached, so it will not be responsive when accessed simultaneously by multiple
players. Features using it should be designed with small player groups in mind, and not allow for
simultaneous writes.
Client permission concerns
There is no role/rank system within a group, meaning any member in the group has absolute authority within
the group (there is no defined leader).
Bluntly, what this means is that unless you disable the Client Shared Group Data methods with our API Access
Policy, the clients will have complete control of the data, which could result in exploitation of the data.
Best practice is to either not use Shared Group Data for gameplay-impacting data, or to disable the Shared
Group Data methods in the Client API.
Leaderboards
5/24/2022 • 2 minutes to read • Edit Online
Using event or tournament leaderboards are great ways of increasing engagement within your game. Using
PlayFab, you can easily set up a recurring tournament that awards prizes to the winners, reaches out to the
participants, and gets your players coming back into your game to try and get the highest score.
Tournaments
Designing your tournament
When creating your tournament it is important to design your game play with the following four items in mind:
1. How are you going to adver tise the tournament to your players?
Look to use Engagement features to promote the tournament to players - both before it begins and while
the competition is on.
2. What are you tr ying to get your players to do?
Make sure you have a game play that is engaging, and brings your players back. Are they trying to clear
the most levels, beat the most monsters or get the highest score? Depending on your engagement goals,
you will identify the statistic that drives the tournament. Your game will send the statistic updates to
PlayFab, and you can use the leaderboards to always show your players where they stand.
3. What ends your tournament?
Is your tournament an ongoing daily or weekly event? If so, you can configure your leaderboard to reset
automatically. If not, you will need to define what ends your tournament -- and trigger the resetting of the
statistic manually.
4. How are you going to reward your players?
When the tournament ends use prize tables to grant your players awards, in game currency and bragging
rights. Remember to notify your players of all of the great rewards they have won (and bring them back
into your game)!
Tournaments and leaderboards quickstart
5/24/2022 • 2 minutes to read • Edit Online
This quickstart describes how to have a statistic that keeps track of the players high score, and how to get a
leaderboard of the top high scores. This can be utilized for a global leaderboard, or in conjunction with
resettable statistics to reset for a specific event or tournament.
Prerequisites
Your player is already logged into PlayFab.
Step 2 - Update the statistic with the high score for a player
Before we can use UpdatePlayerStatistics from the client, we must enable it in API Features .
1. Select Title settings off the Settings menu for your title.
2. Select the API Features tab.
3. Check the box for Allow client to post player statistics . NOTE: In general, this option should not be used
in a live game, as it gives the client authority over values submitted. This is only valid for cases where there is
no concern that players may cheat their statistics. If statistics need to be secure, they should only be updated
via a server authoritative operation, such as a Cloud Script or custom game server.
4. Click the SAVE button at the bottom of the screen.
C# code example - SubmitScore
In this code example we will have a SubmitScore function that would be called at the end of a game.
The tutorials in this section walk you through topics involving tournaments and leaderboards.
Accessing Archived Tournament Results
Friends leaderboards
Using Prize Tables
Using resettable statistics and leaderboards
Using the Profile for Advanced Leaderboards
Accessing archived tournament results
5/24/2022 • 4 minutes to read • Edit Online
This tutorial illustrates how you can access archived leaderboard states.
Each leaderboard can be reset manually or automatically - meaning statistic values will be removed for all the
players, leading to a clear state, and the leaderboard version will be implemented.
Before that happens, however, PlayFab creates a snapshot of all the leaderboard statistic values for each player.
This allows you to access this archived version of the leaderboard.
NOTE
All titles allow you to access the most recently archived version of a leaderboard, and this gives you the current and most
previous versions. For example, if your current leaderboard version is 3 , you may access only version 3 and archived
version 2 .
Initial setup
Before using this guide, please make sure that you have some players already registered for the title. The
following screenshot shows 5 players artificially registered using the LoginWithCustomID API call.
You will end up on the new Leaderboards page which will render blank data (see below).
Our next step is simulating some data for our leaderboard. The quickest way to do this is to create a CloudScript
handler, which will set random statistics for a given player. We will invoke this handler for every player over the
All Players segment.
As a result, each player will get a random statistic value, which is a good enough approximation of a real world
scenario.
Let's start with defining our CloudScript (refer to the code comments for further information).
Next, we need to define a task to execute our CloudScript over a specific segment:
1. Navigate to the Players tab.
2. Then, navigate to the Segments sub-tab.
By default, PlayFab generates an All Players segment for you. This segment is specifically useful when you
need all players registered in your title (which is exactly our case).
3. Select the All Players Segment .
4. Finally, select Run Task ....
NOTE
If you have no All Players segment in the list, please, refer to our Player Segmentation quickstart to create one.
This will create a snapshot of all the data we currently have, and then it will nullify statistic values on every
player and increment the version.
Once your leaderboard is reset, run the CloudScript task again.
Repeat this 2-3 times, then reset and repopulate.
You will end up with several Leaderboard versions (1) :
Current version data will be displayed in the table to the left (3) .
Archived data will be available for previous versions (2) .
Only the latest version will be available. This applies to all titles.
Accessing archived data using Game Manager
You can access archived results directly from the Leaderboard page:
1. Navigate to the Leaderboards tab.
2. Select the Leaderboard you need.
1. If your Leaderboard contains archived revisions, you will be able to download JSON data using the
download link shown in the screenshot below.
Accessing archived data using API
The following code allows you to pull the latest (current) version of the leaderboard.
PlayFabClientAPI.GetLeaderboard(new GetLeaderboardRequest()
{
StatisticName = "TestScore",
}, result =>
{
Debug.Log("Leaderboard version: "+result.Version);
foreach (var entry in result.Leaderboard)
{
Debug.Log(entry.PlayFabId+" "+entry.StatValue);
}
}, FailureCallback);
Alternatively, you may specify a version of the leaderboard you want to load.
PlayFabClientAPI.GetLeaderboard(new GetLeaderboardRequest()
{
StatisticName = "TestScore",
Version = 1
}, result =>
{
Debug.Log("Leaderboard version: "+result.Version);
All titles allow you to access the latest archived version of the leaderboard. Trying to pull an older version will
result in an error (see below).
This tutorial walks you through how to create a prize table that triggers a set of actions on a group of players
within a range of ranks, in a Resettable Leaderboard.
In particular, this is a way to trigger emails, send push notifications, grant Inventory Items and Virtual Currency,
or execute a CloudScript function at the reset of a leaderboard.
In this example, we show you how to create prize table end tournament prizes, which grants virtual currency to
5 players based on their rank in a leaderboard after a reset is performed.
Requirements
IMPORTANT
This is an advanced tutorial. Please make sure that all requirements shown below have been met, or you will not be able
to complete this tutorial.
Basic knowledge of how to create a player will be necessary, as there will need to be players in a leaderboard
before it can perform any actions on those players.
It is also worthwhile to read the Game Manager quickstart if you are unfamiliar with the Game Manager, as it
is the place where prize tables are created.
In order to use Prize Tables, you must have general knowledge of how resettable leaderboards work. Please
read about leaderboards in our tutorial Using Resettable Statistics and Leaderboards.
Additionally, virtual currencies must be set up. Please read our tutorial about Currencies and set up two
currencies with the following parameters:
Currency code : GO
Display name : Gold
Initial deposit : 200
Currency code : SI
Display name : Silver
Initial deposit : 1000
This tutorial provides a complete walkthrough of how to configure and manage statistics with versioning -
which enables resetting of statistics - and by extension, leaderboards.
We'll focus on how to use the Admin API methods, with additional info on how to use the client and Server API
methods to query the data - both for the current version as well as old ones.
Our goal is to provide you with a technical review of how re-settable statistics work in PlayFab, and all the ways
they can be used in your games.
NOTE
Resetting statistics does not delete those values, as you will see below. On reset, statistics in PlayFab are versioned,
making the new version authoritative, while keeping previous versions for later analysis (and so that you can reward
players based on their old scores).
The VersionChangeInterval is the key to this feature, and it can be defined as hourly, daily, weekly, or monthly. It
can also be set to never, if you decide later that you no longer want the statistic to reset on a regular basis.
In the example that follows, the call to the CreatePlayerStatisticDefinition method sets up the statistic
Headshots with a daily reset, meaning that the leaderboard for this statistic in the game will reset every day at
00:00 UTC.
The following shows the response for the preceding API call.
{
"code": 200,
"status": "OK",
"data":
{
"Statistic":
{
"StatisticName": "Headshots",
"CurrentVersion": 0,
"VersionChangeInterval": "Day"
}
}
}
The call demonstrates setting the reset period for the statistic to weekly, with the following response.
{
"code": 200,
"status": "OK",
"data":
{
"Statistic":
{
"StatisticName": "Headshots",
"CurrentVersion": 0,
"VersionChangeInterval": "Week"
}
}
}
The reset periods take effect as soon as they are defined, so in this case, the second call means that the reset is
now defined as 00:00 UTC, Monday morning (midnight on Sunday night/Monday morning, using the UTC
timezone), regardless of what it was before the call.
The remaining reset intervals are also defined using UTC, with Month making the reset occur at 00:00 UTC on
the first day of each month.
For the completed list, the reset periods are:
Never : Stop versioning the statistic on a time-based basis.
Hour : Version the statistic at the top of every Hour (XX:00 UTC).
Day : Version the statistic at midnight (00:00 UTC) every Day .
Week : Version the statistic at midnight (00:00 UTC) every Monday.
Month : Version the statistic at midnight (00:00 UTC) on the first day of every Month.
Preexisting Statistics
All statistics defined in the game can be queried for their definition, regardless of whether they were set up as
resetting statistics or not.
This is important to note, since statistics can be created using the UpdatePlayerStatistics call. Any statistics not
created with a reset period ( VersionChangeInterval ) will not have one to start, and so a query for the statistic
configuration would return with this parameter set to Never .
Using the example above, if the title also had a statistics named FlagsCaptured created using
UpdatePlayerStatistics (or created in the Game Manager directly on a player), and a couple of weeks had passed,
it would appear as shown in the call shown below.
{
"code": 200,
"status": "OK",
"data":
{
"Statistics": [
{
"StatisticName": "Headshots",
"CurrentVersion": 2,
"VersionChangeInterval": "Week"
},
{
"StatisticName": "FlagsCaptured",
"CurrentVersion": 0,
"VersionChangeInterval": “Never”
}]
}
}
In this case, the statistics named Headshots has a reset interval defined, and CurrentVersion indicates that the
statistics has been reset twice.
Meanwhile, FlagsCaptured does not have a VersionChangeInterval , which is also why the CurrentVersion is 0
(since it has never been versioned).
Statistics created via UpdatePlayerStatistics (or the PlayFab Game Manager), can still be defined to have a reset
period using UpdatePlayerStatisticDefinition , as described above.
Once this has been done, they will reset on that interval exactly as if they were originally defined using
CreatePlayerStatisticDefinition .
This increments the Headshots statistic once more, returning information on the version which has just been
made active.
{
"code": 200,
"status": "OK",
"data":
{
"StatisticVersion":
{
"StatisticName": "Headshots",
"Version": 3,
"ActivationTime": "2016-02-03T08:02:29.864Z",
"ArchivalStatus": "NotScheduled"
}
}
}
In this case, the PlayerStatisticVersion information is returned, containing the ID of the statistic (
StatisticName ), as well as its version number, the time when it became the authoritative version (
ActivationTime ), and the ArchivalStatus (which will always be NotScheduled for the current version).
However, for a statistic which also has a VersionChangeInterval , manually resetting will not change the next
scheduled reset time. If a statistic is scheduled to reset on a daily basis - and it is manually reset at 11:30 PM UTC
- it will still reset again at midnight UTC.
When the reset occurs
As stated, when the reset interval occurs, the statistic will be versioned, so that a new version is immediately
available, while the old version of that statistic is archived for later retrieval.
Once the reset interval occurs (or a manual reset is performed), and the statistic is versioned, writes to the old
version will be accepted for up to ten minutes. Beyond that point, the statistic is locked, preventing future
updates.
Once expired, statistics start into the archive process, so that they can be retrieved by the title later.
The stages of the archival process for a statistic are:
NotScheduled - Archiving of the statistic has not started (normally only for the currently active statistic
version).
Scheduled - The archive process has been scheduled, but is not underway yet.
InProgress - The statistic is being backed up to the archive.
Failed - An unexpected failure occurred (in this case, contact our Support Forums).
Complete - This version of the statistic has been archived.
All of the past and current versions of a statistic can be queried using GetPlayerStatisticVersions . This returns
the information for each version, as shown in the previous manual reset example.
In other words, this call should appear like the one presented below.
This could result in the following information being returned for our example title.
{
"code": 200,
"status": "OK",
"data":
{
"StatisticVersions": [
{
"StatisticName": "Headshots",
"Version": 0,
"ActivationTime": "2015-01-20T05:47:27.17Z",
"DeactivationTime": "2016-01-25T00:00:00.000Z",
"ArchivalStatus": "Complete",
"ArchiveDownloadUrl": {{URL}}
},
{
"StatisticName": "Headshots",
"Version": 1,
"ActivationTime": "2016-01-25T00:00:00.000Z",
"DeactivationTime": "2016-02-01T00:00:00.000Z",
"ArchivalStatus": "Complete",
"ArchiveDownloadUrl": {{URL}}
},
{
"StatisticName": "Headshots",
"Version": 2,
"ActivationTime": "2016-02-01T00:00:00.000Z",
"DeactivationTime": "2016-02-03T08:02:29.864Z",
"ArchivalStatus": "InProgress"
},
{
"StatisticName": "Headshots",
"Version": 3,
"ActivationTime": "2016-02-03T08:02:29.864Z",
"ArchivalStatus": "NotScheduled"
}]
}
}
In addition to the values returned from IncrementPlayerStatisticVersion , the response also includes the
timestamps for when each version was expired ( DeactivationTime ) for versions prior to the current active one,
and a URL for downloading the CSV containing the complete record of the old leaderboard, once the archive
process has completed ( ArchiveDownloadUrl ).
Reading and writing to statistic versions
Finally, from the server and client API side of the story, the calls are very similar to what you know from original
PlayFab user and character statistics calls.
The difference is that now, the version is part of either the request or the response.
When retrieving statistics, the value for the current statistic version - as well as the version number itself - is
returned.
The following examples show making the call for the Headshots statistic, as well as the returned data.
Server Request
Server response
{
"code": 200,
"status": "OK",
"data":
{
"PlayFabId": {{PlayFabId}},
"Statistics": [
{
"StatisticName": "Headshots",
"Value": 10,
"Version": "3"
}]
}
}
Client request
Client response
{
"code": 200,
"status": "OK",
"data": {
"Statistics": [
{
"StatisticName": "Headshots",
"Value": 10,
"Version": "3"
}]
}
}
Meanwhile, the Update call takes an optional version, to allow the title to control which version is being
updated, for cases where the version may have incremented during game play.
NOTE
In this example, if the title were to write to the previous version while it is still possible, it would be writing to Version 2, as
shown below.
Server request
Server response
{
"code": 200,
"status": "OK",
"data": {}
}
Client request
Client response
{
"code": 200,
"status": "OK",
"data": {}
}
But remember - while the expired version can be written to for up to 10 minutes, any attempt to write to that
version beyond that time will fail, with a response like the one shown below.
{
"code": 400,
"status": "BadRequest",
"error": "StatisticVersionClosedForWrites",
"errorCode": 1197,
"errorMessage": "The statistic version is not current and is no longer accepting updates"
}
Resources
For completeness, this section provides a list of all the enums, classes, and API methods described above, with
brief descriptions.
Base enums
Inter val - period at which rate the statistic (leaderboard) will be reset:
Never
Hour
Day
Week
Month
StatisticVersionArchivalStatus - the status of the process of saving the player statistic values of a
version to a downloadable archive:
NotScheduled
Scheduled
InProgress
Failed
Complete
Base classes and their members
PlayerStatisticDefinition
StatisticName (string) - The unique name of the statistic.
CurrentVersion (string) - The current active version of the statistic, incremented each time the
statistic resets.
VersionChangeInter val (Interval) - The interval at which the values of the statistic for all players are
reset.
PlayerStatisticVersion
StatisticName (string) - The name of the statistic when the version became active.
Version (string) - The version of the statistic (a hexadecimal number encoded as a string).
ScheduledVersionChangeInter valTime (DateTime) - The time at which the statistic version was
scheduled to become active, based on the configured ResetInter val .
CreatedTime (DateTime) - The time when the statistic version became active.
ArchivalStatus (StatisticVersionArchivalStatus ) - The status of the process of saving player
statistic values of this version to a downloadable archive, if configured.
ResetInter val (Interval) - The reset interval that triggered the version to become active, if configured.
StatisticValue
StatisticName (string) - The unique name of the statistic.
Value (Int32) - The statistic value for the player.
Version (string) - For an existing statistic value for a player, the version of the statistic when it was
loaded.
StatisticUpdate
StatisticName (string) - The unique name of the statistic.
Version (string) - For updates to a statistic value for a player, the version of the statistic to be updated
Value (Int32) - The statistic value for the player.
Admin API methods
CreatePlayerStatisticDefinition
CreatePlayerStatisticDefinitionRequest
Name (string) - min length 1, max length 128 - The unique name of the statistic.
(VersionChangeInter val ) (Interval) - The interval at which the values of the statistic for all
players are reset (resets begin at the next interval boundary).
CreatePlayerStatisticDefinitionResult
Statistic (PlayerStatisticDefinition ) - The created statistic's definition.
UpdatePlayerStatisticDefinition
UpdatePlayerStatisticDefinitionRequest
StatisticName (string) - The unique name of the statistic.
VersionChangeInter val (Interval) - The interval at which the values of the statistic for all
players are reset (resets begin at the next interval boundary).
UpdatePlayerStatisticDefinitionResult
Statistic (PlayerStatisticDefinition ) - The created statistic's definition.
GetPlayerStatisticDefinitions
GetPlayerStatisticDefinitionsRequest (no parameters).
GetPlayerStatisticDefinitionsResult
Statistics (PlayerStatisticDefinition[] ) - The array of definitions for the resetting.
GetPlayerStatisticVersions
GetPlayerStatisticVersionsRequest
StatisticName (string) - The unique name of the statistic.
GetPlayerStatisticVersionsResult
StatisticVersions (PlayerStatisticVersion[] ) - The version change history of the statistic (all
the versions).
IncrementPlayerStatisticVersion
IncrementPlayerStatisticVersionRequest
StatisticName (string) - The unique name of the statistic.
IncrementPlayerStatisticVersionResult
StatisticVersion (PlayerStatisticVersion ) - The statistic version which was expired as a
result of this operation (and its archival status).
Client API methods
GetPlayerStatistics
GetPlayerStatisticsRequest
StatisticNames (string[]) - Array of statistic to be returned, by their unique names.
GetPlayerStatisticsResult
Statistics (StatisticValue[] ) - Array of StatisticValue data for all the statistic requested.
UpdatePlayerStatistics
UpdatePlayerStatisticsRequest
Statistics (StatisticUpdate[] ) - The statistic to be updated, with the provided values.
UpdatePlayerStatisticsResult (no parameters).
Server API methods
GetPlayerStatistics
GetPlayerStatisticsRequest
PlayFabId (string) - The PlayFab ID of the player whose statistics are being updated.
StatisticNames (string[]) - Array of statistics to be returned, by their unique names.
GetPlayerStatisticsResult
Statistics (StatisticValue[] ) - Array of StatisticValue data for all the statistic requested.
UpdatePlayerStatistics
UpdatePlayerStatisticsRequest
PlayFabId (string) - The PlayFab ID of the player whose statistics are being updated.
Statistics (StatisticUpdate[] ) - The statistic to be updated, with the provided values.
UpdatePlayerStatisticsResult (no parameters).
Using the profile for advanced leaderboards
5/24/2022 • 2 minutes to read • Edit Online
With PlayFab, you usually construct leaderboards using the following API methods:
GetFriendLeaderboard
GetFriendLeaderboardAroundPlayer
GetLeaderboard
GetLeaderboardAroundPlayer
The result is a list of PlayerLeaderboardEntr y objects that contain only basic information about the player,
and their relation to the current leaderboard.
However, PlayFab also allows you to use PlayerProfileViewConstraints , to gain additional information about
each player.
NOTE
This example assumes you already have some leaderboard data to play with. Please refer to our Accessing Archived
Tournament Results tutorial, for a method to generate some test data.
if (result.Error != null)
{
// Handle error if any
Console.WriteLine(result.Error.GenerateErrorReport());
}
else
{
// Traverse the leaderboard list
foreach (var entry in result.Result.Leaderboard)
{
// Print regular leaderboard entry information
Console.WriteLine($"{entry.Position + 1} {entry.PlayFabId} {entry.StatValue}");
// Additionally print display name and avatar url that comes from player profile
Console.WriteLine($" {entry.Profile.DisplayName} | {entry.Profile.AvatarUrl}");
}
}
}
NOTE
The individual Profile fields are only available if the client explicitly asks for them using Profile Constraints. Also be aware
that if certain profile constraint are not allowed in the Game Manager - and your client requests them - the API call will
fail with a corresponding error. The result will look similar to the example provided below.
Using this technique, you can fetch a handful of Profile information, including other statistic values.
Friends leaderboards
5/24/2022 • 2 minutes to read • Edit Online
Friends-specific APIs mirror the standard GetLeaderboard and GetLeaderboardAroundPlayer API calls, but
restrict the player pool to the player's friends list.
NOTE
The GetFriendLeaderboardAroundPlayer API does not base the center of the leaderboard around the currently logged in
player - it can be any PlayFab ID supplied with the request. You can use this to allow players to look up any friend's
location on the leaderboard, regardless of their distance from each other.
Trading
5/24/2022 • 2 minutes to read • Edit Online
The PlayFab client API allows players to trade items with one another. These API methods are enabled by default,
so for the security of your title you may need to use our policy API to disable them.
NOTE
Inventory-trading functionality is in a preview phase. The methods are functional, but lack some useful elements that
would make it a complete feature. Currently you can only trade virtual items. You cannot request or trade virtual currency,
and PlayFab does not provide a list of trades that are available to you from other players. Trade methods are only
available in the client API, and not available from the server API.
Key concepts
Catalog - Catalogs offer an easy way to manage your game's virtual items. They are listings of every item that
is available in your game.
Catalog Items – PlayFab Items can represent just about any type of virtual goods that you might use - from
durables, to bundles to locked containers.
Inventor y - All accounts (player accounts and character accounts) have an inventory. The inventory contains all
owned item instances, as well as item history.
Vir tual Currency - PlayFab offers up to 10 virtual currencies per title. Currencies can be used to purchase
items from a catalog or store, can represent soft currency converted from in-app purchases, or they can be used
as a mechanic to drive gameplay.
Prerequisites
Trading requires familiarity with both catalog and inventory items. Players must own inventory items they wish
to trade.
APIs
Trading flow is handled by a handful of APIs:
OpenTrade
Opens a new outstanding trade. This can between two specific players (PlayfabIDs) or with one player opening a
trade open to anyone. Understand that any single given item instance may only be in one open trade at a time.
GetTradeStatus
Allows a client to evaluate a given trade by getting its current status.
AcceptTrade
Accepts an open trade. If the call is successful, the offered and accepted items will be swapped between the two
players' inventories.
CancelTrade
Cancels an open trade. Note that only the player who created the trade can cancel it via this API call, to prevent
grief.
GetPlayerTrades
GetPlayerTrades will return all trades a player has either opened or accepted, optionally filtered by trade
status.
Trading quickstart
5/24/2022 • 2 minutes to read • Edit Online
NOTE
This quickstart assumes you are already familiar with both catalogs and inventory items. The example player must already
own the inventory items they wish to trade away.
The first step is to call the OpenTrade API, to make a trade available to another player. You will need a playfabId
to identify the gift recipient, and the ItemInstanceID for the player who currently has the item in their Inventory.
secondPlayerId : This is the unique string that identifies the gift recipient ( PlayFabId ).
myItemInstanceId : This is the unique string that identifies an item instance owned by the current player (
InstanceID ).
NOTE
All trades are public information. Any player may look at the open trades of another player, as well as another player's
trade history (If they know the playFabId of that player).
In this snip the LogSuccesscallback must also evaluate result.Trade.TradeId , and transfer both
firstPlayFabId and the tradeId to the second player. If not saved, it will not be possible for the second player
to evaluate or accept the trade.
NOTE
In the current preview you need to ensure that your trades are thread-safe from concurrent actions. Thread-safe options
include custom game servers and Webhook calls via CloudScript to an external database/system. Thread-Unsafe options
can be built with CloudScript which directly modifies a Player Data Key. The latter option has concurrency issues where
simultaneous trade-list-updates may not process correctly.
Once the first player has created the trade, and transferred their playFabId and the tradeId to the second
player, the second player can examine the trade requirements (verifying it is a gift) by making a GetTradeStatus
request.
NOTE
The most relevant TradeStatus values are Open , Filled , and Canceled . All other states are intermediate states. Trades
may stay in those intermediate states for a noticeable period of time between calls. A recently-modified trade may not be
available immediately.
If the requirements of that trade are acceptable, the gift can be accepted using AcceptTrade
C# snip
void AcceptGiftFrom(string firstPlayFabId, string tradeId) {
PlayFabClientAPI.AcceptTrade(new AcceptTradeRequest {
OfferingPlayerId = firstPlayFabId,
TradeId = tradeId
}, LogSuccess, LogFailure);
}
Once complete, the AcceptGiftFrom function above will transfer the gifted items from the first player's inventory
to the second.
Introduction to Leaderboards v2
5/24/2022 • 2 minutes to read • Edit Online
IMPORTANT
This feature is currently in Private Preview .
This documentation is provided to give you an early look at an upcoming feature and to allow you to provide feedback
while it is still in development.
Access to this feature is restricted to select titles that PlayFab actively reaches out to.
Overview
Leaderboards are such a significant part of game development that we are constantly iterating on customer
feedback. To cater to new customer needs, we are currently developing a second version of Leaderboards APIs
that would allow many more functionalities that our current Leaderboards APIs don't. Aligned with the new
PlayFab entity model, the new APIs sit on top of entity statistics and is backed by Azure.
Classic Leaderboards Vs. Leaderboards v2
You can now rank other entity types, in addition to Players that v1 supported.
V2 added the feature of child leaderboards, which allows categorization of leaderboards within the title.
You can now dynamically add leaderboards on the go
You can now delete leaderboards
V2 is based on PlayFab's new entity model
Updated UX design to support the new features
Leaderboards Vs. Statistics
Leaderboards are a type, or a subset of Statistics. In other words, it is possible for a Statistic to not be a
Leaderboard, but all Leaderboards have to be Statistics. When a Statistic is not a Leaderboard, it just contains a
list of unranked entries of entities (e.g. players) and values (e.g. scores).
Leaderboards v2 QuickStart
5/24/2022 • 2 minutes to read • Edit Online
IMPORTANT
This feature is currently in Private Preview .
This documentation is provided to give you an early look at an upcoming feature and to allow you to provide feedback
while it is still in development.
Access to this feature is restricted to select titles that PlayFab actively reaches out to.
}
Sample Response
HTTP/1.1 200 OK
Content-Type: application/json; charset=utf-8
Leaderboards v2 tutorials
5/24/2022 • 2 minutes to read • Edit Online
Getting Started
Child Leaderboards
Getting Started Tutorial
5/24/2022 • 3 minutes to read • Edit Online
IMPORTANT
This feature is currently in Private Preview .
This documentation is provided to give you an early look at an upcoming feature and to allow you to provide feedback
while it is still in development.
Access to this feature is restricted to select titles that PlayFab actively reaches out to.
Viewing Statistics
You can call GetLeaderboard to pull the current data on your leaderboard:
ArrayList<PlayFabLeaderboardsModels.EntityLeaderboardEntry> rankings
= PlayFabLeaderboardsAPI.GetLeaderboard(getEntityLeaderboardRequest).Result.Rankings;
You can also call GetStatisticDefinition to see how your leaderboard was configured:
//Now you can do something with the response, or just simply printing them out for testing purposes:
System.out.println("Name: "+ response.Name);
System.out.println("AggregationMethod: "+ response.AggregationMethod);
System.out.println("Created: "+ response.Created);
System.out.println("LastResetTime: "+ response.LastResetTime);
System.out.println("ChildLeaderboardNames: "+ response.LeaderboardDefinition.ChildLeaderboardNames);
}
You can also see a list of all your leaderboard definitions by calling GetStatisticDefinitions :
private static void getAllDefs() {
PlayFabLeaderboardsModels.GetStatisticDefinitionsRequest getStatisticDefinitionsRequest = new
PlayFabLeaderboardsModels.GetStatisticDefinitionsRequest();
ArrayList<PlayFabLeaderboardsModels.StatisticDefinition> results =
PlayFabLeaderboardsAPI.GetStatisticDefinitions(getStatisticDefinitionsRequest).Result.StatisticDefinitions;
results.forEach(result -> System.out.println(result.Name));
}
GetLeaderboardAroundEntity lets you see entities ranked near a certain position on a leaderboard, namely, a
snapshot of a part of the leaderboard.
ArrayList<PlayFabLeaderboardsModels.EntityLeaderboardEntry> rankings =
PlayFabLeaderboardsAPI.GetLeaderboardAroundEntity(req).Result.Rankings;
Finally, it's useful sometimes to immediately see the ranks of select players on a leaderboard to gauge their
relative performance. The GetLeaderboardForEntities call accomplishes just that:
ArrayList<PlayFabLeaderboardsModels.EntityLeaderboardEntry> rankings
=
PlayFabLeaderboardsAPI.GetLeaderboardForEntities(getLeaderboardForEntitiesRequest).Result.Rankings;
//do something about the result rankings, for example:
rankings.forEach(ranking -> System.out.println(ranking.Rank + " " + ranking.Score));
Deleting Statistics
Deleting statistics is a new feature in v2. You can delete an entire leaderboard as follows:
private static void deleteLeaderboard() {
PlayFabLeaderboardsModels.DeleteStatisticDefinitionRequest deleteStatisticDefinitionRequest = new
PlayFabLeaderboardsModels.DeleteStatisticDefinitionRequest();
Alternatively, you could delete a bunch of individual statistics for a single entity at once:
Leaderboard Versions
Say your game has a weekly tournament that produces new rankings of players, it is important to keep track of
the Version your leaderboard as it updates weekly. You can call IncrementStatisticVersion to increment the
version number (starts with 0) of your leaderboard.
// If needed, you can get the current version number from the response
System.out.println("Version: " +response.Result.Version);
System.out.println("Deleted Version: " +response.Result.VersionToBeDeleted);
}
Keep in mind that you can't increment the version too frequently (less than 5 minutes) because it defeats the
purpose of having a leaderboard that everyone can see and engage with.
Child Leaderboard Tutorial
5/24/2022 • 2 minutes to read • Edit Online
IMPORTANT
This feature is currently in Private Preview .
This documentation is provided to give you an early look at an upcoming feature and to allow you to provide feedback
while it is still in development.
Access to this feature is restricted to select titles that PlayFab actively reaches out to.
Child Leaderboards
Child Leaderboards are a new concept in v2. Now a Statistic can contain "children", or leaderboards that belong
to the same category. Adopting Child Leaderboards helps better organize leaderboards.
An example to help understand this concept is to imagine an array of game streaming rooms. Each room has a
list of viewers, who perform some actions to obtain a score. If the goal is to rank the viewers in each room, we
can create a Statistic that contains a child leaderboard for each room.
When you are creating a new Leaderboard, you can specify whether you want child leaderboards. If so, you need
to specify whether you want them to be Fixed or Dynamic:
Fixed Child Leaderboards
If you choose "Fixed", you can add up to 10 child leaderboards. Note that you won't be able to add more once
the parent Statistic is created. Although the maximum number of fixed child leaderboards is 10, you are allowed
to have very large child leaderboards under this option. You can visualize the parent leaderboard under this
option as fairly deep.
Dynamic Child Leaderboards
If you choose "Dynamic", you will need to specify the maximum size of your individual child leaderboards. You
can rank at most 100 items on each child leaderboard. Note that this size limit is maximum size of each
individual child leaderboard, not the total number of child leaderboards that you are allowed to have.
You can add child leaderboards "on-the-go" after you create your parant Statistic. While you are limited to
having a small number of rankings on each child leaderboard, you are allowed to have a lot of child
leaderboards in parallel. You can visualize the parent leaderboard under this option as fairly wide.
Economy
5/24/2022 • 3 minutes to read • Edit Online
Making your economy work is one of the biggest challenges in games. You need to balance between what can
be earned in game and what can be purchased, while supporting both highly engaged players and those with
light engagements. You want to support different store placements and sales events based on player segments.
NOTE
You can learn more about the preview User Generated Content (UGC) service in the User Generated Content
documentation
Key concepts
Catalog - Catalogs offer an easy way to manage your game's virtual items. They are listings of every item
that is available in your game.
Catalog Items – PlayFab Items can represent just about any type of virtual good that you might use, from
Durables, to Bundles to Locked containers.
Inventor y - All accounts (player accounts and character accounts) have an inventory. The inventory contains
all owned Item Instances as well as item history.
Segments - Provides subsets of players grouped by their event history. For example, the "Frequent Players"
segment is comprised of players that have logged in more than 100 times.
Stores - Stores serve a subset of Catalog Items; these items can be offered at alternative prices when
compared to those set on the corresponding Catalog Items.
Vir tual Currency - PlayFab offers up to 10 virtual currencies per title. Currencies can be used to purchase
Items from the Catalog or a Store, can represent soft currency converted from In App Purchases, or can be
used as a mechanic to drive gameplay.
PlayFab helps you build out your economy by providing a suite of tools to support game economy best
practices. These include:
Multiple Currencies : Most games support at least two virtual currencies. Many use a “soft” currency
that can be earned in-game through play, and a “hard” currency that can be bought. Having dual
currencies gives you more control over your economy, since you can determine which items can be
bought. See our tutorial on Currencies.
Ser ver-side receipt validation : To prevent fraud and ensure that the money you think you are making
is, in fact, being made. See our Getting Started with In App Purchasing and our Non-Receipt Payment
Processing tutorials.
Gathering Data on your economy : See our Reports section for tutorials on how to measure
Conversion, and create Daily and Monthly top Items and Spender reports.
Bundles : Generally, Bundles generate more revenue per transaction, and players feel they are getting a
great deal. You can use our Catalog to create and sell bundles of virtual goods. See our Catalog tutorial
for more information on how to create and leverage Bundles.
Segmentation : Your players are different, so you don't treat them all the same. With PlayFab you can
design your store to offer different items and bundles to different player segments, promoting different
items as players progress through your game and their play life-cycle. See our Custom Stores for player
segments and Best practices for store segmentation tutorials.
Sales : You may want to run special sales as part of your events, use limited time discounts, or have
limited-time offers for rare items. See our Stores and Sales tutorials for tips on how to manage these.
A/B Testing : Stores are also great opportunities for A/B testing. Try mixing up the order of items in the
store - the same item will sell differently depending on where it is and how it is displayed. See our tutorial
on A/B testing with Stores and Test Buckets.
Coupons : Special coupons that players can give to friends or share via social media can drive sales and
encourage viral growth. PlayFab supports coupons specifically for this sort of scenario: Coupons and
Promotions.
User Generated Content : Empower players to create, upload and search for moderated content. See
our UGC Quickstart for more information on how to begin using PlayFab UGC.
Economy quickstart
5/24/2022 • 3 minutes to read • Edit Online
Making monetization work is one of the biggest challenges in games. PlayFab simplifies this for you, by building
on top of three foundational pieces: Currencies, Items, and Inventory.
In this quickstart, you will:
1. Set up a virtual currency.
2. Create an item.
3. Add an item to a player's inventory.
4. Learn the next steps for customizing your economy.
Now that a currency has been set up, catalog items can be assigned prices corresponding to the virtual currency.
Creating an item
Many games offer the player items for purchase such as a shield, a level-unlock, or a power-up. These items are
specified in a catalog. Before the player can purchase an item from a catalog, you must create the items to
populate it.
To create a catalog with an item:
1. Select Economy on the left side bar and select the Catalogs tab.
2. Choose the NEW CATALOG button and enter main as the Catalog version . An item with the ID of One
is added automatically.
3. Select One and change these fields (as shown in the image below):
Set Item ID to apple .
Set Display name to apple .
Set Description to Perfectly normal apple .
4. At the bottom of the form is the PRICES section, where you define how much an item costs in your
game's virtual currency.
5. Set the apple's price in gold (GD ) to 5 .
6. Select the SAVE ITEM button.
These tutorials demonstrate features that you can use to create and maintain the economy of your game.
Coupons and Promotions
Currencies
Getting a Player's Value-to-Date (VTD)
Getting started with PlayFab, Unity IAP, and Android
Non-Receipt Payment Processing
Coupons and promotions
5/24/2022 • 3 minutes to read • Edit Online
Coupons are string tokens that are generated by you, for your customers use to redeem inventory items in their
game. Combined with bundles or CloudScript, these coupons could be used to trigger almost any functionality
in your game.
Requirements
Familiarity with Catalogs, bundles, and containers.
Familiarity with Game Manager.
Familiarity with Player Inventory.
This opens a window, which lets you generate coupons for any of the items in the section. If you wish to create
coupons for a specific item:
Select Coupons in the Items tab.
Bundle Coupons under Bundles , and Container Coupons under Containers .
The pop-up window is similar to the one we have provided below. (Your list of items will match your title. The
displayed items are described in our Drop Tables tutorial).
65g-d4q5-zph,ahs-aofk-5ip,rqp-pk6c-yuu,58d-64h9-a6q,zxk-jtmi-5a1,oeu-6e4z-365,mfy-euhb-qj3,ru9-r1ux-wzy,shj-
54cm-5oh,719-7hxc-pzz
Finally, the customer can redeem a coupon if you provide a GUI which lets them input the code, which then calls
RedeemCoupon.
// Unity/C#
void UseCoupon(string couponCode)
{
var primaryCatalogName = "TestCatalog-001"; // In your game, this should just be a constant matching
your primary catalog
var request = new RedeemCouponRequest
{
CatalogVersion = primaryCatalogName,
CouponCode = couponCode // This comes from player input, in this case, one of the coupon codes
generated above
};
PlayFabClientAPI.RedeemCoupon(request, LogSuccess, LogFailure);
}
Usage scenarios
Physical rewards at conventions:
Print out your list of coupon codes, and hand them out as swag at conventions.
Out-of-game communication such as forums, Push Notifications and email.
Send your players coupon codes directly, as part of re-acquisition campaigns or other community
outreach.
Tournaments:
Send coupons to the top ranked players when using Resettable Leaderboards.
NOTE
You can also give out inventory items directly in this case, so pick whichever is more relevant to your game.
Best practices
Using the PlayFab inventory, you should keep inventory sizes relatively small - less than 100 items total per
player. A bundle which grants too many items may be throttled or rate-limited.
Currencies
5/24/2022 • 3 minutes to read • Edit Online
This tutorial describes the function of the Currency tab in the Economy section in Game Manager . Use this
tab to configure virtual currencies to use in your game.
Virtual Currencies are the foundation of in-game economies. Players and characters can be granted these
currencies, which they can use to buy or trade items. Items have a cost in either virtual currency or real money.
It's exactly like real life - except it's virtual! Economic regulation in-game is up to you.
Field reference
This section describes each field in the Currency section of the Economy area in Game Manager . The
following are the fields in the New Currency screen (shown below), which you'll use to create and maintain the
virtual currencies that make up your in-game economy.
Currency code and Display name are required fields with no default values. The other fields have a
default value of zero .
Leaving Recharge rate and Recharge maximum set to zero (default) will specify that this currency
amount will not auto-regenerate.
Currency code
Currency code is a required field. It represents the currency, and will be used in the other economy sections.
It must be a two-character code, and the convention is all upper-case (although a two-digit number is also
allowed).
NOTE
RM is reserved for Real Money and cannot be used as a Currency Code.
Display name
Display name is a required field. It represents the name that is attached to the currency that is typically
displayed to the user in your game.
The only restriction is that it must be at least one letter long. Common examples include Gold or Space Bux .
Initial deposit
Initial deposit indicates how much of this virtual currency is given to each player when they first sign-up for a
PlayFab account (which is typically the first time they play your game).
Recharge rate (units per day)
Recharge rate is an optional field. It specifies how much of this virtual currency is granted to each player per
day. Virtual currency that is granted to the player via a recharge rate is granted to them gradually, and is evenly
distributed over a 24 hour period.
Recharge maximum
Recharge maximum is an optional field. It specifies the maximum amount of this virtual currency that can be
granted to each player per day.
Example
To create a virtual currency, use the following steps:
1. Select your Game in Game Manager .
2. Choose Economy .
3. Select Currency .
4. Choose NEW CURRENCY .
5. Set the Currency code . We'll use GD in this example.
6. Set the Display name . We'll use Gold in this example.
7. Set the Initial deposit . We'll use 1000 in this example. This gives new players 1,000 units of this virtual
currency when they begin the game.
8. By leaving the Recharge rate and Recharge maximum at the default value of 0 - we don't give the players
any additional virtual currency every day, so we're done.
9. Select SAVE CURRENCY .
This returns you to the Currencies screen where you will see that your new virtual currency is added.
For any subsequent operations on your currency, such as deleting, renaming, or modifying the recharge values,
select the Code or Display name of your currency to open the Edit Currency screen.
The grayed-out Currency code means your new currency has been saved.
Getting a player's Value-to-Date (VTD)
5/24/2022 • 2 minutes to read • Edit Online
PlayFab tracks the total amount spent by a player in the player profile model, which is retrieved by calling the
GetPlayerProfile API.
Within the PlayerProfileModel , a player's VTD is tracked in two different fields:
1. totalValueToDateInUSD - The sum of the player's purchases made with real-money currencies, converted to
the US dollars (USD ) equivalent and represented as a whole number of cents (1/100 USD).
2. valuesToDate - An array of ValueToDateModel objects that contain the player's lifetime purchase totals,
summed for each real-money currency in which they have made a purchase. The TotalValue field in each
object expresses the total for that currency as a whole number of 1/100 monetary units.
The following JSON, shows these two fields with example values.
{
…
totalValueToDateInUSD: 1700
valuesToDate: [{ "USD", 1200 }, { "EUR", 320 }]
…
}
Segment examples
The following examples show segments created using each of the VTD totals.
1. Create a segment of all players who have purchased more than 15 USD in any currency.
2. Create a segment of all players who have spent more more than 15 USD in any currency or 15 Chinese
Yuan .
Getting started with PlayFab, Unity IAP, and Android
5/24/2022 • 10 minutes to read • Edit Online
This tutorial shows you how to set up In-App Purchasing (IAP) using PlayFab, the Unity + IAP Service, and the
Android Billing API.
Before we start
Setting up IAP may be tedious, especially if you are not quite sure how different services are supposed to
integrate and cooperate.
The following image illustrates how the Android Billing API and PlayFab work together to provide a solid IAP
experience for your client.
Start by setting up your Product IDs and Prices via PlayMarket. Initially, all the products are faceless - they are
just digital entities your player is able to purchase - but they have no meaning to PlayFab players.
To make those entities useful, we need to mirror them in the PlayFab item catalogs. This will turn faceless entities
into bundles, containers, and individual items.
Each will have their own unique face, with:
Titles
Descriptions
Tags
Types
Images
Behaviors
All of these are linked to market products by sharing IDs.
The best way to access real money items available for purchase is to use GetCatalogItems and GetStoreItems.
These are the same API methods that are used by free-currency stores, so the process should be familiar.
The ID of the item is the link between PlayFab and any external IAP system. So we pass the item ID to the IAP
service.
At this point, the purchase process begins. The player interacts with the IAP interface and - if the purchase is
successful - you obtain a receipt.
PlayFab is then able to validate the receipt and register the purchase, granting the PlayFab player the items that
they just bought.
This is a rough idea of how IAP integration works, and the following example shows most of it in action.
Continue the Unity install, and import procedure up to the point where it has imported all the plugins.
1. Verify that the plugins are in place.
2. Then create a new script, called AndroidIAPExample.cs .
AndroidIAPExample.cs will contain the code shown below (please refer to the code comments for further
explanation).
using PlayFab;
using PlayFab.ClientModels;
using PlayFab.Json;
using System;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.Purchasing;
public class AndroidIAPExample : MonoBehaviour, IStoreListener {
// Items list, configurable via inspector
private List<CatalogItem> Catalog;
// We are initialized when StoreController and Extensions are set and we are logged in
public bool IsInitialized {
get {
return m_StoreController != null && Catalog != null;
}
}
if (!IsInitialized) {
return PurchaseProcessingResult.Complete;
}
// Deserialize receipt
var googleReceipt = GooglePurchase.FromJson(e.purchasedProduct.receipt);
return PurchaseProcessingResult.Complete;
}
// The following classes are used to deserialize JSON results provided by IAP Service
// Please, note that JSON fields are case-sensitive and should remain fields to support Unity
Deserialization via JsonUtilities
public class JsonData {
// JSON Fields, ! Case-sensitive
NOTE
Make sure to come up with your own package name to avoid any PlayMarket collisions.
Finally, build the application as usual, and ensure you have an APK safe and sound.
We have no means to test it just yet. We need to configure PlayMarket and PlayFab first, which is described in
the following sections.
NOTE
Setting up the application itself is beyond the scope of this tutorial. We assume you already have an application, and that
is configured to publish at least Alpha releases.
Useful notes:
Getting to that point will require you to have an APK uploaded. Please use the APK we constructed in the
previous section.
When asked to upload the APK, you may upload it as an Alpha or Beta Application to enable the IAP sandbox.
Configuring Content Rating will include questions about how IAP is enabled in the application.
PlayMarket does not allow Publishers to use or test IAP - so please, pick another Google account for testing
purposes, and add it as a tester for your Alpha/Beta build.
Once you have the application build published:
1. Select In-app products from the menu.
If you are asked for a Merchant Account , link or create one.
2. Select the Add New Product button.
PlayMarket requires you to fill in a Title (1) and a Description (2) . However, these are not much use in our
case.
We will grab Data Item data exclusively from the PlayFab service, and only require IDs to match.
1. Scroll further and select the Add a price button.
1. Enter a valid price (notice how price is converted for each country/region independently).
2. Select the Apply button.
1. Finally, scroll back to the top of your screen, and change the status of the item to Active .
While this concludes configuring the app, we need a couple more tweaks. First, let us save the Licensing Key
(this will come in handy for linking PlayFab with PlayMarket.
1. Navigate to Ser vices & APIs in the menu.
2. Then locate and save the Base64 version of the Key .
The next step is enabling IAP testing. While sandbox is automatically enabled for Alpha and Beta builds, we need
to set up accounts that are authorized to test the app:
1. Navigate to Home .
2. Locate and select the Account details in the menu to the left.
3. Locate the License Testing area.
4. Verify that your Test Accounts are in the list.
5. Make sure the License Test Response is set to RESPOND_NORMALLY .
Don't forget to apply the settings!
The Play Market side of the integration should be set up at this point.
NOTE
Keep in mind that this data has nothing to do with the Play Market Item Title and Description - it is totally
independent.
Testing
For testing purposes, download the app using the Alpha/Beta release.
Make sure to use a test account and a real Android device.
Once you start the app, you should see IAP initialized, and one button representing your item.
Select that button.
The IAP purchase will be initiated. Follow the Google Play instruction up to the point where purchase is
successful.
Finally, navigate to your title in the PlayFab Game Manager dashboard and locate New Events .
This means that purchase was successfully provided, validated, and piped to the PlayFab ecosystem.
At this point you have successfully integrated UnityIAP and the Android Billing API into your PlayFab application.
Non-receipt payment processing
5/24/2022 • 14 minutes to read • Edit Online
In addition to receipt validation for a variety of platforms, PlayFab also provides a mechanism for enabling
purchases via payment providers that don’t use a receipt or entitlement-based systems - such as Facebook,
PayPal, Xsolla, and Steam.
This tutorial will walk you through using this cart-style payments system, showing you how to:
Define the set of goods the player wants to purchase.
Process the player with your chosen provider.
Validate that the payment processed successfully, adding the appropriate items to the player’s inventory.
In addition, it will also cover the player provider part of the process, so that you have a complete
overview of how to complete the purchase using PlayFab.
The following image shows a summary of the API calls used in the payment flow.
NOTE
Some providers, like Facebook and Steam, do more than just handle payments, and you’ll find them in the Platforms
section of this tutorial.
Select the Providers you want to use.
Then choose the Install option for each.
Enter the requested information (commonly an application and secret key), but each provider will have their
own unique requirements.
NOTE
This information allows us to communicate with their service on your behalf, so that we can initiate purchases and check
on their status.
Once that has been completed, you’re ready to start implementing the payment flow.
NOTE
The exception to this is Xsolla, which we'll address separately at the end of this tutorial.
In the examples that follow, you’ll see fields like {{TitleID}} and {{SessionTicket}} . You will need to replace
these values in your own code, with the appropriate values for your game, and the player’s authentication ticket.
PlayFabClientAPI.StartPurchase(new StartPurchaseRequest() {
CatalogVersion = "IAP1_0",
Items = new List<ItemPurchaseRequest>() {
new ItemPurchaseRequest() {
ItemId = "BigBagOfGold",
Quantity = 1,
Annotation = "Purchased via in-game store"
}
}
}, result => {
// Handle success
}, error => {
// Handle error
});
In this example, we’re loading up the cart with an item defined in the game catalog with the ID of IAP1_0 -a
BigBagOfGold . This is the ItemId , as defined in the game catalog.
The player wants to purchase only one of it, and the annotation is being used to indicate how the item wound up
in the player inventory, which is useful for later review.
It’s also possible to specify that this purchase is using the pricing from a store you’ve defined in your game, by
including the StoreId parameter, but we’ll leave that out of this example, for simplicity.
The return from the StartPurchase call contains a lot of information - including the DisplayName and
Description values for the items from your catalog, any defined prices for them, plus the player's virtual
currency balances.
But the primary things you’ll need for the next step are the OrderId (which uniquely identifies this purchase),
and the specific provider you want to use, which is in the PaymentOptions .
NOTE
Only Payment Providers you have enabled for your title will appear in the PaymentOptions .
{
"code": 200,
"status": "OK",
"data": {
"OrderId": "1234567890ABCDEF",
"Contents": [{
"ItemId": "BigBagOfGold",
"ItemInstanceId": "ABCDEF1234567890",
"DisplayName": "A hefty sack of gold",
"Description": "Why, it’s a stonking great bag of shiny!",
"VirtualCurrencyPrices": {
"RM": 999
}
}],
"PaymentOptions": [{
"Currency": "RM",
"ProviderName": "Facebook",
"Price": 999,
"StoreCredit": 0
},
{
"Currency": "RM",
"ProviderName": "PayPal",
"Price": 999,
"StoreCredit": 0
},
{
"Currency": "RM",
"ProviderName": "Steam",
"Price": 999,
"StoreCredit": 0
}
],
"VirtualCurrencyBalances": {
"VC": 0
}
}
}
FB.ui({
method: 'pay',
action: 'purchaseitem',
product:
"https://{{TitleId}}.playfabapi.com/OpenGraphProduct/{{TitleId}}/{{StoreId}}/IAP1_0/BigBagOfGold",
request_id: "1234567890ABCDEF"
}, function (response) {
console.log('Payment completed', response);
print(response);
if (response.payment_id) {
facebookPurchaseId = response.payment_id;
payForOrder(); // This is a function call you need to write
// which makes the call to the Client API PayForPurchase
// (see below)
}
});
When making this call, lease remember that the product is case-sensitive in Facebook.
In particular, the TitleId - which you need to replace with the correct title ID for your game in PlayFab - is
usually in lower-case in their service. If you encounter any issues with Facebook not finding the correct product,
try grabbing the product manually using a GET request, as shown on this page.
In addition, you’ll also need to make sure you’re using the values from earlier in the flow:
The CatalogID of the PlayFab-defined catalog containing the item to be purchased ( IAP1_0 ).
The itemID of the item in the game’s PlayFab catalog which is to be purchased ( BigBagOfGold )
The OrderID returned from the call to StartPurchase , at the beginning of this process ( 1234567890ABCDEF
)
On a successful response, Facebook will return a payment_id , which can then be used as the
ProviderTransactionId in the call to the Client API method PayForPurchase .
This completes the loop, connecting PlayFab to the purchase on both sides of the equation, allowing us to query
for its status.
You can read more about the Facebook payment system on the Facebook Developer Portal:
https://developers.facebook.com/docs/payments/overview
An additional aspect of Facebook Payments is that there is a requirement that titles use webhooks for payments,
to enable real time change notifications to payment status.
This is necessary in the Facebook model, as payments can take a very long time to complete in some cases.
Fortunately, this is simple. In your title setup in Facebook, simply enter the following as your Callback URL.
https://{{TitleId}}.playfabapi.com/ThirdPartyPayments/FacebookPaymentUpdate
Where {{TitleId}} is the Title ID for your game in PlayFab (for example,
https://aaa.playfabapi.com/ThirdPartyPayments/FacebookPaymentUpdate).
There’s no need to specify a token in the Facebook setup - just set the Callback URL, confirm that your PlayFab
setup is correct in the Facebook Add-ons page of the Game Manager , and you’re set.
When Facebook uses this webhook to update the status of the payment, the order status will be updated in
PlayFab (and if it was successful), the appropriate items will be added to the player inventory.
NOTE
Security: Be aware that this API is a prompt for PlayFab to call again to Facebook, and securely authenticate and validate
the transaction. It is not a backdoor for a hacker to bypass Facebook payments.
When using Facebook as the payment provider, it is still important for your client to confirm the purchase, as
shown below.
As a result of the PayForPurchase call, PlayFab uses the web methods provided by Steam to initiate the purchase
in that service. This automatically causes the user to be presented with the purchase confirmation dialog via the
Steam client.
So at the same time you’re getting the response to the Client API PayForPurchase call, the user is being asked to
accept the payment.
{
"code": 200,
"status": "OK",
"data": {
"OrderId": "1234567890ABCDEF",
"Status": "Init",
"PurchaseCurrency": "RM",
"PurchasePrice": 999,
"CreditApplied": 0
}
}
Steam uses a callback mechanism to inform the title of completion of the purchase process, so you will need to
register a callback handler for the MicroTxnAuthorizationResponse_t callback.
Registered Steam developers can get further information on this process at this location:
https://partner.steamgames.com/documentation/MicroTxn#WebPurchasing.
Upon receiving the callback, the title should proceed to the ConfirmPurchase call, shown in the Last Step:
Confirm the Purchase section.
PayPal
With PayPal, the PayForPurchase call is practically the same as with Steam.
PlayFabClientAPI.PayForPurchase(new PayForPurchaseRequest() {
OrderId = "1234567890ABCDEF",
ProviderName = "PayPal",
Currency = "RM"
}, result => {
// Handle success
}, error => {
// Handle error
});
However, in this case there is no convenient client application that sends the payment request to the player.
With PayPal, you need to present the player with the PayPal interface, asking them to verify that they agree to
the purchase. Behind the scenes, this process uses PayPal Express Checkouts, though, because we’re taking care
of all the details.
All you need to do is present the user with the Payment Confirmation page, which is returned to you as the
PurchaseConfirmationPageURL .
{
"code": 200,
"status": "OK",
"data": {
"OrderId": "1234567890ABCDEF",
"Status": "Init",
"PurchaseCurrency": "RM",
"PurchasePrice": 999,
"PurchaseConfirmationPageURL": "https://...",
"CreditApplied": 0
}
}
In this case, once the browser window has been dismissed, that should indicate that it is time to move to
confirming the purchase in PlayFab.
PlayFabClientAPI.ConfirmPurchase(new ConfirmPurchaseRequest() {
OrderId = "1234567890ABCDEF"
}, result => {
// Handle success
}, error => {
// Handle error
});
At this point, if the order has been completed successfully, we iterate through the items in the cart that you set
up with the call to the Client API StartPurchase .
This adds the items to the player's inventory and returns the information about the items purchased to the title.
{
"code": 200,
"status": "OK",
"data": {
"OrderId": "1234567890ABCDEF",
"Status": "Succeeded",
"PurchaseDate": "2016-07-19T09:04:28Z",
"Items": [{
"ItemId": "BigBagOfGold",
"ItemInstanceId": "ABCDEF1234567890",
"CatalogVersion": "IAP1_0",
"DisplayName": "A hefty sack of gold",
"UnitCurrency": "RM",
"UnitPrice": 999
}]
}
}
Transaction states
Behind the scenes, there are a number of state changes the order goes through. The complete list is provided
below, though it should be noted that depending on the specific provider process, some of these states will
never show up in the results of any of the three purchase process API calls, and are included here for
completeness.
CreateCar t - While the order object itself is not returned in the response to the Client API StartPurchase
, it has been created at that point. At this stage, the items and prices are stored in the object, but it has not
been submitted to any payment provider.
Init - As shown above, this is the status returned when the order has been submitted to the payment
provider, but has not yet been authorized by the player.
Approved - This occurs briefly, after the player has approved the payment, but before PlayFab has
completed the process of placing the items in the player inventory. It is only included in this list for
completeness, as titles should never see an order with this status.
Succeeded - This indicates that the order has been completed successfully. The player has approved the
payment, and all inventory items have been added to that player's inventory.
FailedByProvider - If for any reason the provider rejects the payment (which includes the player
declining the payment), the order is considered failed by the provider.
DisputePending - The payment provider has notified PlayFab of a dispute on the payment that is
unresolved.
RefundPending - A payment provider has notified PlayFab that a refund request has been issued. At this
stage, the refund has not actually occurred.
Refunded - The order has been refunded. Most (if not all), payment providers also provide this
information directly to the developer. The developer will need to decide how to manage this status, which
can vary depending on a number of factors, such as whether the items are consumable goods (which
may already have been consumed).
RefundFailed - A refund was requested, but was rejected by the payment provider. PlayFab will not be
able to provide any additional information on this - so if more details are needed, the developer should
contact the payment provider directly.
ChargedBack - This status varies by payment provider, and can indicate that an order is in dispute or has
been charged back. Again, for more information on the specifics of the order, the payment provider
should be contacted.
FailedByPlayFab - This status indicates that an unexpected failure occurred in the payment process. On
seeing this status response, the title should retry the previous payment API call. If this status persists, you
are advised to post this issue on our support forums and provide all the details concerning the issue (title
ID, PlayFab ID, order ID).
PlayFabClientAPI.GetPaymentToken(new GetPaymentTokenRequest() {
TokenProvider = "xsolla"
}, result => {
// Handle success
}, error => {
// Handle error
});
The call will return a ProviderToken , which is the Xsolla token you'll need in the next step, and a PlayFab
OrderId . Behind the scenes, this call initiates the transaction with Xsolla.
{
"code": 200,
"status": "OK",
"data": {
"ProviderToken": "1234567890ABCDEF",
"OrderId": "1234567890ABCDEF"
}
}
https://sandbox-secure.xsolla.com/paystation3/?access_token=[TOKEN]
Live payments :
https://secure.xsolla.com/paystation3/?access_token=[TOKEN]
Once you have performed that, you'll complete the purchase in the Xsolla interface.
Again, you'll need to refer to the Xsolla documentation found in the link we provided earlier in this instruction
for any questions on using their interface.
Once that is done, there's no further need for you to take any action. Xsolla and PlayFab will exchange webhook
calls, and PlayFab will fulfill the purchase by putting the purchased items into the player inventory and posting
the appropriate events to PlayStream.
You can check the transaction status (see the full list above) by polling the Client API GetPurchase .
In most cases, this process should not take more than 2-3 seconds to complete.
PlayFabClientAPI.GetPurchase(new GetPurchaseRequest()
{
OrderId = "1234567890ABCDEF"
}, result =>
{
// Handle success
}, error =>
{
// Handle error
});
{
"code": 200,
"status": "OK",
"data": {
"OrderId": "1234567890ABCDEF",
"PaymentProvider": "Xsolla",
"TransactionStatus": "Succeeded",
"PurchaseDate": "2017-06-07T00:00:00Z"
}
}
Final notes
One thing to be aware of is that payments can take a long time to complete with some providers.
If you find that the status of the purchase in the response from a call to the Client API ConfirmPurchase is still
Init , you should wait before re-querying. The best practice here is to store the OrderId at the start of the
process, and then use an exponential back-off when querying for the result.
So if the status is Init, wait one minute before re-trying the call to the Client API ConfirmPurchase , then wait two
minutes, then four, eight, etc., until you hit some max value. Including a check for completed transactions
option would then provide a way for the user to reset that timer.
Finally, it’s worth noting that you can use sandbox mode for testing purchases with some payment providers.
To do so, check the Use sandbox purchase testing option from your Title’s Add-on tab in the PlayFab Game
Manager.
PlayFab items
5/24/2022 • 2 minutes to read • Edit Online
Items and inventories are common mechanisms that you can use to add customization and depth to your game.
Defining and tracking items in PlayFab gives you top-notch analytics and LiveOps support for your in-game
catalog.
Key concepts
Catalog - Catalogs offer an easy way to manage your game's virtual items. They are listings of every item
available in your game.
Catalog Items – PlayFab Items can represent just about any type of virtual goods that you might use, from
Durables to Bundles to Locked containers.
Player Inventor y - All player accounts have an inventory. The inventory contains all of the owned Item
Instances as well as the item history to-date.
Vir tual Currency - PlayFab offers up to 10 virtual currencies per title. Currencies can be used to purchase
Items from the Catalog or a Store, represent soft currency converted from In App Purchases, or be used as a
mechanic to drive gameplay.
PlayFab provides a large interactive playing field for interaction with items and inventory, and the Item definition
in the Catalog allows for quite a bit of customization. However, most common interactions are through just a
few key APIs:
PurchaseItem - Buys a single catalog item with virtual currency, subtracting the currency and adding an Item
Instance into the Player/Character Inventory.
GetCharacterInventory and GetUserInventory – These APIs retrieve the specified Character or the player’s
current Inventory of virtual goods.
Items quickstart
5/24/2022 • 3 minutes to read • Edit Online
The Items quickstart gives you the building blocks of your in-game economics: virtual currency, catalogs, items,
and purchases.
In this quickstart, you will:
Set up a virtual currency for your game.
Give virtual currency to a player.
Add an item to your in-game catalog.
Use PlayFab APIs to purchase an item from the catalog using virtual currency.
Use information in the Game Manager to confirm that the purchase was successful.
TIP
It can be dangerous to give clients the ability to call the AddUserVirtualCurrency API. For information about setting
restrictions on specific APIs, see API access policy.
Now the player has 100 gold. What can they do with it? Buy an item!
TIP
We don't recommend creating multiple catalogs to differentiate types of items. You can filter items more effectively using
classes, tags, and stores.
These tutorials describe the items that are part of the economy of your game.
Catalogs
Drop Tables
Timed Consumables
Catalogs
5/24/2022 • 7 minutes to read • Edit Online
This tutorial describes the Catalogs tab in the Economy section in Game Manager . Catalogs are used to
define items that the player can purchase or that you can award to a player.
What is a catalog?
Many games offer the player items for purchase such as a shield, a level-unlock, or a power-up. These items are
specified in a catalog in units of either virtual currency or real money. Catalogs offer an easy way to manage
your game's virtual items. They are listings of every item available in your game.
However, before a player can purchase an item from a catalog, you must first create the items that you want to
populate it.
PlayFab’s Player Item Management (Server) and Player Item Management (Client) APIs support many strategies
for item purchasing, including the following:
Simple real money or virtual currency purchases of items.
Triggered item grants based on buying another item.
Locked (with a potentially purchasable key) and unlocked boxes.
Random result tables.
Non-purchasable items that are granted based on events within a game.
NOTE
In catalogs, the currency type of RM is reserved for real money , which is in cents USD. $1.99 is represented as RM 199 .
Field reference
This section describes each field in the Catalogs section of the Economy area in Game Manager .
When you first create a title, you have no catalogs. You won't see any fields in the Catalogs section until you
create a catalog by selecting the NEW CATALOG button.
Once a catalog is created, you will see the following tabs in the Catalogs section:
Items - Things that have a value in virtual currency or real money that can be purchased or awarded. See
PlayFab items for more information.
Bundles - Collections of items and virtual currency that unpack into a player's inventory when granted.
Containers - Collections of items and virtual currency that remain as an item in the player's inventory until
opened.
Drop Tables - Collections of items and virtual currency you can use to reward players.
Stores - Stores serve a subset of catalog items. These items can be offered at alternative prices to those set
in the catalog. See PlayFab Stores for more information.
New Catalog fields
When you select NEW CATALOG from the main Catalogs tab, you will see the following page:
The New Catalog page (shown above) contains these fields:
Catalog version A required field. This is the name of your catalog that is shown in the Catalogs tab.
Make primar y catalog Indicates whether this is the primary catalog for your game.
New Catalog Item fields
When you select a Catalog and choose NEW ITEM , you will see the following page:
The New Catalog Item page (shown above) contains these fields:
PROPERTIES
Item ID : This required field is the unique identifier for the item within the Catalog. The item ID
must be unique within the Catalog, but you can have multiple catalog versions containing items
with the same item ID.
Item Class : This optional field is an identifier you can use to help manage your catalog items.
Tags : This optional field contains tags that you can use to organize your catalog items. Like the
field name implies, the tags are comma-delimited text strings.
Item image URI : This optional field allows you to provide a URI to an image of the item.
OPTIONS
Is stackable : Marking an item as Stackable allows only one item of this type in the inventory and
increments the quantity count of the item.
Is tradable : Indicates whether the item is tradeable via the trade API calls.
Is a token for character creation : Indicates whether the item is involved in character creation.
PRICES
Currency : Specifies the currency used for the item's cost. Real money (RM) is always available as
it's built into PlayFab.
Amount : This field is required when a currency is selected. It indicates the units of currency for the
item's cost.
DISPL AYED TO PL AYERS
Display Name : This optional field is the name displayed for the catalog item. One common usage
is when you want to offer the item in your in-game store. Display names do not need to be unique.
Description : This optional field is the description for the catalog Item. One common usage is
when you want to offer the item in your in-game store.
LIMITED EDITION
Is limited edition : Indicates whether there is a limited supply of this item.
CONSUMABLE Indicates whether the item is Durable or Consumable .
CONVERT TO : Allows you to convert the item to a bundle or container when it is saved.
CUSTOM DATA This optional field allows you to enter attributes for the item as Key Value Pairs (KVPs).
Only the key is required for each attribute. The KVPs can be entered as a string in the text box, or if EDIT
AS KEY/VALUE PAIRS is selected, entered in the following fields:
Key : A required field. The index to the Attribute Value .
Value : This optional field is the value of the attribute. If this is not set, the value is null.
New Catalog Bundle fields
When you select a Catalog , open the Bundles tab, and choose NEW BUNDLE , you will open the New
Catalog Bundle page.
This page contains all of the fields in the New Catalog Item page, plus this field:
BUNDLE CONTENTS :
ADD TO BUNDLE Displays a list of all the items, currencies, and drop tables in the catalog and allows
you to select which ones to add to the bundle.
New Catalog Container fields
When you select a Catalog , open the Containers tab, and choose NEW CONTAINER , you will open the New
Catalog Container page.
This page contains all of the fields in the New Catalog Item page, plus this field:
CONTAINER CONTENTS :
ADD TO CONTAINER Displays a list of all the items, currencies, and drop tables in the catalog and
allows you to select which ones to add to the container.
New Drop Table fields
When you select a Catalog , open the Drop tables tab, and choose NEW DROP TABLE , you will see the
following page:
NOTE
For detailed information on creating and using stores in your game, see our Stores quickstart, and Stores tutorials.
Uploading a catalog
To upload a JSON file to create a catalog in Game Manager, perform the following steps:
Select your Game in Game Manager .
Select Economy .
Select Catalogs .
Select UPLOAD JSON .
Select your JSON file and choose UPLOAD FILE .
NOTE
You can also save or upload catalogs as JSON files using the Admin APIs GetCatalogItems and SetCatalogItems.
Drop tables
5/24/2022 • 6 minutes to read • Edit Online
This tutorial shows you the steps for creating drop tables using the PlayFab Game Manager.
Drop tables allow you to randomly generate inventory items, and sequential drop tables can provide some
randomness to player rewards.
Requirements
We assume that you are already familiar with Catalogs, Inventory, and the PlayFab Game Manager.
You must have a primary catalog - which contains standard, non-bundle/non-container items.
You must have defined at least one virtual currency which you will use as a "free" in-game currency.
You may use your own set of items, but our goal is to create an overlapping categorization of items.
As an example, we'll use the following table of items:
A C C ESSO RY A RM O R SW O RD
Once you have set up a similar set of items to work with in your catalog, we're ready to build the drop tables.
NOTE
GetRandomResultTables does not roll random values or award results. The API lets you read the data and parse the
information however you see fit.
Option 1
The result handler will receive the structure information for the drop table that we created, formatted as a
GetRandomResultTablesResult.
Alternately, you can let PlayFab evaluate the table for you, and give you a single item result using the
EvaluateRandomResultTable API. Doing so returns the itemId that can be used to generate a single item, rolled
according to the weights provided.
You can then make a second call which creates the item and gives it to the player.
Option 2
To summarize:
Option 1 - Allows you to load the data once, cache it, and perform the roll yourself on your own game server.
This has lower latency due to fewer calls to PlayFab, and allows you to customize the rolls based on game-
specific logic.
Option 2 - Lets PlayFab do more of the work, but remember - multiple API calls means higher latency.
Conclusion
A drop table generates a single item randomly from a list of potential items and weights. Bundles and containers
can be one of the simplest ways to deliver one or more items to a player using drop tables.
You can manually use a drop table from CloudScript, using one of these Server API methods:
1. GetRandomResultTables
2. EvaluateRandomResultTable
Timed Consumables
5/24/2022 • 5 minutes to read • Edit Online
This tutorial walks you through creating timed consumables using the PlayFab Game Manager. Timed
consumables are items that are configured to auto-consume after a specific time from the initial grant to the
player.
Requirements
We assume that you are already familiar with Catalogs, Inventory, and the PlayFab Game Manager.
You must have a primary catalog.
Display Name Small Stamina Potion This optional field is the name
displayed for the catalog item. One
common usage is when you want to
offer the item in your in-game store.
Display names do not need to be
unique.
Display Name Medium Stamina Potion This optional field is the name
displayed for the catalog item. One
common usage is when you want to
offer the item in your in-game store.
Display names do not need to be
unique.
NOTE
If you do not specify a time group name for a non-stackable timed consumable, each instance will expire independently of
one another. For example, in the scenario above, if I instead left the time group name blank, if I grant one medium
stamina potion to a player at 1:00pm, the item will be consumed at 1:10pm. If I grant another medium stamina potion at
1:05pm, the first item will still be consumed at 1:10pm, and the second item will be consumed at 1:15pm.
Stores are the best way to let players purchase items in your game. You can use the Game Manager to change
the order of items, and adjust prices at any time. Using segments, you can even give special prices to certain
players without touching your game code.
Key concepts
Catalog - Catalogs offer an easy way to manage your game's virtual items. They are listings of every item
that is available in your game.
Catalog Items – PlayFab Items can represent just about any type of virtual good that you might use, from
durables, to bundles to locked containers.
Player Inventor y - All player accounts have an inventory. The inventory contains all of the owned Item
Instances, as well as the item history to-date.
Character Inventor y - Similar to player inventory, except stored at a per-character level.
Vir tual Currency - PlayFab offers up to 10 virtual currencies per title. Currencies can be used to purchase
Items from the Catalog or a Store, represent soft currency converted from In App Purchases, or be used as a
mechanic to drive gameplay.
Segments - Provides subsets of players grouped by their event history. For example, the "Frequent Players"
segment is comprised of players that have logged in more than 100 times.
Stores - Stores serve a subset of Catalog Items. These items can be offered at alternative prices when
compared to those set on the corresponding Catalog Items.
Stores contains an array of references to items defined in your catalog, along with the prices for the item, in both
real world and virtual currencies. Store prices act as an override to any prices defined in the catalog.
In this way, the base definitions of the items may be defined in the catalog, with all associated properties, while
the pricing can be set for each store as needed. This allows for subsets of goods to be defined for different
purposes, and can be used to:
Easily organize your in-game storefront.
Create and organize sales.
Make the Items available for a set time period.
Appropriate certain Catalog Items to specific in-game vendors.
Override the Base Catalog prices for certain player Segments.
Stores are built on top of your game's Virtual Catalogs and Currencies. Think of your primary Catalog as a
definition of all the items in your game, and Stores as an override.
Although you can use the Title Data Management APIs SetStoreItems and UpdateStoreItems to control them
programmatically, Stores are normally set up in Game Manager.
Stores quickstart
5/24/2022 • 4 minutes to read • Edit Online
Stores are the best way to let players purchase items in your game.
As shown in the Items quickstart, PlayFab supports buying items out of a catalog, but that's not how most
games structure their purchases. Whether you're making an idle clicker, an RPG, an FPS, or an endless runner,
you probably have vendors in your game where players can buy weapons, armor, or running shoes.
Our solution for this is Stores, a subset of your catalog with prices you can override.
In this stores quickstart, you will:
Add items to a catalog with regular prices.
Create a store that contains the same items with discounted prices.
Use PlayFab APIs to purchase an item from the store.
Use information in the Game Manager to confirm that the item was purchased at the discounted store price.
TIP
You don't have to assign a virtual currency price to items in a catalog for them to appear in a store.
In the following example, an item called apricot is added to the main catalog with a GD price of 4 .
Creating a store
You should now have a few items with prices in your catalog. Let's create a store to sell them to a player.
1. Open your main catalog and select Stores .
2. Select New store .
3. Set the Store Id and Store name to fruits (as shown in the following example).
TIP
You can drag-and-drop the rows in the store contents to rearrange the order of the items.
1. Add some GD prices to your items, but make them lower than the catalog prices:
Apricot: 3 .
Pear : 2 .
Grape: 1 .
2. Select SAVE STORE when you're done.
In the following example, an item called apricot with a catalog price of 4 GD is given a store price of 3 GD .
Purchasing an item from the store
Now that you have a store, let's use the PlayFab APIs to buy an item from the store in your game.
1. Get your store by calling GetStoreItems with these parameters in the request:
CatalogVersion = "main"
StoreId = "fruits"
2. The Store field in GetStoreItemsResult should contain a list of your store items and their prices.
3. Call PurchaseItem with values in the request that specify the currency and store price of the item you
want to buy.
CatalogVersion = "main"
StoreId = "fruits"
ItemId = "pear"
VirtualCurrency = "GD"
Price = 2
TIP
If you don't specify the StoreId when calling PurchaseItem, the purchase is attempted against the catalog price.
Next steps
Now that you've learned how to create and utilize stores in your game, you're ready to explore some more
advanced uses of stores.
For example, by using segments in conjunction with stores, you can give special prices to certain players without
touching your game code.
Custom stores for player segments
Best practices for store segmentation
Also, by combining stores and segments with A/B testing, you can produce several versions of a store available
to different A/B testing groups (buckets).
A/B testing with stores and test buckets
Stores tutorials
5/24/2022 • 2 minutes to read • Edit Online
In our Stores and Sales tutorial, we demonstrate how to set up a store and make a few items available to a
player at special or alternate prices.
In our Player segmentation quickstart, we provide an example of how to group your players into segments,
based on player information or behavior.
This tutorial describes how to combine these features, and produce alternate stores available only to players
from defined player segments.
1. Let's begin with some example segments. In the screen shot shown below, we have provided some segments
that are segmented-store-testing friendly.
2. Next, we'll reuse the Equipment Store created in the Stores and Sales tutorial, and add player segmentation.
To do this, you must create each store separately, and give it an identifiable name. Each store should have
content that is customized for that segment.
TIP
Using the DUPLICATE feature on the Stores screen, you can duplicate stores quickly, and then modify the Store Id ,
Store name , and other parameters to make the new store unique.
In PlayFab, Stores are built upon Catalogs and Currencies. Your primary catalog should define all of the items in
your game and assign them prices in the currencies that you've created.
Stores should define subsets of the items in your catalog, and make them available for purchase at specific
prices that can be different than the catalog prices.
A store allows you to single out a specific set of items, and make them available at specific prices for a set time
period.
This tutorial illustrates the best practices for defining stores based on virtual currency and real money.
Requirements
Familiarity with the PlayFab Game Manager.
You must have defined one or more Virtual Currencies. The latter example in this tutorial uses:
SS (Silver Shekels )
GS (Gold Shekels ).
You must have a primary catalog with one or more items defined.
The first example uses multiple item/bundles, similar to the ones described in the Drop Tables tutorial.
The second example in this tutorial uses small, medium, and large health potions.
Best practice
Catalog prices should be fixed long-term - they define the real price of an item.
Stores should be temporary, being added and removed according to your LiveOps strategies.
NOTE
Expect to get most of your revenue by cycling stores, and transitioning items in and out of active stores.
NOTE
Any item can be sold for real money, but it is a best practice to make only specific valuable items or bundles directly
available.
The screenshot provided below shows a complete new Store , containing three Item Bundles available for Real
Money .
The specifics for completing real money purchases are covered in our advanced tutorial, non-receipt payment
processing.
Best practices for real money stores
How you use real money is largely dependent on the specific design of your game. Direct purchase of in-game
items is valid, but less common.
More typically, your game should allow purchase of a premium virtual currency using real money. You can cycle
multiple stores with different ratios of premium currency to real money.
TIP
The primary takeaway is - make sure your players can always give you money.
Defining a virtual-currency store
Let's get into the gritty details and code for purchasing in-game items with virtual currency.
The initial steps are nearly identical to the preceding example:
Create 3 new items: Small , Medium , and Large Health Potions with a free Currency price, and a
premium Currency price.
Create a new store which puts these items on sale.
The LogSuccess callback in this example receives a GetStoreItemsResult that contains a full description of all the
items in the store, their store prices, and any additional metadata contained in the store itself.
Best practices for displaying stores
Games with stores should call and cache their primary catalog using the GetCatalogItems method. This allows
you to display both the catalog price and the store price, along with a 10% OFF or similar bonus decoration
beside items for sale.
TIP
Players are more likely to buy items on sale, especially if the sale is a limited-time offer.
At this point, it is the responsibility of your GUI code to present the user with the opportunity to select which
items they wish to buy and how many.
Between your game and PlayFab, the remaining steps are several separate API calls, but you can make the
sequence of multiple calls invisible to the player.
Collect all information about the purchase up front, and make the full sequence of calls after all player
input is collected.
void DefinePurchase()
{
var primaryCatalogName = "TestCatalog-001"; // In your game, this should just be a constant matching
your primary catalog
var storeId = "Potion Store"; // At this point in the process, it's just maintaining the same storeId
used above
var request = new StartPurchaseRequest
{
CatalogVersion = primaryCatalogName,
StoreId = storeId,
Items = new List<ItemPurchaseRequest> {
// The presence of these lines are based on the results from GetStoreItems, and user selection
- Yours will be more generic
new ItemPurchaseRequest { ItemId = "Small Health Potion", Quantity = 20,},
new ItemPurchaseRequest { ItemId = "Medium Health Potion", Quantity = 100,},
new ItemPurchaseRequest { ItemId = "Large Health Potion", Quantity = 2,},
}
};
PlayFabClientAPI.StartPurchase(request, result => { Debug.Log("Purchase started: " + result.OrderId); },
LogFailure);
}
During the item selection process, you must allow the user to select which currency they wish to spend for these
items. In this example, all items have costs in SS and GS , which means the user has a choice of which currency
to spend.
NOTE
The result from the StartPurchase API in the code example above, contains a list of PaymentOptions . Each payment
option contains the Currency , Price , and ProviderName that can be used to make the purchase.
Restrictions
Only one virtual currency is allowed in a single purchase. All selected items must be purchasable with a single
currency.
The currency must be specified in the call, which is important when there are multiple possible currencies. The
sequence will fail if there are items in the request which don't have corresponding costs in the selected currency.
The ProviderName must also be specified in the call. For real money purchases, this will be the name of the
provider that is used to fund the purchase. For example, Facebook, PayPal, or Steam. For VC purchases, it will be
a string based on your title ID. The ProviderName can be obtained from the PaymentOptions field of the
StartPurchaseResult as described in the previous Note .
TIP
For VC purchases, the ProviderName for your title is a string constructed from the word "Title" concatenated with the
decimal equivalent of your hexadecimal TitleId . For example, "Title123456".
Finally, once the purchase is fully defined, you can complete the process, as shown below.
// Unity/C#
void FinishPurchase(string orderId)
{
var request = new ConfirmPurchaseRequest { OrderId = orderId };
PlayFabClientAPI.ConfirmPurchase(request, LogSuccess, LogFailure);
}
Conclusion
Stores are a great mechanism for encouraging your players to purchase items.
Stores work with any kind of virtual currency. Stores can also work with real money through an alternate set of
API methods.
You can set up a single-item purchase with VC via PurchaseItem.
You can set up a multiple-item purchase with real money or VC via the sequence:
StartPurchase
PayForPurchase
ConfirmPurchase
For more information on real money purchases, consult our advanced tutorial Non-Receipt Payment Processing.
For advanced store usage, see our Custom Stores for Player Segments tutorial.
PlayFab User Generated Content
5/24/2022 • 2 minutes to read • Edit Online
PlayFab User Generated Content (UGC) empowers your players to create, upload, and search for moderated
content. Designed to provide out-of-the box capabilities that normally require custom work and service
expertise to accomplish, our UGC services can enable you to build an engaging creator community around your
title in no time! Watch our UGC Microsoft Game Dev video to learn more.
Key features
UGC provides the following key features:
Easy-to-integrate APIs to allow you to build your own in-game experiences
Moderation built into the publishing pipeline to ensure content is safe and appropriate for your players
Search experiences to allow your UGC catalog to scale and players to quickly find interesting content for
them
Review and reporting capabilities to empower players to keep the quality high
Key concepts
There are a few common terms used throughout the UGC service:
Catalog - Catalogs are a place for you to store and manage your content. There are two main catalogs, the
draft catalog and the public catalog which store draft and published items, respectively
(Published) Items - PlayFab UGC Items are data blobs containing information about a specific item.
Published Items are accessible to other players through the GetItems and Search APIs
Draft Items - Draft Items are accessible to only the item creater and the Title Entity. Draft Items can
become Published Items by calling the PublishDraftItem API
Content - Content are the images and files that are uploaded to Items
Getting Started
The UGC Quickstart guide walks you through the steps of publishing an item
The Publish your first user generated content tutorial goes over the details of uploading content and
populating URL blobs.
The Search Guide goes over the different ways you can query your public UGC catalog
User-Generated Content (UGC) quickstart
5/24/2022 • 2 minutes to read • Edit Online
The purpose of this guide is to explain how to quickly get started with UGC, using direct service-to-service calls.
We will show you step by step how to connect to the draft UGC content items, publish those items, and then
search and find them.
{
"CustomId": "exampleUser",
"CreateAccount": true,
"TitleId": "DC7B"
}
{
"Item": {
"Type": "ugc",
"Title": {
"NEUTRAL": "Neutral Title Test",
"en-GB": "en-gb Title",
"en-US": "en-us Title"
},
"Description": {
"NEUTRAL": "Neutral Description Test",
"en-GB": "en-gb Description",
"en-US": "en-us Description"
},
"startDate": "2018-10-18T20:01:26.1520582Z"
}
}
This will return the created Draft Item with an Id . We'll want to keep track of this Id for later.
"Item": {
"SourceEntity": {
"Id": "1184A",
"Type": "title",
"TypeString": "title"
},
"SourceEntityKey": {
"Id": "1184A",
"Type": "title",
"TypeString": "title"
},
"Id": "44857e2b-c93b-4054-80be-7890028201ff",
"Type": "ugc",
"Title": {
"NEUTRAL": "Neutral Title Test",
"en-GB": "en-gb Title",
"en-US": "en-us Title"
},
...
}
{
"Count": 2,
"Entity": {
"Id": "C88F55C6A734B1DC",
"Type": "title_player_account",
"TypeString": "title_player_account"
}
}
{
"Id": "44857e2b-c93b-4054-80be-7890028201ff"
}
{
"Id": "44857e2b-c93b-4054-80be-7890028201ff"
}
The possible publish Result values are as follows:
Unknown
Pending
Succeeded
Failed
Canceled
Republishing an item will update the Published Item to match the current Draft Item.
Do a simple search
Once the publish call succeeds, the item can be accessed by all players via the Public Catalog. The SearchItems
API executes a search against published catalog (including UGC items) using the provided parameters and
returns a set of paginated results. The Filter , OrderBy , and Select fields use OData as the query standard.
{
"Search": "Test",
"Count": 2
}
SearchItems
5/24/2022 • 6 minutes to read • Edit Online
The SearchItems API executes a search against the public Catalog using the provided search parameters and
returns a paged list of items.
At its most basic, the Search parameter is a plain-text fuzzy search against the Title , Description , Keywords ,
and Searchable String Display Proper ties fields. However Filter , OrderBy , and Select are OData Query
additions that can be used to alter the search parameters. Search results can be filtered and ordered by any field
in the search document (barring Title and Description).
More information on the OData Query Syntax can be found here
An example SearchItems request:
{
"Search": "Pirates",
"Filter": "Tags/any(t:t eq 'desert') and ContentType eq 'map'",
"OrderBy": "lastModifiedDate asc",
"ContinuationToken": "abc=",
"Count": 2,
"ConfigurationName": "SearchConfigurationA",
"ExpandReferencedItems": false
}
A sample response:
{
"code": 200,
"status": "OK",
"data": {
"Items": [
{
<item metadata>
}
],
"PartialExpandedResults": false,
"ContinuationToken": "MTA="
}
}
Continuation Tokens
The ContinuationToken field that is returned from a search response can be passed into a search request to
paginate through multiple counts of results.
Display Properties
Searches, filters, and orderings can be also done on specific DisplayProperties fields that are configured for
custom search. Titles can configure their custom search and filter properties in the Display Properties Mappings
setting in Game Manager.
When you add a field to DisplayProperties , it will create a new index for you in the database. Only documents
added or updated after index creation will be included. If you need the Display Property to apply to all items you
will need to republish the entire catalog.
DateTime , Double , and Queryable String display properties are quer yable , these properties can be used in
Filter and OrderBy statements.
Searchable String display properties are searchable , these properties will be queried with fuzzy search
against the Search field. Searchable properties cannot be used in Filter and OrderBy statements.
Titles are limited to 5 display properties of each type.
WARNING
Display property mappings are stored as an indexed list of key-value pairs. Deleting existing display property mappings
can shift indexes and break the behavior of all remaining properties. It is suggested to add an additional property rather
than deleting or editing an existing one and you should avoid deleting property mappings unless absolutely necessary
Filter
The Filter parameter allows you to filter the collection of items returned by the search request. The expression
specified with filter is evaluated against each Catalog Item in the results, and only items where the expression
evaluates to true are included.
Filter supports OData logical operators and precedence using parenthesis:
Equal: ‘eq’
Not Equal: ‘ne’
Greater Than: ‘gt’
Greater than or Equal: ‘ge’
Less than: ‘lt’
Less than or Equal: ‘le’
Logical And: ‘and’
Logical Or: ‘or’
Logical Negation ‘not’
Filter does not support arithmetic operators or string functions.
The following are a number of Filter examples:
Filtering by ContentType
NOTE
By default, Search will NOT return contents for items unless specified with a Select statement. If the above query is run
without a `"Select": "contents"`` statement, it will correctly apply the filter but all returned Search results will have empty
content fields
OrderBy
OrderBy is a comma-separated list used to sort search results.
"OrderBy": "rating/average asc"
When using order sorting you can pass a secondary property to break sorting ‘ties’
If you don’t pass in a secondary value, catalog items do have an internal ‘score’ attribute that used for breaking
ties, however that scoring is arbitrary and inconsistent (it’s based on the storage order in the underlying
database and is constantly changing as items are added and removed).
OrderBy supports a handful of OData properties for ordering:
asc
desc
If you don't specify a direction, the default is ascending. If there are null values in the field, null values appear
first if the sort is asc and last if the sort is desc . If no OrderBy value is passed, a default id asc value is used.
The following are a number of OrderBy examples:
Sorting by Title
Use the title/<LANG> parameter combined with asc or desc to indicate order preference.
Select
By Default, Search returns a rich set of item metadata:
Id
Type
AlternateIds
Title (NEUTRAL or Accept-Language locale)
Description (NEUTRAL or Accept-Language locale)
Keywords (NEUTRAL or Accept-Language locale)
ContentType
Images (Thumbnail only)
Tags
CreationDate
LastModifiedDate
CreatorEntityKey ( CreatorId in earlier API versions)
DisplayProperties
Only the neutral strings used in title and description are returned by default. If a Thumbnail image exists, it is
returned by default. Each item is limited to only one image of a "Thumbnail" type.
Using Select additional fields can optionally be returned within the paged search results, including content
metadata (contents), images, StartDate, EndDate and the full set of localized strings in title and description. Note
that if the select field is left empty, the search results will be a subset of the full document metadata, to facilitate
faster load times.
This request would return the default item metadata in addition to the content and images:
"Select": "contents,images"
Selecting title , description , and/or keywords will return the full set of localized string data:
"Select": "title,description,keywords"
Localization
A locale can be passed into the Accept-Language header. This will cause all Title , Description , Keywords fields
to return the locale by default or NEUTRAL if the item doesn't have that localization.
Limits
We are limiting the complexity of search filter queries that can run in any given request. Expensive queries can
be rejected and titles should ensure that they are not attempting overly complicated queries. The following are
examples of queries close to maximum complexity:
contentType eq 'testType' and tags/any(t: t eq 'blue') or tags/any(t: t eq 'green') or tags/any(t: t eq
'violet')
contents/any(c: c/minClientVersion gt '1.2.3' and c/maxClientVersion lt '4.5.6')
High complexity filter queries will throw a 400 error with a message that "The filter provided in the request does
not meet the complexity requirements for source"
This guide will go through the API calls that can be used to create moderation flows for the content in your
game.
Report an item
Players can report an item by calling the ReportItem API from a client. An item Id or AlernateId must be
provided. Additional optional parameters can be added. These include:
ConcernCategory : A category of concern for the report
Reason : A free text input for the report
{
"Id": "3f5dd8d4-4ee1-4748-8855-56a8a0277bf9"
"ConcernCategory": "Profanity",
"Reason": "There was swearing in the description."
}
If not specified, ConcernCategory will default to None . The valid ConcernCategory values are as follows:
None
OffensiveContent
ChildExploitation
MalwareOrVirus
PrivacyConcerns
MisleadingApp
PoorPerformance
ReviewResponse
SpamAdvertising
Profanity
Calling the ReportItem API will only fire a PlayStream event under the Event Name, item_reported . This can be
queried using the Data Explorer in the Game Manager. Example queries can be seen below:
The following query returns The total number of repor ts by ConcernCategor y per ItemId in the last 3
days
['events.all']
| where Timestamp > ago (3d)
| where FullName_Name == "item_reported"
| project ItemId = tostring(EventData.Payload.ItemId), ConcernCategory =
tostring(EventData.Payload.ConcernCategory)
| summarize TotalReportCount = count() by ItemId, ConcernCategory
| sort by TotalReportCount desc
| render columnchart kind=stacked
The following query returns All submitted repor ts against a specific ItemId in the last 3 days
['events.all']
| where Timestamp > ago (3d)
| where FullName_Name == "item_reported"
| where EventData.Payload.ItemId == "3f5dd8d4-4ee1-4748-8855-56a8a0277bf9"
| project Timestamp, ItemId = tostring(EventData.Payload.ItemId), ConcernCategory =
tostring(EventData.Payload.ConcernCategory), Reason = tostring(EventData.Payload.Reason), ReportingPlayer =
Entity_Id
| sort by Timestamp
{
"Status": "AwaitingModeration",
"Reason": "User reports over threshold",
"Id": "3f5dd8d4-4ee1-4748-8855-56a8a0277bf9"
}
By default, a published item will not have a moderation status. Republishing the draft item will not change the
moderation status. The valid Status values are as follows:
AwaitingModeration
Approved
Rejected
The following query returns All items currently in the AwaitingModeration status in the last 3 days
Delete an item
An item can be deleted by calling the DeleteItem API. This call will remove an item from the draft catalog and
corresponding item from the public catalog (if it has been published). An item Id or AlernateId must be
provided.
{
"Id": "852a2d2b-7754-427e-9ad4-fce2b24a4cef"
}
Adding ratings to your user generated content
5/24/2022 • 4 minutes to read • Edit Online
This guide will go through the API calls that can be used to add a ratings and review system to your game.
Review an item
A rating or review can be attached to an item by calling the ReviewItem API from a client. In order for an item to
be reviewed it must be visible in the public catalog for all players. Ratings and reviews are attached to the player
calling the API and only a single review per player can be associated with an item. The creator of an item cannot
submit a review for their own item. The review is updated every time ReviewItem is called. The following data is
required for the call:
Id : The unique ID of item that is wished to be reviewed.
Rating : A numeric rating the form of a 1 to 5 scale.
{
"Review": {
"ItemVersion": "2.4.1",
"Rating": 5,
"Title": "Best Game Ever",
"ReviewText": "I play this game every day. It's my favorite game yet.",
"IsInstalled": true
},
"Id": "3f5dd8d4-4ee1-4748-8855-56a8a0277bf9"
}
Calling GetEntityItemReview from a player who hasn't made a review returns a Review object with zeroed
values:
{
"code": 200,
"status": "OK",
"data": {
"Review": {
"ReviewId": "00000000-0000-0000-0000-000000000000",
"Rating": 0,
"IsInstalled": false,
"HelpfulnessVotes": 0,
"HelpfulPositive": 0,
"HelpfulNegative": 0,
"Submitted": "0001-01-01T00:00:00Z"
}
}
}
ContinuationToken : An opaque token used to retrieve the next page of items, if any are available.
Count : Number of items to retrieve. Maximum page size is 200. If not specified, defaults to 10.
OrderBy : An OData orderBy used to order the results of the query. Possible values are Helpfulness , Rating ,
and Submitted .
{
"Count": 2,
"Id": "3f5dd8d4-4ee1-4748-8855-56a8a0277bf9",
"OrderBy": "Submitted desc"
}
{
"ReviewId": "730de69c-d6af-f313-4653-09fb14bedeef",
"Vote": "Helpful/UnHelpful"
}
Report a review
Players can report a review by calling the ReportItemReview API from a client. A ReviewId must be provided. An
additional optional ConcernCategory parameter can be added.
{
"ReviewId": "730de69c-d6af-f313-4653-09fb14bedeef",
"ConcernCategory": "OffensiveContent"
}
If not specified, ConcernCategory will default to None . The valid ConcernCategory values are as follows:
None
OffensiveContent
ChildExploitation
MalwareOrVirus
PrivacyConcerns
MisleadingApp
PoorPerformance
ReviewResponse
SpamAdvertising
Profanity
Calling the ReportItemReview will only fire a PlayStream event under the Event Name, item_reported . This can
be queried using the Data Explorer in the Game Manager. Example Kusto queries can be seen below:
The following query returns The total number of repor ts by ConcernCategor y per ItemId in the last 3
days
['events.all']
| where Timestamp > ago (3d)
| where FullName_Name == "review_reported"
| project ReviewId = tostring(EventData.Payload.ReviewId), ConcernCategory =
tostring(EventData.Payload.ConcernCategory)
| summarize TotalReportCount = count() by ReviewId, ConcernCategory
| sort by TotalReportCount desc
| render columnchart kind=stacked
Takedown a review
You can submit a request to takedown one or more reviews using the TakedownItemReviews API. This API can
only be called by the title entity . The call takes in a set of reviews that is to be taken down.
{
"Reviews": [
{
"ItemId": "3f5dd8d4-4ee1-4748-8855-56a8a0277bf9",
"ReviewId": "730de69c-d6af-f313-4653-09fb14bedeef"
}
]
}
NOTE
There can be a delay of up to 24 hours until a review is taken down due to the request processing
Both routes are asynchronous and have timing delays that it is important to understand.
Direct Ratings (GetItemReviews, etc.)
All these ratings and reviews are served directly. There are two categories of latency here.
1. Individual Reviews - Near Real Time
Individual reviews will not available immediately, but should show up within a few seconds. We expect
that retrying with a backoff will be sufficient for reading a brand-new review.
2. Aggregate Ratings - Under 15 minutes
There's a cache for aggregates
Catalog Item Ratings (SearchItems, etc.)
All these ratings are served as part of the catalog item from our published catalog.
1. Aggregate Ratings - Under 8 hours
The system aggregates the ratings and pushes updates into the catalog which can take anywhere from 4-8
hours.
Settings and Policy Page
5/24/2022 • 3 minutes to read • Edit Online
The Economy Settings page contains various options to configure UGC and Economy features for your game.
These settings can be found under the Economy tab under Title Settings. These settings can also be set and
accessed via APIs using the UpdateCatalogConfig and GetCatalogConfig calls respectively. Note that these APIs
can only be called by title entities.
Display Properties
Display Properties are custom item properties that can be added to all items in your catalog. Certain properties
can be set in the Display Property Mappings section to be used searches, filters, and orderings when using the
SearchItems API
When you add a field to DisplayProperties , it will create a new index for you in the database. Only documents
added or updated after index creation will be included. If you need the Display Property to apply to all items you
will need to republish the entire catalog.
DateTime , Double , and Queryable String display properties are quer yable , these properties can be used in
Filter and OrderBy statements.
Searchable String display properties are searchable , these properties will be queried with fuzzy search
against the Search field. Searchable properties cannot be used in Filter and OrderBy statements
Titles are limited to 5 display properties of each type.
WARNING
Display property mappings are stored as an indexed list of key-value pairs. Deleting existing display property mappings
can shift indexes and break the behavior of all remaining properties. It is suggested to add an additional property rather
than deleting or editing an existing one and you should avoid deleting property mappings unless absolutely necessary
Content Types
A pre-set list of content types for UGC can be set by providing a list of valid string types. ContentType is an
optional property, but if it is desired to be set, it must be one of the pre-listed values.
Tags
A pre-set list of tags for UGC can be set by providing a list of valid strings. Tags are optional for any item and
an item can contain any number of the pre-listed tags.
Policies
The Policies page allows you to control the client access to the Economy APIs.
Playfab UGC uses the Admin API Policies to control API Access. Please note that if you have or will make any
changes to the JSON, it may break or cause unintentional behavior with the Economy API policies.
Even if it the APIs are enabled, Players are only able to publish, edit, and delete content they have created. Title
Entities are always able to access, delete, and edit any content.
NOTE
Although Admin Players are given title-level edit, delete, and access privileges, they are still considered players for the
purposes of Policies. For example, if the DeleteItem API was disabled for all players, Admins will not be able to delete
content (but titles will continue to be able to)
Item Permissions and Visibility
5/24/2022 • 2 minutes to read • Edit Online
Catalog Items can be given different parameters and values that change whether the item is visible to different
players through the public catalog or other APIs. This document will go over the different states an item can be
in and how it can affect who can see or modify them.
Published Items
Published Items that have a valid start and end date pair (ie. StartDate < CurrentDate < EndDate), are visible to
all players via the Public Catalog. Players can access published items using the SearchItems and GetItem APIs.
Scheduled Items
Scheduled Items are Published Items that have future start date (ie. CurrentDate < StartDate). These items are
only accessible by the Item Creator, Catalog Admins, Catalog Reviewers, and Title Entities. These items will not
show up in the Published Catalog and cannot be accessed using GetItem API for regular players.
Expired Items
Expired Items are Published Items that have past end date (ie. CurrentDate > EndDate). These items will not
show up in the Published Catalog via the SearchItems API but these items can be accessed using GetItem API
for all players.
Hidden Items
Expired Items are Published Items that have the IsHidden flag set to true. These items will not show up in the
Published Catalog via the SearchItems API but these items can be accessed using GetItem API for all players.
{
"Item": {
"Id": "e08acd29-f28a-4cbb-b8d6-7df74c7f0e4a",
"Type": "ugc",
"AlternateIds": [],
"Title": {
"NEUTRAL": "ETag Test"
}
}
}
UpdateDraftItem Response
{
"code": 200,
"status": "OK",
"data": {
"Item": {
"Id": "e08acd29-f28a-4cbb-b8d6-7df74c7f0e4a",
"Type": "ugc",
"Title": {
"NEUTRAL": "ETag Test"
},
...
"ETag": "\"7800e585-0000-0300-0000-623364bf0000\""
}
}
}
This ETag will be returned from any of the APIs that return the draft item (such as GetDraftItem ,
GetEntityDraftItems , and GetDraftItems ). This ETag will also be updated every time an update is made with
UpdateDraftItem
Using ETags
ETags can be passed in as an optional parameter to UpdateDraftItem and PublishDraftItem calls. If passed in, a
check will be done between the draft item's ETag and the passed in parameter. If the two ETags don't match, the
request will be rejected.
Publish Item Request
{
"Id": "e08acd29-f28a-4cbb-b8d6-7df74c7f0e4a",
"ETag": "\"7800e585-0000-0300-0000-623364bf0000\""
}
The above request would publish the item successfully. While providing any other ETag value would throw an
error and reject the request.
ETags are useful in situations where you're expecting multiple sources to be simultaneously modifying an item
and you want to ensure that no data is overridden by another update.
UGC Pricing Meters
5/24/2022 • 3 minutes to read • Edit Online
PlayFab User Generated Content has two categories of consumption-based meters - Requests and Storage. This
page outlines and defines those meters, including how it is measured and calculated. For more information on
PlayFab's pricing model, see PlayFab Pricing Overview.
NOTE
General usage of PlayFab UGC may contribute toward other PlayFab meters, like PlayStream Events.
Requests
The request meters are determined by the response size of any UGC API calls or CDN requests. For each of the
three PlayFab plans, there are five different rates, depending on the size:
NOTE
Please contact us if you are planning on storing content larger than 100 MBs.
Storage
The storage meter is determined by the total size of all content (both files and images). 5GB is included in all
pricing plans. For additional storage, there is a three different rates for this meter depending on the plan.
This includes content associated with items that haven't been published, and items that aren't visible via the
public catalog. For more information on how items can be hidden from the public catalog, see Item Visibility.
Included Meters
There is a set of included meters for all PlayFab customers, regardless of the selected plan:
M ET ER IN C L UDED A M O UN T
Storage 5 GB
NOTE
Studios in Development Mode are required to enter payment information before enabling UGC, and overages will be
charged based on the rates above.
Example Bill
Let's walk through an example customer's UGC consumption and look at their monthly bill. This example title is
on the Pay-as-you-go plan. Let's start with a single user. This user goes to the content discovery page and
searches for 'dinosaurs'. 10 results are displayed to the user, each with a title and thumbnail image. The user
selects a piece of content, which displays the full metadata, including the description, ratings, and 4 more
images. The user decides the content looks interesting enough, so they select the download button.
Now let's see what meter consumption this scenario just drove:
This user goes to the content discovery page and searches for 'dinosaurs'. 10 results are displayed to the
user, each with a title and thumbnail image.
The SearchItems call returned 10 items with the base metadata, resulting in a single Up to 1 MB
Request .
Each of the 10 thumbnails is requested from the CDN. Let's pretend 5 of these are just under 1 MB,
and 5 are just over 1 MB. This results in 5 Up to 1 MB Requests and 5 Up to 5 MBs Requests .
The user selects a piece of content, which displays the full metadata, including the description, ratings, and 4
more images.
The GetItem call returned a single item with the full metadata, resulting in a single Up to 1 MB
Request
The GetRatings call returned a single item's ratings, resulting in a single Up to 1 MB Request
Each of the 4 images is requested from the CDN. These are higher quality images, so let's pretend 2 of
these are just under 5 MBs, and 2 are just over 5 MBs. This results in 2 Up to 5 MBs Requests and 2
Up to 25 MBs Requests .
The user decides the content looks interesting enough, so they select the download button.
This content is requested from the CDN. This is a large piece of content, so let's pretend it is 20 MBs.
This results in a single Up to 25 MBs Requests .
M ET ER REQ UEST C O UN T
Up to 1 MB 8
Up to 5 MBs 7
Up to 25 MBs 3
Up to 50 MBs 0
Up to 100 MBs 0
Now let's pretend this title has 10 thousand users that perform this exact same scenario once a day in a 30-day
month (300 thousand times) - this is roughly the same as a single user performing this exact same scenario on
average once every 9 seconds. This would result in the following meter consumption:
M ET ER REQ UEST C O UN T
Up to 1 MB 2.4 million
Up to 50 MBs 0
Up to 100 MBs 0
Let's also pretend this is the only title leveraging UGC in the studio, and the title has 4 GB of UGC stored (which
is fully covered by the 5 GB included, so no charges are incurred on the Storage meter). If this were the total
consumption at the end of the month, here is what the final UGC bill would look like:
Additional resources
For the most up-to-date view of prices per meter, see PlayFab.com/Pricing
See Consumption Best Practices to learn how to maintain the lowest rate of meter usage and cost for your
game
Limits
5/24/2022 • 2 minutes to read • Edit Online
The purpose of this guide is to detail the limits that are enforced when creating, updating, and reading from
your catalog of items.
Item Creation/Updates
Binary Content Size
Files or images that are greater than 100MB in size cannot be added to items. It is recommended that larger
files are split into several smaller partitions if possible.
NOTE
Please contact us if you require storing content larger than 100 MBs.
NOTE
Each blob should only be used in one item. If you wish to have a piece of content repeated in multiple items, you should
re-upload the content to different blobs.
CreateUploadUrls
Content blobs/urls will be garbage collected after 24hrs if not attached to a draft or published item.
Item Updates
These limits affect calls to APIs that create items or modify existing item properties (such as UpdateDraftItem ,
CreateDraftItem , and DeleteItem )
Item Reads/Searches
RPS Limits
These limits affect calls to APIs that query items and their properties (such as SearchItems , GetItem , and
GetDraftItem )
Filter Complexity
There are checks enforced to prevent the use of overly complicated Filter queries used in SearchItems calls.
More information can be found here
Item Metadata
Titles
Titles have a 512 character limit per country code.
Descriptions
Descriptions have a 10000 character limit per country code.
Keywords
Keywords have a 50 character limit per keyword and up to 32 keywords can be added per country code.
Display Properties
The Display Properties field has a 10000 character limit .
Tags
Tags have a 32 character limit per tag. Titles can have a maximum of 1024 Tags and up to 32 Tags can be
added to an item
Content Types
Content Types have a 32 character limit per content type. Titles can have a maximum of 128 Content Types .
User Generated Content (UGC) Tutorials
5/24/2022 • 2 minutes to read • Edit Online
These tutorials demonstrate features that you can use to create and maintain the economy of your game.
Publish your first user generated content
Publish your first user generated content
5/24/2022 • 7 minutes to read • Edit Online
This tutorial walks you through publishing UGC with content through both APIs and the Game Manager UX,
diving into more detail than the quickstart.
Requirements
A PlayFab developer account
A UGC-enabled title
Via APIs
In this section, we will leverage the Postman Collections to interact with the PlayFab UGC APIs, but you can
leverage any of our SDKs.
Create Blob URLs
The UGC system works with the PlayFab Entity Model, so we need to use entity tokens instead of session
tickets to call these APIs. You can learn how to get a title entity token in the Postman Collections
Quickstart.
The UGC system leverages Azure Blob Storage to store all content (files and images) associated with your
title's UGC. To upload the content, we first need to call the CreateUploadUrls API, passing in the file names
and sizes (in bytes) to create the new blobs. For example, if I wanted to upload a text file and PNG image, I
would pass in the following to the request body:
{
"Files": [
{
"FileName": "HelloWorld.txt",
"FileSize": 12
},
{
"FileName": "PlayFabLogo.png",
"FileSize": 20725
}
]
}
The response will include an Id and Url for each piece of content:
{
"code": 200,
"status": "OK",
"data": {
"UploadUrls": [
{
"Id": "[Content ID]",
"Url": "[Content Url + '?' + Token]",
"FileName": "HelloWorld.txt"
},
{
"Id": "[Image ID]",
"Url": "[Image Url + '?' + Token]",
"FileName": "PlayFabLogo.png"
}
]
}
}
NOTE
Each create token (returned in the "Url" field of the response) is valid for 6 hours, after which you will not be able
to upload content to the blob. If you did not upload any content to the blob, it will get cleaned up by our service
and you will need to create a new blob by calling CreateUploadUrls again. This URL will also not allow access to
content until is has been uploaded to a draft item where it will receive a different (now publicly accessible) URL
NOTE
Each blob should only be used in one item. If you wish to have a piece of content repeated in multiple items, you
should re-upload the content to different blobs.
Via AzCopy
Another option is using the AzCopy tool. You can download the tool and get started with AzCopy here.
In your terminal of choice, call azcopy with the following parameters:
[relative path to azcopy.exe] copy [relative path to local content] [Url + '?' + Token]
{
"Item": {
"Type": "ugc",
"Title": {
"neutral": "Hello World!"
},
"Description": {
"neutral": "My first UGC item (with content!)"
},
"ContentType": "Game Item",
"IsHidden": false,
"Contents": [
{
"Id": "[Content ID]",
"Url": "[Content Url]"
}
],
"Images": [
{
"Id": "[Image ID]",
"Type": "Thumbnail",
"Url": "[Image Url]"
}
]
},
"Publish": false,
"AllowOverwrite": false
}
NOTE
When uploading images to items, every image must be classified with a Type parameter. This can either be a
"Thumbnail" or a "Screenshot". Each item is limited to only one image of a "Thumbnail" type and by default, Searches will
return the "Thumbnail" image (if it exists) by default.
The response will return the metadata you passed in, along with an item ID:
{
"code": 200,
"status": "OK",
"data": {
"Item": {
...
"Id": "e5427509-1b72-4ee1-9e6c-03fc055a94f3",
...
}
}
}
NOTE
The content/image URLs returned by the created draft item and the original CreateUploadUrls call will be different.
Regardless of how you chose to upload content, you can test that the upload was successful by copying the base Url
(before the '?') and navigating to it in your browser. This will only return the image after it has been uploaded to a draft
item, not by using the URL from CreateUploadUrls .
The draft UGC item now exists in the draft catalog! As long as the UGC item is not yet published, it will
not be searchable via the public catalog. You can find this UGC item by calling either of the following APIs:
GetDraftItem , passing in the item ID obtained from the CreateDraftItem response
GetDraftItems , passing in a list of known item IDs
GetEntityDraftItems, passing in an Entity ID and/or passing in the ContinuationToken from each
previous response to page through the list of draft items
NOTE
If you wanted to publish immediately, you could change the Publish field to true
When you are ready to publish the UGC item, call PublishDraftItem , passing in the item ID (obtained
from the CreateDraftItem response).
If your UGC item contains multiple particularly large files, publishing the item can take some time, and
when there are many other players concurrently uploading content, this process can take even more
time. You can check on the status of the publish by calling GetItemPublishStatus , passing in the item ID
(obtained from the CreateDraftItem response). There are a few possible statuses:
Succeeded - the UGC item has successfully published
Pending - the UGC item is still in the process of getting published
Failed - the UGC item publish failed and will not get published until the offending content has
been modified
Unknown- this is the default status, and will be returned before calling PublishDraftItem on the
UGC item
Canceled - an internal error has occurred, please try publishing the item again (if you see this
status multiple times, please reach out to the PlayFab engineering team)
Once the UGC item has been successfully published, you can search for it via SearchItems or grab it
directly via GetItem if you have the item ID.
You can make changes to the UGC item before or after publishing by doing the following:
Call GetDraftItem , passing in the item ID (obtained from the CreateDraftItem response)
Copy the UGC item's data (everything in the data field)
Call UpdateDraftItem , passing in the modified UGC item's data
If you want to update any of the files or images, you would need to create another blob by calling
CreateUploadUrls again
F IEL D N A M E VA L UE
Under the Files and Images sections, upload the appropriate content by selecting the Upload button.
Select Save and publish .
The UGC item will now automatically be created as a draft item and published to the public catalog - you
will now be able to find this item in the table with other published UGC items.
NOTE
There is currently no way to check the draft item or publishing status within Game Manager - this can only be done via
the APIs
If you want to make any changes to the published UGC item, you can do so by doing the following:
Select the published UGC item from the table
Make the appropriate edits
Select Save and publish
Troubleshooting
Invalid Request - The content type 'Game Item' is not supported.
If content types have been specified in your title's config (either through GetCatalogConfig /
UpdateCatalogConfig or in Game Manager under the Economy Settings tab), you will need to add
Game Item to the list, or change the content type to one your title already supports
Invalid Request - This title is not configured to use this service.
Your title currently has UGC disabled - you can enable this by updating your title's config (through
GetCatalogConfig / UpdateCatalogConfig , in Game Manager under the Economy Settings tab, or by
navigating to the Economy > Catalog (Preview) tab and selecting Enable )
Next Steps
You now have published UGC items in your catalog! You can leverage SearchItems to create content discovery
experiences for your players.
Search Tutorial >
What is PlayFab Engagement?
5/24/2022 • 2 minutes to read • Edit Online
PlayFab Engagement is a set of tools to engage your player community and keeping them coming back for
more. The features are Title news, Email templates, Push notifications.
Title News enables broadcasting of updates as news to your player base. It can be used to inform users of
upcoming events, share release notes for a recent update, or disseminate any other information you want your
players to have. To get started, see the Title news Quickstart.
Email messaging allows you to send customized emails to players basd on predefined schedule, rules based on
PlayStream event, or by calling an API. Emails are fully customizable with HTML templates which can include
player profile properties. To get started, see the Email templates Quickstart.
Push notifications let's you to send unlimited customized messages to players' home screens in real time. To get
started, see the Push notifications Quickstart.
News
5/24/2022 • 2 minutes to read • Edit Online
Title News is a mechanism for broadcasting information to your players. It allows you to post updates about
things such as upcoming in-game events, patch notes, future downtime, community activity, or anything else
you'd like your players to know.
Each post contains a few basic elements:
Title
Date
Status
Body
Posts can be published and made available to users immediately upon creation, or scheduled to go live at a time
in the future. After publishing posts in PlayFab via Game Manager or the AddNews API, your client can call
GetTitleNews to retrieve a list of all active posts and then display them to the user however you choose.
Title News quickstart
5/24/2022 • 4 minutes to read • Edit Online
Title News is a mechanism for communicating with your players for patch notes or big events your game may
be hosting. It contains a few basic elements:
Date
Status
Title
Body
Language(s)
NOTE
The Body element is a string which can contain raw text or JSON.
Requirements
This quickstart builds on information presented in other topics. Please refer to the topic links that follow if you
have questions.
You should be familiar with the PlayFab Game Manager.
NOTE
You must already have a title default language set to continue with localized title news.
Title news can now be localized. For details on working with the default languages in your title and with the
preferred languages for your players, please review the Setting Default Languages tutorial. Remember - to
continue with localized title news, you must have title default language set accordingly.
PlayFab supports storing localized strings on behalf of game developers, by associating a title and body with a
language for a title news entry.
We have added the necessary logic to provide your players with the correct strings for the language they prefer.
When the client queries for title news, they will receive different versions of title news, based on the players
preferred language. You can add multiple translated versions to a single title news entry.
void ReadTitleNews() {
PlayFabClientAPI.GetTitleNews(new GetTitleNewsRequest(), result => {
Debug.Log("Got latest news!");
// Process news using result.News
}, error => Debug.LogError(error.GenerateErrorReport()));
}
void ReadTitleNews() {
PlayFabServerAPI.GetTitleNews(new GetTitleNewsRequest(), result => {
Debug.Log("Got latest news!");
// Process news using result.News
}, error => Debug.LogError(error.GenerateErrorReport()));
}
This tutorial shows you how to set a default language for your title and for your players.
Setting default languages
Setting default languages
5/24/2022 • 5 minutes to read • Edit Online
PlayFab is introducing support for storing localized strings on behalf of game developers. In addition, we are
adding the necessary logic to provide your players with the correct strings for the language they prefer.
To accomplish this, we will be leveraging two new language settings: one is associated with your title, and the
other is stored on each of your players' entity profiles:
1. Title default language : Indicates your title's primary supported language. Once set, we will require your
title to support this language to be used at least for features using localized strings.
2. Player language : Indicates the player's preferred language. This can be set on a per-title basis.
Using these two settings, PlayFab logic will match up localized strings with the players who prefer that language.
Players without a language preference will receive strings in your title's specified default language.
NOTE
Players with a preference for a language that your title doesn't support will also receive strings, based on your title's
default language.
This tutorial walks you through how to set the default language of your title and the preferred language of your
players.
Requirements
This tutorial assumes you have the following working knowledge about using PlayFab:
A basic knowledge of how to create a player. This is necessary, because players must already exist with a
username and password before calling preferred language logic. Refer to Getting started for developers
for information on creating a player for the title.
That you have read the Game Manager quickstart if you were unfamiliar with the Game Manager, as it is
the place where language information is viewed.
That you have knowledge of how to work with player profiles, as it will be necessary to confirm that a
preferred language has been added to a player's profile.
Please take a moment to review the information provided on how to get a player's profile in the Getting
player profiles tutorial.
NOTE
When using the SetProfileLanguage API, the language string must be specified in the ISO 639-1 format (for example,
"en", "es", or "ja"). At the current time, the code "zh" is not supported.
First, we will update a player's profile to include the language in which they would prefer to get content from
your title.
C# Code Example
Selecting the info icon on the event should show JSON similar the example shown below.
{
"EventName": "entity_language_updated",
"Source": "PlayFab",
"Language": "en",
"EntityChain": "title_player_account!4CDA57A14A596E70/<YourTitleId>/C9458B4D3A115F4B/36163DA3783B0C8A/",
"EntityLineage": {
"NamespaceId": "4CDA57A14A596E70",
"TitleId": "YourTitleId",
"MasterPlayerAccountId": "C9458B4D3A115F4B",
"TitlePlayerAccountId": "36163DA3783B0C8A",
"CharacterId": null,
"GroupId": null
},
"EventNamespace": "com.playfab",
"EventId": "f643e22a2a76462aaeaa3469afa31434",
"EntityType": "title_player_account",
"EntityId": "36163DA3783B0C8A",
"SourceType": "BackEnd",
"Timestamp": "2018-08-24T18:49:47.8755292Z",
"History": null,
"CustomTags": null,
"Reserved": null
}
Selecting the info icon on the event should display JSON similar to the example provided below.
{
"EventName": "title_api_settings_changed",
"PreviousSettingsValues": {
"DefaultLanguage": null
},
"SettingsValues": {
"DefaultLanguage": "en"
},
"UserId": "EAF83D52E282C291",
"DeveloperId": null,
"EventNamespace": "com.playfab",
"EntityType": "title",
"Source": "PlayFab",
"EventId": "108849a5e1424051b42256bc75b2e34b",
"EntityId": "YourTitleId",
"SourceType": "BackEnd",
"Timestamp": "2018-08-24T21:51:02.2215614Z",
"History": null,
"CustomTags": null,
"Reserved": null
}
NOTE
You can always change your title default, but PlayFab will require that your current communications templates support
the language you're changing to.
If you update your title's default language, you'll see that the interface now shows an Edit link.
Following this link, you will see the same drop-down as before. However, if you try to save a default language
that isn't fully supported by your email templates, you will see one or more error messages like the one shown
below.
If there are errors, you can follow the links provided to update your content to support the language which is
missing. When all errors have been addressed, the default language change will be accepted.
Conclusion
In this tutorial, you've seen how to set and update your title's default language and your players' preferred
language.
If you have any questions or feedback on this tutorial, please contact us through our forums or slack channel.
Push Notifications
5/24/2022 • 2 minutes to read • Edit Online
Push notifications give games a channel to send immediate customized messages to a player’s device - even
when the player is not currently running the game.
Notifications might be used to indicate that a user has received a message, that some update is available in
game, or that the user needs to take some action. When used properly, they can be a very effective tool for
improving your game’s retention by drawing players back into your game at key moments before churn.
Using PlayFab's push notifications feature, developers may send unlimited push notifications to any number of
devices completely free of charge.
The following screenshot is an example from an Android device's notifications area showing a push notification.
As a best practice, you should tell players up front how you will be using the push notification service - including
the value the notifications will provide to the player before they are given a system OS prompt to allow or
disallow them.
Explaining how your game rewards or communicates via push notification can be the difference between
building community engagement and driving players away. For more information about push notification best
practices, check out this blog post.
Push notifications quickstart
5/24/2022 • 4 minutes to read • Edit Online
Push notifications from PlayFab are enabled by a linkage of three major systems:
1. The player’s device OS (Android, iOS, etc.)
2. The vendor-specific channel (Google, Apple, etc.)
3. Cross-platform message routing (PlayFab via Amazon Simple Notification Service [SNS]).
NOTE
If any of these systems are unlinked, clients will stop getting notifications. It is fairly simple to accidentally change one of
the three systems, and wind up breaking the link. Furthermore, it is difficult to know at any individual point in the flow if
all of the systems are configured properly.
TIP
Please see the FCM documentation for instructions on how to set up the FCM Unity plugin, or push on Android Studio.
Now, consider the following statistics defined for each player (see the Accessing Archived Tournament Results
tutorial for information on how to generate a test leaderboard).
Once you've set up these prerequisites, you can set up a push notification challenge system.
The following client code will call the CloudScript ChallengePlayer .
public void ChallengeRandomClosePlayer(string currentPlayerId) {
PlayFabClientAPI.GetLeaderboardAroundPlayer(new GetLeaderboardAroundPlayerRequest() {
MaxResultsCount = 10,
StatisticName = "Rank",
PlayFabId = currentPlayerId,
}, result => OnLeaderboardLoaded(result,currentPlayerId),OnPlayFabError);
}
PlayFabClientAPI.ExecuteCloudScript(new ExecuteCloudScriptRequest() {
FunctionName = "ChallengePlayer",
FunctionParameter = new Dictionary<string, object>() {
{ "TargetId", targetId }
}
}, null, OnPlayFabError);
}
The ChallengePlayer CloudScript code will handle the request, validate the leaderboard state, and send the
challenge push notification to the target.
handlers.ChallengePlayer = function (args) {
var targetId = args.TargetId;
var leaderboard = server.GetLeaderboardAroundUser({
MaxResultsCount : 10,
PlayFabId : currentPlayerId,
StatisticName : "Rank"
});
NOTE
Remember that there is no guarantee that your players will receive, open, or engage with your message. Given that
caveat, it is a good practice to use messages as bonus functionality, rather than as a critical part of your gameplay loop.
For iOS platforms, apps are given a one-time dialog prompt from the OS, allowing the user to determine the
status of push notifications. After the user has made their initial selection, this setting will persist until:
The App is updated or reinstalled.
The user makes changes to the settings from their phone’s settings menu.
For Android apps, notifications are enabled by default, and can be turned on and off at will from the client.
TIP
It is a good practice to re-initialize your notification listeners with every session.
Resources
The following resources provide additional information about the topics in this quickstart:
Firebase Unity SDK: An all-in-one FCM solution for Unity. This SDK, among all other features, allows you to
receive and process push notifications sent via FCM.
Push It Real Good: How to Get Players to Say Yes to Push Notifications: This blog post details additional
strategies and techniques for using push notifications.
Push Notifications: This blog post describes the most recent upgrade in Push functionality, and switching to
FCM as the primary plugin for Android.
Postman Quickstart: This quickstart shows you how to test our APIs using Postman.
Push notifications tutorials
5/24/2022 • 2 minutes to read • Edit Online
These tutorials have been designed to instruct you on how to use push notifications.
Getting Started with Android Push Notifications
Push notification templates
Push Notifications for Android
Push Notifications for iOS
Getting Started with Android Studio and push
notifications
5/24/2022 • 11 minutes to read • Edit Online
Overview
This tutorial has been designed to help you get up and running with Android PlayFab integration with push
notifications.
Push notifications require a configuration in several systems. Before getting started, let's talk about how the
infrastructure works. There are 4 entities participating in the process:
1. Google Play Ser vices
2. Firebase Cloud Messaging Ser vice s (FCM , built on top of the old Google Cloud Messaging .)
3. PlayFab Ser vices
4. Client Applications
1. Google Play Services
Google Play Services identifies your page on the play market using a package name.
An example of this would be: com.bob.games.matchthree .
When registered in Google Play, the package name becomes a unique application ID and serves many purposes,
from installing through play store to preventing impersonation.
2. Firebase Cloud Messaging (FCM )
Firebase Cloud Messaging services offer you a cloud-based system to send, direct, and deliver your push
notifications.
It also allows other services (like PlayFab) to send push notifications on your behalf using the FCM server key.
3. PlayFab Services
PlayFab Services then uses the FCM server key to send push notifications to your clients.
4. Client Services
Finally, your client application may receive notifications and process them as needed.
Four -way split
As a result of this, we need to set up 4 different systems. To do this, our tutorial is split into 4 chapters, covering
the configuration for each piece.
NOTE
The order that you use to configure the systems is important.
Prerequisites
You must have a Google account.
You must have a PlayFab account.
A generated notification icon using the Android Asset Studio Notification icon generator.
Scenario
In this section of our tutorial, we will be assembling an application called the Foo PlayFab App. It is an Android
app that has the following functions:
It signs into PlayFab using an Android Device ID.
It receives push notifications from PlayFab.
Our package name will be com.foo.playfab.app.
IMPORTANT
Make sure to use your own package name and title when following this tutorial.
You will be asked to provide a Project Name (in this tutorial we use our Foo PlayFab App , but make
sure to come up with your own name when following this tutorial).
Select the Create Project button to advance to the next step.
You will be redirected to the New Project Dashboard .
Add a new Android Application to the project by selecting the area as shown in the following picture.
A new Application requires 3 steps to be added.
1. First, you must provide an Android Package Name . We are using com.foo.playfab.app , but make
sure to come up with your own Package Name when following this tutorial.
2. Select the Register App button to move to the next step.
Step 2 allows you to download a settings file called google-ser vices.json . It will be used later in the App to
automatically configure Google services.
After you download it, select the Continue button to move to the next step.
3. The final step offers information on how to set up your build process to wire up the Firebase and Google Play
SDKs.
NOTE
You may ignore this information, as we will be using an automated tool built into the Android studio that performs this
setup automatically.
At this point, we have done everything we need in Firebase to enable push notifications.
Chapter 2: Configuring the Google Play console
When your app is ready, you will most likely create a Google Console Project to maintain a product Play Store
page. Let's go though the process of creating a GooglePlay Project, and linking it to the Firebase Project.
Start by visiting the Google Play Console page and creating a new project as shown in the following picture.
Assign the Title .
NOTE
In this example, we use Foo PlayFab App . Please make sure to come up with your own title and package name while
following this tutorial.
Take a moment to verify that the Sender ID displayed in the Google Play Console matches the one from
the Firebase Console , as shown in the example below.
At this point, the Google Play Console Project is successfully linked to the Firebase Project .
Chapter 3: Configuring the PlayFab title
The purpose of this chapter is to show you how to configure PlayFab Services, so that it can send push
notifications to the player on your behalf.
First, you must go to Title settings in your title's Settings menu.
Select the Push Notifications tab.
For the Android option, select the Settings icon.
You will be asked for your Google ser ver API key .
Copy the one you received through the Firebase console, as shown in the example provided below.
If everything is correct, you will be presented with a page that shows Push Notifications as Active .
NOTE
In the previous Chapter, you downloaded the google-services.json configuration file from the Firebase console. Use
this for your next step.
Verify that this file is placed under the App folder (2) .
Then, navigate to Tools (3) .
Select Firebase (4) , as shown in the example provided below.
The Firebase Assistant will open on the right side of the window.
Locate the Cloud Messaging folder, and select Set up Firebase Cloud Messaging , as shown below.
In the Firebase Notifications Assistant , select the Add FCM to your app (1) button as shown in the
following image.
A dialog will open indicating that new dependencies will be added via Gradle .
Select Accept Changes (2) to grant the changes.
NOTE
Unfortunately, the dependencies that are added automatically by the Gradle sync process (3 ) are incorrect and
will report failure!
To set up the dependencies correctly, replace the auto-added sentences with the following:
implementation 'com.google.firebase:firebase-core:16.0.3
implementation 'com.google.firebase:firebase-messaging:17.0.0
Once that process is complete:
Verify that the Firebase Notifications Assistant indicates that dependencies are now set up correctly (1) .
NOTE
In the beginning of this chapter, we acquired the necessary JAR files. Normally, the build file automatically fetches these
files.
To ensure that these JAR files are listed under the app/libs folder (2) , select all of the files and right-click
them.
Then choose Add as librar y... (3) , as shown in the example provided below.
Using the Android asset studio Notification icon generator, prepare the icons and place them inside
app/src/main/res .
In the example shown below, the icon is called ic_stat_blur_on .
Now we can start implementing code for receiving and handling notifications. We are going to modify (and
create if needed) 4 files:
1. app/src/main/AndroidManifest.xml
2. app/src/main/java/..packagePath../MainActivity.java
3. app/src/main/java/..packagePath../FooAppFirebaseInstanceIdSer vice.java
4. app/src/main/java/..packagePath../FooAppFirebaseMessagingSer vice.java
NOTE
The current implementation is crafted to be as short as possible, just to quickly test the notifications. Consider FCM
Guides for high-quality best practices and more complex implementation examples.
AndroidManifest.xml
In the following code, replace any MY_PACKAGE_IDENTIFIER placeholders with your own package identifier.
<application
android:allowBackup="true"
android:icon="@mipmap/ic_launcher"
android:label="@string/app_name"
android:supportsRtl="true"
android:theme="@style/AppTheme">
<activity android:name=".MainActivity">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
<!-- The following block enables our custom Firebase Instance ID Service-->
<service android:name=".FooAppFirebaseInstanceIdService" android:exported="true">
<intent-filter>
<action android:name="com.google.firebase.INSTANCE_ID_EVENT"/>
</intent-filter>
</service>
<service
android:name=".FooAppFirebaseMessagingService" android:exported="true">
<intent-filter>
<action android:name="com.google.firebase.MESSAGING_EVENT"/>
</intent-filter>
</service>
</application>
</manifest>
MainActivity.java
The following placeholders in the code should be replaced according to your scenario.
PLAYFAB_TITLE_ID
Use the ID for your title that you received in PlayFab Game Manager.
PACKAGE_IDENTIFIER
import android.os.AsyncTask;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.util.Log;
import com.playfab.PlayFabClientAPI;
import com.playfab.PlayFabClientModels.*;
import com.playfab.PlayFabErrors;
import com.playfab.PlayFabSettings;
import java.util.List;
import java.util.Map;
PlayFabErrors.PlayFabResult<LoginResult> response =
PlayFabClientAPI.LoginWithAndroidDeviceID(request);
if(response.Error != null){
Log.d("Foo PlayFab App",CompileErrorsFromResult(response.Error));
return false;
}
return true;
}
package PACKAGE_IDENTIFIER;
import android.text.TextUtils;
import android.util.Log;
import com.google.firebase.iid.FirebaseInstanceId;
import com.google.firebase.iid.FirebaseInstanceIdService;
import com.playfab.PlayFabClientAPI;
import com.playfab.PlayFabClientModels;
import com.playfab.PlayFabErrors;
import java.util.List;
import java.util.Map;
PlayFabErrors.PlayFabResult<PlayFabClientModels.AndroidDevicePushNotificationRegistrationResult>
response = PlayFabClientAPI.AndroidDevicePushNotificationRegistration(request);
if (response.Error != null) {
Log.d("Foo PlayFab App", CompileErrorsFromResult(response.Error));
}
}
FooAppFirebaseMessagingService.java
The placeholder in the code shown below should be replaced according to your scenario.
PACKAGE_IDENTIFIER
The Java package identifier that matches your setup.
package com.foo.playfab.app;
import android.util.Log;
import com.google.firebase.messaging.FirebaseMessagingService;
import com.google.firebase.messaging.RemoteMessage;
@Override
public void onMessageReceived(RemoteMessage message) {
// Intercept the message here
Log.d("Foo PlayFab App","Message received: "+message.getNotification().getBody());
}
}
Testing
At this point, you should be able to deploy the application to the device.
Once you start the application, it will automatically log in and register for push notifications.
Select the Home button on your device to minimize the Application. This is important, as it allows us to
test the Notification that arrives into the system tray.
Next, go to your PlayFab title Game Manager page, and use the Dashboard to locate the latest Push
Registration .
Select the Player ID (1) .
This will open a Send Push Notification page for that player.
Select the Send Push Notification button (1) .
Type in the Title (2) .
Enter the body of your message (3) .
Commit your changes by selecting the Send Push Notification button (4) .
If your message arrives, messages are successfully being delivered into your application.
At this point you have successfully integrated. You may use the FooAppFirebaseMessagingSer vice to handle
the incoming message while your application is actually running.
Push notification templates
5/24/2022 • 4 minutes to read • Edit Online
Do you have a player base which prefers different languages? PlayFab simplifies localized push notifications by
allowing multiple languages to be stored against a single template ID. You provide the strings - and we’ll provide
the smarts to send the right localized versions to your players.
NOTE
Before we added support for push notification templates, developers were able to explicitly define their push notifications
inside the rules or scheduled tasks that triggered them. These will continue to behave as they have before - however, in
order to add additional languages, you must use templates.
This tutorial walks you through the steps required to create a basic localized push notification template, and
then discusses how to configure PlayFab to automatically send it, when one of your players meets the specified
criteria.
Requirements
This is an advanced tutorial. It focuses on how to create a push notification template with localized strings, and
then configure logic to trigger the sending of that template to your players.
Please make sure that all requirements have been met or you will not be able to complete this tutorial. This
tutorial assumes your title has already been configured to send push notifications.
NOTE
For an introduction to push notifications and instructions for how to enable them on your title, please refer to the Push
notifications quickstart. It includes pointers for both iOS and Android (including configuring advanced payloads), as well as
how to use Postman to validate behavior.
Please become familiar with how to leverage our title default language and preferred player language support
in the Setting Default Languages tutorial. You must have a title default language set to continue with push
notification templates.
Message:
Select the SAVE PUSH NOTIFICATION TEMPL ATE button and you’re ready to go!
Sending this template to players who prefer Korean will get the localized version of the notification, all other
players will receive your default language message in English.
NOTE
We’re defining “lapsed” as not logging into the game for over 30 days (43200 minutes).
If you were to select the SAVE SEGMENT button at this point, you’d be able to use this segment to identify and
analyze players who haven’t visited your title for a while. When a player goes from 29 days without logging in
to 30 days, PlayFab will automatically add that player to this Lapsed Players segment.
Then, if a lapsed player logs in again, PlayFab will automatically remove them from this segment. Let’s have
PlayFab send our push notification when a player enters this segment:
With the entered Segment tab selected, select ADD ACTION that appears just above the Save Segment
button.
Then go to the Type field, and use the drop-down menu to select Send push notification .
Go to the Push notification template field next to it, and select Lapsed Players template from the second
drop-down menu.
Below is an example of how your screen should appear.
Now, when a player enters the Lapsed Players segment, PlayFab will send your localized push notification to
them. That’s all it takes to configure your push notification going out to your players.
While we’re here, let’s quickly discuss how you might make good on the promise of the “Welcome Back”
goodies we mention in the notification itself. Configuring actions to fire when the player leaves the segment is
an easy way (but not the only way) to make sure the player gets the gift you promised.
For this game, we have a CloudScript function which triggers an in-game experience welcoming the player back,
so we want to execute that for the player and grant them a special item from our catalog.
Push notifications for Android
5/24/2022 • 5 minutes to read • Edit Online
Prerequisites
Push Notifications quickstart
Unity3D quickstart
[Optional] Unity Editor Extensions
[Optional] Postman Quickstart
You should receive an HTTP 200 OK response with data similar to the following.
Once set up properly (using either method), you should see this in the Game Manager UI Settings
(for your title) > Push Notifications > Android .
using PlayFab;
using PlayFab.ClientModels;
using PlayFab.Json;
using UnityEngine;
// OnGUI should be deleted/replaced with your own gui - This is only provided for debugging
public void OnGUI()
{
GUI.Label(new Rect(0, 0, Screen.width, 200), pushToken);
GUI.Label(new Rect(0, 200, Screen.width, Screen.height - 200), lastMsg);
}
#if UNITY_ANDROID
var request = new AndroidDevicePushNotificationRegistrationRequest {
DeviceToken = pushToken,
SendPushNotificationConfirmation = true,
ConfirmationMessage = "Push notifications registered successfully"
};
PlayFabClientAPI.AndroidDevicePushNotificationRegistration(request, OnPfAndroidReg, OnPfFail);
#endif
}
Build and run your Unity project on a device. If you receive a push notification with the text, Push notifications
registered successfully , then everything worked as expected.
NOTE
PlayFabSettings.TitleId = TITLE_ID . You must set your own TitleId . This example will not work if you don't
update this TitleId , because our title is registered with our Firebase Keys and settings, not yours. You can do so by un-
commenting this line and replacing TITLE_ID with your titleId , or you can choose your title from the optional Editor
Extensions plugin mentioned in the previous section.
Troubleshooting Android
Verify that you can send a test push notifications from the Firebase Console.
If you cannot, then your Firebase plugin is not set up correctly, and you should review the Firebase
Documentation to find out why, or contact Firebase Support.
Ensure your FCM client pushToken is set properly.
The OnTokenReceived function in the example should be called, and should have a valid token.
If it is not called, your Firebase plugin is not set up correctly, and you should review the Firebase
Documentation to find out why, or contact Firebase Support.
Ensure your titleId is set to a title that you own, and that it has been registered with the server API key
from your Firebase project.
Advanced Features
In ser ver.SendPushNotification , you can use request.Package .CustomData to deliver arbitrary data to the
device. In the example previously, this is delivered to the section with the following comment.
You can customize your client receiver to utilize that data however you like. CustomData is not displayed to the
player, so it can be used to deliver custom game information to your client, or to locally schedule another future
notification using the FCM plugin.
You can also use request.Package .CustomData or request AdvancedPlatformDeliver y to deliver to many
3rd party plugins.
NOTE
3rd party plugin delivery is not supported or guaranteed, but is available for advanced users.
Additional Support
For help, example bugs, and related questions, drop us a line in our Forums.
Currently, we only support our services for the standard flow described in this document. If you team is looking
for additional functionality with other common push services or plugins, please let us know! We love getting
feedback from our developer community.
For documentation on the push payload via Amazon SNS:
Amazon SNS Message & JSON Formats
Push notifications for iOS
5/24/2022 • 3 minutes to read • Edit Online
Prerequisites
This tutorial assumes that you are familiar with the concepts covered in our Push Notifications quickstart.
Convert the .p12 file to a .pem file using the following console command:
openssl pkcs12 -in apns-dev-cert.p12 -out apns-dev-cert.pem -nodes -clcerts
Once you have the .pem file , you can upload it directly through the PlayFab Game Manager
under your Title's settings > Push Notifications .
Alternatively, use the generator below to craft a JSON request for SetupPushNotification .
JSON Request generator for SetupPushNotification
The request generator uses the following pieces of information to create a JSON Request:
Platform - Use one of the following values: APNS (iOS), APNS_SANDBOX (iOS), GCM (Android)
Application Name - Enter the name of the application sending the message.
NOTE
Application names must only be made up of uppercase and lowercase ASCII letters, numbers, underscores, hyphens, and
periods, and must be between 1 and 256 characters long. They must also be must be unique.
PEM Cer tificate / API Key - For iOS (APNS or APNS_SANDBOX), use the complete contents of your PEM
file.
Once the JSON is generated, use it to execute a call to SetupPushNotification . The response should look like the
example that follows.
{
“code” : 200,
“status” : “OK”,
“data” :
{
“ARN” : “arn:*******/GCM/your_game_name”
}
}
Congratulations! You have now configured your title’s iOS messaging channel.
At this point, if the user has opted in for notifications, we can call the PlayFab API
RegisterForIOSPushNotification.
byte[] token = UnityEngine.iOS.NotificationServices.deviceToken;
if(token != null)
{
RegisterForIOSPushNotificationRequest request = new RegisterForIOSPushNotificationRequest();
request.DeviceToken = System.BitConverter.ToString(token).Replace("-", "").ToLower();
PlayFabClientAPI.RegisterForIOSPushNotification(request, (RegisterForIOSPushNotificationResult result)
=>
{
Debug.Log("Push Registration Successful");
}, OnPlayFabError);
}
else
{
Debug.Log("Push Token was null!");
}
If no errors occurred, congratulations! Your iOS client has been successfully linked to your title’s Apple
Notification channel.
Troubleshooting iOS
Verify that you have valid .pem files.
Ensure that the same certificate used in SetupPushNotification is used by XCode to sign your App.
Verify that the Push Notification API is enabled for your build in XCode.
Verify that your signing certificate matches the PlayFab platform. When running SetupPushNotification ,
use OverwriteOldARN = true to rebind the channel to a new platform. Only one iOS environment (APNS or
APNS_SANDBOX) can be active on a title at a given time.
Additional Support
For help, example bugs, and related questions, drop us a line in our Forums.
NOTE
Currently, we only support our services for the standard flow described in this document. If your team is looking for
additional functionality with other common push services or plugins, please let us know! We love getting feedback from
our developer community.
Email Messaging
5/24/2022 • 2 minutes to read • Edit Online
To send emails from PlayFab, you will need to have your own external SMTP server with a username and
password. Once you have an SMTP server available, check out Setting up an SMTP server with add-ons to
configure your title to send emails.
NOTE
You can use Gmail as an SMTP server for testing - but with Gmail, you are limited to 2,000 emails per day.
Once your SMTP Server is set up and configured in PlayFab, you can follow our tutorials for Using a rule to
verify a contact email address or Using email templates
You can also use the following APIs to manage player contact information and email functionality:
AddorUpdateContactEmail - Updates or adds a contact email to the player’s profile.
RemoveContactEmail - Deletes a contact email from the player’s profile.
SendEmailFromTemplate - Sends a template email to a player’s primary contact email.
SendAccountRecoveryEmail - Sends an Account Recovery email to the specified player.
ResetPassword - Resets the player’s password for a given title.
GetPlayerIdFromAuthToken - Gets a player’s ID from an authorization token.
Emails Tutorials
5/24/2022 • 2 minutes to read • Edit Online
PlayFab is introducing support for storing localized strings on behalf of game developers. In addition, we are
adding the necessary logic to provide your players with the correct strings for the language they prefer.
This tutorial walks you through how to use localized email templates. With localized email templates, you can
make multiple translated versions of an email, and associate all of them with one template ID.
NOTE
Any templates introduced before this feature was released will retain their behavior. However, you can easily update them
to use the new localized format used by new email templates.
Requirements
This is an advanced tutorial. Please make sure that all requirements have been met, or you will not be able to
complete this tutorial.
For an introduction to email templates, refer to the Using Email Templates to Send an Account Recovery
Email tutorial.
Please review the information on how to work with default languages on your title, and the preferred
languages for your players in the Setting Default Languages tutorial. You must have a title default language
set to continue with localized email templates.
For the purposes of this tutorial, we will assume your title default language is English. You’ll see that your
existing version of the template shows up as the default language version.
Adding more languages is as simple as selecting the + ADD L ANGUAGE link that is provided, then choosing
the language you want to add to the template, and typing in the localized strings.
In this example, we're going to add the following French strings to our existing template.
French email subject:
<head></head>
<body><p>Vous avez récemment demandé un mot de passe avec nous. </p>
<p>Cliquez <a href="$ConfirmationUrl$">ici</a> s'il vous plaît pour être dirigé vers une page pour
réinitialiser votre mot de passe.
Here's what it should look like:
When you select the SAVE EMAIL TEMPL ATE button, you'll be redirected back to the page containing the list
of your email templates.
As you can see, a new language version was added, but a new template was not added, since all language
versions are stored under the same template ID.
NOTE
When using the SetProfileLanguage API, the language string must be specified in the ISO 639-1 format (for example,
"en", "es", or "ja"). At the current time, the code "zh" is not supported.
Make sure you have set the contact email on both players as explained in Step 2 of the Using Email Templates to
Send an Account Recovery Email tutorial, before continuing on to the next step.
Use the SendCustomAccountRecoveryEmail API once per player to send this template:
Once in French to the player whose preferred language is French.
Once in the default language to a player with no preferred language set.
Sample email to the player with no preferred language is shown below.
Sample email to the player whose preferred language is French is shown below.
Conclusion
As you can see, PlayFab noticed there was a match between your template's support for French, and the player's
language preference.
Where there was no match or no preference, the player received your title's default language strings.
If you have any questions or feedback on this tutorial, please contact us through our forums or slack channel.
Setting up an SMTP server with add-ons
5/24/2022 • 2 minutes to read • Edit Online
This tutorial walks you through how to set up an SMTP add-on, to support sending custom emails through
PlayFab.
Requirements
Game Manager will be required, as the SMTP server for the title is set up using an add-on. Read our Game
Manager Quickstart if you are unfamiliar with it.
Configure SMTP
A form should appear with the Host name , Por t number , Username , and Password fields.
Fill out the form with Host name , Por t number , Username , and Password for your SMTP server.
Select the SAVE SETTINGS button, and the add-on should now be installed.
NOTE
If your SMTP server requires SSL/TLS, use por t 587 .
Testing
To test this feature, you can use the Gmail SMTP server, provided you have a Gmail account. To use Gmail, fill in
the fields as follows:
Host name: smtp.gmail.com
Port number: 587
Username: (your gmail address - e.g., "support@playfab.com")
Password: (your password )
NOTE
If you have 2-factor authentication enabled, you will need to create an App password. See Sign in using an App password
for more information.
The SMTP add-on is now installed, and will show a green check and message indicating success.
Using a rule to verify a contact email address
5/24/2022 • 6 minutes to read • Edit Online
This tutorial walks you through the steps for creating a rule that sends a verification email when a player
changes their contact email address.
Requirements
IMPORTANT
This is an advanced tutorial. Please make sure that all of the requirements have been met, or you will not be able to
complete this tutorial.
To send custom emails with email templates, you will need to have your own SMTP server with a username
and password. Please verify that you have your own SMTP server before following our tutorial Setting up an
SMTP server with add-ons.
NOTE
You can use Gmail for testing - but with Gmail you are limited to 2,000 emails per day.
Basic knowledge of how to create a player will be necessary, since there will need to be players with a
username and password before calling account recovery logic.
Read the Game Manager quickstart if you are unfamiliar with the Game Manager, as it is the place where
email templates are created.
Knowledge of how to work with player profiles will be required, to confirm that emails will be necessary for
checking that a contact email has been added to a player's profile. Please read up on how to get a player's
profile in the Getting Player Profiles tutorial, and make sure that under the Client Profile Options on your
Title you allow Contact email addresses .
Creating a rule will be necessary in this tutorial it is a good idea to read up on how Rules work.
<head></head>
<body><p> You recently registered a new email with us.</p>
<p>Please click <a href="$ConfirmationUrl$">here</a> confirm your email. Thanks!</p>
From Name : The name you want to show in the From field in the email.
From Email Address : The email address you want to show in the From field in the email. This must be
an email domain that the SMTP server enables you to send emails from.
NOTE
Some email servers, like Gmail, will ignore this field and send from the account set up with the SMTP server.
NOTE
A Contact Email field in a Player Profile is different from the Login Email field on a Player Profile, even though they
may both contain the same email address. Any time you send email to the player, it will only go to the contact email
address.
C# code example
In the following example, we log in a player, then add a contact email using AddOrUpdateContactEmail. Make
sure the email address associated with the player is one that you can access.
void AddContactEmailToPlayer()
{
var loginReq = new LoginWithCustomIDRequest
{
CustomId = "SomeCustomID", // replace with your own Custom ID
CreateAccount = true // otherwise this will create an account with that ID
};
Step 4 - Confirm that the contact email was added to the player's
profile
Next, confirm that the contact email was added to the player's profile. Log into the Game Manager , and visit
the Players Profile page.
You should see a Contact Email listed for that player, with Verification Status : Pending .
NOTE
The Verification Status could be Unverified , if the verification email was not sent out yet, but will move to the
Pending state as soon as the email is sent.
You can also make a call to GetPlayerProfile with ShowContactEmailAddresses in the
PlayerProfileViewConstraints set as True to show that the player now has the contact email that we just added.
Selecting the Info icon on the Event should show JSON similar to the one shown below.
{
"EventName": "sent_email",
"EventNamespace": "com.playfab",
"Source": "PlayFab",
"EntityType": "player",
"TitleId": "YourTitleId",
"EventId": "a05625e48b1f4194bd08d1ff6a889cf8",
"EntityId": "64647AA368D6448E",
"SourceType": "BackEnd",
"Timestamp": "2017-10-27T09:35:16.2946918Z",
"History": null,
"CustomTags": null,
"Reserved": null,
"emailTemplateId": "7D6438687903D4DC",
"emailTemplateName": "MyFirstEmailVerificationTemplate",
"emailTemplateType": "EmailVerification",
"success": true,
"emailName": "Primary"
}
To verify that you actually received the email, go to the email of the player you created in Step 3. There should be
an email that looks similar to the one shown below.
If you inspect the URL in that email, you will see that it looks something like this one.
https://a5f3.playfabapi.com/EmailConfirmation/Confirm/?
token=2346241B7C277796&titleId=A5F3&templateId=38017AAE7F494AB3
Conclusion
So that's it for this tutorial. You've seen how to setup your SMTP server, create an email template, and create a
rule that sends an email to a player verifying their email address.
If you have any questions or feedback on this tutorial, please let us know in our community forums.
Using email templates to send an account recovery
email
5/24/2022 • 7 minutes to read • Edit Online
This tutorial walks you through how to use the email template feature of PlayFab to send an account recovery
player's contact email address, to let a player reset their password.
Requirements
IMPORTANT
This is an advanced tutorial. Please make sure that all requirements have been met, or you will not be able to complete
this tutorial.
To send custom emails with email templates, you will need to have your own SMTP server with a username
and password. Please be sure that you have your own SMTP server before using our tutorial Setting up an
SMTP server with add-ons.
NOTE
You can use Gmail for testing, but Gmail limits you to 2,000 emails per day.
Basic knowledge of how to create a player will be necessary, since there will need to be players with a
usernames and passwords before calling account recovery logic.
Read the Game Manager quickstart if you are unfamiliar with the Game Manager, as it is the place where
email templates are created.
Knowledge of how to work with player profiles will be required to confirm that emails will be necessary for
checking that a contact email has been added to a player's profile. Please read up on how to get a player
profile in the Getting Player Profiles tutorial, and make sure that under the Client Profile Options on your
Title you allow Contact email addresses .
<head></head>
<body><p> You recently requested a password reset with us.</p>
<p>Please click <a href='$ConfirmationUrl$'>here</a> to be directed to a page to reset your password.
Thanks!</p>
From Name : The name you want to show in the From field in the email.
From Email Address : The email address you want to show in the From field in the email. This must be an
email domain that the SMTP server enables you to send emails from.
NOTE
Some email servers, like Gmail, will ignore this field and will send from the account set up with the SMTP server.
Callback URL : A callback URL to a password recovery form. At the minimum, the form must contain a
Password field for the player to enter a new password.
A few things to note
The $ConfirmationUrl$ in the email body generates a customized URL that, when selected, tracks that a user
has chosen the URL, and then issues a redirect to the Callback URL . In this case, it is injected into an anchor
tag.
The Callback URL is the URL that PlayFab will redirect to after the player selects the confirmation URL link.
It will need to be a hosted web form that contains at very minimum a Password field, in order to make a
ResetPassword API call later in this tutorial.
After filling the form out, select the SAVE EMAIL TEMPL ATE button, and you will be redirected back to the
page containing the list of your Email Templates showing. Make a note of the ID of the Email Template as it
will be used in Step 4.
Step 2 - Add username, password, login email, and contact email to a
player
For this next step, you will need an existing player account.
We will add a username, password, and login email using AddUsernamePassword. Additionally, we add a
contact email to the player using AddOrUpdateContactEmail.
NOTE
A contact email field on a player profile is different from the login email field on a player profile, even though they may
both contain the same email address. Any time you send email to the player, it will go to the contact email address.
C# code example
In the following example, we log in a player, then add a username, password, and login email using
AddUsernamePassword. We then add a contact email using AddOrUpdateContactEmail. Make sure the email
address associated with the player is one that you can access.
void CreatePlayer()
{
var loginReq = new LoginWithCustomIDRequest
{
CustomId = "SomeCustomID", // replace with your own Custom ID
CreateAccount = true // otherwise this will create an account with that ID
};
void AddUserNamePassword()
{
var request = new AddUsernamePasswordRequest
{
Username = "yourusername",
Password = "yourpassword",
Email = "exampleemail@emaple.com" // Login email
};
PlayFabClientAPI.AddUsernamePassword(request, result =>
{
Debug.Log("The player's account now has username and password");
}, FailureCallback);
}
Step 3 - Confirm that the contact email was added to the player's
profile
Next, confirm that the contact email was added to the player's profile. Log into the Game Manager , and visit
the Player's Profile page. You should see a Contact email listed for that player.
You can also make a call to GetPlayerProfile with ShowContactEmailAddresses in the
PlayerProfileViewConstraints set as true, to show that the player now has the contact email that we just added.
Selecting the Info icon on the event should show JSON similar to what appears below.
{
"EventName": "sent_email",
"EventNamespace": "com.playfab",
"Source": "PlayFab",
"EntityType": "player",
"TitleId": "YourTitleId",
"EventId": "655f14ac45b341b59c217dcf04d26ef9",
"EntityId": "64647AA368D6448E",
"SourceType": "BackEnd",
"Timestamp": "2017-10-27T23:53:58.8717009Z",
"History": null,
"CustomTags": null,
"Reserved": null,
"emailTemplateId": "DC3E1B28881C6071",
"emailTemplateName": "PasswordRecoveryTemplate",
"emailTemplateType": "AccountRecovery",
"success": true,
"emailName": "Primary"
}
To check that you actually receive the email, go to the email of the player you created in Step 2. There should be
an email that looks similar to what is shown below.
If you inspect the URL in that email, you will see that it looks something like this example.
https://a5f3.playfabapi.com/EmailConfirmation/Confirm/?
token=2346241B7C277796&titleId=A5F3&templateId=38017AAE7F494AB3
Conclusion
That's it for this tutorial! You've seen how to set up your SMTP server, create an email template, send an account
recovery email, and reset a player's password.
If you have any questions or feedback on this tutorial, please let us know in our community forums.
What is PlayFab Data?
5/24/2022 • 2 minutes to read • Edit Online
PlayFab Data is a set of tools for data analytics, storage, processing, and exports. The features are Title data,
Players data, Characters data, Groups data, along with data management and provisiong features like Entities,
Content delivery network and Webhooks.
Players data, Characters data, Groups data are saved which manage the store settings, game save state, or other
data. To get started, see the Player data Quickstart.
Title data manages the remote configurations of the game as key-value pairs. To get started, see the Title data
Quickstart.
Entities are the most basic addressable "things" that PlayFab APIs operate on. Each entity has a Type and an Id
which together uniquely identify it. The parent/child relationships between entities exists which governs the
permissions on how an entity's resources may be accessed by other entities. To get started, see the Entities
Quickstart.
Content delivery network is an infrastructure used to deliver assets - such as images, audio, binary content, etc. -
to the end user that focuses on speed and availability. To get started, see the Content delivery network
Quickstart.
Webhooks enables you to do event handling in your own custom server. To get started, see the Webhooks
Overview.
Player Data
5/24/2022 • 2 minutes to read • Edit Online
Player data is information about a player that is stored to the PlayFab service that you can share across multiple
devices and multiple games.
PlayFab provides two ways to store player data:
Entities: Allows you to store data in objects and files across Players, Characters, and Groups.
Player Data/UserData: Allows you to store Key/Value pair data for players.
To provide the most flexibility and best performance, we recommended that all new titles use Entity objects.
In the PlayFab APIs, the function names use the term UserData . In the Game Manager , this concept is
described as Player Data . They are identical, and interchangeable.
There are three modes of access to player data:
Client: This is player data that is available to your title client to read and update. You use the client APIs
UpdateUserData to create, update, or delete and GetUserData to read data for the player.
Read Only: This is player data that is created or updated by your server. Your title client can read, but not
update, this data. You use the server API UpdateUserReadOnlyData to create, update, or delete and the client
API GetUserReadOnlyData to read title-specific data for the player. This data is visible to the player, but can
only be modified by the server.
Internal: This is player data that is only available to your server. You use the server APIs
UpdateUserInternalData to create, update, or delete and GetUserInternalData to read title-specific data for the
player. This data is server-only, and cannot be seen by the client.
When you use player data, only User Data and User Read Only Data are available to the Client API. If you have
player data that another player should be able to read, you need to set the Permission value to Public when
you write the data.
Player Publisher data usage is nearly identical to player data usage. They are both dictionaries mapping a string
to a JSON blob (or other arbitrary string value).
For more information, see How to use player publisher data to grant a reward for playing multiple titles.
Quickstart: Set and get player data
5/24/2022 • 4 minutes to read • Edit Online
NOTE
In the PlayFab APIs, the function names utilize the term UserData . In the Game Manager , this concept is described as
Player Data . They are identical, and interchangeable.
Get started using PlayFab Player Data. This quickstart shows you how to set and retrieve player data using C# in
Unity and using PlayFab CloudScript.
Player data is information that applies to an individual player or player group (shared data) and is stored as
Key/Value Pairs (KVPs) by PlayFab. This topic covers client API calls, which are safe to call from any process or
context. It also covers server API calls, which should only be made from a dedicated server process you control,
or a carefully secured CloudScript call. Server APIs require your dev secret key, which you should never provide-
to or publish-with your client.
The C# Samples in this topic are written for the Unity SDK. The Unity SDK uses an event driven model to handle
non-synchronous tasks. To run the sample code using the standard C# or Xamarin C# SDKs you must modify
the code to use an async Task model. Methods that must be modified have Async append to the method name in
the signature. For example, SetObject in the Unity SDK becomes SetObjectAsync in the standard C# SDK. For
more information, see Asynchronous programming with async and await.
Requirements
A PlayFab developer account.
An installed copy of the Unity Editor. To install Unity for personal use via Unity Hub, or Unity+ for
professional use, see Download Unity.
NOTE
The PlayFab Unity3D SDK supports Unity Editor version 5.3 (released December 2015) and higher.
Add a methods to set the player data and retrieve the player data
1. In the Unity Editor, open your sample project.
2. In the Project window, open Assets > Scripts and then open the PlayFabLogin script.
3. In Visual Studio, add the following to the following using statement:
using System.Collections.Generic;
4. To set player data, add a SetUserData method to the PlayFabLogin class. SetUserData uses the
UpdateUserData method to create or update the player data for the logged in player.
The method creates (or updates, if the Key Value Pairs (KVPS) already exist) the KVPs Ancestor with the
value Arthur , and Successor with the value Fred .
void SetUserData() {
PlayFabClientAPI.UpdateUserData(new UpdateUserDataRequest() {
Data = new Dictionary<string, string>() {
{"Ancestor", "Arthur"},
{"Successor", "Fred"}
}
},
result => Debug.Log("Successfully updated user data"),
error => {
Debug.Log("Got error setting user data Ancestor to Arthur");
Debug.Log(error.GenerateErrorReport());
});
}
5. To get player data, add a GetUserData method to the PlayFabLogin class. SetUserData uses the
GetUserData method to retrieved the player data for the specified player.
void GetUserData(string myPlayFabeId) {
PlayFabClientAPI.GetUserData(new GetUserDataRequest() {
PlayFabId = myPlayFabeId,
Keys = null
}, result => {
Debug.Log("Got user data:");
if (result.Data == null || !result.Data.ContainsKey("Ancestor")) Debug.Log("No Ancestor");
else Debug.Log("Ancestor: "+result.Data["Ancestor"].Value);
}, (error) => {
Debug.Log("Got error retrieving user data:");
Debug.Log(error.GenerateErrorReport());
});
}
6. To call the add calls to the SetUserData and GetUserData in the OnLoginSuccess medthod:
See Also
How to set internal player data
How to get internal player data
How to set read-only player data
How to get read-only player data
How to modify read-only or internal player data from CloudScript
Title Data quickstart
Using Publisher Data
CloudScript quickstart
How to set internal player data
5/24/2022 • 2 minutes to read • Edit Online
To set internal player data, use the Server API UpdateUserInternalData method. This is data that the client cannot
access.
The C# Sample in this topic are written for the Unity SDK. The Unity SDK uses an event driven model to handle
non-synchronous tasks. To run the sample code using the standard C# or Xamarin C# SDKs you must modify
the code to use an async Task model. Methods that must be modified have Async append to the method name in
the signature. For example, SetObject in the Unity SDK becomes SetObjectAsync in the standard C# SDK. For
more information, see Asynchronous programming with async and await.
C# code example
The following C# code example uses the PlayFab server API to create (or update, if a key value already exists)
the KVPs with the key named Class , with the value Fighter , and Race with the value Human .
See also
How to get internal player data
How to get internal player data
5/24/2022 • 2 minutes to read • Edit Online
To get internal player data, use the Server API GetUserInternalData method. This is internal data that you should
not expose it to the client.
The C# Sample in this topic are written for the Unity SDK. The Unity SDK uses an event driven model to handle
non-synchronous tasks. To run the sample code using the standard C# or Xamarin C# SDKs you must modify
the code to use an async Task model. Methods that must be modified have Async append to the method name in
the signature. For example, SetObject in the Unity SDK becomes SetObjectAsync in the standard C# SDK. For
more information, see Asynchronous programming with async and await.
C# code example
The following C# code example retrieves the Key Value Pairs of the player internal data.
See also
How to set internal player data
How to set read-only player data
5/24/2022 • 2 minutes to read • Edit Online
To set read-only KVPs, you must call the Server API UpdateUserReadOnlyData method from a server process.
This is data that the server can modify, but the client can only read.
The C# Samples in this topic are written for the Unity SDK. The Unity SDK uses an event driven model to handle
non-synchronous tasks. To run the sample code using the standard C# or Xamarin C# SDKs you must modify
the code to use an async Task model. Methods that must be modified have Async append to the method name in
the signature. For example, SetObject in the Unity SDK becomes SetObjectAsync in the standard C# SDK. For
more information, see Asynchronous programming with async and await.
C# code example
The following C# code example uses the PlayFab server API to create (or update, if the KVPs already exist) the
KVPs with the key named Father , with the value Fred , Mother with the value Alice , Sister with the value
Lucy , and Brother with the value Doug .
See also
How to get read-only player data
How to get read-only player data
5/24/2022 • 2 minutes to read • Edit Online
To get read-only player data, use the Server API GetUserReadOnlyData method.
The C# Sample in this topic are written for the Unity SDK. The Unity SDK uses an event driven model to handle
non-synchronous tasks. To run the sample code using the standard C# or Xamarin C# SDKs you must modify
the code to use an async Task model. Methods that must be modified have Async append to the method name in
the signature. For example, SetObject in the Unity SDK becomes SetObjectAsync in the standard C# SDK. For
more information, see Asynchronous programming with async and await.
C# code example
The following C# code example uses the PlayFab server API to get all of the player read-only data.
See also
How to set read-only player data
How to modify read-only or internal player data
from CloudScript
5/24/2022 • 2 minutes to read • Edit Online
Player data is accessible from CloudScript if you require it for your title.
For more information about using CloudScript, see CloudScript quickstart.
The C# Sample in this topic are written for the Unity SDK. The Unity SDK uses an event driven model to handle
non-synchronous tasks. To run the sample code using the standard C# or Xamarin C# SDKs you must modify
the code to use an async Task model. Methods that must be modified have Async append to the method name in
the signature. For example, SetObject in the Unity SDK becomes SetObjectAsync in the standard C# SDK. For
more information, see Asynchronous programming with async and await.
function IncrementReadOnlyUserData(args) {
var playerData = server.GetUserInternalData({
PlayFabId: currentPlayerId,
Keys: ["ReadOnlyTest"]
});
C# code example
As explained in the CloudScript quickstart, you can call the following logic from the client.
public void CloudIncrement() {
PlayFabClientAPI.ExecuteCloudScript( new ExecuteCloudScriptRequest {
FunctionName = "IncrementReadOnlyUserData"
},
result => Debug.Log("CloudScript call successful"),
error => {
Debug.Log("CloudScript call failed");
Debug.Log(error.GenerateErrorReport());
});
}
How to use player publisher data to grant a reward
for playing multiple titles
5/24/2022 • 3 minutes to read • Edit Online
Rewards usually involve other systems outside of player data, so this example demonstrates awarding virtual
currency for the sake of simplicity.
Requirements
A PlayFab developer account.
A player must sign into both titles using the same credentials. One approach is to use Recoverable
Credentials , as described in our Login Basics and Best Practices tutorial. To add a Recoverable login to an
anonymous account, see our Account Linking tutorial.
This example requires a working knowledge of CloudScript:
Our example demonstrates basic data security to avoid player cheating. One could likewise use the
server API on a custom game server, if the title makes use of them.
Rewards triggered through PlayFab require usage of the appropriate PlayFab features. PlayFab Rewards can
be in the form of Vir tual Currency , Inventor y Items , Custom Player Data , Statistics , etc. Distributing
rewards outside of PlayFab systems is an advanced topic, and is not covered in this tutorial.
We also recommended that developers use good error handling on all server API calls made from CloudScript.
NOTE
This particular example demonstrates the use of server.GetUserPublisherInternalData (requesting multiple keys),
server.UpdateUserPublisherInternalData, and server.AddUserVirtualCurrency.
Conclusion
Player publisher data and player data are structurally identical.
Player data should be title-specific, while player publisher data should only contain information relevant across
all of your titles.
See also
Simple In-Game Cross Promotion: Reward players participating in more than one of your games.
Player Data Tutorials
5/24/2022 • 2 minutes to read • Edit Online
These tutorials describe how to create and use player statistics, profile information, and other types of player
data.
Getting player profiles
Player Ban system
Player inventory
Player Logins report
Player Segment configuration
Player Segments
PlayFab GDPR
Using Player details
Using Player Publisher Data
Using player statistics
Using the Players page
Tutorial: Get a player profile
5/24/2022 • 4 minutes to read • Edit Online
Requirements
A PlayFab developer account.
An installed copy of the Unity Editor. To install Unity for personal use via Unity Hub, or Unity+ for
professional use, see Download Unity.
NOTE
The PlayFab Unity3D SDK supports Unity Editor version 5.3 (released December 2015) and higher.
It is also worthwhile to read the Game Manager quickstart if you are unfamiliar with the Game Manager, as it is
the place where we configure profile constraints.
The C# Samples in this topic are written for the Unity SDK. The Unity SDK uses an event driven model to handle
non-synchronous tasks. To run the sample code using the standard C# or Xamarin C# SDKs you must modify
the code to use an async Task model. Methods that must be modified have Async append to the method name in
the signature. For example, SetObject in the Unity SDK becomes SetObjectAsync in the standard C# SDK. For
more information, see Asynchronous programming with async and await.
void UpdateDisplayName() {
PlayFabClientAPI.UpdateUserTitleDisplayName( new UpdateUserTitleDisplayNameRequest {
DisplayName = "UnicornTossMaster"
}, result => {
Debug.Log("The player's display name is now: " + result.DisplayName);
}, error => Debug.LogError(error.GenerateErrorReport()));
}
The response includes a PlayerProfileModel object that contains the display name UnicornTossMaster for the
player.
The next step is to get even more profile data for the player. To do so, call GetPlayerProfile with additional
fields in the PlayerProfileViewConstraints request parameter.
The following C# example modifies the GetPlayerProfile method from step 2 and calls GetPlayerProfile to
request the Created and LastLogin fields by setting their flags in the ProfileConstraints.
NOTE
This will be an unsuccessful call at this step!!!
void CreatePlayerAndUpdateDisplayName(string playFabId) {
PlayFabClientAPI.GetPlayerProfile( new GetPlayerProfileRequest() {
PlayFabId = playFabId,
ProfileConstraints = new PlayerProfileViewConstraints {
ShowDisplayName = true,
ShowCreated = true,
ShowLastLogin = true
}
},
result => Debug.Log("The player's profile Created date is: " + result.PlayerProfile.Created),
error => Debug.LogError(error.GenerateErrorReport()));
}
If you run this sample code at this point, it returns an error with an Error Code 1303 .
RequestViewConstraintParamsNotAllowed , and an error message stating that there are Invalid view constraints
with a JSON output of constraints that the title currently has set.
The error occurs because you have not yet configured the ability to show Created and LastLogin in your title's
profile constraint settings.
NOTE
This works with every login mechanism.
void CreatePlayerAndUpdateDisplayName(string customId) {
PlayFabClientAPI.LoginWithCustomID( new LoginWithCustomIDRequest() {
CustomId = customId,
// Define info request parameters
InfoRequestParameters = new GetPlayerCombinedInfoRequestParams() {
// And make sure PlayerProfile is included
GetPlayerProfile = true,
// Define rules for PlayerProfile request
ProfileConstraints = new PlayerProfileViewConstraints() {
// And make sure that both AvatarUrl and LastLogin are included.
ShowAvatarUrl = true,
ShowLastLogin = true,
}
}
},
result =>
{
// Extract the data you have requested
var avatarUrl = result.InfoResultPayload.PlayerProfile.AvatarUrl;
},
error => Debug.LogError(error.GenerateErrorReport()));
}
Player inventory
5/24/2022 • 7 minutes to read • Edit Online
Requirements
In order to use the player inventory, you must have a catalog defined for your title. Please read our Catalogs
tutorial for more information.
NOTE
Optionally, you can also define stores for your catalog.
While a catalog is the list of all of the items available in the game, a store is a subset of items from the catalog
that has the option of unique pricing.
Multiple stores can be defined per catalog, so that you can have distinct sets of items for presentation to the
player, based upon user segmentation or other factors.
Once you have defined a catalog through the Game Manager , or though our admin SetCatalogItems or
UpdateCatalogItems API calls, you will be able to use a wide variety of Inventory API calls on the client and
server.
API Overview
All inventory API calls are designed to be server-authoritative and secure. Used properly, customers will not be
able to cheat or acquire items they did not earn.
Clients :
Buy Items with virtual currency: PurchaseItem
Make Real Money purchases: Star tPurchase , PayForPurchase , ConfirmPurchase
Can view the items a player has: GetUserInventor y
Can remove items: ConsumeItem , UnlockContainerInstance
Can trade items: OpenTrade , GetPlayerTrades , AcceptTrade , CancelTrade
Ser ver :
May Gift/Grant items: GrantItemsToUser
Can view the items: GetUserInventor y
Can modify items: ModifyItemUses , UpdateUserInventor yItemCustomData
Can remove items: RevokeInventor yItem , ConsumeItem , UnlockContainerInstance
The example shown below illustrates the code blocks that call these API methods, and sets up basic use-cases
for player inventory.
NOTE
For reference, these examples come from Unicorn Battle , a game we built as an example to demonstrate the PlayFab
features.
The AU virtual currency used below is Gold , a free currency earned by fighting monsters (See our Currencies
tutorial).
Before we get started, we will be defining a few utility functions that will be used and reused in most of the
examples in this guide.
// Error handling can be very advanced, such as retry mechanisms, logging, or other options
// The simplest possible choice is just to log it
void LogFailure(PlayFabError error) {
Debug.LogError(error.GenerateErrorReport());
}
void MakePurchase() {
PlayFabClientAPI.PurchaseItem(new PurchaseItemRequest {
// In your game, this should just be a constant matching your primary catalog
CatalogVersion = "CharacterClasses",
ItemId = "MediumHealthPotion",
Price = 5,
VirtualCurrency = "AU"
}, LogSuccess, LogFailure);
}
void GetInventory() {
PlayFabClientAPI.GetUserInventory(new GetUserInventoryRequest(), LogSuccess, LogFailure);
}
void ConsumePotion() {
PlayFabClientAPI.ConsumeItem(new ConsumeItemRequest {
ConsumeCount = 1,
// This is a hex-string value from the GetUserInventory result
ItemInstanceId = "potionInstanceId"
}, LogSuccess, LogFailure);
}
Client code
void OpenContainer() {
PlayFabClientAPI.UnlockContainerInstance(new UnlockContainerInstanceRequest {
// In your game, this should just be a constant matching your primary catalog
CatalogVersion = "CharacterClasses",
ContainerItemInstanceId = "containerInstanceId",
KeyItemInstanceId = "keyInstanceId"
}, LogSuccess, LogFailure);
}
The following CloudScript function combines the two described server calls into a single client-accessible call.
Best practices
Make sure to verify all client input information as valid before making any changes.
CloudScript is not atomic, so call order matters: AddUserVir tualCurrency may succeed and
RevokeInventor yItem may fail.
TIP
It is generally better to give the player something they didn't earn in this process, than to take something away without
compensation.
Monitoring players
It is possible to inspect the players you have in your title using the Players page.
Go to the Game Manager page.
Select Players from the menu on the left.
Select the Players tab.
On this page, You can inspect the list of registered players in a table format. The table contains general
information about the player.
You can select a player ID label (blue) to inspect details about a particular player. You can also use the Search
Quer y field to look up players.
Search Techniques
The Search query field accepts two types of queries:
1. Simple : Type plain text in the search box to return literal string matches on the ID column.
2. Complex : Construct queries using the KQL syntax.
Sample complex queries can be accessed from the Search Tips button in the upper right. Selecting a sample
query will automatically populate the search box with the correct KQL syntax. You can then edit the query to suit
your use case.
There are many attributes of the Player Profile table, not all of which are visualized in the UI. However, you may
search on any of these PlayerProfile columns using a complex query.
NOTE
Remember - you can use any searchable player field as a query parameter.
Using player details
5/24/2022 • 3 minutes to read • Edit Online
Overview
The Player Over view (or details page), is a starting point for controlling your player. A lot of other player
pages are available from this page (we'll list them later in this tutorial).
1. The Player ID - Shows you the identity of the player you have selected.
2. The Player toolbar - Gives you access to various player-related pages.
3. The Run CloudScript button - Gives you access to cloud scripting on behalf of the player.
NOTE
You can read more about this in our CloudScript quickstart.
Additionally, you can manage linking. Read more about linking in our quickstart on Account linking.
NOTE
It is only possible to manually link Custom ID, Android Device, or iOS Device accounts. For more sophisticated options
(Steam, GameCenter, etc.), consider using other Client Account Management APIs listed in our PlayFab API Reference
documentation.
Running CloudScript
The Run CloudScript button on the Player Over view page opens the REVISION AND FUNCTION page
shown below. On the REVISION AND FUNCTION screen:
1. The Run CloudScript button - Allows you to access a player's CloudScript settings.
2. Revision - Lets you select the revision level of the CloudScript to use. You can select Refresh to grab the
latest changes.
3. The Function name - Lets you select the function to run. The list of available functions is based on your
CloudScript revision content.
4. The Arguments field - Lets you supply optional JSON arguments.
5. The RUN CLOUDSCRIPT button - Lets you commit any changes you make on this screen.
Players logins
5/24/2022 • 2 minutes to read • Edit Online
The Players logins page offers an overview of all the login attempts for a specific player.
Overview
The Players Login page contains the following information:
Player ID - A label that identifies the player you are inspecting.
Total login attempts - The total number of login attempts by this player.
Date of login attempt - A human readable date label for each login attempt.
IP address - A label showing the IP address.
Source - A label that indicates where the login attempt came from.
Result - Indicates whether the login attempt was successful.
Player ban system
5/24/2022 • 2 minutes to read • Edit Online
The player ban feature allows you to restrict access to the game for certain players who break the rules.
NOTE
Bans can be temporary or permanent.
The following tutorial shows you how to utilize the ban system, using the PlayFab API and Game Manager.
Identify
While your game may have a custom system to identify cheaters and rule-breakers, PlayFab offers a player-to-
player reporting mechanism. In essence, you rely on your players to report other problematic players.
Use the following snippet in your client code to let the client report a specific player.
If everything is set correctly, you will see a new Ban in the table. You may optionally remove a Ban manually by
selecting it in the REVOKE BANS field.
Bans applied via code will also be displayed in the table of bans for the target player in Game Manager.
NOTE
The PlayFab server SDK methods provide more options, such as IP and MAC address bans.
Each ban you apply gets an assigned ID. Consider the following Server SDK API methods for precise ban
management:
GetUserBans
RevokeAllBansForUser
RevokeBans
UpdateBans
NOTE
You can use CloudScript functions as part of an automated system that may ban a player. To find out more about
CloudScript, see our tutorial Writing Custom CloudScript.
Player segments
5/24/2022 • 2 minutes to read • Edit Online
Players can be collected together into a segment, with the idea that all players in the segment meet certain
conditions (filters).
Once the segment is defined, you can monitor the total number of players in the segment and run custom
actions on those players automatically or manually.
Overview
The Segments page displays the segments that you currently have defined, and offers basic management
capabilities.
1. Use the NEW SEGMENT (1) button to create a new segment.
2. The segment ID (2) uniquely identifies the segment.
3. The segment Name (3) identifies the player(s).
4. The Matching players (4) area displays the total number of players matching the segment filter.
5. Using the check boxes (5) to the left of the screen, you can select certain segments, and X Delete or > Run
Task ... custom actions on the chosen segments.
For more information about defining segments and the filtering criteria, see our tutorial on Player
Segment configuration.
For more information about executing custom code for all players in a segment (as a one-time event, or
on a regular schedule), see our tutorial on Bulk Actions for an Entire Player Segment.
Player segment configuration
5/24/2022 • 6 minutes to read • Edit Online
The segment configuration page allows you to configure new or existing segments. You can:
Adjust the name.
Define the filters.
Assign tasks.
Each segment allows you to define useful or interesting groups of players, and perform exclusive actions on that
group.
NOTE
For more about this, see Using CloudScript actions with PlayStream.
Configuring
In this example we are going to:
Configure a segment using the defining characteristic that: all players that come from Canada.
Run a CloudScript function helloWorld for each player that enters the segment.
A defining characteristic of a player might be a:
Login time
Linked device type
Tags
A real-world location
Their statistic values
Their virtual currency values
Real money purchases, etc.
NOTE
Player's location is only one of your many possible options, and is only required for this example. Feel free to replace the
country/region requirement with another filter of your choice.
When a segment is defined, you have a variety of action options to run when a player enters or leaves the
segment.
CloudScript is by far the most flexible action, granting you full control of the player and segment information at
the time of segment-transition.
Use the second parameter - context - in your CloudScript handler to identify the player and segment transition.
Afterwards, you can perform any action you wish for the player, such as granting inventory items, virtual
currency, player data, or statistics.
In our example shown here, the segment configuration requires 4 simple steps.
1. Assign an appropriate Segment name (1) (in our example, that's Canadian Players ).
2. In the Player (2) area, assign any conditions that the Player must meet to enter the segment. (In our
example, we want a Location (countr y/region) filter with a strict value: Canada .
3. In the Type area, add an Execute CloudScript (3) action for the entered segment trigger.
4. Configure the action to run the function we want (helloWorld (3) ).
5. Use the Save Segment button (4) to commit your activities.
Advanced segment filtering
Segment filtering allows you to define what players are included in the segment.
Formally speaking, area (1) on the left of the screen shown below is a set of Players that belong to at least one
group.
Group (2) is a set of Players that meet all defined conditions, called filters (3) .
So to be part of a segment:
A player must be part of at least 1 group.
To be part of a group, a player must meet all conditions (filters).
This is denoted by the OR/AND operators:
Filters are combined using the AND operator.
Groups are combined using the OR operator.
The screenshot shown above is an example of how a segment can be defined. This segment consists of 2
groups:
1. The first group is defined by 2 filters:
A player must be from Canada. a. And must have Apple push notifications enabled.
The second group is also for players from Canada, but they must have Google push notifications
enabled.
In the end, we have a segment of players from Canada with either Google or Apple push notifications.
Each filter has a unique configuration and purpose. As of 4/30/2017 the following filters are available:
All Players filter - This filter has no configuration and is unique, because it allows you to create a
segment of all players. This comes in handy when you want to run automatic operations for every new
player (segment actions are described later in this tutorial).
First login (date) filter - Allows you to filter based on the first login datetime (example - players that
have first logged in after 1/1/2017).
First login (timespan) filter - Allows you to filter based on first login timespan relative to the current
datetime (example - players that have first signed in 20 minutes ago [from now]).
Last login (date) filter - Allows you to filter based on the last login datetime (example - players that
have not signed in since 1/1/2017).
Last login (timespan) filter - Allows you to filter based on the last login timespan relative to the current
datetime (example, players that have not signed in for a week [from now]).
Linked user account to filter - Allows you to filter based on the users' linked accounts (example -
players that have a Steam account linked with email).
Location (countr y/region) filter - Allows you to filter based on player's country/region (example -
players from Canada).
Push notifications enabled with filter - Allows you to filter based on player push notification settings
and capabilities (example - players that have Google push notifications enabled.
Statistics value filter - Allows you to filter based on your own custom statistic attribute (example -
players that inflicted 20000 damage in total).
Tag filter - Allows you to filter based on whether a player has or doesn't have a certain tag (example -
players that have a cheater tag).
Total value to date in USD filter - Allows you to filter based on how much USD currency a player spent
in your game (example - players that have spent over $30.
Value to date filter - Allows you to filter based on how much of a certain currency a player spent in your
game (example - players that have spent 50 RUB).
User Origination filter - Allows you to filter based on the first authentication method that a player used
to start playing the game.
NOTE
The trick here is that a player may start with authentication based on, say, an iOS Device ID. Later, a player may have a
GameCenter account linked. In this case, the player origination will be the iOS Device ID (example, players that first signed
in using an iOS Device ID).
Vir tual currency balance filter - Allows you to filter based on a player's custom virtual currency deposit
(example - players that have less than 50 Crystal).
NOTE
PlayFab offers a variety of actions. If, at any point, you need a more flexible action, consider a CloudScript action. This
action type allows you to run your own CloudScript function.
PlayFab is committed to being General Data Protection Regulation (GDPR) compliant - and as your service
provider, ensuring that we provide you with the hooks you need to allow Players to view or delete the data
stored about them.
While we can’t provide you with legal advice — and we do encourage you to seek legal counsel to ensure your
compliance with the GDPR — we are here to help you fulfill your obligations under GDPR.
PlayFab has three available APIs to help you respond to Player data requests:
GetPlayedTitleList - Call this API to get a list of TitleIds which have data associated with the given player. This
list is scoped by PublisherID and represents the set of titles which would be impacted were you to delete or
export this player's data.
DeleteMasterPlayerAccount - Call this API to delete the records of a given player.
ExportMasterPlayerData - Call this API to export all of the associated data and records of a given player.
You know your titles and how they authenticate your players. Before calling DeleteMasterPlayerAccount or
ExportMasterPlayerData , make sure you collect the right set of device IDs and/or credentials from your players.
With these credentials, we can identify the PlayFabIds for each Master Player account.
The following APIs will help you translate from credential to PlayFabId :
GetUserAccountInfo - This API will help you find players by email, TitleDisplayName , PlayFabId , or a
PlayFabUsername .
GetPlayerIdFromAuthToken - This API will allow you to find a player from a specific AuthToken which is
granted to the player when they log in.
GetPlayFabIDsFromFacebookIDs - This API derives the player's PlayFabId from one or more FacebookId (s).
GetPlayFabIDsFromSteamIDs - This API derives the player's PlayFabId from one or more SteamIds .
NOTE
All of these APIs are title-specific. The first two are Admin APIs and the last two are Server APIs.
Even if your player only has one PlayFabId, they may have played more than one of your titles with that ID. This
means their data request may span multiple titles.
To get this list of titles, call GetPlayedTitleList for each PlayFabId. You may wish to inform the player their
request will impact the returned list of titles.
Additionally, GetPlayedTitleList returns TitleIds , not Title Names - consider converting these to
Title Names before displaying them in a confirmation page.
Here's a little pseudo code to paint a better picture of what we mean...
//Here you would iterate through a request of known Ids, Emails, linked accounts
//or other PlayFab searchable info on the player that you have.
//and store it in user credentials for that player.
user {
credentials: (email/ids/linked accounts)
}
//create a variable to hold a list of all the PlayFabIds you want to remove.
PlayFabIdList
//each user record you have for the player, you should have a list of credentials for that player
//so you can find them in PlayFab
foreach(cred in user.credentials){
//There are a few helper Admin and Server API's that help you do this part.
//See below this pseudo code block for some tips!
pfid = <find PlayFabId in Title using the credential>
PlayFabIdList.add(pfid)
}
//go through the list of PlayFabIds that you have and fine all titles that
//performing the action would affect
foreach(pfid in PlayFabIdList){
AffectedTitles = title.GetPlayedTitleList(pfid)
}
}
if(task.Error != null)
{
callback(task.Error);
return;
}
At this this point you have a list of PlayFabIds for this player (based on the credentials they’ve shared) and a list
of titles for each PlayFabId . Now what?
Now you’re ready to delete or export!
if(task.Error != null)
{
callback(task.Error);
}
NOTE
Because this deletion cannot be undone, we suggest confirming with your player that they are comfortable with the
scope and impact of their deletion request.
So, once the action has been confirmed… Back to pseudo code.
//You only need to remove the Master Player once per namespace, so check that you have not
//already performed this action in the namespace, or you will get an error that
//the player is already queued for deletion.
if(title not in listOfTitlesRemovedFrom){
foreach(pfid in PlayFabIdList){
//Note: you should do some error handling around this API call.
response = title.DeleteMasterPlayerAccount(pfid)
foreach(titleId in response.titleids){
listOfTitlesRemoved.add(titleId)
}
listOfReceipts.add(response.jobreceiptid)
}
}
}
if(task.Error != null)
{
callback(task.Error);
}
callback(null);
}
NOTE
The URL will be available for up to 30 days after the export has completed. After this time, the file will be deleted, and you
will need to initiate a new export request.
Other considerations
It is easy to do harm with these APIs. Exporting data for or deleting the wrong player could be very damaging
and it is permanent!
It is your responsibility as the game developer to verify that the credentials are owned by the player requesting
an export or deletion of their player data. PlayFab does not provide any type of verification when using these
APIs.
However PlayFab does offer an email verification feature. But our solution is not the only option for verification.
You can create your own process too.
Regardless of which technology you use, we suggest that you do some sort of verification before performing
any of these actions.
This tutorial describes how to create and use player statistics. Player statistics are stored as Key Value Pairs
(KVPs) where the Key is a string, and the Value is a 32-bit integer (for compatibility with languages which do not
support 64-bit).
Player statistics are also used by leaderboards, but this guide only covers player statistics exclusively. If you wish
to read about how player statistics and leaderboards work together, please read our tutorial Using resettable
statistics and leaderboards.
NOTE
In some documentation and API calls, you may find the term UserStatistics . For the purposes of this discussion, the
terms user and player are identical and interchangeable. In the Game Manager page, the Players tab provides access
to the Users/Players for your title, and within that, their statistics. Player statistics refers specifically to information
bound to a player, not analytics information about player.
Client API
The client has access to read player statistics, but to prevent cheating, the client is not able to update statistics by
default.
To enable this:
Log into PlayFab
Select your Title .
Select Settings from the left-menu.
Select the API Features tab.
Find and activate Allow client to post player statistics .
NOTE
Doing this disables a security layer for your title, allowing players to post arbitrary scores to all of their statistics. If your
game has any competitive play aspect, we would recommend that you never post statistics from the client.
Setting statistics
The following Unity/C# code creates (or updates if it already exists) a strength statistic value for a player.
PlayFabClientAPI.UpdatePlayerStatistics( new UpdatePlayerStatisticsRequest {
// request.Statistics is a list, so multiple StatisticUpdate objects can be defined if required.
Statistics = new List<StatisticUpdate> {
new StatisticUpdate { StatisticName = "strength", Value = 18 },
}
},
result => { Debug.Log("User statistics updated"); },
error => { Debug.LogError(error.GenerateErrorReport()); });
Getting statistics
The following Unity/C# code retrieves all current statistic values for a player.
void GetStatistics()
{
PlayFabClientAPI.GetPlayerStatistics(
new GetPlayerStatisticsRequest(),
OnGetStatistics,
error => Debug.LogError(error.GenerateErrorReport())
);
}
Aggregation method
PlayFab supports some convenience options for Statistic Aggregation. The 4 options include:
Last
Min
Max
Sum
You can create a statistic definition via the CreatePlayerStatisticDefinition API call, though it's not required. Any
call to update a player statistic for the title will automatically create the default statistic definition, using the Last
Aggregation method.
To change a statistic aggregation method, you can use the Game Manager or the UpdatePlayerStatisticDefinition
API call.
To edit a statistic definition in Game Manager :
Log into PlayFab
Select your Title .
Select Leaderboards from the menu on the left (Statistics and Leaderboards are closely related).
Select the existing statistic you want to modify, or -
Select the New Leaderboard button.
For an existing statistic, you'll have another page, with an Edit Leaderboard button.
At this point you should see the page shown below.
Some examples of how to use statistic aggregation:
Max and Min can be used to save best/worst scores such as Headshots or Accuracy:
In short, they apply the rule of: if this is higher (or lower) than the existing score, update the
score .
Post the statistic for the session ending, and the Min/Max Aggregation takes care of whether or not
to update.
These can be very useful for resettable leaderboards, as well as a PlayStream Rule that grants
achievements.
Sum could be used to save experience points:
You post the experience gained this battle, and it is added to the existing statistic value for the player.
Last allows you to manage the stat yourself:
Each time you post a statistic, the most recent value is used.
Leaderboards
A leaderboard is generated for all statistics saved in PlayFab. Accessing a leaderboard for a specific stat is
optional.
Reset frequency and aggregation methods play a major role in how dynamic the leaderboards are in your game.
The Tournaments feature focuses on leaderboards with automatic reset frequencies, and is described in the
tutorial Using resettable statistics and leaderboards.
We encourage you to use statistics in every manner relevant to your game. You can use resettable statistics to
run daily tournaments, and long-term statistics like experience points, side-by-side.
Title Data
5/24/2022 • 2 minutes to read • Edit Online
Title Data is a set of key/value pairs that you can use to manage configuration for your game remotely. You can
set this data in Game Manager, or via APIs. This is commonly referred to as Primary Title Data.
Internal Title Data is a special set of Title Data that cannot be accessed by clients directly, and can be used for
storing configuration that is only available to services you control.
NOTE
Title Data values are copied and distributed to potentially hundreds of machines in the PlayFab server cluster. As part of
this process, Title Data is cached, and changes may take up to fifteen minutes to refresh in those caches. Title Data is best
suited for Global Constant/Static Data and is not suitable or reliable as Global Variables.
Links
Title Data quickstart
Title Data Tutorials
Title Data quickstart
5/24/2022 • 3 minutes to read • Edit Online
Title data is the set of plain text key-value pairs, used for storing and managing the game’s configuration data
remotely on the server. It keeps the title wide configuration variables accessible and organized which can be
retrieved on the client-side.
This QuickStart describes how to programmatically create and use title data.
This an important topic because storing a game's configuration data remotely on the server - where it can be
changed at any time - is one of the most basic reasons to use a service like PlayFab.
NOTE
This override set of key/value pairs comes in-effect only using Experiments for now. If the player belongs to an experiment
variant which contain title data overrides, the overrides are applied automatically on server side and returned with the
title data on client side. Title Data Override values may take up to one minute to refresh and persist.
Internal title data
Similarly to User Data, title data has internal storage that is hidden from the client. This data can also be set in
the Game Manager, or via a server API.
Getting internal title data by calling the server API in C#
See also
Using Publisher Data
Player Data Quickstart
CloudScript Quickstart
Title Data Tutorials
5/24/2022 • 2 minutes to read • Edit Online
These tutorials describe how to programmatically create and use publisher and title data.
Using publisher data
Using Publisher data
5/24/2022 • 4 minutes to read • Edit Online
This tutorial describes how to create and use Publisher (Studio) data.
Publisher data is data that spans more than one title - such as when you have multiple games that need to share
common information.
NOTE
This category also includes data for players that spans multiple games. PlayFab stores data as Key/Value Pairs (KVPs).
Most of these APIs are server APIs that your program must call from a dedicated server, or through a
CloudScript function within the PlayFab service.
Use the server APIs SetPublisherData to update, and GetPublisherData to retrieve, Publisher-specific
custom KVPs.
Use UpdateUserPublisherData to create or update, and GetUserPublisherData to retrieve, Publisher-
specific custom KVPs for the player.
Use the server API UpdateUserPublisherReadOnlyData to update, and the client API
GetUserPublisherReadOnlyData to retrieve, the read-only Publisher-specific custom KVPs for the user.
Use the server APIs UpdateUserPublisherInternalData to update, and GetUserPublisherInternalData
to retrieve, the internal Publisher-specific custom KVPs for the user.
You must call the server APIs from a dedicated server or through a CloudScript function through the PlayFab
service. This is by design, as the PlayFab server APIs require that you supply your secret key.
TIP
We do not recommend using server APIs from within a game client. If you need to make use of a server API, use
CloudScript for this type of functionality.
Publisher data values are copied and distributed to potentially hundreds of machines in the PlayFab cluster
server. As part of this process, this data is cached and changes may take up to fifteen minutes to refresh in those
caches.
NOTE
Publisher data is best suited for global constant/static data, and is not suitable or reliable as global variables.
Publisher data
Publisher data is used to store static data for a set of titles. Each entry is not bound to any PlayFab entity, such as
a player (as opposed to user publisher data).
Setting Publisher data
The following snippet demonstrates how to set Publisher data using the Server API.
NOTE
There is an admin API counterpart for this operation.
NOTE
There are server and admin API counterparts for this operation.
// Use Client API to set User Publisher Data for current user
public void ClientSetUserPublisherData() {
PlayFabClientAPI.UpdateUserPublisherData(new UpdateUserDataRequest() {
Data = new Dictionary<string, string>() {
{ "SomeKey", "SomeValue" }
}
},
result => Debug.Log("Complete setting Regular User Publisher Data"),
error =>
{
Debug.Log("Error setting Regular User Publisher Data");
Debug.Log(error.GenerateErrorReport());
});
}
// Use Server API to set Read-Only User Publisher Data for selected user
public void ServerSetUserPublisherReadOnlyData() {
PlayFabServerAPI.UpdateUserPublisherReadOnlyData(new UpdateUserDataRequest() {
PlayFabId = "< PlayFab Player Id >",
Data = new Dictionary<string, string>() {
{ "SomeKey", "SomeValue" }
}
},
result => Debug.Log("Complete setting Read-Only User Publisher Data"),
error =>
{
Debug.Log("Error setting Read-Only User Publisher Data");
Debug.Log(error.GenerateErrorReport());
});
}
// Use Server API to set Internal User Publisher Data for selected user
public void ServerSetUserPublisherInternalData() {
PlayFabServerAPI.UpdateUserPublisherInternalData(new UpdateUserInternalDataRequest() {
PlayFabId = "< PlayFab Player Id >",
Data = new Dictionary<string, string>() {
{ "SomeKey", "SomeValue" }
}
},
result => Debug.Log("Complete setting Internal User Publisher Data"),
error =>
{
Debug.Log("Error setting Internal User Publisher Data");
Debug.Log(error.GenerateErrorReport());
});
}
// Use Client API to get Read-Only User Publisher Data for selected user
public void ClientGetUserPublisherReadOnlyData() {
PlayFabClientAPI.GetUserPublisherReadOnlyData(new GetUserDataRequest() {
PlayFabId = "<PlayFab Player Id>"
}, result => {
if (result.Data == null || !result.Data.ContainsKey("SomeKey")) Debug.Log("No SomeKey");
else Debug.Log("SomeKey: " + result.Data["SomeKey"]);
},
error => {
Debug.Log("Got error getting Read-Only Publisher Data:");
Debug.Log(error.GenerateErrorReport());
});
}
// Use Server API to get Internal User Publisher Data for selected user
public void ServerGetUserPublisherInternalData() {
PlayFabServerAPI.GetUserPublisherInternalData(new GetUserDataRequest() {
PlayFabId = "<PlayFab Player Id>"
}, result => {
if (result.Data == null || !result.Data.ContainsKey("SomeKey")) Debug.Log("No SomeKey");
else Debug.Log("SomeKey: " + result.Data["SomeKey"]);
},
error => {
Debug.Log("Got error getting Internal Publisher Data:");
Debug.Log(error.GenerateErrorReport());
});
}
See also
Title Data quickstart
CloudScript quickstart
Entity Programming Model
5/24/2022 • 5 minutes to read • Edit Online
Entities are the most basic addressable "things" that PlayFab APIs operate on. Each entity has a Type and an Id
which together uniquely identify it. Some types of entities are "standard" or "built-in", in that PlayFab knows
something about their meaning and/or automatically creates them, for example namespace , title , group ,
master_player_account , and title_player_account . Others might have no inherent meaning to PlayFab but have
meaning in your game.
Every entity has a profile that contains various resources owned by that entity. For example, objects, files,
language settings, policies, and others to come. An entity profile is retrieved directly with the GetProfile API,
and many other APIs operate on specific resources inside of the profile, such as SetObjects .
Finally, there are parent/child relationships between entities which factor into the permissions governing how an
entity's resources may be accessed by other entities. The "ancestors" of a given entity can be found in the
Lineage property of its profile.
Functionality Overview
The entity programming model is the foundation for PlayFab's next generation of data and game services.
Authentication
Profiles
Groups
Data - File
Data - Object
Events
CloudScript
Multiplayer
Supported Entity types
The following list describes the available Entity types, which can be used to construct an EntityKey . Entity Keys
are used to identify entities in most newer API methods.
These values are meant to be used in the EntityKey.Type field.
NOTE
These are case sensitive. Other/custom values will not currently work.
Namespace
Namespace is the singular Entity that refers to all global information for every Title within a Studio. This
information should be static. Changes to this Entity are not reflected in real time.
Set the ID field to your GamePublisherId . To retrieve your GamePublisherId :
Log in to Game Manager.
From the My Studios and Titles page, select the appropriate Title.
Select the gear icon in the left corner of the Title page and then select Title Settings .
Select the API Features tab.
The Publisher ID on the API Features page is your GamePublisherId .
Title
Title is the singular Entity that refers to all global information for that Title. This information should be static.
Changes to this Entity are not reflected in real time.
Set the ID field to your game's TitleId . To retrieve your TitleId :
Log in to Game Manager.
On the My Studios and Titles page locate your Title.
The Title ID is located just below the name of your Title.
master_player_account
The master_player_account is a Player Entity that is shared among all Titles within a Studio.
Set the ID field to PlayFabId from the Classic API, returned by any LoginResult.PlayFabId .
title_player_account
title_player_account , for most developers, represents the Player in the most traditional way.
Set the ID field to LoginResult.EntityToken.Id in the Client API, or GetEntityTokenResponse.Entity.Id in the
Authentication API.
Character
Character is a sub-entity of title_player_account and is a direct mirror of Characters in the Classic APIs.
Set the ID field to any characterId from result.Characters[i].CharacterId .
Group
Group is an Entity that contains other Entities. It is currently limited to Players and Characters.
Set the ID field to the result.Group.Id if you are creating a group, or the result.Groups[i].Group.Id when
listing your memberships.
Entities quickstart
5/24/2022 • 9 minutes to read • Edit Online
This entities quickstart demonstrates how to work with entity objects and entity files.
For information on migrating from the legacy account and data systems to PlayFab entities, see Entities
migration information
Requirements
A PlayFab developer account.
An installed copy of the Unity Editor. For information on installing the Unity Editor, see Installing Unity in the
Unity documentation. You can also install a version of the Unity using the Visual Studio feature installer.
NOTE
The PlayFab Unity3D SDK supports Unity Editor version 5.3 and higher.
A Unity Project. For information on creating a Unity Project, see the Quickstart guide.
NOTE
If you are unfamiliar with Unity, recent installation packages give you the option of installing game creation
walkthroughs. You can use one of the walkthroughs to create a sample game to use in the following quickstart.
Terminology
Entities are any PlayFab concept that can contain data. The built-in entity types are:
title - A title contains global information available to all players. This is similar to TitleData. It is identified by
the title ID ( TitleId ) of the game/application.
master_player_account - This entity Type allows you to share information about a player across multiple
games within a namespace. It is identified by the player ID ( PlayFabId ) of the player, which is returned as
part of any login or any call to retrieve account information for the player account (for example, the PlayFab
Client API GetAccountInfo).
title_player_account - Identifies a player account that contains some information for the current title. This
is identified by the entity ID ( EntityKey.Id ) you get back in the EntityKey object on any login.
character - Identifies a character that the player owns which contains information that you can retrieve. It is
identified by the character ID ( CharacterId ) of the character.
For more information on the built-in entity types, see Available built-in Entity types.
Entity initialization
To call any of the Entity API you must obtain the entity ID and entity Type . You use the ID and Type to make
calls to other Entity API methods. These are members of an EntityKey object.
You do this by calling any of the login methods, such as LoginWithCustomID .
void Login()
{
var request = new PlayFab.ClientModels.LoginWithCustomIDRequest
{
CustomId = SystemInfo.deviceUniqueIdentifier,
CreateAccount = true,
};
PlayFabClientAPI.LoginWithCustomID(request, OnLogin, OnSharedFailure);
}
You can also obtain the entity ID and entity Type by calling the GetEntityToken method.
PlayFabAuthenticationAPI.GetEntityToken(new GetEntityTokenRequest(),
(entityResult) =>
{
var entityId = entityResult.Entity.Id;
var entityType = entityResult.Entity.Type;
}, OnPlayFabError); // Define your own OnPlayFabError function to report errors
When called from the client, this typically represents the logged-in player. When called from game servers, this
represents your title.
Entity objects
Entity objects allow you to read and write small JSON-serializable objects attached to an entity. All entity types
support the GetObjects and SetObjects methods.
The following code snippets show how to set and read an Object on a title_player_account entity.
Use the SetObjects method to set entity objects on a player or a title.
var data = new Dictionary<string, object>()
{
{"Health", 100},
{"Mana", 10000}
};
var dataList = new List<SetObject>()
{
new SetObject()
{
ObjectName = "PlayerData",
DataObject = data
},
// A free-tier customer may store up to 3 objects on each entity
};
PlayFabDataAPI.SetObjects(new SetObjectsRequest()
{
Entity = new EntityKey {Id = entityId, Type = entityType}, // Saved from GetEntityToken, or a specified
key created from a titlePlayerId, CharacterId, etc
Objects = dataList,
}, (setResult) => {
Debug.Log(setResult.ProfileVersion);
}, OnPlayFabError);
var getRequest = new GetObjectsRequest {Entity = new EntityKey {Id = entityId, Type = entityType}};
PlayFabDataAPI.GetObjects(getRequest,
result => { var objs = result.Objects; },
OnPlayFabError
);
Entity files
Entity files allow you to read and write files attached to an entity, in any format.
Use the GetFiles method to retrieve entity files.
void LoadAllFiles()
{
if (GlobalFileLock != 0)
throw new Exception("This example overly restricts file operations for safety. Careful
consideration must be made when doing multiple file operations in parallel to avoid conflict.");
ActiveUploadFileName = fileName;
Use the AbortFileUploads method to abort a pending file upload to an entity's profile.
Use the FinalizeFileUploads method to finalize file uploads to an entity's profile. The entity system does not
consider the file upload complete, nor reflect any changes to other callers until the atomic upload operation is
successfully finalized.
The example shown below demonstrates a full entity-file loop, from logging in, to loading a file, and uploading a
new file.
The steps for this are:
login and retrieve the entity ID and entity Type .
Initialize the atomic upload operation.
Upload all of the files.
Finalize the atomic upload operation.
For simplicity, this example saves one file at a time, but files can be uploaded atomically in sets.
The example assumes that you're familiar with using the Unity 3D engine.
using PlayFab;
using PlayFab.Internal;
using System;
using System.Collections.Generic;
using System.Text;
using UnityEngine;
if (PlayFabClientAPI.IsClientLoggedIn())
{
// Display existing files
_tempUpdates.Clear();
var index = 0;
foreach (var each in _entityFileJson)
{
GUI.Label(new Rect(100 * index, 60, 100, 30), each.Key);
var tempInput = _entityFileJson[each.Key];
var tempOutput = GUI.TextField(new Rect(100 * index, 90, 100, 30), tempInput);
if (tempInput != tempOutput)
_tempUpdates[each.Key] = tempOutput;
if (GUI.Button(new Rect(100 * index, 120, 100, 30), "Save " + each.Key))
UploadFile(each.Key);
index++;
}
// Apply any changes
foreach (var each in _tempUpdates)
_entityFileJson[each.Key] = each.Value;
// Add a new file
NewFileName = GUI.TextField(new Rect(100 * index, 60, 100, 30), NewFileName);
if (GUI.Button(new Rect(100 * index, 90, 100, 60), "Create " + NewFileName))
UploadFile(NewFileName);
}
}
void Login()
{
var request = new PlayFab.ClientModels.LoginWithCustomIDRequest
{
CustomId = SystemInfo.deviceUniqueIdentifier,
CreateAccount = true,
};
PlayFabClientAPI.LoginWithCustomID(request, OnLogin, OnSharedFailure);
}
void LoadAllFiles()
{
if (GlobalFileLock != 0)
throw new Exception("This example overly restricts file operations for safety. Careful
consideration must be made when doing multiple file operations in parallel to avoid conflict.");
_entityFileJson.Clear();
foreach (var eachFilePair in result.Metadata)
{
_entityFileJson.Add(eachFilePair.Key, null);
GetActualFile(eachFilePair.Value);
}
GlobalFileLock -= 1; // Finish GetFiles
}
ActiveUploadFileName = fileName;
In addition, files and objects now have their own sections in the Players tab.
See also
Introducing Entities, Objects and Files on the PlayFab blog.
Available built-in entity types
5/24/2022 • 2 minutes to read • Edit Online
This topic describes the available entity types that you can use to construct an EntityKey.
Entity keys identify entities in most of the newer API methods.
You use the value of the EntityKey.Type field to determine the type of value to set in the ID field.
NOTE
Entity keys are case sensitive.
namespace
The namespace entity refers to all global information for all titles within your studio.
NOTE
Changes to this entity are not reflected in real time.
title
The title entity refers to all global information for that title.
NOTE
Changes to this entity are not reflected in real time.
master_player_account
The master_player_account is a player entity that is shared by all titles within your studio.
Set the ID field to the LoginResult.PlayFabId from the classic API. To retrieve the LoginResult , call one of the
login methods in Client Authentication.
title_player_account
For most developers, title_player_account represents the player in the most traditional way.
Set the ID field to LoginResult.EntityToken.Entity.Id in the client API, or GetEntityTokenResponse.Entity.Id in
the authentication API.
To retrieve the , call one of the login methods in Client Authentication. To retrieve the
LoginResult
GetEntityTokenResponse , call Get Entity Token.
character
The character entity is a sub-entity of title_player_account , and is a direct mirror of Characters in the Classic
APIs.
Set the ID field to any characterId from result.Characters[i].CharacterId .
group
The group entity is a container for other entities. It is currently limited to players and characters.
Set the ID field to the result.Group.Id if you are creating a group, or the result.Groups[i].Group.Id when
listing your memberships.
service
The service entity is reserved for internal use.
Entities migration information
5/24/2022 • 2 minutes to read • Edit Online
The entity API introduces new access patterns that are designed to alleviate the pain points of the current
account and data systems.
The information presented here is useful if you have previously used the following methods to implement data
management for your Title, Player, or Character information.
Title access:
client/GetTitleData
admin/GetTitleData
server/GetTitleData
Player access:
client/GetUserReadOnlyData
client/UpdateUserData
client/UpdateUserPublisherData
Character access:
client/GetCharacterData
client/UpdateCharacterData
Using the entities API, you can call a single method to save the data values for title, player, and character entity
types. The API provides access rules that replicate and expand the current system behavior of custom data in a
better interface.
In some regards, these changes are not backwards compatible. However, you can add calls to the entity API
without changing the behavior of the existing APIs.
Terminology
The following table describes refinements in terminology related to the entity APIs.
See also
Introducing Entities, Objects and Files on the PlayFab blog.
Entities quickstart
Entity files
5/24/2022 • 4 minutes to read • Edit Online
Entity files allow you to read and write files attached to an entity, in any format. The example shown below
demonstrates a full entity-file loop, from logging in, to loading a file, and uploading a new file.
using PlayFab;
using PlayFab.Internal;
using System;
using System.Collections.Generic;
using System.Text;
using UnityEngine;
void OnGUI()
{
if (!PlayFabClientAPI.IsClientLoggedIn() && GUI.Button(new Rect(0, 0, 100, 30), "Login"))
Login();
if (PlayFabClientAPI.IsClientLoggedIn() && GUI.Button(new Rect(0, 0, 100, 30), "LogOut"))
PlayFabClientAPI.ForgetAllCredentials();
if (PlayFabClientAPI.IsClientLoggedIn())
{
// Display existing files
_tempUpdates.Clear();
var index = 0;
foreach (var each in _entityFileJson)
{
GUI.Label(new Rect(100 * index, 60, 100, 30), each.Key);
var tempInput = _entityFileJson[each.Key];
var tempOutput = GUI.TextField(new Rect(100 * index, 90, 100, 30), tempInput);
if (tempInput != tempOutput)
_tempUpdates[each.Key] = tempOutput;
if (GUI.Button(new Rect(100 * index, 120, 100, 30), "Save " + each.Key))
UploadFile(each.Key);
index++;
}
// Apply any changes
foreach (var each in _tempUpdates)
_entityFileJson[each.Key] = each.Value;
void Login()
{
var request = new PlayFab.ClientModels.LoginWithCustomIDRequest
{
CustomId = SystemInfo.deviceUniqueIdentifier,
CreateAccount = true,
LoginTitlePlayerAccountEntity = true
};
PlayFabClientAPI.LoginWithCustomID(request, OnLogin, OnSharedFailure);
}
void OnLogin(PlayFab.ClientModels.LoginResult result)
{
entityId = result.EntityToken.Entity.Id;
entityType = result.EntityToken.Entity.Type;
}
void LoadAllFiles()
{
if (GlobalFileLock != 0)
throw new Exception("This example overly restricts file operations for safety. Careful
consideration must be made when doing multiple file operations in parallel to avoid conflict.");
_entityFileJson.Clear();
foreach (var eachFilePair in result.Metadata)
{
_entityFileJson.Add(eachFilePair.Key, null);
GetActualFile(eachFilePair.Value);
}
GlobalFileLock -= 1; // Finish GetFiles
}
void GetActualFile(PlayFab.DataModels.GetFileMetadata fileData)
{
GlobalFileLock += 1; // Start Each SimpleGetCall
PlayFabHttp.SimpleGetCall(fileData.DownloadUrl,
result => { _entityFileJson[fileData.FileName] = Encoding.UTF8.GetString(result); GlobalFileLock
-= 1; }, // Finish Each SimpleGetCall
error => { Debug.Log(error); }
);
}
ActiveUploadFileName = fileName;
In addition, files and objects now have their own sections in the Players tab.
Use entity objects to store player data
5/24/2022 • 2 minutes to read • Edit Online
Entity objects allow you to read and write small JSON-serializable objects attached to an entity. All entity types
support the same GetObjects and SetObjects methods.
The examples that are shown below demonstrate setting and reading an Object on a title_player_account .
var getRequest = new GetObjectsRequest {Entity = new EntityKey {Id = entityId, Type = entityType}};
PlayFabDataAPI.GetObjects(getRequest,
result => { var objs = result.Objects; },
OnPlayFabError
);
The following tutorials show you how to use the PlayFab Entities API to enhance your coding for account and
data systems.
Available built-in Entity types
Entity API Restructure Upgrade Tutorial
Entity Groups
Entity groups
5/24/2022 • 7 minutes to read • Edit Online
Entity groups
Entity groups are the root concept that was inspired by the need for clans/guilds.
At its core, entity groups are any logical group of entities, which can serve any purpose. Entity groups can
simultaneously serve many purposes within your game.
Examples
Clans/Guilds - This was the starting point, and the main driving need. Entity groups can be used to
describe a set of players who are playing together on a regular basis, for whatever social glue that holds
them together on a long-term basis.
Par ties - Entity groups can be used for short-term groups created to allow individual players to
accomplish an immediate goal, and then easily disbanded afterward.
Chat Channels - Short or long term chat channels can be defined as an entity group.
In-Game subscription to information - Do you have a single-instance legendary item in your game?
Do players want constant updates about what is happening with that item? Create an entity group
focused on that item, with all player entities interested in the item as members.
In short, entity groups can be any collection of entities (whether NPC or player-controlled, real or abstract),
which need a persistent-state bound to that group.
A friends list is a group. A three person private chat is a group. Go nuts!
NOTE
We'd appreciate some warning in the forums if you are trying something we might not be expecting...
In addition, since entity groups are also entities themselves, they will contain all the initial features of entities:
Object data
File data
Profiles
They will be generally eligible for new entity features going forward, if those features are relevant to groups.
using PlayFab;
using PlayFab.GroupsModels;
using System;
using System.Collections.Generic;
using UnityEngine;
namespace TestGuildController
{
/// <summary>
/// Assumptions for this controller:
/// + Entities can be in multiple groups
/// - This is game specific, many games would only allow 1 group, meaning you'd have to perform some
additional checks to validate this.
/// </summary>
[Serializable]
public class GuildTestController
{
// A local cache of some bits of PlayFab data
// This cache pretty much only serves this example , and assumes that entities are uniquely
identifiable by EntityId alone, which isn't technically true. Your data cache will have to be better.
public readonly HashSet<KeyValuePair<string, string>> EntityGroupPairs = new
HashSet<KeyValuePair<string, string>>();
public readonly Dictionary<string, string> GroupNameById = new Dictionary<string, string>();
// Presumably, this would be part of a separate process where the recipient reviews and accepts
the request
var request = new AcceptGroupInvitationRequest { Group = EntityKeyMaker(prevRequest.Group.Id),
Entity = prevRequest.Entity };
PlayFabGroupsAPI.AcceptGroupInvitation(request, OnAcceptInvite, OnSharedError);
}
public void OnAcceptInvite(EmptyResponse response)
{
var prevRequest = (AcceptGroupInvitationRequest)response.Request;
Debug.Log("Entity Added to Group: " + prevRequest.Entity.Id + " to " + prevRequest.Group.Id);
EntityGroupPairs.Add(new KeyValuePair<string, string>(prevRequest.Entity.Id,
prevRequest.Group.Id));
}
// Presumably, this would be part of a separate process where the recipient reviews and accepts
the request
var request = new AcceptGroupApplicationRequest { Group = prevRequest.Group, Entity =
prevRequest.Entity };
prevRequest.Entity };
PlayFabGroupsAPI.AcceptGroupApplication(request, OnAcceptApplication, OnSharedError);
}
public void OnAcceptApplication(EmptyResponse response)
{
var prevRequest = (AcceptGroupApplicationRequest)response.Request;
Debug.Log("Entity Added to Group: " + prevRequest.Entity.Id + " to " + prevRequest.Group.Id);
}
public void KickMember(string groupId, EntityKey entityKey)
{
var request = new RemoveMembersRequest { Group = EntityKeyMaker(groupId), Members = new
List<EntityKey> { entityKey } };
PlayFabGroupsAPI.RemoveMembers(request, OnKickMembers, OnSharedError);
}
private void OnKickMembers(EmptyResponse response)
{
var prevRequest= (RemoveMembersRequest)response.Request;
Server vs client
Like all new entity API methods, there is no distinction between the server API and the client API.
The action is performed by the caller, according to how the process was authenticated. A client will be identified
as such, and will call these methods as a title player entity, and their roles and permissions within the group will
be evaluated with every call, ensuring they have permission to perform this action.
A server is authenticated with the same developerSecretKey , which identifies that process as a title entity. A title
will bypass the role checks, and API calls executed by a title will only fail if the action is impossible to perform, in
an instance such as if an entity cannot be removed if they are not a member.
Entity API restructure upgrade tutorial
5/24/2022 • 2 minutes to read • Edit Online
Introduction
We have restructured the APIs that were lumped under the Entity API group into coherent logical groups that
make their consumption easier, both via the documentation site, and the PlayFab SDKs.
The immediate impact is that if you have been using the entity-based APIs in your game, the code will need to
be updated when you upgrade your SDKs.
Prerequisites
The following conditions must be true for this upgrade guide to apply to you:
1. You are using the entity-based PlayFab APIs.
2. You have upgraded to a PlayFab SDK, published on 8/9/2018 or later.
NOTE
There are no service level changes. For example, existing titles using old SDKs will work without requiring changes.
How to upgrade
The fundamental impact of this change is that the PlayFabEntityModel API group has been separated out into six
different API groups that are logically bound together, as shown in the following picture.
A full list of Previous Entity API -> New API mapping can be found in APPENDIX 1 of this tutorial.
NOTE
The Classic API mapping has not been affected.
The next section will walk you through an example of upgrading a C# SDK using the PlayFabEntityAPIGroup to
the new set of API groups.
using PlayFab.EntityModels;
using PlayFab.DataModels;
You can now be granular in your selection of which of these APIs you want to bring in, instead of importing the
whole Entity API group.
Step 2 : A more in-depth coding example of the New API, with comments in regard to how it looked before is
provided below.
Please follow suit for other SDKs, using the mapping from APPENDIX 1 in this tutorial.
Conclusion
We’re excited to expose the Entity APIs in a more intuitive way on our documentation site and in our code, based
on your feedback.
If you have any questions and comments, please contact us via the PlayFab Forums.
Data Connections enables the continuous near real-time distribution and ingestion of PlayStream and
Telemetry data into your chosen and authorized storage resource in your Azure subscription, such as Azure Blob
Store.
It provides control of your data in your storage account with less than 5-minute data ingestion latency. The
architecture is designed for better batch processing that facilitates Parquet files in blob storage with the highest
throughput, low storage cost, and most flexibility.
You can configure up to three Azure blob storage accounts in the WestUS2 region. In case of failure in data
distribution, a built-in automatic retry mechanism is in place to ensure data quality.
You can get started with Data Connections for event ingestion using PlayFab’s Game Manager portal or scalable
APIs.
NOTE
Make sure to create your Storage Account in the West US 2, otherwise, egress cost will be applied to your storage
account.
For PlayFab to ingest data in your storage account, container details along with authorization using a SAS token
are required. To create a SAS token using the Microsoft Azure portal, follow the steps below.
Option 1: Create the SAS token on the container level.
IMPORTANT
Generate and retrieve the shared access signature for your container, not for the storage account itself.
Define Permissions by selecting or clearing the appropriate checkbox. Make sure the Create and Write
permissions are selected.
Specify the signed key Star t and Expir y times.
Select Generate SAS token and URL .
The Blob SAS token query string appears in the lower area of the window.
Copy and paste the Blob SAS token values into a secure location for use in the Azure PlayFab Data
Connections . It's displayed only once and can't be retrieved after the window is closed.
Option 2: Create the SAS token on the account level.
IMPORTANT
Generate and retrieve the shared access signature for your storage account itself.
Pre-requisite:
For Data Connections, you need an Azure subscription and a storage account.
For PlayFab to ingest data in your storage account, container details along with authorization using a SAS
token are required. To create a SAS token using Microsoft Azure portal, follow the steps below.
IMPORTANT
Make sure to create your Storage Account in the West US 2, otherwise, egress cost will be applied to your storage
account.
Overview
PlayFab Manage Events feature helps you configure the percentage of events data that you want to receive in
the title tenant database. By default, all PlayStream and Telemetry (custom) events are stored. However, in some
situations, you might want to retrieve only a sample set of events. To achieve that, use Manage Events with
Sampling rate.
Benefits of Manage Events
Sampling leads to a reduction of the volume of the total event, particularly benefitting you with below in a
controlled and flexible manner:
Reduced cost of storage on your title tenant database
Increased performance of event searches
Easy data exploration to determine the characteristics of a large data set
Uncompromised validation of the data format, statistical calculations, and other analysis without any loss of
data fidelity
Sampling Ratio
The sampling ratio is the probability percentage of any event being included in the sample result set. It ranges
from 0% to 100%. By default, event sampling isn't active, meaning the sampling rate is set to 100%, and every
event of the title is ingested and stored into the title tenant database.
To take advantage of sampling using our Manage Events page, configure a sampling percentage on individual
event levels. When you specify a sampling percentage on a certain event, sampling comes into effect by
overriding the default or existing value and remains in effect until you change it. The percentage specified in the
sample ratio field is the percentage of events that will be filtered out.
The sampling rate can be as high as 100% and as low as 0%. By default, the sampling rate for all events is 100%,
thus, leading to 100% event retention in the sample set.
NOTE
Sampling comes into play after all the events are processed by the PlayStream rules engine. So, all events will support
actions/ rules, if specified and independent of sampling.
IMPORTANT
PlayFab CDN is a legacy feature supported for accounts with at least one title that has previously configured CDN. For
new PlayFab developers interested in a content management solution, we recommend using Azure CDN. To get started,
see the Azure CDN documentation.
The Content Delivery Network (CDN) is an infrastructure used to deliver assets - such as images, audio, binary
content, etc. - to the end user that focuses on speed and availability.
Pricing
CDN costs are independent of your pricing tier (Essentials, Professional, etc.), and require that you have an active
PlayFab payment account. CDN has one key meter, Egress , which is billed at $0.10 per GB.
Links
Content Delivery network quickstart
Content Delivery Network quickstart
5/24/2022 • 3 minutes to read • Edit Online
IMPORTANT
PlayFab CDN is a legacy feature supported for accounts with at least one title that has previously configured CDN. For
new PlayFab developers interested in a content management solution, we recommend using Azure CDN. To get started,
see the Azure CDN documentation.
The PlayFab Content Delivery Network (CDN) stores individual assets as files uniquely identified by the file
name (also referred to as a key). This implies that you add, update, remove, and retrieve assets by key.
PlayFab CDN allows segregating assets by folders. The folder path to the asset becomes part of the asset key.
The following example is a valid asset key stored inside the folder named Android .
Android/Image.png .
When the user is fetching assets, their requests are automatically routed to the nearest edge location, so content
is delivered with the best possible performance.
This, however, can introduce delays into file management actions, like those found in the following examples:
File uploading : Your file will be available immediately.
File over writing : The old file will appear to users for up to 24 hours, until it's overwritten with the new
file.
File deletion : The file will continue to exist for up to 24 hours, while the delete command removes it
from all edge locations.
Uploading assets
Before your users are able to fetch an asset, it must be uploaded to the CDN. This can be done in Game
Manager :
Select Content from the menu on the left.
Choose the File Management tab.
Then select the Upload Files .
You may:
Select multiple Files (1) .
Every file selected will appear in the list (2) .
Submit your files by selecting the Upload Files button (3) .
You may then check the result through the PlayFab Game Manager. Make sure the file is in the list.
Fetching assets
Downloading the asset via code is identical to uploading the asset. As wwe mentioned earlier, it is a two step
process.
1. First, make a call to GetContentDownloadUrl and obtain a pre-signed URL that will authorize your download.
2. You then use the pre-signed URL to make a HTTP GET request, and fetch the data.
Consider using the snippet provided below that shows the bare bones of the process.
public void DownloadFileFromCDN(string key) {
GetDownloadUrl(key, presignedUrl =>
{
GetFile(presignedUrl);
});
}
As mentioned above, CDN may involve latency in regards to file updates. During development, it is sometimes
useful to force-fetch the latest, freshest files.
The GetContentDownloadUrl call allows you to set the ThruCDN parameter to False . The URL returned will then
point to non-cached fresh files.
NOTE
Your published game client should never use this option!
Webhooks
5/24/2022 • 2 minutes to read • Edit Online
In complex systems, you may want to provide additional event handling on your custom server. To achieve this,
PlayFab offers Webhooks.
Whenever a new event is emitted, it can be forwarded to your server by making a POST request to your custom
web endpoint. The event data is then passed as the JSON body of the request.
IMPORTANT
Entity PlayStream Events do not currently support forwarding with Webhooks.
Accessing Webhooks
To access the Webhooks panel in the PlayFab Game Manager screen:
1. Select Data in the sidebar menu.
2. Then choose the Webhooks tab.
Configuring a Webhook
The image shown below describes the options for configuring a Webhook.
1. Use the Name field to create a Webhook name that will uniquely identify the Webhook.
2. Set up the Endpoint URI . This URI will be hit when the Event occurs.
3. You may set the Webhook as Enabled - true or false . This allows you to temporarily suspend a Webhook
without completely removing (deleting) it from the system.
4. You may set the option to Post multiple events in JSON array if you want to have multiple events posted
to your service in an array. If you select this option your service must be able to handle both multiple and
single events.
5. You can add up to three request headers and the value of those headers. This allows you to post headers in a
secure way to services such as Azure Event Hubs, Azure Functions, Google Functions and Amazon Lambda.
NOTE
The request header keys can be up to 64 characters and the values can be up to 256 characters for each header.
1. Set up the Filters to only process the Events you need. You can filter by Event Name , Event Source , and
PlayerID .
NOTE
You can have several Filters per Group , but each Filter setting must be matched for the event to fall into the Filter
Group .
1. You may define several Filter Groups to include different filters. Events must fall into at least one group to
be passed to the Webhook.
What is PlayFab Analytics?
5/24/2022 • 2 minutes to read • Edit Online
PlayFab Analytics is a set of tools for data analytics, storage, processing, and exports. The features included are
Experiments, Metrics, Reports, and Segmentation.
Segmentation lets you create groups of players based on their player properties. Players will move in and out of
segments in real-time, as Playstream events occur. Segmentation can be integrated with many other services
across PlayFab. To get started, see the Segmentation Quickstart.
Experiments allows you to create and manage multiple concurrent experiments through Game Manager.
Experiments can be scheduled to run at certain times, and run across targeted player segments. To get started,
see the Experiments Quickstart.
Metrics automatically calculates a daily report of industry-standard metrics on engagement and revenue.
Explore your metrics in the Reports and Trends tabs of the Dashboards section in Game Manager. To get started,
see the Metrics Quickstart.
Reports automatically generates daily, monthly, and 30-day rolling views for engagement and monetization. To
get started, see the Reports Quickstart.
Experiments
5/24/2022 • 3 minutes to read • Edit Online
Overview
PlayFab Experiments feature helps you identify the best strategies for your game. It does so by helping you run
multiple concurrent experiments and ensure statistical trustworthiness.
You can elevate the player experience by comparing different versions of game configurations, pricing models,
and outreach mechanisms, determining the best variation for your title’s goals (engagement, monetization,
retention, etc.) via experiments.
Capabilities of PlayFab's Experiments
PlayFab Experiments is a tailored solution for running experiments in your games. It is powered by Microsoft's
internal experimentation platform which unlocks the best-in-class capabilities which are used by Minecraft,
Azure, Office, Bing, and many other Microsoft products. PlayFab Experiments empowers you by providing the
following capabilities:
Creation and management of multiple concurrent experiments with the (interactive and self-directing) user
interface on PlayFab Game Manager and via scalable APIs.
Targeting of the desired audience at random but in a controlled manner by making use of existing traffic. You
can experiment over a segment and define the percentage of the target audience in each variant.
Scheduling of experiments or to run immediately.
Analysis of experiments' scorecard results. The scorecards are computed reliably and possess enriched
statistical details. This gives you an indication of statistical significance and alerts if a Sample Ratio Mismatch
is observed.
Integrability with other PlayFab services such as Title Data, Player Profile, PlayStream events, CloudScript and
Insights Explorer, etc.
Experiment Configurations using PlayFab’s Experiments Variants
The experiment compares the game configurations, be it the in-game experience, or the other game growth
strategy. These configurations can be enabled through a game code and mapped to the variant-variable pair or
variant-override pair. Each configuration is easily mappable to variants of an experiment to enable any game
experience.
A control experience is mapped to a control variant and is compared against one or more treatment experience
mapped to a treatment variant to study the player behavior and determine which variant experience or
configuration works better.
Game Configurations mapped to Variables (Requiring no new code deployment)
Each configuration is easily mappable to variants where each variant is supported by variables. These
variables allow you to bundle a different set of game experiences via parameterization.
Overrides as Game Configuration (Requiring no game code change)
Game configuration using PlayFab services can be experimented using Overrides without adding any extra
code.
Overrides are subsets of configuration which contain modifications to the default title data, that can be used
as variants in Experimentation. Currently, experiments with overrides are only available when using Title
Data.
Configurations involving Title Data are a set of key-value pairs that are ideal for storing and managing
the game’s remote configuration on the server. It keeps the title wide configuration variables
accessible and organized which can be retrieved on the client-side.
NOTE
For concurrent experiments using overrides, it is recommended to experiment on a mutually exclusive target audience.
This will ensure the correct assignment of overriding configuration and no interaction on the client-side. Thus, resulting in
statistically correct experiment design and thereby analysis results.
PlayFab Experiments enables you to run multiple concurrent randomized experiments in a managed and
controlled manner. In the process,
A unique identifier for each running experiment's variant groups called a variant ID is tagged to each player
profile. These variant IDs are assigned to different treatments via client or server-side code. Thus,
instrumenting different treatment behaviour.
Each variant group is supported and defined by variables. These variables are attributes on variant groups
that allow you to bundle a different set of game experience via parameterization.
Reliable computation of results of an experiment with statistical significance calculation is provided.
Detection of issues when the targeted audience traffic is way off. This is often caused by a treatment causing
crashes or affecting logging. PlayFab's experimentation feature flags such issues enabling you to run a
reliable experiment.
Quick Start
5/24/2022 • 7 minutes to read • Edit Online
Create an Experiment
An experiment is created to compare a control variant against one or more treatment variants (up to 9). The
experiment is managed through a target audience controlled by the user.
From the Game Manager:
Navigate to your Title
Select Experiments from the menu on the left
Select New Experiment , experiment configuration page is opened
Enter Experiment Name , Description , Star t Date & Time , Duration (up to 90 days)
Select your target Audience for the experiment. By default, the experiment's audience is “Run across all
title players”
Configure to run the experiment on a Segment by selecting the radio button “Select player segment” and
select on the drop-down
(Optional) Under Exclusion Group , select exclusion group from the drop-down list of the existing
Exclusion group name and enter % traffic allocationto , to run a mutually exclusive experiment
Under Variants , define the Control Variant and Treatment Variant(s)
Enter Variant name and Description
Each variant is supported and defined by Variables (up to 10) and Overrides
The variables are attributes on variant groups that allow you to bundle different sets of user-
experience via parameterization
This variable parametrization configures the feature settings for variants without deploying
new code. This allows you to iterate faster on changes and make fixes and updates to live
games. It is recommended to have the same variable name in each of the variant group as part
of best practices of experimentation
The overrides are attributes on variant groups that allow you to bundle different sets of
configurations of PlayFab services via parameterization, i.e., no game code is required.
Currently, overrides are available for title data remote configuration service only
Each variant is associated with the % of target audience . For a controlled experiment, it determines
the traffic stream and instrumentation of variants
Sufficient traffic is required to make the changes from your experiments more detectable. An
experiment with equal traffic in each variant will have the best ability to detect a change
For concurrent experiments using overrides, it is recommended to experiment on a mutually
exclusive target audience
Select Schedule , Save as Draft , or Run Now
With Schedule, the experiment will be in Scheduled status in the experiments overview and timeline
page
With Save as Draft, the experiment will be in the Draft status in the experiments overview and
timeline page
With Run Now, the experiment will be in Running status in the experiments overview and timeline
page
Manage Experiments
The Experiments’ overview (landing) page displays the available experiments categorized based on the status,
which is Running , Scheduled , Drafted , Completed .
The Running and Scheduled experiments are shown in a timeline view. Here the high-level details on each
experiment are available, like the experiment's Name , number of Variants , Star t Date & Time , End Date &
Time . Interestingly, for an experiment in running state, one can also see a near-real-time metric of Player
Count which gives insights into the number of players that have been assigned to the experiment in the last 8
hours.
The Drafted experiments are shown in the same ‘In-progress’ tab. Just below the timeline card view.
The Completed experiments after their run completion are shown in the ‘Completed’ tab with details of the
experiment's Name , number of Variants , Star t Date & Time , End Date & Time .
The Experiments page can also be used to manage experiments by selecting on any experiments’ ellipsis.
Here,
A scheduled experiment is automatically picked to run based on the configured schedule
The configuration's variations mapped in each variant of the experiment is enabled to the qualifying traffic
immediately at random
A previously scheduled experiment can be started at any time before its start date, just select the ellipsis of
the intended experiment from the list of scheduled experiments and Select Run. Different actions can be
taken on experiments based on their state, and the action set comprises of Run , Stop , Clone as draft . More
precisely like,
Stop and Clone as draft of a running experiment
Run, Delete and Clone as draft of a scheduled experiment
Delete of a drafted experiment
Delete and Clone of a stopped/ completed experiment
Note: One can also Clone an existing experiment from the experiment's edit configuration page which allows
further edits
A scheduled and drafted experiment's fields are completely modifiable and vice-versa for a stopped/
completed experiment. Select on the ellipsis to make Edit . Although, for any experiment in running state,
only Experiment description and duration modifications are possible
A running experiment status is turns Completed , once the duration of the experiment is reached or a user
explicitly stops the experiment
Analyze Experiment
Experiments' results are shown in Experiment details and scorecard page . The scorecard is generated in a
regular cadence. The first scorecard is generated in 12 hours, followed by scorecard(s) every 24 hours for the
entire duration of an experiment.
Once the experiment is completed, select the Completed tab view, and select on the name of the experiment to
view the Scorecard , along with the experiment details. Additionally, the at-run experiments’ scorecard and
details can be viewed by selecting the name of the experiment.
The Experiment details and scorecard page lists the experiment name, description, start and end date, intended
duration, audience, and variant count. The actions like Stop, Run, Clone as draft is available on the page based on
the state of the experiment.
NOTE
To learn more about SRM and how to resolve it, see the Sample Ratio Mismatch section in Experimentation Best
Practices and Recommendations)
For details on the variant, its associated variables, and overrides, select Configuration and Experiment
configuration page will be displayed with details.
At the completion of the experiment:
The overall statistical computation of each metric is available for analysis.
At the experiment run:
If an issue of Sample Ratio Mismatch (SRM) is identified, then it is flagged to the user for investigation.
SRM indicates sampling bias in the randomization which leads to the options of resolving bugs (if any),
immediately stop the experiment based on the estimated impact or take the risk and let the experiment to
continue.
Scorecard Metrics
PlayFab has pre-identified a set of simple, effective, and actionable metrics for analysis of experiment results.
These are tracked and categorized to measure impact on the acquisition, activation, retention, and revenue of
the title. These are computed based on the player_logged_in and player_realmoney_purchase events.
The identified metrics are calculated for the time the experiment has ran so far based on the configured
duration. The metrics are:
Experimentation APIs
PlayFab has scalable and integrable APIs for experimentation. The APIs and associated operation details are as
below:
Get Experiments Lists all the experiments and its details, no matter which
state (drafted, running, and completed/stopped) for the title.
Get Treatment Assignment List the treatment assignments for a player for every
running experiment in the title.
Get Latest Scorecard Gives the latest scorecard result for an experiment of the
title.
NOTE
For more information about the Experiments APIs, see Experimentation APIs.
WARNING
A new player login only has attributes associated with the player_logged_in PlayStream event. An experiment that targets
a new player with PlayStream event-based configuration variations can only use attributes that are part of the
player_logged_in PlayStream event. This ensures treatment assignment to the new players who have no PlayStream
events associated yet.
Prevent Interaction Effects with Exclusion Group
5/24/2022 • 3 minutes to read • Edit Online
For related concurrent experiments, it is important for players to only see one of the experiments in order to
prevent skewed results. This is where exclusion groups come into play. PlayFab exclusion groups allow you to
create mutually exclusive experiments.
With an exclusion group, you limit the participating target audience (players) to participate in one experiment at
a time. This ensures that the same users don't see overlapping experiments within an exclusion group. This
means that the data collected for one experiment is not affected by any other experiment, even if both the
experiments are set up on the same game flow and targets the same set of players.
In an exclusion group, the traffic allocation happens without overlapping players’ data between the experiments
and is distributed at random in different buckets of players for each experiment. This ensures clean results
where the change in conversion rate is attributed to the correct experiment without bias and overlap of the
target audience, eliminating any interaction effects.
For unrelated experiments, it does not matter if your players become a part of more than one experiment.
However, if the experiments are related like below, with concurrent or overlapping run schedule, you may want
to keep the players exclusive to each experiment:
Variation of configurations on the same game flow
Variation of configuration involving the same funnel where there is a possibility of player overlap
Please note, use of exclusion group reduces the statistical power of your experiments as each one competes with
others for traffic. So, use exclsuion group when experiments are related and interaction effects are anticipated.
You can create experiment(s) with exclusion group(s) through Game Manager and APIs.
This guide introduces you to the practice of experimentation. It details why you should experiment early, best
practice recommendations, and provides information to help your become comfortable with the process.
In this scenario, even though the actual ratio between the two flights are the same in each scenario, one have an
increasingly smaller p-value for larger user counts in Treatment and Control. This indicates that the observed
outcome is not as expected.
How to investigate SRM
SRM investigation and resolution is a complex and uncertain process. Therefore, resolving an SRM requires a
structural approach, with a panoramic view, and an awareness of the likelihood of root causes and resolutions
strategies. For this,
Start with the question "why did this happen?"
Formulate a hypothesis on the cause of that SRM
Predict what would be the evidence observed if that hypothesis was true
Find those pieces of evidence
Analyze the cause to identify a solution
Asking follow-up questions can help in the investigation to devise the necessary steps for resolution. For
example:
Did this happen in only one analysis/experiment or in multiple?
What does the treatment do? What is the nature of the experiment?
Did something change between now (SRM) and before (previous experiment with no SRM)
Did any of the views, pipelines, filters change?
Common root-causes for SRMs
Treatment experience in the game crashes more than control experience
Treatment experience unintendedly sending different amounts of data. For example, an experiment on the
client that increases the telemetry buffer will certainly increase the amount of data that makes it back, which
will cause an SRM
Experiments as a Practice
Star t with a hypothesis
Hypothesize to ensure that the experiment has a clear goal and scenario for the experiment. Also, make
sure the changes you are testing are significant enough to matter.
To form a hypothesis, use the following template:
Because of observation [A] and feedback [B], the belief is that changing [C] for players [D] will make [E]
happen. It will be validated when I see [F] and obtain [G].
Schedule experiment correctly
To get reliable results, run your A/B experiments for comparable periods. Do account for seasonal peaks
and troughs.
Duration of an experiment
Give the experiment enough time. Insufficient time allocated for the experiment can skew the results. If
the run time is too short, you might not collect enough data points for a statistically accurate conclusion.
If the run time is too too long, you might risk missing out on conversions by not rolling the winning
variant to the potentials. If you are in doubt, it is perfectly reasonable to retest.
Pay attention to % of a flight
% of flight determines your sample size. Target the audience with the right sample size, otherwise, you
will not get reliable results and the decisions made based on that data may be flawed.
Avoid Type 1 and Type 2 errors Statistics in experiments provides probability, not a certainty.
Therefore, it cannot provide 100% certainty whether one variant of the experiment is best. So, avoid Type
1 and Type 2 errors.
To avoid type 1 error, raise the required significance level before reaching a decision (which we have done
for you by setting it to 95%, by default) and running the experiment longer to collect more data. And to
reduce the chance of type 2 error, increase the experiment's flighting population (sample size).
Do not make changes mid-way to an experiment
If you interrupt the test before the end of the ideal duration or introduce new variables that were not part
of the original hypothesis, the results will not be reliable. Meaning, it would be difficult to determine
whether one of the changes caused the lift in conversions or just a random chance.
Please note, the more variations there are, the longer you must run the tests to get reliable results. Take a
granular approach. The recommendation is to experiment with 2-4 variables in any variant group at the
same time. That gives the best balance of test duration and efficiency.
Pay attention to statistical significance as reflected in p-value
Make sure that the data is reliable. The measure of data reliability is the statistical significance which
determines that the results are not due to random chance.
p-values are used to determine statistical significance in a null hypothesis onto which AB experiments are
based. It measures the compatibility between the collected data and the null hypothesis. The lower it is,
the more confident one can be in rejecting the null hypothesis.
Keep an open mind
At times, you might be tempted to ignore statistical information in favor of using conventional
knowledge or even previous experience, to make the decision – no matter how much it surprises you. If
you are not convinced by the results of a test, run it again and compare the data.
Experiment Design
Feature Design Review Finalize design for feature/ experience change. As part of the
experiment, it is introduced to a treatment variant group via
variables
Prod Deployment Review the experiment design. Deploy the associated code
Experiment Creation
Experiment Execution
Experiment Analysis
Roll-out or roll-back
To get comfortable with experiment as a practice and develop an understanding of the key-terms, read below:
Experiments
A/B experiments is a method of comparing two or more configurations of game experience (variants), whereas
multivariate experiments allows you to configure several game elements and determine which combinations
(variants) perform best at achieving your conversion goals.
This is done by splitting users randomly into two or more groups and providing different experiences to each
group over a period of time, and statistical analysis is done on the collected telemetry to determine which
variation performs better based on the goals you decide for the experiment
With PlayFab Experiments support both A/B testing (also known as split testing) and multivariate testing.
Conversion Rate
A conversion refers to any desired action that you want the player to take. Conversions do not have to be tied to
monetary goals. This can include anything from a click on a button to making a purchase and becoming a player.
Conversion is the goal of experiments. Conversions are an absolute number, whereas a conversion rate is the
number of conversions divided by the total player traffic.
Hypothesis
A hypothesis presents a claim about how a given intervention will affect player behavior. The hypothesis is a
combination of an idea about what scenarios to experiment and why, and what changes might appear after the
changes.
Segment
Segments organizes individual players into group(s) which shares common characteristic(s) as per the user-
defined qualifying condition(s)/criteria(s).
You can flight an experiment with a customized experience for a Segment to verify the hypothesis that an
audience will respond more positively.
% of target audience
A percentage of the total player base that are considered for the experiment and is associated with the control or
treatment variant.
Control Variant
A control variant is an existing experience that is used in an experiment as a measure of comparison to ensure
that the experiment works. It provides a baseline measurement for the experiment. It makes sure that the
treatment you are giving is causing the experimental results, and not something outside the experiment.
Treatment Variant
A treatment variant receives the experimental treatment(s) or difference in experience(s) in an experiment. It is
the treatment variant(s) that are studied in an A/B experiment and contains the experience changes.
Variables
Variables are defined to set the feature or experience configuration. Defining feature variables allows you to
iterate on your feature without redeploying the code.
P-value
The p-value in an A/B experiment is the probability that there is no difference between variant groups.
When the p-value is high it implies that any difference between the A and B groups is due to sampling noise.
When the p-value is low (below our threshold) it implies that the there is a real difference between variants and
the shown delta is the most likely actual difference.
Confidence Interval
In A/B testing, confidence intervals mitigate the risk of sampling errors, in a sense manages the risk associated
with implementing a new variant. If the tool indicates, “We are 95% confident that the conversion rate is X% +/-
Y%,” then you need to account for the +/- Y% as the margin of error. How confident you are in your results
depends largely on how large the margin of error is. If the two conversion ranges overlap, you need to keep
testing to get a valid result.
Type 1 Error : A type 1 error is a measure of “false positive,” an incorrect belief that a variation in an experiment
has made a statistically significant difference. A conclusive winner is declared although the test turned out as
inconclusive.
Type 2 Error : A type 2 error is a measure of “false negatives,” an incorrect belief that a variation in an
experiment has made no statistically significant difference. No conclusive winner is declared between a control
and a variation when there should be one.
Billing for PlayFab Experiments
5/24/2022 • 2 minutes to read • Edit Online
This document describes how Experiments are metered and billed. In PlayFab's free Development mode, titles
can use Experiments without a fee as long the aggregate number of player accounts is less than 100,000
(attempts to create additional player accounts will fail). For Live titles (on the pay-as-you-go model – Standard,
Premium, or Enterprise), Experiments is billed under the Insights credit system with no consumption limits.
Insights credits are a virtual currency that allows all Insights services to be billed through a common value.
Please note, Experiments service operation has no association with the performance characteristics control of
Insights service.
The billing summary page page provides a daily snapshot of your month-to-date estimate charges with
Experiments service’s Insights credit as breakdown. Admin or billing permissions are required to view the Billing
Summary page. The comprising factors which account for the accrued Insights credits based on the
consumption of the Experiments service are below.
What factors contribute to the consumption billing for Experiments service under Insights meter? The metering
starts only during the run of an experiment and stops when the experiment is completed or stopped. There are
three key factors used to bill additional Insights credit utilization for Experiments service.
1. Size of the target audience for treatment assignment. The participating audience of an experiment is either all
the active players or is determined based on the selected Segment’s computation in a real-time manner. Also,
the process of assignment and instrumentation of a treatment configuration is done by stamping variant IDs
onto the player profile. So, the larger the target audience, the more resources are consumed, which results in
higher Insights metering.
2. Computation of metrics. This is measured in analysis computation job minutes for each scorecard. This is
variable and the determining factors are the set of metrics (i.e., each metric’s definition and complexity) and
the number of relevant Entity events (with type ‘player’) associated with the involved metric set. So, the
larger the associated event set (PlayStream or Telemetry) for a metric set, the higher the Insights metering.
Please note, currently, we support a pre-defined metric set, so there are only two events—player_logged_in
and player_realmoney_purchase—for which the scorecard computation happens, and the events’ variable
size could add to the computation job minutes.
3. Experiment duration. The longer the duration of an experiment, the higher the consumption of the
Experiments service, which results in higher Insights metering.
Please note, the Experiment APIs and PlayStream events are accounted for outside of the Insights credit system.
The Experiment APIs along with the Overrides assignment usage are accrued under the profile read/ writes
meters. Also, the Experiments’ PlayStream events are accrued under the events meters.
Metrics
5/24/2022 • 2 minutes to read • Edit Online
Engagement metrics
M ET RIC DEF IN IT IO N
DAU Daily Active Users gives you the count of unique players
who logged in on a given day, from 12AM to 11PM UTC.
Logins The count of player login events. Unique logins count the
number of unique players. The total logins counts all login
events, which can be used to track number of sessions
played. Average logins per user tracks the average number
of login events per active player. Note: To obtain an accurate
distribution of session counts, we recommend logging in the
player on each session start - even if the old login ticket is
still valid.
New Users The count of players who logged in for the first time, thus
creating new player profiles.
Revenue metrics
M ET RIC DEF IN IT IO N
Top Items The top 100 items which generated the most revenue in
your game within a specified report period.
Top Spenders The top 100 players who spent the most money in your
game within a specified report period.
Unique Paying Users The count of unique players who spent money in your game.
Terminology
M ET RIC DEF IN IT IO N
Timestamp (TS) All PlayFab real-time analytics and reports are based on
Coordinated Universal Time (UTC ).
Real-time analytics: core concepts
5/24/2022 • 2 minutes to read • Edit Online
The analytics system gives you precise insights into the activities going on inside of your game.
How many players did you have today?
Where do they struggle?
What do they like?
How many games were played?
How much XP was gained?
How many chests were opened - and on which levels?
What is the average time for completing a certain level?
Such information is invaluable to you for marketing, level design, UX troubleshooting, and other aspects of your
product development.
At its core, the analytics system provides you with the tools to aggregate, query, and analyze the events
generated by your game, build reports, and export and manipulate the raw data.
PlayFab event
An event - as a data structure - represents a change in state for your game. Events are represented as JSON
objects. Each event has four parts:
1. Name (or unique type identifier) - (What happened?)
2. Entity (player, title, or character) - (Who's guilty?)
3. Timestamp - (When did it happen?)
4. Associated Data ( a.k.a. Body ) - (What are the relevant details?)
It is important to distinguish between Automatic and Custom events. Our Generating PlayStream Events Tutorial
explains the difference.
Event flow
The core of any analytics system is the event flow - which is a all-inclusive list of events sorted by time.
Your players are going to produce a large number of different events. But these events are not captured by
themselves - you need an analytics system to capture them for later analysis.
A solid analytics system allows you to group, sort, filter, count, transform, and perform calculations on a given
set of events, turning the event flow into valuable, up-to-date information that you can use to run efficient
LiveOps.
Guides
Webhooks: Game Manager page for automatically triggering non-PlayFab servers on specific game events.
S3 Event Archiving: Game Manager page for accessing recent PlayStream events.
Metrics quickstart
5/24/2022 • 2 minutes to read • Edit Online
There are two primary ways to explore your metrics from PlayFab Game Manager:
1. Trends - A collection of graphs visualizing performance over time.
2. Repor ts - Data tables comparing. Covered in detail in the Reports Section.
Trends tab
The Trends tab offers an easy way to view and analyze performance across eight key performance indicators:
1. MAU
2. DAU
3. New Players
4. Screen Time
5. Screen Frequency
6. Classic Retention
7. Revenue
8. Stickiness
The Trends tab is updated once daily at the close of the UTC day. For details on each metric, see Metrics and
terminology.
The Trends tab consists of three sections:
1. Filters
2. Spark Cards
3. Graphs
Filters
At the top, there are three page-level filters that can be applied. Choosing any filter will update all Spark Cards
and Graphs to match the current active selection:
Time: Choose the time interval to explore, from seven days to six months.
Platform: See only data for individual device types such as Android, iPhone, or Windows.
Region: See only data from a specific geographic region.
NOTE
Platform and Region filters are not currently supported for Revenue. This will be resolved in a future release.
Spark Cards
The Spark Cards are designed to offer an at-a-glance view of what happened that particular day. Each Spark
Card consists of:
A trend line
The actual value from the most recent UTC day
The trend comparing the most recent value against the period start.
Definitions for each are obtained by hovering over the metric or by tapping, if using a mobile phone.
Graphs
The Graphs provide trend data for each of the six metrics, through that day. In some cases, the drop-down over
each graph can be used to toggle the active metric. For example, the Active Players graph can show either DAU
or the Rolling 30-Day MAU.
In the upper right-hand corner of each graph, individual lines can be toggled on and off. Doing so dynamically
re-scales the y-axis. Additionally, in the Retention Graph, D1 and D7 can be disabled to emphasize variations in
D14 and D30.
Hover over any data point to display the actual value for the selected day. To the right of each graph, supporting
metrics offer additional insights such as the average and/or total for the period.
Data Collection
If your title is not collecting device information or sessions events, some components of the Trend Explorer will
be unavailable. To enable these, change your settings in the Data Collection tab. SeeData Collectionfor more
details.
Metrics Tutorials
5/24/2022 • 2 minutes to read • Edit Online
This tutorial provides an overview of automatic and custom PlayStream events in PlayFab.
PlayFabClientAPI.LoginWithEmailAddress(new LoginWithEmailAddressRequest() {
Email = "my@email.com",
Password = "qwerty"
},
result=> Debug.Log(result.PlayFabId),
error=> Debug.LogError(error.GenerateErrorReport()));
This topic describes how to set up an Amazon S3 bucket so that you can archive your PlayFab events to it.
PlayFab supports logging events to calculate focus time and session duration. You can learn even more on our
blog.
NOTE
Disabling this option will prevent these events from being emitted by the client.
You can also disable these from the code, by setting the option shown below to true in your title setup, as
shown below.
PlayFabSettings.DisableFocusTimeCollection = true
Legacy Instructions
If your game uses an SDK between the 180716 and 180809 , it's possible for you to send the focus time events,
although it requires additional steps.
Because these events leverage the WriteEvents API, you'll first need to ensure the Enable Entity API flag is
enabled (checked) in the SDK settings at the time you update the SDK.
Next, you'll need to log into the entity system, by adding the line shown below to each of your login requests.
LoginTitlePlayerAccountEntity
Once you've done that, you should see these same events.
Reports
5/24/2022 • 2 minutes to read • Edit Online
We know the hard work doesn’t end at launch – that’s just the beginning. To maximize a game’s potential to
connect with players, to keep them engaged, and earn revenue, you need to a reporting solution to monitor
your progress.
PlayFab Reports are designed for easy access to the critical metrics of your game at a glance. This set of pre-
generated reports is available in the Analytics section of Game Manager.
From there, you can dive into daily, monthly, and 30-day rolling views that focus on engagement and
monetization. Each report can be downloaded as a CSV for use in custom applications. In addition, you can opt
to receive daily summary e-mails delivered to your inbox.
Reports quickstart
5/24/2022 • 2 minutes to read • Edit Online
The Repor ts page gives you access to various reports composed from events, and broken down by dates.
IMPORTANT
Before using Repor ts , make sure you have executed some API calls which have been captured by the Repor ts system
already.
Access reports
To access the Repor ts page:
1. Use the side bar menu and navigate to Analytics .
2. Select the Repor ts tab.
Reports overview
The example shown below shows an overview of the Repor ts page.
1. The first section allows you to filter Repor ts by Type (Name ).
2. The Date column lists the time intervals for all Repor ts that have been generated. You can select the
Date label to access report details for a specific date.
3. The Name column identifies the Repor t Type uniquely. You can select the Name label to access report
details for the corresponding Date .
4. When Repor t data is available, you can download a CSV representation of the data by selecting
Download CSV .
5. When Repor t data is not available for a given day (no events that day), the Date and Name labels will
render black, will not be selectable, and the option of downloading the report as a CSV will not be
available.
Report Types
Daily, Monthly, and Rolling Thirty-Day Overview and Totals Reports
Tracks hourly, daily, and monthly logins, revenue, and API usage.
Thirty-day Retention Report
Tracks the percentages of all active players who return to your game over 30 days.
Thirty-day New User Retention Report
Tracks the percentages of new players who return to your game over the first 30 days.
Thirty-day New User Conversion Report
Tracks the percentages of new players who spend money within the first 30 days.
Daily and Monthly Top Spender Report
Tracks the top 100 spenders in your game.
Daily and Monthly Top Items Report
Tracks the top 100 items in your game.
Daily AB Test KPI Report
Evaluates the effectiveness of your A/B test experiments.
Daily API Usage Details Report
Tracks the PlayFab API calls used by your title.
Daily and Monthly CDN Usage Report
Tracks Content Deliver y Network (CDN ) usage by your players.
Daily Abuse Reports History Report
View and read player bug reporting, and/or let players report each other for cheating.
NOTE
The Name column is never selectable on this report, but the Download CSV column will still work if there is data
present.
Reports Tutorials
5/24/2022 • 2 minutes to read • Edit Online
The Reports tutorials show you how to create and run reports.
Daily A/B Test KPI Report
Daily Abuse Reports History Report
Daily and Monthly CDN Usage Report
Daily and Monthly Top Items Report
Daily and Monthly Top Spender Report
Daily and Monthly Top Details Report
Daily and Monthly Rolling 30-Day Overview and Totals Reports
Thirty-day New User Conversion Report
Thirty-day New User Retention Report
Thirty-day Retention Report
Daily A/B test KPI report
5/24/2022 • 2 minutes to read • Edit Online
Overview
The Daily A/B test Key Performance Indicators (KPI) report shows the outcome of an A/B test, broken down by A
and B buckets.
NOTE
You can have up to 5 Buckets with independent ratios (%).
Please refer to the Customer Stores for Player Segments tutorial for further information on A/B testing with
stores that are available only to players from defined player segments.
Daily Abuse Reports History Report
5/24/2022 • 2 minutes to read • Edit Online
Overview
The Daily Abuse Reports history report contains a CSV document with all of the player reports that happened
during the specified day.
In the example shown below, a player with ID of 6079A16A9E4FB67 is reporting a player with ID of
94A248B3B9E628F2 for the reason Test Repor t on 5/14/2017.
NOTE
For GDPR compliance reasons, the Daily Abuse History Reports are only available for the past 30 days. To learn more, visit
our GDPR documentation.
Using this information, you can then use the reportee ID, to quickly look up the reported player and investigate.
});
}
It is important to understand that the GetContentDownloadUrl API call, on its own, does not produce a new
entry in the report.
Instead, it provides you with a URI for the content download. You may use any HTTP request technique to
execute a GET request. Once this is done, a new entry will be added and reflected in both reports.
3. The metrics available in the Timeline area contain the sum of all the instance across the time period (SUM ),
the average number of instances through all the timestamps (AVG ), the peak value (MAX ), and the lowest
value (MIN ).
Daily and Monthly Top Items report
5/24/2022 • 2 minutes to read • Edit Online
Overview
The Daily and Monthly Top Items report contains a list of top selling items, or bundles, in a given day or month.
This list includes:
Item names from your primary catalog
Associated numbers of sales
Total revenue
The report can assist you in identifying trending items over time, which can be useful for planning future
promotions or events.
The Daily and Monthly Top Items report contains a list of top selling items or bundles in a given day or month.
Both daily and monthly tables within these reports include item names from your primary catalog, associated
number of sales, and total revenue.
You can utilize the data contained within this report to identify trending items on visible timelines - a feature
that is useful for the design and execution of promotions and events.
Overview
The Daily and Monthly Top Spender report shows the list of players who spent money in your game on a given
day or month, sorted by the transaction amount.
NOTE
For GDPR compliance reasons, the Daily Abuse History Reports are only available for the past 30 days. To learn more, visit
our GDPR documentation.
You can select the PlayFab ID label to quickly navigate to the Player's Details page.
The Daily and Monthly Top Spender report shows the list of players who spent money in your game on a given
day or month, sorted by the transaction amount.
You can select the PlayFab ID label to quickly navigate to the Player's Details page.
Populating the Reports
Please refer to Non-receipt Payment Processing tutorial to learn how to conduct payments.
Daily API Usage Details report
5/24/2022 • 2 minutes to read • Edit Online
Overview
The daily API Usage Details report contains statistics for each API call, aggregated by the API name on an hourly
basis. The table contains the following metrics:
Total API Calls , Total Errors and Total Successful - These columns allow you to check the overall usage
and stability of your API calls.
Average Response Time , Total Response Time , Average Received bytes , Total Received bytes ,
Average Sent bytes , and Total Sent (MB ) - These columns are useful for monitoring system performance,
as well as optimizing some user-defined, heavy-duty function calls (for example, CloudScript).
If you experience lag spikes in your application while executing API calls, you can refer to this report to track
down the underlying cause.
For example - using the report, you will be able to check whether the data was too large, or that a handler
worked inefficiently. You can further utilize the report to tune the performance of CloudScript execution by
adjusting its behavior and associated data.
Introduction
PlayFab offers a set of daily and monthly Key Performance Indicator (KPI) reports, including:
Total Logins
Unique Logins : Daily reports (DAU ) or Monthly and Rolling Thirty Day Reports (MAU )
New Users
Unique Paying Users
Transaction Revenue
Purchases
Total API Calls
Total Successful API Calls
Total API Call Errors
Average Revenue Per User (ARPU )
Average Revenue Per Paying User (ARPPU )
Average Purchase Price
An Overview report contains trend charts of each metric during the past 24 hours (daily), past 30 days (rolling
30-day), and in last month (monthly).
A Totals report contains the summary of each metric shown in the overview report. Daily and Rolling Thirty Day
reports are generated on a daily basis, whereas Monthly reports are generated on the first day of each month.
Report times are based on Coordinated Universal Time (UTC). For additional details on metrics, see Metrics and
Terminology.
Totals reports
Totals reports include a table, which contains the 12 Key Performance metrics described in the introduction.
Overview reports
Overview reports consist of 12 trend charts - one for each metric described in the introduction. Working with
charts is described later in this tutorial.
Populating the reports
Any API call may introduce new data for total API calls, total successful API calls, and total API call errors.
Once executed, an API call will be added to total API calls.
If there is an error that is introduced, it will be recorded to total API call errors.
If no error is introduced, it will belong to total successful API calls.
Please consult our PlayFab API Reference documentation to review all available API calls.
The following API calls will introduce new data for total logins and total unique logins:
LoginWithAndroidDeviceID
LoginWithCustomID
LoginWithEmailAddress
LoginWithFacebook
LoginWithGameCenter
LoginWithGoogleAccount
LoginWithIOSDeviceID
LoginWithKongregate
LoginWithPlayFab
LoginWithSteam
LoginWithTwitch
LoginWithWindowsHello
The API calls shown below will introduce new data for total new users.
RegisterPlayFabUser
RegisterWithWindowsHello
The API calls shown below will introduce new data for total new users if the CreateAccount flag is set.
LoginWithAndroidDeviceID
LoginWithCustomID
LoginWithFacebook
LoginWithGameCenter
LoginWithGoogleAccount
LoginWithIOSDeviceID
LoginWithKongregate
LoginWithSteam
LoginWithTwitch
The unique paying users, revenue, purchases, Average Revenue Per User (ARPU), Average Revenue Per Paying
User (ARPPU) and average purchase price metrics are used to analyze purchases and payments.
See the Non-receipt Payment Processing tutorial, for more information on conducting payments.
Overview
The Thirty Day New User Conversion report illustrates the percentage of players in a given Cohort who spent
money in the game during their first 30 days.
A Cohort of players is formed every day by grouping newly-registered players. Cohort size is indicated by the
number of players in a cohort.
NOTE
Unlike Retention reports, the Conversion report tracks a cumulative total of players who converted within a given time
span.
The example report shown below was generated on 2/13/2018 . On 1/14/2018 under the Cohor t column,
77,532 new players created accounts in the example title.
Under the Day 0 column of that date, 0.50% of these players made at least one transaction in the game.
Since conversion reflects a cumulative total of players, these percentage values increase along the time span,
and reach 1.07% on the 30th Day - which corresponds to the report generation date, 2/13/2018 .
For additional details, see Metrics and Terminology.
Overview
The Thirty Day New User Retention report tracks the percentage of new user cohorts who return to the game on
subsequent days.
A Cohort of players is defined by grouping newly registered players on a given day (Day 0 ) and their retention
is tracked over a 30-day period.
Cohort size is determined by the number of players within it.
The example report shown below, was generated on 2/5/2018 . On 1/6/2018 , 39,132 new players created
accounts in the example title.
Since Day 0 is an initiation date for a new Cohort, this column always has 100% retention rate.
Then 33.84% of those players logged in again the next day, 24.64% in two days later, and so on. 10.84% of the
Cohort returned on the 30th day, which corresponds to 2/5/2018 .
For additional details, see Metrics and Terminology.
Overview
The Thirty day Retention report table illustrates how many of your players came back to the game within a 30-
day period.
A new Cohort of players is formed every day, based on all the players (new and returning), who have logged in
to your game on a given day (Day 0 ).
Cohort size is determined by the number of players within it. Then each cell shows the percentage of players
(%) from a given Cohort who returned on each subsequent day.
The Thirty Day Retention report table illustrates how many of your players came back to the game within a 30-
day period.
The example report shown below was generated on 1/24/2018 . It shows, for instance, that on 12/25/2017 ,
1.38M users logged in.
Then 61.85% of them logged in the next day, and 55.85% of them logged in two days later.
Finally, 18.6% came back 30 days later, which corresponds to the report generate date, 1/24/2018 .
This report, in addition to the New User Retention Report, is especially useful when you are running a LiveOps
event, and want to check its effect on boosting engagement of existing players. For additional details, see
Metrics and Terminology.
Segmentation lets you create targeted groups of players based on their player properties. When PlayStream
events are processed, your configuration will drive the addition of players into and out of the segments you
define.
This all happens in real time - so there should be no perceptual lag, even at large scale. If you can tie an event to
the thing you want to use as a differentiating factor, you can make a segment for it, and that segment will apply
retroactively to all players, based on the data in their profiles.
Let's say that you want to define a segment of players where XP > 3,000, then every player with XP > 3,000 will
now be in that segment.
In the example shown below, this particular segment will be evaluated anytime the statistic called
Total_XPGained changes. If the condition (> 3000) evaluates to true , then the player will enter the High XP
Players segment, and the corresponding action(s) will be triggered.
In this case, it will send a push notification, and grant gold to the player.
NOTE
You can also trigger a different custom action(s) when the player leaves a segment, allowing you to make any other
changes needed as a result.
There are a variety of basic actions available, including granting an item to the player, granting virtual currency,
changing a statistic, banning a player, sending a player an email or sending a Push notification. You can also
trigger custom CloudScript to be run instead.
Player segmentation quickstart
5/24/2022 • 2 minutes to read • Edit Online
Player segmentation is defined in Game Manager. Segments allow you to define useful or interesting groups of
players, and perform exclusive actions on that group.
Requirements
Players with and without a distinctive characteristic defined in PlayFab.
A defined CloudScript PlayStream Hook.
Example case: Run a custom CloudScript for every player who reaches an in-game goal
The defining characteristic of a player might be:
Login time
Linked device type
Tags
Real-world location
Statistic values
Virtual currency values
Real money purchases, and more.
For this example, our distinctive characteristic will be a statistic - specifically, players who achieve 50 str .
NOTE
Statistics are one of many possible options, and only specifically required for this example. Feel free to replace the statistic
requirement with another filter of your choice.
Our action will be to run a CloudScript function. CloudScript is by far the most flexible trigger option, granting
you the full control of player and segmentation information at the time of segment transition.
From the Game Manager screen:
Navigate to your Title .
Select Players from the menu on the left.
Move to the Segments tab.
Select New Segment .
The screen shown below is an example of the Segment described above.
The most complex part of this example is the CloudScript. Utilize the second parameter, Context, in your
CloudScript handler to identify the player, and segment transition.
Afterwards, perform any action you wish on the player, such as granting inventory items, virtual currency, player
data, or statistics.
See also: Best Practices for store segmentation
Segmentation Tutorials
5/24/2022 • 2 minutes to read • Edit Online
Segment Configuration
This tutorial show you how to set up player Segments.
Export Player in a Segment
This tutorial show you how to set export players in a Segments using ExportPlayersInSegment and
GetSegmentExport APIs. These APIs are a newer and better version of GetPlayersInSegment API.
Segment configuration
5/24/2022 • 7 minutes to read • Edit Online
The Segment configuration page, accessed from the Players tab in Game Manager , allows you to configure
a new or existing segment by adjusting the name, defining filters, and assigning tasks.
Each segment allows you to define useful or interesting groups of players, and perform exclusive actions on that
group.
NOTE
The trick here is that a player may start with authentication based on, say, an iOS device ID, but later, the same player
may have a GameCenter account linked. In this case, user origination will be the iOS device ID. For example, players that
first signed in using an iOS device ID.
The Vir tual currency balance filter - Allows you to filter based on the custom virtual currency deposit of
a player. For example, players that have less than 50 Crystal.
This tutorial walks you through the steps needed to export the Player Profiles in a Segment using the
ExportPlayersInSegment API and GetSegmentExport API. These APIs are a newer and better version of
GetPlayersInSegment API.
Step 1
Send a POST request with the Segment Id as the payload to the ExportPlayersInSegment API. The ‘ExportId‘ in
the response is the unique identifier of the export operation.
NOTE
The API requires the ‘X-SecretKey’ header with the value being a Title Secret key. The ‘Content-Type’ header should be set
to ‘application/json’
Step 2
Send a POST request to GetSegmentExport API with the ExportId received in the above API call as the payload.
The response has the ‘State’ of the export operation. If the export has a status of ‘Complete,’ then the response
contains the ‘IndexUrl’ from which the Index file can be downloaded.
NOTE
The API requires the ‘X-SecretKey’ header with the value being a Title Secret key. The ‘Content-Type’ header should be set
to ‘application/json’
Step 3
Download the Index file from the IndexUrl. The Index file is a file in which each line is a URL from which a
fragment of the player profiles in the Segment can be downloaded. Given below is an example of an Index file.
There are 2 URLs (export fragments) in the Index file.
Step 4:
Download the player profiles from each URL by iterating through the lines in the Index file. The player profile
files use tsv formatting. For example, the player profile downloaded from the first URL in the above Index file is
given below:
What is A/B testing?
5/24/2022 • 3 minutes to read • Edit Online
A/B testing is a technique for running experiments to determine the optimal setting for a particular variable. For
example, let’s say you want to test out different sale prices for an item in your in-game store.
With A/B testing, you create a series of player “buckets” into which you partition your players randomly, with
weights assigned to each bucket. Each bucket is assigned a different price. Players see the price assigned to their
bucket. You then compare the results for each bucket, to determine the most effective price.
The following table of values gives you an example of what this might look like.
VA RIA B L E A B C
Here, bucket “C”, despite having the highest price, ended up generating the higher Average Revenue Per User
(ARPU), and would appear to be the “winner” of the test.
Note that bucket assignment is probabilistic, so the populations of each bucket may vary by up to a few percent
of the specified weight. This evens out as your player base grows.
Reviewing Results
Once you’ve created a test, we will begin to generate a daily report referred to as the Daily A/B Test KPI Report.
This will give you key KPIs by player bucket for each test you are currently running.
We recommend letting this report run for at least a few days, to get a baseline before configuring store
overrides. We partition your users based on their PlayFab IDs, which are randomly assigned at creation time.
Due to the probabilistic assignment of players, it is unlikely that the KPI will be uniform at the beginning of the
test.
Once you're confident about the results of your test, you can then reconfigure your primary store and safely
delete the test.
This quickstart explains how to create A/B tests with player buckets.
A/B tests allow you to use the buckets as Player Segments. Unlike player segments, however, A/B buckets
distribute players randomly. The buckets defined for these tests may then be used in some of the features,
where you would normally use player segments.
For an example of this, see our tutorial A/B Testing with Stores and A/B Test Buckets.
Links
To dive deeper into A/B testing, read the following tutorials:
A/B Testing with Stores and test buckets
A/B Testing with Title data
A/B Testing Tutorials
5/24/2022 • 2 minutes to read • Edit Online
In our Stores and Sales tutorial, we demonstrate how to set up a store and make a few items available to a
player at special or alternate prices.
In our A/B Testing quickstart, we demonstrate how to create A/B tests and form player buckets for random,
percentage-based user distribution.
This tutorial lets you combine these features, and produce several versions of the store available to different A/B
testing groups (buckets).
We first define an A/B test. In this case we define a test called Store A/B Testing, which splits users into 3 groups.
The first group (control) contains 34% of all the players. The other 2 test groups each contain 33% of all players,
as shown in the example provided below.
Next, we create one store to be the original version, and then create 3 other stores, which are A/B tested
variations of the original.
Each store is created independently, has its own unique identifier, and should have content that is customized for
that segment (see below).
Return to the original Store page:
Locate the SEGMENT OVERRIDES section.
It will not only contain the usual Player Segments , but it will also expose all the Buckets for all A/B Tests
that you currently have.
Make sure your A/B Test Buckets are on the top of the list, and assign Store override settings for each Bucket ,
as shown in the following picture.
Do not forget to save the settings. You have an A/B test where players are distributed into 3 groups of 50% ,
30% and 20% .
For each group of players, you assign a different version of the store. You may then use A/B testing reports to
track user conversion for each version of the store.
Best practices for store segmentation
Please consult the following tutorial: Best practices for Store Segmentation.
A/B testing with TitleData, A/B test buckets, and
CloudScript
5/24/2022 • 5 minutes to read • Edit Online
This tutorial illustrates how to complement PlayFab's built-in features with something which is not a fully
integrated feature yet.
A/B Testing title data is a planned feature. However, It is possible to build your own solution now , using
CloudScript.
Requirements
Writing Custom CloudScript, and CloudScript quickstart
Title Data
A/B Testing quickstart
Optional Requirements
The final example uses Unity, but this technique can be used with any SDK.
Functionally, a bucket ID is the same as a normal segment ID. An API call to GetPlayerSegments will return both
segment IDs and A/B test bucket IDs.
We can use this to our advantage, and introduce a convention for A/B-Tested title data keys, as shown below.
First, we introduce a regular entry with the Key called MyMessage .
We then introduce an A/B -version for each Bucket . The Key is composed using the original Key and a suffix
in the form _BUCKETID .
At any point in time, if we are given an original key and segment ID, we can easily compose a key that is
entry-specific for this segment/bucket.
Our next step is defining one more entry - a list of all the bucket IDs participating in the testing. In this case
we have three of those, as shown below.
NOTE
Make sure to use double quotes ( " ). Otherwise, the JavaScript runtime will not be able to parse it properly.
Now let us define a brand new API call using CloudScript. This API call is named GetTitleDataAB , and performs a
very simple procedure:
1. We receive a regular title data key (ex. MyMessage ) from the client, via args.
2. We get all the bucket IDs participating in the testing.
We do this by reading the TitleDataAbTestSegmentIds key from our title data.
3. We get all the segment IDs a player belongs to.
We do this by making a call to GetPlayerSegments and passing the current player ID.
4. If a player does not belong to any bucket, we return the value for the original key:
For example, MyMessage -> This is normal message .
5. If a player belongs to one of the tested segments, we assemble a new key using our convention, and try
to fetch the value for this key:
For example, if a player belongs to a bucket with the ID 920BD7F496ACB328 , we read the value for the
MyMessage_920BD7F496ACB328 key.
6. If no bucket-specific value was defined, we, again, return the value for the original key.
Let's inspect the following implementation (please read the code comments for further explanation).
// Special key in the Title Data that contains an array of AB buckets that participate in the testing
var TITLE_AB_TEST_TITLE_KEY = "TitleDataAbTestSegmentIds";
handlers.GetTitleDataAB = function (args, ctx) {
// The data key the player originally requested.
var dataKey = args.TitleKey;
/*
* We store a list of bucket IDs that participate in the AB testing in the title data.
* This line extracts an array of such ids
*/
var requestedTitleData = server.GetTitleData({ Keys: [TITLE_AB_TEST_TITLE_KEY, dataKey] });
var defaultValue = requestedTitleData.Data.hasOwnProperty(dataKey) ? requestedTitleData.Data[dataKey] :
null;
var segmentIdJson = requestedTitleData.Data.hasOwnProperty(TITLE_AB_TEST_TITLE_KEY) ?
requestedTitleData.Data[TITLE_AB_TEST_TITLE_KEY] : null;
var abTestSegmentIds = JSON.parse(segmentIdJson);
// If player does not belong to any tested segment, return a value for the original key
if (!currentAbTestSegmentId)
return defaultValue;
/*
* If player belongs to one of AB tested segments
* we use ID of this segment to construct special key
* First part of this key is the original key
* Followed by underscore ('-') we add a suffix, which is ID of the bucket the player belongs to.
*/
var abTestedKey = dataKey + "_" + currentAbTestSegmentId;
Testing
Once the CloudScript from the previous section is uploaded, the code snippet shown below can be used to test
the described technique.
// Coroutine will wait here, until we set log in waiting flag to true
while(!isLoggedIn) yield return null;
}, result =>
{
// Once data is obtained, we set isAbDataFetched to true and log the result
isAbDataFetched = true;
Debug.Log(result.FunctionResult);
},OnError);
At this point, you can use this implementation to A/B test any data in your title.
Getting started with business intelligence
5/24/2022 • 2 minutes to read • Edit Online
Getting to know your players and their behavioral patterns in your game is critical to increasing retention,
engagement and monetization.
The goal of this document is to help you get up to speed on how PlayFab empowers your business intelligence,
and to quickly immerse you in the tool sets that we provide.
NOTE
Before you can use Game Manager for your title, you need to create a PlayFab Developer Account.
In general, you can analyze what players are doing in your game by following their event patterns. In PlayFab,
these come from PlayStream events.
PlayStream is an event processing system that unifies the entire data flow from your game into a single event
stream. You can then visualize and take actions on that stream in real time.
Thank you for either choosing PlayFab as your platform for back-end services and LiveOps or evaluating the
PlayFab offering. Welcome!
The first step in adding PlayFab to any Title is adding code to authenticate and log in the player. Logging in the
player returns a security token that is needed for all other API calls.
In this topic we show you how to retrieve the TitleId for your Title. You can then follow the quickstart guides
listed later on in this topic to learn how to use the TitleId to log a player in.
NOTE
The quickstart guides use a test TitleId . When you follow a guide, use a TitleId for a Title that you have created in your
PlayFab Developer account.
Before you can make your first API call to log a player in, you must create a PlayFab Developer account.
TIP
To leverage rules in the automation system, write custom events in your Title which creates a PlayStream event. For more
information on custom events, see Custom event overview in Generating PlayStream events.
Next steps
Every Title is different, so you will have a unique set of features that you must build every time. It is important to
know and understand how to map those features onto PlayFab.
This generally starts with the configuration of your Title. You will want to store variables in PlayFab and pull
them down on to game clients. But these are not the only types of configurations that you'll want to make.
Some of the different ways that you can map PlayFab onto a Title are shown below; use these to find the
combination of tools that is just right for your Title:
Title Data – Map variables containing data on PlayFab to data structures in your game clients.
Entity Objects (aka: Player Data) – Store and retrieve data on a per player basis.
Catalogs (Items) - Very useful for storing configuration data about your Items and potentially being able to
sell them as virtual goods.
Groups – Groups are generally used for things like guilds or clans. Groups are arbitrary and have members,
roles and other guild-like features.
Finally, check out each of our feature areas in the links provided below to find the right feature set for your Title:
Authentication
Data
Automation
Social
Economy
Multiplayer
Analytics
Engagement
PlayFab Pricing Overview
5/24/2022 • 2 minutes to read • Edit Online
WARNING
PlayFab customers on the legacy pricing model (MAU based pricing) will need to update their account plans to the
modern pricing model prior to 10/31/2020 at which time MAU based pricing will no longer be supported. Learn how
to update your account .
Want to learn more about PlayFab pricing? The following articles can help you understand PlayFab's
pricing model, how to view your estimated bill, and how to manage account upgrades and titles launches
through Game Manager. View the most up-to-date offers and prices at PlayFab.com/Pricing.
1. Billing Summar y : View past and present estimated costs.
2. Development Mode : Understand technical limits applied to titles in development mode.
3. Pricing Meters : Learn about meter pricing and related APIs.
4. Multiplayer Ser ver Pricing : Learn about multiplayer server (MPS) pricing when MPS is enabled.
5. Par ty Pricing : Learn about Party pricing when Party is enabled.
6. User Generated Content Pricing : Learn about User Generated Content (UGC) pricing when UGC is
enabled.
7. Experiments Pricing : Learn about Experiments pricing when used.
8. Technical Suppor t : Access support included in paid account plans.
9. Upgrading Accounts : Upgrade your account plan using the self-serve plans experience in Game
Manager.
10. Launching Titles : Launch your titles in Game Manager.
Billing Summary and Base Rate
5/24/2022 • 4 minutes to read • Edit Online
Admin or billing permissions are required to view the Billing Summar y page.
The billing details page provides a daily snapshot of your month-to-date estimate charges. Use the information
on this page to estimate what your bill will look like at the end of the month and view past months to
understand trends and comparisons. The billing details page helps you determine what the biggest consumers
of your metered resources are and gives you information that you can use to reduce your charges in
subsequent months.
NOTE
The values reported on the billing summary page are an estimate of usage and associated costs for an account. The
amount shown might not depict the final invoice amount charged to an account.
To view the billing details page for your studio navigate to the My Studios and Titles page. Click the ellipsis on
the right side of your studio, and then selecting the Billing summary option in the drop-down.
NOTE
As the storage meters are billed based off average consumption instead of total consumption, the data is
represented differently. The first day of data contains the MTD average, and the remainder of the days are
purposefully left blank.
6. Contact Information
This is the contact information we use to send you an invoice. This can be changed by navigating to
the Billing Information page.
7. Title Filter
Use the Title filter to understand consumption and apportioned cost by title. Namespace events are
counted in the "All" calculation, but aren't currently available to drill down (as they aren't tied to a title).
Development mode titles are not charged to the account and do not display cost data.
8. Month Filter
Use this filter to choose the month to display. All billing summary data from the time the account was
updated to usage-based pricing is visible through the billing summary page.
9. Meter Categor y
The Pay as you Go section buckets the full set of meters into logical categories. You can find the full
set of meters in meter documentation.
10. Meter
This is a billable meter that at least one of your titles is consuming. You only see meters that you are
using. For a full list of meters, see meter documentation.
11. Usage
This column provides estimated, rounded usage (for readability purposes) for each tier/SKU, as well as
the aggregated amount. To see the exact usage, download the .csv (5).
12. Rate
This column provides the rounded rates (for readability purposes) for each tier/SKU. To see the exact
rates, please download the .csv (5).
13. Cost
This column provides the estimated cost for each tier/SKU, as well as the aggregated amount.
14. Description
Each meter provides a brief description in the billing summary page. You can find a more detailed
explanation of the meters in meter documentation.
NOTE
Titles in Development Mode are not counted against included base rate usage.
All PlayFab titles are in one of two possible states - development mode and live. Development Mode is, as the
name suggests, meant for titles currently in development. This mode provides developers with the flexibility to
connect a title to PlayFab without running up the bill. However, there are functional limitations for titles in
development mode (detailed below). A title in development mode can only have up to 100k users. These titles
can be launched through Game Manager and is then considered live. Launching a title removes all development
mode limitations and allows the title to expand outside of test markets.
By default, every title created starts in development mode. The My Studios and Titles main page will indicate
which state a title is in through a mark on the bottom, left corner of the title block. This indicator can also be
viewed at the top of the left nav within a title. Titles in development mode are labeled Development . Live titles
are blank.
My Studios view of development mode title tag
The following walks you through an example of a fictional customer called Fun Studios:
T IT L E T IT L E M O DE M ET ER C O N SUM P T IO N
Fun Game 2: The Return of Fun Development Mode 100K PlayStream Events
When Fun Studios visits their Billing Summary page, they only see the consumption for their Live title, Fun
Game, count against their Standard Plan included resources.
For more information on these topics, check out these pages:
Meters
Upgrades
Billing Summary
Limits
There are some studio and title limits associated with development mode:
Studio Limits
L IM IT A M O UN T
Title Limits
L IM IT A M O UN T
Profile Storage 2 GB
Definition of Unique Users: Unique Users are simply the total amount of player profiles you have in your
title, which is different from MAU - you can delete player profiles through the Players page in Game Manager to
reduce the total number of Unique Users if you are approaching the limit but aren't ready to launch your title
NOTE
You can learn more about title limits at PlayFab.com/Pricing page.
Pricing Meters
5/24/2022 • 6 minutes to read • Edit Online
PlayFab's pricing is calculated from a set of consumption-based meters. This page outlines and defines the full
set of PlayFab's pricing meters and how they are measured and calculated. For more information on PlayFab's
pricing model, see PlayFab Pricing Overview.
NOTE
This page does not include Add-ons like Community Sift, Snowflake, or Photon, and is subject to change as new services
and capabilities are added to PlayFab.
Core Meters
PlayFab Events, Profile, and Content & Configuration are the services that make up the core PlayFab product.
Most PlayFab features use of a mix of functionality across the core services and will accrue usage against one or
more core meters.
Events
View and take action on your game's real-time data. Events can be generated in two ways. Standard events are
automatically generated by PlayFab Game Services APIs and written to the event pipeline. Custom events can be
created to trigger specific actions within the event pipeline.
PlayStream Events - PlayStream unifies your game data into a single stream and allows you to trigger
player engagement actions. These events show up in the PlayStream Monitor to provide real time
visualization of event data. For more information, see PlayStream Event Model reference.
Telemetr y Events - Telemetry events are custom events that bypass PlayStream and go straight to the data
warehouse. For more information, see PlayStream Events - Write Telemetry Events.
[!NOTE] Events are metered in 1 KB blocks against average event size. For example, 10 events with an
average size of 2 KB are billed as 20 events, while 10 events with an average size of 0.5 KB are billed as 10
events.
EVEN T N A M E C O UN T SIZ E
player_leveled_up 40 50KB
player_bought_item 30 10KB
player_statistic_changed 20 30KB
player_executed_cloudscript 10 20KB
By adding up the total size (110KB) and dividing by the total count (100), we get an average size of 1.1KB.
Therefore, we need to multiply the total count by 1.1 to get the effective count of 110 PlayStream Events. Let's
look at the same example with some adjusted numbers:
EVEN T N A M E C O UN T SIZ E
player_leveled_up 40 40KB
player_bought_item 30 10KB
player_statistic_changed 20 20KB
player_executed_cloudscript 10 20KB
By adding up the total size (90KB) and dividing by the total count (100), we get an average size of 0.9KB.
Therefore, we don't multiply the total count by anything - we stick with 100 PlayStream Events, even though the
player_executed_cloudscript event had an average size larger than 1KB.
Profile
There is nothing more important to the success of your games than your players. The Profile is what helps you
understand and engage with your players - it includes any stored data related to player profile, entity profile,
character profile, groups membership, and inventory. Data reads, writes, and storage are billed as part of this
metered service.
Reads - Metered based on the total number of reads to profile data which are processed by PlayFab. For a
list of read APIs, see Profile read APIs. This meter is weighted to 1KB.
Writes - Metered based on the total number of writes (and deletes) which are processed by PlayFab. For a
list of write APIs, see Profile write APIs. This meter is weighted to 1KB.
Storage - Metered based on the average total volume of profile data hosted by PlayFab across daily
snapshots.
Content & Configuration
Content & Configuration files are used to remotely manage configuration for your game. You can update game
content remotely in real-time (or on a schedule), and deliver personalized news and events that keep players
coming back for more. Content & Configuration files include the following items: entity files, actions, rules,
scheduled tasks, matchmaking, push notifications, emails, and title news. Content & Configuration files are a set
of key/value pairs that are primarily used to manage configuration for your game remotely. Files data reads,
writes, and storage are billed as part of this metered service.
Reads - Metered based on the total number of files data reads which are processed by PlayFab. For a list of
read APIs, see Content & Configuration read APIs. This meter is weighted to 10KB.
Writes - Metered based on the total number of files data writes (and deletes) which are processed by
PlayFab. For a list of write APIs, see Content & Configuration write APIs.
Storage - Metered based on the average total volume of files data hosted by PlayFab across daily snapshots.
Service-specific Meters
The following services are metered directly in addition to any usage they accrue against core meters.
CloudScript
CloudScript enables you to use client code to request execution of any custom server-side functionality you can
implement. It enables you to build server-side logic and functionality that scales to meet your demand, without
worrying about servers or infrastructure. Both total number of CloudScript executions and corresponding
execution time, are billed as part of this metered service.
Execution Time - CloudScript execution time is metered based on the per-second resource consumption
across all CloudScript executions, measured in GB-s (average memory size in GBs x total execution time in
milliseconds).
NOTE
The minimum billable memory size and execution time per execution is 128MB and 100ms, respectively.
Total Executions - Total number of ExecuteFunction API calls that are processed by PlayFab, including ones
triggered by actions, rules, and scheduled tasks. For more information on the ways executions can occur, see
Server-Side Cloud Script - Execution Function, Actions & Rules, and Scheduled Tasks.
Insights
Real-time analytics give you immediate insight into a game's performance and potential issues. Insights include
services such as the performance of the data warehouse, long-term storage of data, custom visualization
technology, managed external data sources or specialized data projects. The total combined usage of Insights
products, represented by an aggregate value ("Insights Credits"), is billed as part of this metered service. Insight
Credits are derived from conversion rates for usage of each Insight services.
Insights Credits - The total number of Insights Credits used across all Insights products. For a detailed
breakdown of how Insights Credits are calculated, see Insights Pricing.
Multiplayer Servers
PlayFab Multiplayer Servers deliver secure and reliable low-latency gameplay at global scale. Multiplayer
Servers facilitate interoperable multiplayer infrastructure and cross-network gameplay, and allow you to
operate a dynamically scaling pool of custom game servers in Azure.
Vir tual Machine Instance Hours - The hours of virtual machine time that your game servers use,
including overhead hours generated by standby servers and virtual machine fragmentation. Price varies by
datacenter, virtual machine and container selection. For more information, see Multiplayer Servers detailed
price sheet.
Network Egress - The volume of data transmitted by your game servers to the Internet (in
gigabytes). Network egress is billed depending on the originating datacenter. Price varies by zone.
Party
PlayFab Party is a low-latency chat and data communication solution for cross-platform and cross-device
multiplayer games. The voice and text features in Party can be used as a standalone chat solution or in
conjunction with other features in PlayFab's Multiplayer product. There are four key meters used to bill Party
utilization:
Connectivity : Metered by number of player minutes connected to a network. Metering starts when a player
creates a network or joins a network, and it stops when they have disconnected.
Voice : Metered by number of player minutes speaking. When a player is connected to a network and is
actively speaking, that player voice activity is measured and metered.
Cognitive Ser vices : Metered by number of player minutes using Speech to Text, Text to Speech, or
Translation features.
Network Egress This is data sent from PlayFab's relay and voice servers. This is congruent to the aggregate
amount of data that players receive from the network.
NOTE
Party Network Egress is metered and priced separately from Multiplayer Servers Network Egress.
Additional resources
For the most up-to-date view of prices per meter, see PlayFab.com/Pricing
See Consumption Best Practices to learn how to maintain the lowest rate of meter usage and cost for your
game
Profile Reads
5/24/2022 • 14 minutes to read • Edit Online
Profile includes any data stored related to the player profile, entity profile, character profile, groups, and
inventory. Profile data is information that applies to an individual player, group of players, or items, and is stored
as Key/Value Pairs (KVPs) by PlayFab.
The following APIs cause the Profile read meter to increment.
Admin APIs
CheckLimitedEditionItemAvailability Checks the global count for the limited edition item.
GetAllSegments Retrieves an array of player segment definitions. Results from this can be used in
subsequent API calls such as GetPlayersInSegment which requires a Segment ID. While segment names
can change the ID for that segment will not change.
ExportMasterPlayerData Exports all associated data of a master player account.
GetCatalogItems Retrieves the specified version of the title's catalog of virtual goods, including all defined
properties.
GetContentList List all contents of the title and get statistics such as size.
GetDataReport Retrieves a download URL for the requested report.
GetPlayerSegments List all segments that a player currently belongs to at this moment in time.
GetPlayerTags Get all tags with a given Namespace (optional) from a player profile.
GetPolicy Gets the requested policy.
GetPublisherData Retrieves the key-value store of custom publisher settings.
GetRandomResultTables Retrieves the random drop table configuration for the title.
GetStoreItems Retrieves the set of items defined for the specified store, including all prices defined.
GetTitleData Retrieves the key-value store of custom title settings which can be read by the client.
[GetUserAccountInfo](Retrieves the relevant details for a specified user, based upon a match against a
supplied unique identifier) Retrieves the relevant details for a specified user, based upon a match against
a supplied unique identifier.
GetUserBans Gets all bans for a user.
GetUserData Retrieves the title-specific custom data for the user which is readable and writable by the
client.
GetUserInternalData Retrieves the title-specific custom data for the user which cannot be accessed by the
client.
GetUserInventory Retrieves the specified user's current inventory of virtual goods
GetUserPublisherData Retrieves the publisher-specific custom data for the user which is readable and
writable by the client.
GetUserPublisherInternalData Retrieves the publisher-specific custom data for the user which cannot be
accessed by the client.
GetUserPublisherReadOnlyData Retrieves the publisher-specific custom data for the user which can only
be read by the client.
GetUserReadOnlyData Retrieves the title-specific custom data for the user which can only be read by the
client.
ListVirtualCurrencyTypes Retuns the list of all defined virtual currencies for the title
GetMatchmakerGameInfo Retrieves the details for a specific completed session, including links to
standard out and standard error logs.
GetMatchmakerGameModes Retrieves the details of defined game modes for the specified game server
executable.
GetPlayerIdFromAuthToken Gets a player's ID from an auth token.
GetPlayersInSegment Allows for paging through all players in a given segment. This API creates a
snapshot of all player profiles that match the segment definition at the time of its creation and lives
through the Total Seconds to Live, refreshing its life span on each subsequent use of the Continuation
Token. Profiles that change during the course of paging will not be reflected in the results. AB Test
segments are currently not supported by this operation.
GetExperiments Gets the details of all experiments for a title.
GetLatestScorecard Gets the latest scorecard of the experiment for the title.
GetTreatmentAssignment Gets the treatment assignments for a player for every running experiment in
the title
Client APIs
GetAllUsersCharacters Lists all of the characters that belong to a specific user. CharacterIds are not
globally unique; characterId must be evaluated with the parent PlayFabId to guarantee uniqueness.
GetCatalogItems Retrieves the specified version of the title's catalog of virtual goods, including all defined
properties.
GetCharacterData Retrieves the title-specific custom data for the character which is readable and writable
by the client.
GetCharacterInventory Retrieves the specified character's current inventory of virtual goods.
GetCharacterLeaderboard Retrieves a list of ranked characters for the given statistic, starting from the
indicated point in the leaderboard.
GetCharacterReadOnlyData Retrieves the title-specific custom data for the character which can only be
read by the client.
GetCharacterStatistics Retrieves the details of all title-specific statistics for the user.
GetFriendLeaderboard Retrieves a list of ranked friends of the current player for the given statistic,
starting from the indicated point in the leaderboard.
GetFriendLeaderboardAroundPlayer Retrieves a list of ranked friends of the current player for the given
statistic, centered on the requested PlayFab user. If PlayFabId is empty or null will return currently logged
in user.
GetFriendsList Retrieves the current friend list for the local user, constrained to users who have PlayFab
accounts. Friends from linked accounts (Facebook, Steam) are also included. You may optionally exclude
some linked services' friends.
GetGameServerRegions Get details about the regions hosting game servers matching the given
parameters.
GetLeaderboard Retrieves a list of ranked users for the given statistic, starting from the indicated point in
the leaderboard.
GetLeaderboardAroundCharacter Retrieves a list of ranked characters for the given statistic, centered on
the requested Character ID.
GetLeaderboardAroundPlayer Retrieves a list of ranked users for the given statistic, centered on the
requested player. If PlayFabId is empty or null will return currently logged in user.
GetLeaderboardForUserCharacters Retrieves a list of all of the user's characters for the given statistic.
GetPaymentToken For payments flows where the provider requires playfab (the fulfiller) to initiate the
transaction, but the client completes the rest of the flow. In the Xsolla case, the token returned here will be
passed to Xsolla by the client to create a cart. Poll GetPurchase using the returned OrderId once you've
completed the payment.
GetPlayerProfile Retrieves the player's profile.
GetPlayerSegments List all segments that a player currently belongs to at this moment in time.
GetPlayerStatistics Retrieves the indicated statistics (current version and values for all statistics, if none
are specified), for the local player.
GetPlayerStatisticVersions Retrieves the information on the available versions of the specified statistic.
GetPlayerTags Get all tags with a given Namespace (optional) from a player profile.
GetPlayerTrades Gets all trades the player has either opened or accepted, optionally filtered by trade
status.
GetPlayFabIDsFromFacebookIDs Retrieves the unique PlayFab identifiers for the given set of Facebook
identifiers.
GetPlayFabIDsFromFacebookInstantGamesIds Retrieves the unique PlayFab identifiers for the given set of
Facebook Instant Game identifiers.
GetPlayFabIDsFromGameCenterIDs Retrieves the unique PlayFab identifiers for the given set of Game
Center identifiers (referenced in the Game Center Programming Guide as the Player Identifier).
GetPlayFabIDsFromGenericIDs Retrieves the unique PlayFab identifiers for the given set of generic service
identifiers. A generic identifier is the service name plus the service-specific ID for the player, as specified
by the title when the generic identifier was added to the player account.
GetPlayFabIDsFromGoogleIDs Retrieves the unique PlayFab identifiers for the given set of Google
identifiers. The Google identifiers are the IDs for the user accounts, available as "id" in the Google+
People API calls.
GetPlayFabIDsFromKongregateIDs Retrieves the unique PlayFab identifiers for the given set of
Kongregate identifiers. The Kongregate identifiers are the IDs for the user accounts, available as "user_id"
from the Kongregate API methods(ex: http://developers.kongregate.com/docs/client/getUserId).
GetPlayFabIDsFromNintendoSwitchDeviceIds Retrieves the unique PlayFab identifiers for the given set of
Nintendo Switch identifiers.
GetPlayFabIDsFromPSNAccountIDs Retrieves the unique PlayFab identifiers for the given set of
PlayStation Network identifiers.
GetPlayFabIDsFromSteamIDs Retrieves the unique PlayFab identifiers for the given set of Steam
identifiers. The Steam identifiers are the profile IDs for the user accounts, available as SteamId in the
Steamworks Community API calls.
GetPlayFabIDsFromTwitchIDs Retrieves the unique PlayFab identifiers for the given set of Twitch
identifiers. The Twitch identifiers are the IDs for the user accounts, available as "_id" from the Twitch API
methods (ex: https://github.com/justintv/Twitch-API/blob/master/v3_resources/users.md#get-usersuser).
GetPlayFabIDsFromXboxLiveIDs Retrieves the unique PlayFab identifiers for the given set of XboxLive
identifiers.
GetPublisherData Retrieves the key-value store of custom publisher settings.
GetPurchase Retrieves a purchase along with its current PlayFab status. Returns inventory items from the
purchase that are still active.
GetSharedGroupData Retrieves data stored in a shared group object, as well as the list of members in the
group. Non-members of the group may use this to retrieve group data, including membership, but they
will not receive data for keys marked as private. Shared Groups are designed for sharing data between a
very small number of players, see Using Shared Group Data.
GetStoreItems Retrieves the set of items defined for the specified store, including all prices defined.
GetTitleData Retrieves the key-value store of custom title settings
GetAccountInfo Retrieves the user's PlayFab account details.
LoginWithAndroidDeviceID Signs the user in using the Android device identifier, returning a session
identifier that can subsequently be used for API calls which require an authenticated user.
LoginWithCustomID Signs the user in using a custom unique identifier generated by the title, returning a
session identifier that can subsequently be used for API calls which require an authenticated user
LoginWithEmailAddress Signs the user into the PlayFab account, returning a session identifier that can
subsequently be used for API calls which require an authenticated user. Unlike most other login API calls,
LoginWithEmailAddress does not permit the creation of new accounts via the CreateAccountFlag. Email
addresses may be used to create accounts via RegisterPlayFabUser.
LoginWithFacebook Signs the user in using a Facebook access token, returning a session identifier that
can subsequently be used for API calls which require an authenticated user.
LoginWithFacebookInstantGamesId Signs the user in using a Facebook Instant Games ID, returning a
session identifier that can subsequently be used for API calls which require an authenticated user.
Requires Facebook Instant Games to be configured.
LoginWithGameCenter Signs the user in using an iOS Game Center player identifier, returning a session
identifier that can subsequently be used for API calls which require an authenticated user.
LoginWithGoogleAccount Signs the user in using an iOS Game Center player identifier, returning a
session identifier that can subsequently be used for API calls which require an authenticated user.
LoginWithIOSDeviceID Signs the user in using their Google account credentials.
LoginWithKongregate Signs the user in using a Kongregate player account.
LoginWithNintendoSwitchDeviceId Signs the user in using a Nintendo Switch Device ID, returning a
session identifier that can subsequently be used for API calls which require an authenticated user.
LoginWithOpenIdConnect Logs in a user with an Open ID Connect JWT created by an existing
relationship between a title and an Open ID Connect provider.
LoginWithPlayFab which require an authenticated user. Unlike most other login API calls,
LoginWithPlayFab does not permit the creation of new accounts via the CreateAccountFlag.
Username/Password credentials may be used to create accounts via RegisterPlayFabUser, or added to
existing accounts using AddUsernamePassword.
LoginWithPSN Signs the user into the PlayFab account, returning a session identifier that can
subsequently be used for API calls which require an authenticated user. Unlike most other login API calls,
LoginWithPlayFab does not permit the creation of new accounts via the CreateAccountFlag.
Username/Password credentials may be used to create accounts via RegisterPlayFabUser, or added to
existing accounts using AddUsernamePassword.
LoginWithSteam Signs the user in using a Steam authentication ticket, returning a session identifier that
can subsequently be used for API calls which require an authenticated user.
LoginWithTwitch Signs the user in using a Twitch access token.
LoginWithXbox Signs the user in using a Xbox Live Token, returning a session identifier that can
subsequently be used for API calls which require an authenticated user.
GetCurrentGames Get details about all current running game servers matching the given parameters.
GetPlayerCombinedInfo Retrieves all of the user's different kinds of info.
Data APIs
GetObjects Retrieves objects from an entity's profile.
Groups APIs
GetGroup Gets information about a group and its roles.
IsMember Checks to see if an entity is a member of a group or role within the group.
ListGroupApplications Lists all outstanding requests to join a group.
ListGroupBlocks Lists all entities blocked from joining a group.
ListGroupInvitations Lists all outstanding invitations for a group.
ListGroupMembers Lists all members for a group.
ListMembership Lists all groups and roles for an entity.
ListMembershipOpportunities Lists all outstanding invitations and group applications for an entity.
Profile APIs
GetGlobalPolicy Gets the global title access policy.
GetProfile Retrieves the entity's profile.
GetProfiles Retrieves the entity's profile.
GetTitlePlayersFromMasterPlayerAccountIds Retrieves the title player accounts associated with the given
master player account.
Server APIs
EvaluateRandomResultTable Returns the result of an evaluation of a Random Result Table - the ItemId
from the game Catalog which would have been added to the player inventory, if the Random Result Table
were added via a Bundle or a call to UnlockContainer.
GetAllSegments Retrieves an array of player segment definitions. Results from this can be used in
subsequent API calls such as GetPlayersInSegment which requires a Segment ID. While segment names
can change the ID for that segment will not change.
GetAllUsersCharacters Lists all of the characters that belong to a specific user. CharacterIds are not
globally unique; characterId must be evaluated with the parent PlayFabId to guarantee uniqueness.
GetCatalogItems Retrieves the specified version of the title's catalog of virtual goods, including all defined
properties.
GetCharacterData Retrieves the title-specific custom data for the user which is readable and writable by
the client.
GetCharacterInternalData Retrieves the title-specific custom data for the user's character which cannot be
accessed by the client.
GetCharacterInventory Retrieves the specified character's current inventory of virtual goods.
GetCharacterReadOnlyData
GetCharacterStatistics Retrieves the details of all title-specific statistics for the specific character.
GetFriendLeaderboard Retrieves a list of ranked friends of the given player for the given statistic, starting
from the indicated point in the leaderboard.
GetFriendsList Retrieves the current friends for the user with PlayFabId, constrained to users who have
PlayFab accounts. Friends from linked accounts (Facebook, Steam) are also included. You may optionally
exclude some linked services' friends.
GetLeaderboard Retrieves a list of ranked users for the given statistic, starting from the indicated point in
the leaderboard.
GetLeaderboardAroundCharacter Retrieves a list of ranked characters for the given statistic, centered on
the requested user.
GetLeaderboardAroundUser Retrieves a list of ranked characters for the given statistic, centered on the
requested user.
GetLeaderboardForUserCharacters Retrieves a list of all of the user's characters for the given statistic.
GetPlayerCombinedInfo Returns whatever info is requested in the response for the user. Note that PII (like
email address, facebook id) may be returned. All parameters default to false.
GetPlayerProfile Retrieves the player's profile.
GetPlayerSegments List all segments that a player currently belongs to at this moment in time.
GetPlayersInSegment Allows for paging through all players in a given segment. This API creates a
snapshot of all player profiles that match the segment definition at the time of its creation and lives
through the Total Seconds to Live, refreshing its life span on each subsequent use of the Continuation
Token. Profiles that change during the course of paging will not be reflected in the results. AB Test
segments are currently not supported by this operation.
GetPlayerStatistics Retrieves the current version and values for the indicated statistics, for the local player.
GetPlayerStatisticVersions Retrieves the information on the available versions of the specified statistic.
GetPlayerTags Get all tags with a given Namespace (optional) from a player profile.
GetPlayFabIDsFromFacebookIDs Retrieves the unique PlayFab identifiers for the given set of Facebook
identifiers.
GetPlayFabIDsFromFacebookInstantGamesIds Retrieves the unique PlayFab identifiers for the given set of
Facebook identifiers.
GetPlayFabIDsFromGenericIDs Retrieves the unique PlayFab identifiers for the given set of generic service
identifiers. A generic identifier is the service name plus the service-specific ID for the player, as specified
by the title when the generic identifier was added to the player account.
GetPlayFabIDsFromNintendoSwitchDeviceIds Retrieves the unique PlayFab identifiers for the given set of
Nintendo Switch Device identifiers.
GetPlayFabIDsFromPSNAccountIDs Retrieves the unique PlayFab identifiers for the given set of
PlayStation Network identifiers.
GetPlayFabIDsFromSteamIDs Retrieves the unique PlayFab identifiers for the given set of Steam
identifiers. The Steam identifiers are the profile IDs for the user accounts, available as SteamId in the
Steamworks Community API calls.
GetPlayFabIDsFromXboxLiveIDs Retrieves the unique PlayFab identifiers for the given set of XboxLive
identifiers.
GetPublisherData Retrieves the key-value store of custom publisher settings.
GetRandomResultTables Retrieves the configuration information for the specified random results tables
for the title, including all ItemId values and weights.
GetServerCustomIDsFromPlayFabIDs Retrieves the associated PlayFab account identifiers for the given
set of server custom identifiers.
GetSharedGroupData Retrieves data stored in a shared group object, as well as the list of members in the
group. The server can access all public and private group data. Shared Groups are designed for sharing
data between a very small number of players, see Using Shared Group Data.
GetStoreItems Retrieves the set of items defined for the specified store, including all prices defined, for
the specified player.
GetTitleData Retrieves the key-value store of custom title settings.
GetTitleInternalData Retrieves the key-value store of custom internal title settings.
GetUserAccountInfo Retrieves the relevant details for a specified user.
GetUserBans Gets all bans for a user.
GetUserData Retrieves the title-specific custom data for the user which is readable and writable by the
client.
GetUserInternalData Retrieves the title-specific custom data for the user which cannot be accessed by the
client.
GetUserInventory Retrieves the specified user's current inventory of virtual goods.
GetUserPublisherData Retrieves the publisher-specific custom data for the user which is readable and
writable by the client.
GetUserPublisherInternalData Retrieves the publisher-specific custom data for the user which cannot be
accessed by the client.
GetUserPublisherReadOnlyData
GetUserReadOnlyData Updates the title-specific custom data for the user which can only be read by the
client.
LoginWithServerCustomId Securely login a game client from an external server backend using a custom
identifier for that player. Server Custom ID and Client Custom ID are mutually exclusive and cannot be
used to retrieve the same player account.
LoginWithXbox Signs the user in using a Xbox Live Token from an external server backend, returning a
session identifier that can subsequently be used for API calls which require an authenticated user.
LoginWithXboxId Signs the user in using an Xbox ID and Sandbox ID, returning a session identifier that
can subsequently be used for API calls which require an authenticated user.
Profile Writes
5/24/2022 • 17 minutes to read • Edit Online
Profile includes any data stored related to the player profile, entity profile, character profile, groups, and
inventory. Profile data is information that applies to an individual player, group of players, or items, and is stored
as Key/Value Pairs (KVPs) by PlayFab.
The following APIs cause the Profile writes meter to increment.
Admin APIs
AddPlayerTag Adds a given tag to a player profile. The tag's namespace is automatically generated based
on the source of the tag.
AddUserVirtualCurrency Increments the specified virtual currency by the stated amount
AddVirtualCurrencyTypes Adds one or more virtual currencies to the set defined for the title. Virtual
Currencies have a maximum value of 2,147,483,647 when granted to a player. Any value over that will be
discarded.
BanUsers Bans users by PlayFab ID with optional IP address, or MAC address for the provided game.
CreateActionsOnPlayersInSegmentTask Create an ActionsOnPlayersInSegment task, which iterates
through all players in a segment to execute action.
CreatePlayerSharedSecret Creates a new Player Shared Secret Key. It may take up to 5 minutes for this
key to become generally available after this API returns.
CreatePlayerStatisticDefinition Adds a new player statistic configuration to the title, optionally allowing
the developer to specify a reset interval and an aggregation method.
DeleteMasterPlayerAccount Removes a master player account entirely from all titles and deletes all
associated data.
DeletePlayer Removes a user's player account from a title and deletes all associated data
DeletePlayerSharedSecret Deletes an existing Player Shared Secret Key. It may take up to 5 minutes for
this delete to be reflected after this API returns.
DeleteStore Deletes an existing virtual item store.
DeleteTitle Permanently deletes a title and all associated configuration.
GrantItemsToUsers Adds the specified items to the specified user inventories
IncrementLimitedEditionItemAvailability Increases the global count for the given scarce resource.
IncrementPlayerStatisticVersion Resets the indicated statistic, removing all player entries for it and
backing up the old values.
RefundPurchase Attempts to process an order refund through the origin'l real money payment provider.""
RemovePlayerTag Remove a given tag from a player profile. The tag's namespace is automatically
generated based on the source of the tag.
RemoveVirtualCurrencyTypes Removes one or more virtual currencies from the set defined for the title.
ResetCharacterStatistics Completely removes all statistics for the specified character, for the current game.
ResetUserStatistics Completely removes all statistics for the specified user, for the current game.
ResolvePurchaseDispute Attempts to resolve a dispute with the original order's payment provider.
RevokeAllBansForUser Revoke all active bans for a user.
RevokeBans Revoke all active bans specified with BanId.
RevokeInventoryItem Revokes access to an item in a user's inventory
RevokeInventoryItems Revokes access for up to 25 items across multiple users and characters.
SetCatalogItems Creates the catalog configuration of all virtual goods for the specified catalog version.
SetPlayerSecret Sets or resets the player's secret. Player secrets are used to sign API requests.
SetPublishedRevision Sets the currently published revision of a title Cloud Script.
SetPublisherData Updates the key-value store of custom publisher settings
SetStoreItems Sets all the items in one virtual store.
SetTitleData Creates and updates the key-value store of custom title settings which can be read by the
client.
SetTitleInternalData Updates the key-value store of custom title settings which cannot be read by the
client.
SubtractUserVirtualCurrency Decrements the specified virtual currency by the stated amount.
UpdateBans Updates information of a list of existing bans specified with Ban Ids.
UpdateCatalogItems Updates the catalog configuration for virtual goods in the specified catalog version.
UpdatePlayerSharedSecret Updates a existing Player Shared Secret Key. It may take up to 5 minutes for
this update to become generally available after this API returns.
UpdatePlayerStatisticDefinition Updates a player statistic configuration for the title, optionally allowing
the developer to specify a reset interval.
UpdateRandomResultTables Updates the random drop table configuration for the title
UpdateStoreItems Updates an existing virtual item store with new or modified items.
UpdateUserData Updates the title-specific custom data for the user which is readable and writable by the
client.
UpdateUserInternalData Updates the title-specific custom data for the user which cannot be accessed by
the client.
UpdateUserPublisherData Updates the publisher-specific custom data for the user which is readable and
writable by the client.
UpdateUserPublisherInternalData Updates the publisher-specific custom data for the user which cannot
be accessed by the client.
UpdateUserPublisherReadOnlyData Updates the publisher-specific custom data for the user which can
only be read by the client.
UpdateUserReadOnlyData Updates the title-specific custom data for the user which can only be read by
the client.
UpdateUserTitleDisplayName Updates the title specific display name for a user.
Client APIs
AcceptTrade Accepts an open trade (one that has not yet been accepted or cancelled), if the locally signed-
in player is in the allowed player list for the trade, or it is open to all players. If the call is successful, the
offered and accepted items will be swapped between the two players' inventories.
AddFriend Adds the PlayFab user, based upon a match against a supplied unique identifier, to the friend
list of the local user. At least one of FriendPlayFabId,FriendUsername,FriendEmail, or
FriendTitleDisplayName should be initialized.
AddGenericID Adds the specified generic service identifier to the player's PlayFab account. This is
designed to allow for a PlayFab ID lookup of any arbitrary service identifier a title wants to add. This
identifier should never be used as authentication credentials, as the intent is that it is easily accessible by
other players.
AddOrUpdateContactEmail Adds or updates a contact email to the player's profile.
AddSharedGroupMembers Adds users to the set of those able to update both the shared data, as well as
the set of users in the group. Only users in the group (and the server) can add new members. Shared
Groups are designed for sharing data between a very small number of players, see Using Shared Group
Data.
AddUsernamePassword Adds playfab username/password auth to an existing account created via an
anonymous auth method, e.g. automatic device ID login.
AndroidDevicePushNotificationRegistration Registers the Android device to receive push notifications
ConsumePSNEntitlements Checks for any new consumable entitlements. If any are found, they are
consumed and added as PlayFab items.
ConsumeXboxEntitlements Grants the player's current entitlements from Xbox Live, consuming all
availble items in Xbox and granting them to the player's PlayFab inventory. This call is idempotent and
will not grant previously granted items to the player.
CreateSharedGroup Requests the creation of a shared group object, containing key/value pairs which
may be updated by all members of the group. Upon creation, the current user will be the only member of
the group. Shared Groups are designed for sharing data between a very small number of players. For
more info, see Using Shared Group Data.
GrantCharacterToUser Grants the specified character type to the user. CharacterIds are not globally
unique; characterId must be evaluated with the parent PlayFabId to guarantee uniqueness.
LinkAndroidDeviceID Links the Android device identifier to the user's PlayFab account
LinkCustomID Links the custom identifier, generated by the title, to the user's PlayFab account.
LinkFacebookAccount Links the Facebook account associated with the provided Facebook access token to
the user's PlayFab account.
LinkFacebookInstantGamesId Links the Facebook Instant Games Id to the user's PlayFab account.
LinkGameCenterAccount Links the Game Center account associated with the provided Game Center ID to
the user's PlayFab account.
LinkGoogleAccount Links the currently signed-in user account to their Google account, using their
Google account credentials.
LinkIOSDeviceID Links the vendor-specific iOS device identifier to the user's PlayFab account.
LinkKongregate Links the Kongregate identifier to the user's PlayFab account.
LinkNintendoSwitchDeviceId Links the NintendoSwitchDeviceId to the user's PlayFab account.
LinkOpenIdConnect Links an OpenID Connect account to a user's PlayFab account, based on an existing
relationship between a title and an Open ID Connect provider and the OpenId Connect JWT from that
provider.
LinkPSNAccount Links the PlayStation Network account associated with the provided access code to the
user's PlayFab account.
LinkSteamAccount Links the Steam account associated with the provided Steam authentication ticket to
the user's PlayFab account.
LinkTwitch Links the Twitch account associated with the token to the user's PlayFab account.
LinkWindowsHello Link Windows Hello authentication to the current PlayFab Account.
LinkXboxAccount Links the Xbox Live account associated with the provided access code to the user's
PlayFab account.
OpenTrade Opens a new outstanding trade. Note that a given item instance may only be in one open
trade at a time.
PurchaseItem Buys a single item with virtual currency. You must specify both the virtual currency to use
to purchase, as well as what the client believes the price to be. This lets the server fail the purchase if the
price has changed.
PayForPurchase Selects a payment option for purchase order created via StartPurchase
RegisterForIOSPushNotification Registers the iOS device to receive push notifications
RegisterPlayFabUser Registers a new Playfab user account, returning a session identifier that can
subsequently be used for API calls which require an authenticated user. You must supply either a
username or an email address.
RegisterWithWindowsHello Registers a new PlayFab user account using Windows Hello authentication,
returning a session ticket that can subsequently be used for API calls which require an authenticated user
RemoveContactEmail Removes a contact email from the player's profile.
RemoveFriend Removes a specified user from the friend list of the local user.
RemoveGenericID Removes the specified generic service identifier from the player's PlayFab account.
RemoveSharedGroupMembers Removes users from the set of those able to update the shared data and
the set of users in the group. Only users in the group can remove members. If as a result of the call, zero
users remain with access, the group and its associated data will be deleted. Shared Groups are designed
for sharing data between a very small number of players, see Using Shared Group Data.
ReportAdActivity Report player's ad activity
ReportDeviceInfo Write a PlayStream event to describe the provided player device information. This API
method is not designed to be called directly by developers. Each PlayFab client SDK will eventually report
this information automatically.
ReportPlayer Submit a report for another player (due to bad bahavior, etc.), so that customer service
representatives for the title can take action concerning potentially toxic players.
RestoreIOSPurchases Restores all in-app purchases based on the given restore receipt
SetFriendTags Updates the tag list for a specified user in the friend list of the local user.
SubtractUserVirtualCurrency Decrements the user's balance of the specified virtual currency by the
stated amount. It is possible to make a VC balance negative with this API.
UnlinkAndroidDeviceID Unlinks the related Android device identifier from the user's PlayFab account.
UnlinkCustomID Unlinks the related custom identifier from the user's PlayFab account.
UnlinkFacebookAccount Unlinks the related Facebook account from the user's PlayFab account.
UnlinkFacebookInstantGamesId Unlinks the related Facebook Instant Game Ids from the user's PlayFab
account.
UnlinkGameCenterAccount Unlinks the related Game Center account from the user's PlayFab account.
UnlinkGoogleAccount Unlinks the related Google account from the user's PlayFab account
(https://developers.google.com/android/reference/com/google/android/gms/auth/GoogleAuthUtil#publi
c-methods).
UnlinkIOSDeviceID Unlinks the related iOS device identifier from the user's PlayFab account.
UnlinkKongregate Unlinks the related Kongregate identifier from the user's PlayFab account.
UnlinkNintendoSwitchDeviceId Unlinks the related NintendoSwitchDeviceId from the user's PlayFab
account.
UnlinkOpenIdConnect Unlinks an OpenID Connect account from a user's PlayFab account, based on the
connection ID of an existing relationship between a title and an Open ID Connect provider.
UnlinkPSNAccount Unlinks the related PSN account from the user's PlayFab account.
UnlinkSteamAccount Unlinks the related Steam account from the user's PlayFab account.
UnlinkTwitch Unlinks the related Twitch account from the user's PlayFab account.
UnlinkWindowsHello Unlink Windows Hello authentication from the current PlayFab Account.
UnlinkXboxAccount Unlinks the related Xbox Live account from the user's PlayFab account.
UnlockContainerInstance Opens the specified container, with the specified key (when required), and
returns the contents of the opened container. If the container (and key when relevant) are consumable
(RemainingUses > 0), their RemainingUses will be decremented, consistent with the operation of
ConsumeItem.
UnlockContainerItem Searches target inventory for an ItemInstance matching the given CatalogItemId, if
necessary unlocks it using an appropriate key, and returns the contents of the opened container. If the
container (and key when relevant) are consumable (RemainingUses > 0), their RemainingUses will be
decremented, consistent with the operation of ConsumeItem.
UpdateAvatarUrl Update the avatar URL of the player.
UpdateCharacterData Creates and updates the title-specific custom data for the user's character which is
readable and writable by the client
UpdateCharacterStatistics Updates the values of the specified title-specific statistics for the specific
character. By default, clients are not permitted to update statistics. Developers may override this setting in
the Game Manager > Settings > API Features.
UpdatePlayerStatistics Updates the values of the specified title-specific statistics for the user. By default,
clients are not permitted to update statistics. Developers may override this setting in the Game Manager
> Settings > API Features.
UpdateSharedGroupData Adds, updates, and removes data keys for a shared group object. If the
permission is set to Public, all fields updated or added in this call will be readable by users not in the
group. By default, data permissions are set to Private. Regardless of the permission setting, only members
of the group can update the data. Shared Groups are designed for sharing data between a very small
number of players, see Using Shared Group Data.
UpdateUserData Creates and updates the title-specific custom data for the user which is readable and
writable by the client.
UpdateUserPublisherData Creates and updates the publisher-specific custom data for the user which is
readable and writable by the client.
UpdateUserTitleDisplayName Updates the title specific display name for the user
Data APIs
SetObjects Sets objects on an entity's profile.
Groups APIs
AcceptGroupApplication Accepts an outstanding invitation to to join a group
AcceptGroupInvitation Accepts an invitation to join a group.
AddMembers Adds members to a group or role.
ApplyToGroup Applies to join a group.
BlockEntity Blocks a list of entities from joining a group.
ChangeMemberRole Changes the role membership of a list of entities from one role to another.
CreateGroup Creates a new group.
CreateRole Creates a new group role.
DeleteGroup Deletes a group and all roles, invitations, join requests, and blocks associated with it.
DeleteRole Deletes an existing role in a group.
InviteToGroup Invites a player to join a group,
RemoveGroupApplication Removes an application to join a group.
RemoveGroupInvitation Removes an invitation join a group.
RemoveMembers Removes members from a group.
UnblockEntity Unblocks a list of entities from joining a group.
UpdateGroup Updates non-membership data about a group.
UpdateRole Updates metadata about a role.
Profile APIs
SetGlobalPolicy Sets the global title access policy.
SetProfileLanguage Updates the entity's language. The precedence hierarchy for communication to the
player is Title Player Account language, Master Player Account language, and then title default language if
the first two aren't set or supported.
SetProfilePolicy Sets the profiles access policy.
Server APIs
AddCharacterVirtualCurrency Increments the character's balance of the specified virtual currency by the
stated amount.
AddFriend Adds the Friend user to the friendlist of the user with PlayFabId. At least one of
FriendPlayFabId,FriendUsername,FriendEmail, or FriendTitleDisplayName should be initialized.
AddGenericID Adds the specified generic service identifier to the player's PlayFab account. This is
designed to allow for a PlayFab ID lookup of any arbitrary service identifier a title wants to add. This
identifier should never be used as authentication credentials, as the intent is that it is easily accessible by
other players.
AddPlayerTag Adds a given tag to a player profile. The tag's namespace is automatically generated based
on the source of the tag.
AddSharedGroupMembers Adds users to the set of those able to update both the shared data, as well as
the set of users in the group. Only users in the group (and the server) can add new members. Shared
Groups are designed for sharing data between a very small number of players, see Using Shared Group
Data.
AddUserVirtualCurrency Increments the user's balance of the specified virtual currency by the stated
amount.
AwardSteamAchievement Awards the specified users the specified Steam achievements.
BanUsers Bans users by PlayFab ID with optional IP address, or MAC address for the provided game.
ConsumeItem Consume uses of a consumable item. When all uses are consumed, it will be removed
from the player's inventory.
CreateSharedGroup Requests the creation of a shared group object, containing key/value pairs which
may be updated by all members of the group. When created by a server, the group will initially have no
members. Shared Groups are designed for sharing data between a very small number of players, see
Using Shared Group Data.
DeleteCharacterFromUser Deletes the specific character ID from the specified user.
DeleteSharedGroup Deletes a shared group, freeing up the shared group ID to be reused for a new
group. Shared Groups are designed for sharing data between a very small number of players, see Using
Shared Group Data.
GrantCharacterToUser Grants the specified character type to the user. CharacterIds are not globally
unique; characterId must be evaluated with the parent PlayFabId to guarantee uniqueness.
GrantItemsToCharacter Adds the specified items to the specified character's inventory.
GrantItemsToUser Adds the specified items to the specified user's inventory.
GrantItemsToUsers Adds the specified items to the specified user inventories,
LinkServerCustomId Links the custom server identifier, generated by the title, to the user's PlayFab
account.
LinkXboxAccount Links the Xbox Live account associated with the provided access code to the user's
PlayFab account.
ModifyItemUses Modifies the number of remaining uses of a player's inventory item.
MoveItemToCharacterFromCharacter Moves an item from a character's inventory into another of the
users's character's inventory.
MoveItemToCharacterFromUser Moves an item from a user's inventory into their character's inventory.
MoveItemToUserFromCharacter Moves an item from a character's inventory into the owning user's
inventory.
NotifyMatchmakerPlayerLeft Informs the PlayFab match-making service that the user specified has left
the Game Server Instance.
RedeemCoupon Adds the virtual goods associated with the coupon to the user's inventory. Coupons can
be generated via the Economy->Catalogs tab in the PlayFab Game Manager.
RedeemMatchmakerTicket Validates a Game Server session ticket and returns details about the user.
RemoveFriend Removes the specified friend from the user's friend list.
RemoveGenericID Removes the specified generic service identifier from the player's PlayFab account.
RemovePlayerTag Remove a given tag from a player profile. The tag's namespace is automatically
generated based on the source of the tag.
RemoveSharedGroupMembers Removes users from the set of those able to update the shared data and
the set of users in the group. Only users in the group can remove members. If as a result of the call, zero
users remain with access, the group and its associated data will be deleted. Shared Groups are designed
for sharing data between a very small number of players, see Using Shared Group Data.
RevokeAllBansForUser Revoke all active bans for a user.
RevokeBans Revoke all active bans specified with BanId.
RevokeInventoryItem Revokes access to an item in a user's inventory.
RevokeInventoryItems Revokes access for up to 25 items across multiple users and characters.
SetFriendTags Updates the tag list for a specified user in the friend list of another user.
SetPlayerSecret Sets the player's secret if it is not already set. Player secrets are used to sign API requests.
To reset a player's secret use the Admin or Server API method SetPlayerSecret.
SetPublisherData Updates the key-value store of custom publisher settings.
SetTitleData /rest/api/playfab/server/title-wide-data-management/setpublisherdata?
SetTitleInternalData Updates the key-value store of custom title settings
SubtractCharacterVirtualCurrency Decrements the character's balance of the specified virtual currency by
the stated amount. It is possible to make a VC balance negative with this API.
SubtractUserVirtualCurrency Decrements the user's balance of the specified virtual currency by the
stated amount. It is possible to make a VC balance negative with this API.
UnlinkServerCustomId Unlinks the custom server identifier from the user's PlayFab account.
UnlinkXboxAccount Unlinks the related Xbox Live account from the user's PlayFab account.
UnlockContainerInstance Opens a specific container (ContainerItemInstanceId), with a specific key
(KeyItemInstanceId, when required), and returns the contents of the opened container. If the container
(and key when relevant) are consumable (RemainingUses > 0), their RemainingUses will be decremented,
consistent with the operation of ConsumeItem.
UnlockContainerItem Searches Player or Character inventory for any ItemInstance matching the given
CatalogItemId, if necessary unlocks it using any appropriate key, and returns the contents of the opened
container. If the container (and key when relevant) are consumable (RemainingUses > 0), their
RemainingUses will be decremented, consistent with the operation of ConsumeItem.
UpdateAvatarUrl Update the avatar URL of the specified player.
UpdateBans Updates information of a list of existing bans specified with Ban Ids.
UpdateCharacterData Updates the title-specific custom data for the user's character which is readable and
writable by the client.
UpdateCharacterInternalData Updates the title-specific custom data for the user's character which cannot
be accessed by the client.
UpdateCharacterReadOnlyData Updates the title-specific custom data for the user's character which can
only be read by the client.
UpdateCharacterStatistics Updates the values of the specified title-specific statistics for the specific
character.
UpdatePlayerStatistics Updates the values of the specified title-specific statistics for the user.
UpdateUserData Updates the title-specific custom data for the user which is readable and writable by the
client.
UpdateUserInternalData Updates the title-specific custom data for the user which cannot be accessed by
the client.
UpdateUserInventoryItemCustomData Updates the key-value pair data tagged to the specified item,
which is read-only from the client.
UpdateUserPublisherData Updates the publisher-specific custom data for the user which is readable and
writable by the client.
UpdateUserPublisherInternalData Updates the publisher-specific custom data for the user which cannot
be accessed by the client.
UpdateUserPublisherReadOnlyData Updates the publisher-specific custom data for the user which can
only be read by the client.
UpdateUserReadOnlyData Updates the title-specific custom data for the user which can only be read by
the client.
Content & Configuration Reads
5/24/2022 • 2 minutes to read • Edit Online
Content & Configuration files include the following items: entity files, actions, rules, scheduled tasks,
matchmaking, push notifications, emails, and title news. Content & Configuration files are a set of key/value
pairs that are primarily used to manage configuration for your game remotely.
The following APIs cause the Content & Configuration reads meter to increment.
Admin APIs
GetContentUploadUrl Retrieves the pre-signed URL for uploading a content file. A subsequent HTTP PUT
to the returned URL uploads the content. Also, please be aware that the Content service is specifically
PlayFab's CDN offering, for which standard CDN rates apply
GetActionsOnPlayersInSegmentTaskInstance Get information about a ActionsOnPlayersInSegment task
instance.
Client APIs
GetTitleNews Retrieves the title news feed, as configured in the developer portal.
GetContentDownloadUrl This API retrieves a pre-signed URL for accessing a content file for the title. A
subsequent HTTP GET to the returned URL will attempt to download the content. A HEAD query to the
returned URL will attempt to retrieve the metadata of the content. Note that a successful result does not
guarantee the existence of this content - if it has not been uploaded, the query to retrieve the data will
fail. See this post for more information:
https://community.playfab.com/hc/community/posts/205469488-How-to-upload-files-to-PlayFab-s-
Content-Service. Also, please be aware that the Content service is specifically PlayFab's CDN offering, for
which standard CDN rates apply.
GetPhotonAuthenticationToken Gets a Photon custom authentication token that can be used to securely
join the player into a Photon room. See
https://docs.microsoft.com/gaming/playfab/features/multiplayer/photon/quickstart for more details.
GetTitlePublicKey Returns the title's base 64 encoded RSA CSP blob.
GetTradeStatus Gets the current status of an existing trade.
GetWindowsHelloChallenge Requests a challenge from the server to be signed by Windows Hello
Passport service to authenticate.
Data APIs
GetFiles Retrieves file metadata from an entity's profile.
Server APIs
GetContentDownloadUrl This API retrieves a pre-signed URL for accessing a content file for the title. A
subsequent HTTP GET to the returned URL will attempt to download the content. A HEAD query to the
returned URL will attempt to retrieve the metadata of the content. Note that a successful result does not
guarantee the existence of this content - if it has not been uploaded, the query to retrieve the data will
fail. See this post for more information:
https://community.playfab.com/hc/community/posts/205469488-How-to-upload-files-to-PlayFab-s-
Content-Service. Also, please be aware that the Content service is specifically PlayFab's CDN offering, for
which standard CDN rates apply.
GetTitleNews Retrieves the title news feed, as configured in the developer portal.
SendCustomAccountRecoveryEmail Forces an email to be sent to the registered contact email address for
the user's account based on an account recovery email template.
SendEmailFromTemplate Sends an email based on an email template to a player's contact email.
SendPushNotification Sends an iOS/Android Push Notification to a specific user, if that user's device has
been configured for Push Notifications in PlayFab. If a user has linked both Android and iOS devices, both
will be notified.
SendPushNotificationFromTemplate Sends an iOS/Android Push Notification template to a specific user, if
that user's device has been configured for Push Notifications in PlayFab. If a user has linked both Android
and iOS devices, both will be notified.
Content & Configuration Writes
5/24/2022 • 2 minutes to read • Edit Online
Content & Configuration files include the following items: entity files, actions, rules, scheduled tasks,
matchmaking, push notifications, emails, and title news. Content & Configuration files are a set of key/value
pairs that are primarily used to manage configuration for your game remotely.
The following APIs cause the Content & Configuration writes meter to increment.
Admin APIs
AddLocalizedNews Update news item to include localized version
AddNews Adds a new news item to the title's news feed
DeleteContent Delete a content file from the title. When deleting a file that does not exist, it returns
success.
-ModifyMatchmakerGameModes Updates the game server mode details for the specified game server
executable
-ResetPassword Reset a player's password for a given title.
SetupPushNotification Sets the Amazon Resource Name (ARN) for iOS and Android push notifications.
Documentation on the exact restrictions can be found at:
http://docs.aws.amazon.com/sns/latest/api/API_CreatePlatformApplication.html. Currently, Amazon
device Messaging is not supported.
UpdatePolicy Changes a policy for a title
Data APIs
FinalizeFileUploads Finalize file uploads to an entity's profile.
DeleteFiles Delete files on an entity's profile.
InitiateFileUploads Initiates file uploads to an entity's profile.
Server APIs
DeletePushNotificationTemplate Deletes push notification template for title
SavePushNotificationTemplate Saves push notification template for title
Accessing PlayFab Technical Support
5/24/2022 • 2 minutes to read • Edit Online
To make integration with PlayFab as seamless and efficient as possible, PlayFab offers a variety of support
options ranging from online documentation to live conversations with PlayFab engineers. Different support
options are included in each account plan as determined by the tier of the account. Customers can upgrade their
accounts to access higher levels of support.
Support Offerings
PUBLIC DOCUMENTATION
Purpose: Use the PlayFab documentation to view service offerings, API functionality, and how-to guides.
Minimum Required Account Plan: No account needed, open to the public.
How to access: To view PlayFab documentation, see PlayFab Documentation.
PLAYFAB FORUMS
Purpose: The PlayFab Forums provide community based product support. Use the forums to post questions,
share answers, and discuss the PlayFab product experience..
Minimum Required Account Plan: No account needed to view, free PlayFab user account needed to post.
How to access: Anyone can read the forums. To contribute, you must sign in with your PlayFab account. To
access the forums, visit PlayFab Forums.
SUPPORT TICKET SUBMISSION
Purpose: Use support tickets to report a bug, to understand how to use a particular PlayFab feature, or to
request help with a technical problem. Customers with paid accounts may submit support tickets directly to the
PlayFab team through the "Contact Us" Page in Game Manager. Customers will receive a response within 1
business day.
Minimum Required Account Plan: Standard Account Plan
How to access: Qualified accounts can access the Contact Us page in Game Manager:
1. Log in to PlayFab.com.
2. Navigate to the Title Over view page of the title needing support.
3. To access the help menu, select the ? in the top right navigation bar.
4. Select Contact Us .
EMERGENCY ESCALATIONS
Purpose: To provide PlayFab's fastest incident response time to customers during emergencies by notifying on-
call PlayFab engineers.
NOTE
Emergency escalations should be used sparingly and only in the case of high-impact service errors or outtages.
PlayFab customers on the legacy pricing model (MAU-based pricing) must update their account plans to the
modern pricing model (Usage-based pricing) prior to 11/01/2020 at which time MAU-based pricing will no
longer be supported.
Customers can understand changes to monthly costs and initiate their account's pricing update through the self-
serve experience in Game Manager (detailed below) or through contacting the PlayFab team.
FAQ
Q. What will happen to my account on November 1st, 2020?
Customers already on usage-based pricing plans (Standard Plan, Premium Plan)
Nothing! You have already transitioned to our new pricing and you should experience business-as-usual.
Essentials customers
Essentials customers will be transitioned to the Free to Start Plan with their titles in Development Mode. As long
as your titles are in Development Mode, you can continue using PlayFab for free. You can have up to 10 titles in
Development Mode at a time, and Development Mode allows up to 100,000 users per title.
Once your first title reaches 100,000 users, you will need to upgrade your plan to add more users to your title.
Once you have upgraded, you will need to launch your title in order to have unlimited users.
If your account has a title with over 100k users, you will not be able to add any more users until you add a
payment plan or delete users to 100k or fewer. For some titles, this may disrupt the availability of your game for
new players, so you should understand which of your current titles are approaching or are above 100k users to
understand which are at risk.
If your account has more than 10 titles, you will not be able to add any new titles until you have either deleted
titles to total under 10, or you have upgraded your plan and launched titles so that you have no more than 10 in
Dev Mode.
We recommend selecting a plan prior to the transition date of November 1st, 2020 so that your game
availability is not disrupted.
Indie & Pro Tier customers
Indie and Pro customers will be automatically transitioned to the Standard plan, which has a monthly minimum
of $99, and includes monthly meters valued at $400 USD along with Gold Level Support, which is the same
support level as you received in the Indie and Pro Tiers. Therefore, you will continue to have Public Forum
access as well as, be able to submit support tickets as needed.
Those customers who need Platinum Support with emergency escalations or estimate heavier usage will be able
to self-upgrade (available in October) to the Premium Plan which includes monthly meters valued at $8,000
USD for only $1,999 USD per month.
Customers that estimate low title usage or who do not need ticketed support, can select the Pay-as-you-Go plan
with no monthly minimum (available in October). You will still have access to the Public Forums and can
upgrade your plan as you grow.
For more information, go to Accessing PlayFab technical support.
Q. I have not selected a plan, will my account be shut off?
No. Based on your current tier, your titles will either be transitioned to Dev Mode or the Standard Plan. However,
If you are an Essentials customers with titles with over 100k users, you will need to select a plan in order for new
users to play your game. We recommend understanding which of your titles are currently exceeding 100k users
so that you can select that plan that works best for you prior to the transition date of November 1, 2020.
Q. I am an Enterprise customer. What will happen to my account?
Enterprise accounts will be migrated to the new pricing plans according to their contract renewal date and will
not automatically transition on November 1. If you have questions about your Enterprise contract, email us at:
sales@playfab.com
Q. How can I understand the costs for my studio prior to the transition?
To preview the impact of moving your titles to consumption-based pricing, go to the Billing Summar y page by
selecting Studio settings from the My Studios and Titles homepage.
Q. It looks like I might save money with the new pricing. Do I have to wait until Nov. 1 before I make the transition?
No, you can upgrade your account to a new pricing plan at any time. To do so, select Update Pricing from your
My Studios and Titles homepage or Title's Dashboard.
Q: I can see my total meter usage in the billing summary, and I’ve read the best practices doc, but I’m still not sure how to figure
out where the costs are coming from in my title. What tools are available to figure out which specific API calls are the ones costing
me the most?
In addition to the API graph on the main dashboard of your game, which shows the overall traffic and can be
filtered to show each individual call and response, there’s also the Daily API Usage Details Report in the
Dashboards > Repor ts section of the Game Manager for your title. That report breaks down, on a per-hour
basis, the API calls made in the title, as well as the average and total bytes sent/returned hourly. So, for example,
the total calls to UpdateUserData will be shown for each hour, along with the total bytes sent, which allows
you to quickly calculate the expected meter usage (given that a Profile Write ticks the meter at a per KB rate for
data written).
Account Upgrades
5/24/2022 • 5 minutes to read • Edit Online
Customers can upgrade their account plan using the self-serve plans experience found in Game Manager.
Account Plans
A PlayFab account has five plan options:
1. FREE TO START : This plan has no cost to the customer. Studios that belong to free accounts may only
contain titles that are in development mode. Once a title reaches its development mode limits, it must be
launched by upgrading to a paid plan. To learn how to launch a title, see Title Launches.Once a title reaches its
development mode limits, it must be launched by upgrading to a paid plan. To learn how to launch a title, see
Title Launches.
2. PAY-AS-YOU-GO : This paid plan has no monthly base rate. Accounts are only charged for their monthly
consumption for live titles.
3. STANDARD : This paid plan has a monthly base rate and private support options (Paid Technical Support).
This plan comes with included meter usage amounts that live titles associated with the account may access.
Once the included meter amounts have been used, the account will be charged for additional consumption.
4. PREMIUM : This paid plan has a monthly base rate and private support options (Paid Technical Support).
This plan comes with more included meter usage than the Standard plan. Once the included meter amounts
have been used, the account will be charged for additional consumption.
5. ENTERPRISE : An Enterprise account has a monthly base rate and private support channels that offer 24/7
assistance. This plan comes with more included meter usage than the Premium plan. Once the included
meter amounts have been used, the account will be charged for additional consumption. An account can
upgrade to an Enterprise plan through contacting the PlayFab Team .
The base rate's included consumption is cumulative across titles linked to an account.
[! NOTE] All PlayFab account plans adhere to the PlayFab Terms of Service.
FAQ
How do I know which subscription plan my account and its associated studios are currently on?
There are two ways to know which plan your account is currently on.
1. Presence of Upgrade Account Button: Navigate to the "My Studios" page. If a Studio displays the
Upgrade Account button, the Studio and its associated account are currently free and have no account plan
(1).
2. Base Rate Amount: While on the "My Studios" page, if no "Upgrade Account" button is present, navigate to
the Billing Summar y page (3). A lack of the Upgrade Account button means that the Studio and its
associated account are on a paid subscription plan.
The amount of the base rate will represent the paid subscription plan of an account. A Base Rate of $99
indicates that the Studio and its associated account are on the Standard plan . A base rate of $1999 indicates
that the Studio and its associated account are on the Premium plan . The Premium plan can only be acquired
through contacting PlayFab.
How do I know which subscription plan I am upgrading my account to? All accounts upgraded
through Game Manager are automatically upgraded to the Standard plan, as indicated by the agreed-to base
rate listed within the Upgrade Account (1) flow.
To upgrade to a Premium plan, please contact PlayFab.
Title Launches
5/24/2022 • 2 minutes to read • Edit Online
Customers can upgrade their account plan and launch titles using the self-service upgrade and launch
experiences found in Game Manager.
Title Modes
A PlayFab title has two possible modes:
1. DEVELOPMENT MODE : A Development Mode title has no cost to the customer for the core services
(multiplayer server hosting, Party, and Insights are not core services, though they do have limited free usage
available in Development Mode - please see the individual feature pages for more information). Use
Development mode to experiment with most PlayFab offerings. A title in development mode is subject to the
specific player count and meter usage limits determined by PlayFab. For more information about included
limits, see development mode.
2. LIVE MODE : A Live Mode title is charged to the customer based on its tier of service. Any meter usage over
what is included in the account plan's base rate results in charges per meter consumed. For more
information, see Meters. Note that Live Mode should not be confused with a title being "live". A title may
have players using it even in Development Mode, though the title will be limited to the player account
maximum for Development Mode. Moving to Live Mode removes that limit.
Launching a title
WARNING
Launching a title is a permanent action. The title cannot return to Development mode after the launch is completed.
To be able to move a title from Development Mode to Live Mode, a title must be in a Studio with a paid account
plan.
Launching a Title within a Free Account Plan
Titles may only be changed to Live Mode in Studios owned by paid accounts. Follow the steps listed under
Upgrading from Free to a paid account to launch a title in conjunction with upgrading an account.
Launching a Title within a Paid Account Plan
To launch a title within a paid account plan:
1. Log in to PlayFab.com
2. Navigate to the My Studios page and identify the Development Mode title to be launched (2).
3. Select the down arrow on the title to open the drop-down menu (2).
4. From the drop down, select Launch Title .
5. If the title is linked to a free account plan, Launch Title takes you to the account upgrade flow described
in the Upgrading from Free to Standard section. If the title is linked to a paid account, continue to the
next step.
6. A pop-up will prompt you to confirm the title launch. Once Launch Title is selected, the launch is
complete and the title is no longer bound by Development Mode limits.
PlayFab Consumption: Best Practices
5/24/2022 • 24 minutes to read • Edit Online
With PlayFab's consumption-based pricing model, you only pay for the actual service usage of your titles. But
this raises an obvious question: how do you best optimize those titles to save money, while still implementing all
the features you need? In this document, we'll dive into those details, and talk about best practices that will help
you to plan ahead.
Before you move your titles from Development Mode to Live you can review the meter information in the Billing
Summary tab of the Game Manager. A good starting practice is to periodically confirm the meters by using a
separate title to check meter usage for real-world-player activity. You can have multiple titles in Development
Mode, so that you can create titles on the fly as you reach development stages where you want to checkpoint
that usage, and then delete those titles after you're done.
There are six consumption meters: Events, Profile, Content and Configuration, CloudScript, Insights, and
Multiplayer Services. The best way to begin optimizing a title is to look at each of the meters that it uses and see
how it accumulates over time. This allows you to quickly derive some obvious improvements. For more
information about meters, see Pricing Meters.
Events
There are two types of events in PlayFab: PlayStream and Telemetry.
PlayFab processes PlayStream events to check if they trigger PlayStream Actions you have defined, and to
update User Segmentation. Some PlayStream events are automatically generated as a result of calls to service
features such as authentication and statistic updates. Titles can generate their own custom events to extend this
functionality.
Telemetry events are not processed by PlayStream. These events are used for analytics, and they go straight to
the data warehouse. Telemetry events are not generated automatically in PlayFab; they are custom events
generated by the title.
For both event types, larger payloads of data increase the total amount of meter usage. You can reduce that
overall usage by making sure you're only sending the data you need. A rough guide is that any given event
increments the meter in question by 1 for every 1 KB of data in the event body.
To choose which event path best suits your usage, you should have a clear plan for how you intend to use each
custom event that you generate. Events that are only needed for offline evaluation of the title should go the
Telemetry route. This can help to significantly reduce cost, as the overage charge on Telemetry events are less
than half that of PlayStream.
If you're using one of the pre-built SDKs, it's important to remember that some analytics data on user behavior
is generated automatically as described in the PlayStream Event Model reference. To turn off optional events,
change the analytics setting in the Settings/Data Collection tab of your game in the PlayFab Game Manager.
Similarly, while it's a good idea to have the "generate PlayStream event" option turned on for your CloudScript
executions during debugging, you should make sure to disable that before going live. In the case of PlayStream
Action triggered CloudScripts, you can always turn them on later if you need to debug some behavior in the
wild.
Profile
The profile is effectively "everything about the player", including common elements such as inventory, saved
data, and statistics. It also contains the meta-information that you use to drive unique experiences through the
LiveOps capabilities in PlayStream, such as the User Segmentation mentioned above. In addition, some title-
level legacy features, such as Title Data, Catalogs, and Stores, are included in this meter, as their data
implementation is effectively the same as User Data. Since this set of meters is driven by all player actions, as
well as actions taken on players, it is overwhelmingly the one that needs the most optimization planning.
The primary contributing factors to the usage captured by the pricing meters is the amount of data that is read,
stored, and written, and how frequently you call the APIs that generate data that is metered.
For more information about the specific API calls that result in "spin" on these meters, see Pricing Meters.
We'll start with User Data and Statistics, since their usage patterns are similar, and then we'll talk about player
inventory management.
Data and Statistics
When evaluating your usage of User Data, the same approximation logic as for events applies–each 1 KB
increases the meter count by 1–though keep in mind that each "element" of a call should be thought of as
distinct for purposes of this calculation. Each key value pair in a call to update User Data is counted separately.
For reads, this 1 KB calculation applies to the total data returned, regardless of the number of key value pairs.
This means that writing 10 keys of 100 bytes each is 10 "ticks" of the profile write meter, since each key value
pair write is a minimum of 1 KB, while a read of those 10 keys is 1 "tick", since it's a total of 1 KB. For more
specific details on the usages, see Pricing meters.
Statistics are slightly more complex, as they also have an impact on leaderboards. As a general rule, you can
think of each statistic updated as incrementing the meter by 1, while reads are based on the total size of the data
read in each call. And since storage is priced per gigabyte (GB) and statistics typically consume only a few bytes
each, we'll focus on reads and writes.
Since the total data size is important, optimizing it is the first step. Fortunately, there are a wide range of well-
known techniques for this–using enums or IDs in place of spelled-out text for items, packing large data as
binary, or even using bitfields to pack data into smaller spaces. After that's done, the next step is to carefully
evaluate when you need to make those read and write calls.
If you're coming from PC or console development–especially single player games–this might be a new pattern.
But in those environments, you must be careful about resource hits and garbage collection on the client device
since those can cause degradation in performance at critical times. When your title uses resources that are in the
cloud, it's necessary to extend that logic to consider each resource hit as having a real cost, in addition to a
performance cost.
How do you determine the optimal frequency of reads and writes? Two of the most common concerns of
developers who want to update data and statistics more frequently are protecting against cheating, and having
timely information stored server-side either for player-to-player interactions or to prevent data loss if the game
exits unexpectedly.
Cheat Protection
While it might seem like you need to constantly update your backend data to ensure essential security, frequent
updates are rarely necessary if your game doesn't require fully server-authoritative control of the session. To
start, the fundamental question is how much security that you actually need.
For some games, particularly those that monetize primarily through in-game advertisements and don't have
leaderboards, cheating isn't much of a concern. In this case, trusting the data the client sends up is often a viable
approach, since the security of that data isn't really a concern. To identify cheating behaviors and decide how you
want to handle them, we recommend that you implement processes to review the events, data, and statistics of
your players.
For other games in which you need to support the integrity of competition or protect the overall player
experience, stronger security is more important. Depending on your specific requirements, certain approaches
can reduce the frequency of data reads and writes in those situations.
If your game is not real-time, one approach that we recommend is to aggregate information about the player's
game over some period of time–often a "round" of the game, taking several minutes–and then send that data to
a script that determines whether it is valid. The key elements to evaluate can be game-dependent, but some
examples of common concepts to consider are:
How long has it been since the last session report, and how long does the client say that it played in the
latest one?
What scores did the player register, and are they reasonable for that player given their level, equipment,
etc.?
For games with more real-time requirements, such as needing to update the server-authoritative player state
frequently, a better solution than frequent updates to the PlayFab-stored data is to use hosted game servers. In
that model, you connect the player to a server on session start. The server reads all the needed data from the
service for the player, and then host the simulation state for that player over time, with the client exchanging
data with the server at whatever rate you need. The server then updates the "long term storage" in PlayFab with
the latest data for the player, either at the end of a session, or every few minutes if your sessions are particularly
long.
This is the model used by real-time multiplayer games. It's also a valid technique for single-player titles that
require server-authoritative checks, though if that frequency is only a few times a minute per player, Azure
Functions CloudScript could be the better option. The total CloudScript cost is easy to compute. It's the total
gigabyte-seconds that you consume, with a minimum of 128 MB and 100 ms per execution, plus the normal
calculations for any other service API calls the script uses. For example, if you have a total memory footprint,
between your script code and variable usage in the script, of 250 MB, you would need to run that script for 4
seconds (across multiple users, most likely) to get to 1 GB/s. And within that script code, if you read or write
Entity Objects, Title Data, User Data, etc, you'll need to calculate the spin that each of those calls has on the
profile meters. Since hosted game server costs are dependent on how many servers you're running, and that in
turns depends upon how many players can be hosted on a server at a time, it's not necessarily trivial to
determine where the break-even point is between the two. But if you find that you need to call your scripts at a
high frequency, and need to read and write data from the service each time, it's very likely that a game server
solution is the better way to go.
Data Timeliness
One common theme we've heard among developers with high profile write rates is that they're concerned about
the player losing progress. If the player exits the game before it can save and the local state cannot be used the
next time the game is played, or that state needs to travel between devices, you want to have the PlayFab-stored
state information for the player be as up-to-date as possible.
For many games, you can address this issue by having a regular, infrequent heartbeat of updates to the service
(every fifteen minutes, for example). But including additional logic to lengthen or shorten that frequency can
also help. For example:
Include an "important update" override that causes an immediate write, and resets the timer, if the player
actively does something significant, so that it can't be lost.
If your game continues to progress with no player input, consider lengthening the heartbeat period if
there has been no input for a long time. This is especially important for idle games, where players
frequently leave them running overnight.
Give players a way to force an update directly, such as a button in a user menu. In this case though, be
sure to throttle the rate at which calls are actually made from the client device to PlayFab, so that a player
hitting that button over and over isn't generating a call each time.
If the client does have the state information the next time the game is played, you can compare the timestamp
locally to that of the data from the service and decide which to use, or even provide the player with the option to
choose.
A player's profile information may be relevant to more than just themselves. In some games, you might need it
to query cross-player, whether to spur competition or to directly influence the player experience through
asynchronous friend interactions, challenges, and so on.
For competition, Leaderboards are an ideal way to generate that tension by sharing a subset of information
about other players (often those close to the current player's score) via a single call to the service. Since it's
possible to return other profile elements, such as statistics and tags, using the Profile View Constraints, you can
present a rich set of information about these other players. But it's important to not iterate over the list of all
players in the leaderboard, trying to read additional information from each, as this would rapidly multiply the
total number of profile reads, driving up your costs.
For games that use cross-player data directly in the session, the most common optimization is to read only the
information about the few specific players with whom the local player is interacting. For real-time action games,
this is usually done on the server hosting the session. For others–such as games where players can attack each
others' bases–the most common approaches are to either read all that data onto the local device or to send the
local player only the subset of the other player's data that the local player should know. Games that do the
former use server-side logic to evaluate the final results the client sends. Games that do the latter update the
data iteratively over the course of the session with more data, when the local player should have access to it. But
even then, they also use server-side logic to evaluate the final results. Again, the tipping point in deciding
whether this should be done through script or on a hosted server is down to frequency. If it's more than a few
times a minute, you're better off using a hosted server for the portion of the session that requires that data.
Inventory
Inventory, and economy in general, requires a different approach. There's no avoiding the fact that if a player is
giving up something of real (money) or perceived (virtual currency or consumable containers) value, they have
an implicit expectation that the transaction will be honored. For any game with in-app purchases, an increment
to the profile meter for a purchase made by the player with real-world currency is a trivial cost. In many types of
games, inventory updates are infrequent enough to pose little concern for greatly increasing your overall usage.
But for those with more frequent inventory updates–even if you don't have in-game monetization–there are
optimization tricks to help reduce your costs.
A best practice is to only think of inventory in the literal sense, as reasonably finite inventory. For example, in an
incremental (or "idle") game, it can be tempting to think of each resource that the player acquires as an item,
incrementing the total number each time the player purchases another of it. But that model breaks down rapidly,
as you calculate the frequency with which players take those actions. Right away, you would have to deal with
each player hitting the meter hundreds or even thousands of times in a session. For situations like this, it's better
to think of those elements as User Data, and to update it to the service using the recommendations in the Profile
section above.
When it comes to games that have higher rates of update to inventory, we're back to the question of data
timeliness. For example, an action game might track on the number of bullets a player has, but the backend data
for that "stack" of bullets does not need to be updated with every pull of the trigger, especially if the game state
is managed in a hosted server. Stackables give you a performance and cost advantage, since you can represent
many virtual instances of an item as a single actual instance with a count. You can often aggregate changes to
stacks of items over time and update them at the end of a session, or periodically throughout the session. When
updating a stack, it's a good idea to call Player Item Management - Modify Item Uses to check whether you can
just change the count of the stack, rather than adding N instances of the item which must each be processed for
addition to the stack, then cleaned up.
By their nature, certain game genres, such as collectible card games, do need to update the player inventory at a
somewhat higher rate. But even here, there are still opportunities to aggregate inventory changes and reduce
the total usage on the profile meters. For example, in games that use drop tables, the design frequently employs
a container that has one or more "pulls" from each of several different drop tables. Typically, if these pulls are
only an occasional action the incremental cost is small enough to not cause concern. But if players can collect
many of those containers, and open multiples in a short period of time, you could provide an "open N" or even
"open all" option. In that case, you use PlayFab CloudScript using Azure Functions or your custom game server
to either query Player Item Management - Get Random Result Tables for the set of drop tables or call Player
Item Management - Evaluate Random Result Table without generating the inventory items. You could then
update the player inventory far more efficiently by only adding instances where needed, and then updating the
count of item stacks for the rest.
CloudScript
This is one of the major "expansion joints" of the PlayFab service, allowing you to run server-authoritative logic
from a client device or a server, or even trigger it via PlayStream Rules (for example, when a player enters a
Segment). As opposed to custom game server hosting, you're only paying for the gigabyte seconds (GB/s) that
the script runs, with per-execution minimums of 128 MB and 100 ms. So if your script uses a total of 250 MB of
space (between script code and data), it would need to run a total of 4 seconds–likely across multiple
executions–to get to one GB/s.
Since the use cases for CloudScript generally revolve around taking actions on behalf of your players, we've
covered the majority of what you should be thinking about for optimizations in the last two sections on profile
and content/configuration meters. However, the total number of executions for a title is also tracked as part of
metering CloudScript usage, so it's valuable to review how often you need to make calls to CloudScript on a per-
player basis. For some games it might be significantly more cost efficient to use a hosted game server to have a
"hot" data store for active players, rather than try to manage a data store in iterative calls to CloudScript.
Insights
This meter is associated with all the analytics capabilities of the PlayFab service, from event ingestion and export
to Event History search and Data Explorer queries. Your usage here is influenced by how fast you need events
processed, how much event data that you want to keep hosted "hot" (for queries in the Game Manager), and
how much you use the service to evaluate your data, either through Data Explorer queries or visualization
software you connect to your data directly. This meter is impacted by both in-game activity (events) and out-of-
game activity (analytics).
Ultimately, this means that the costs on Insights are driven by how much event data you get from players and
how much analytics processing you do on that data. In terms of best practices, the advice on events above
applies to the former, while for the latter you can control your costs in two ways. First, and simplest, is that you
can set the total storage in the Insights Management tab of the Game Manager for your title to control how
much total event data you retain in PlayFab. Next, and in that same tab, you can set the performance level for
your title. This determines the total amount of CPU resources allocated to your title, as well as how much data is
stored "hot" for queries in the Event History. How much you need for each depends upon the needs of your data
analytics team members, so it's best to review this with them to understand what your settings should be.
For information about Insights and how to use it, see What is PlayFab Insights.
For information about Insight best practices, see Best Practices & FAQ.
Multiplayer Services
This one is the simplest of all, since the pricing is completely unchanged. In short, hosted Multiplayer Servers
and the Party service have always been charged on a usage basis.
For hosted game servers specifically, you can minimize your costs by optimizing the number of server cores you
have to have running at any given time to support as many players as possible.
If low ping times are important on those servers, you can choose which regions to run the servers. For most
games, the largest concentrations of players are limited to certain key regions, but if you have a widely
dispersed player population—particularly when you're in the long tail of your game—you'll need to weigh the
cost of running servers in every region near your players versus the impact of longer ping times on the subset
of players in areas with few players. One thing that can help with that is to make sure you're using our QOS
service to choose which regions to put players in, and then determine what your cut-off is for the minimum
number of players you need playing in a region for it to be viable.
To help get you through development without running up costs, we provide a significant number of free server
hours in our hosting service, and our Party service is free for all Development Mode titles. It's also worth calling
out that our Party service is also free for all use with Xbox Live signed-in players, and for titles in our Standard,
Premium, and Enterprise tiers, we provide a generous allowance of connectivity, voice, and Cognitive Services
(voice transcription and translation) at no additional cost, to help with 21st Century Communications and Video
Accessibility Act (CVAA) compliance.
Summary
Ultimately, it's the features your game needs that determine its usage of a backend service like PlayFab. Really, it
all boils down to one comprehensive question: what requirements do you have for those features? Whether you
prioritize security, timeliness of data, level of player interaction/competition, or something else entirely, there are
any number of factors that can push you towards a higher level of interaction with backend data. Being able to
look at those requirements with a critical eye and discern which are hard needs and which are not, is very much
akin to optimization of any other code in your game. It's a matter of taking a careful look at where your resource
utilization is high and deciding whether you truly need it to be, or if there are ways you can redesign that logic
to reduce usage.
If the interaction is real-time, player-to-player, it's down to the complexity of that interaction. For most games of
this type, hosted servers that manage the simulation state and only update the backend data at the end of a
session (or every few minutes, if the sessions are long) are usually the best solution. But there are plenty of
cases where interaction is fully trusted, such as co-operative games, or those played only with (or against)
friends, minimizing the incentive to cheat. Still others have only minimal requirements for how the data for a
session must be checked, allowing both players to simply submit their reports after each session, so that server-
side checks can compare the two.
For any game without a real-time requirement, consider whether the player really needs up-to-the-second
accuracy. In highly competitive games with strong community interaction, that may very well be the case. But for
plenty of games, information that's a few minutes out of date doesn't impact the player experience.
Looking Ahead
As a service, PlayFab continues to evolve, and as it does we will continue to update our documentation to help
guide you through managing your costs while making use of the services that power the features you need. If
you have any suggestions or thoughts on how we can improve on this, feel free to reach out to our team via the
Contact Us form on our main site. For feedback on how to optimize a feature you have in mind, or for any
general technical questions on using PlayFab, you can contact our support team via the community forums or, if
you're in any paid tier of service, by submitting a ticket in the PlayFab Game Manager (click on the ? in the upper
right hand corner from any page of your title). Our partnership with our developer community provides us with
the feedback we need to keep growing and to stay ahead of your needs, so we're always happy to hear from
you!
Azure PlayFab roadmap
5/24/2022 • 4 minutes to read • Edit Online
What’s new
Data Connections (formally Bring Your Own Storage): We're introducing the ability to write
PlayStream and telemetry events to your own storage account. With the ability to export data from PlayFab
to your own data storage of choice, you'll be able to take advantage of Azure services and have full control
over your data in terms of access, scale, latency, retention and privacy. This feature enters Public Preview this
week. To read more about the release, see Take control of data in your resources using Data Connections
blog post.
Matchmaking: We're adding real time notifications to avoid polling the ticket status and integration with a
new Lobby feature. The updated client SDK for Matchmaking with real-time notifications is now available
to ever yone in public preview . To learn more, see Matchmaking documentation and download the SDK
today to try it out. Remember to check out our new ID@Azure program. Sign up benefits includes the use of
this new matchmaking service at no cost for most games. To learn more, see Introducing ID@Azure: Your
Journey in the Cloud Starts Today blog post.
Lobby: A new feature that allows for temporary grouping of players for orchestrating multiplayer
experiences, including searching for available lobbies to join. It includes member properties, as well as lobby
and search properties to use for gameplay coordination. The new Lobby service with real-time notifications
is now available to ever yone in public preview . To learn more, see Lobby documentation. Remember to
check out our new ID@Azure program. Sign up benefits includes the use of this new Lobby service at no cost
for most games. To learn more, see Introducing ID@Azure: Your Journey in the Cloud Starts Today blog post.
UGC General Availability (GA): We've moved UGC out of public preview and into full release (GA). In
addition to various API tweaks and bug fixes, we’ve added Game Manager improvements and features to
help developers better manage their User Generated Content catalog. To learn more, see Growing
marketplace engagement with Azure PlayFab UGC GDC video and PlayFab User Generated Content
documentation.
What's on-deck
Leaderboards v2: Leaderboards v2 remains in private preview for now.
Economy V2 Public Preview coming in third quar ter of 2022! Player inventories and wallets, receipt
validation on the most popular marketplaces, bundles, stores, currencies, and more.
Segmentation: We'll be introducing a new API called Expor tPlayersInSegment into a beta release as an
enhancement to the existing GetPlayersInSegment API. Also, we'll be making it easier to define segments
comprising a fixed list of players.
NOTE
For release notes about service releases and product updates, see the release notes section on PlayFab's public GitHub
repository
220509
Date: 2022-05-09
Supports the February 8 2022 PlayFab service release
Minor bug fixes
220214
Date: 2022-02-14
Supports the February 8 2022 PlayFab service release
Minor bug fixes
220131
Date: 2022-01-31
Supports the November 17 2021 PlayFab service release
Minor bug fixes
220118
Date: 2022-01-18
Supports the November 17 2021 PlayFab service release
PlayFab Release Notes 2021
5/24/2022 • 2 minutes to read • Edit Online
NOTE
For release notes about service releases and product updates, see the release notes section on PlayFab's public GitHub
repository
211108
Date: 2021-11-08
Supports the October 21 2021 PlayFab service release
211012
Date: 2021-10-12
Supports the August 24 2021 PlayFab service release
210927
Date: 2021-09-27
Supports the August 24 2021 PlayFab service release
Updated Postman collection format to V2
210913
Date: 2021-09-13
Supports the August 24 2021 PlayFab service release
Adds bug fixes to UnrealMarketplacePlugin
210830
Date: 2021-08-30
Supports the August 24 2021 PlayFab service release
210816
Date: 2021-08-16
Supports the July 21 2021 PlayFab service release
Adds bug fixes to UnitySDK
210802
Date: 2021-08-02
Supports the July 21 2021 PlayFab service release
210628
Date: 2021-06-28
Supports the June 9 2021 PlayFab service release
210521
Date: 2021-05-21
Supports the April 28 2021 PlayFab service release
210427
Date: 2021-04-27
Supports the March 31 2021 PlayFab service release
210406
Date: 2021-04-06
Supports the March 31 2021 PlayFab service release
210315
Date: 2021-03-15
Supports the March 8 2021 PlayFab service release
210208
Date: 2021-02-08
Supports the February 3 2021 PlayFab service release
210125
Date: 2021-01-25
Supports the January 20 2021 PlayFab service release
210111
Date: 2021-01-11
Supports the January 2021 PlayFab service release
PlayFab Release Notes 2020
5/24/2022 • 6 minutes to read • Edit Online
NOTE
For release notes about service releases and product updates, see the release notes section on PlayFab's public GitHub
repository
201218
Date: 2020-12-18
Minor bug fixes
201207
Date: 2020-12-07
Supports the December 2nd PlayFab service release
UnrealMarketplacePlugin specific changes
Fixed static settings issues. Please follow the new upgrade guide.
201119
Date: 2020-11-19
PostmanCollection specific changes
Added an auto-login for Title Entity, when appropriate
UnitySDK specific changes
Fixed a spammy log for Unity 2020
Unity 2020 fully supported now
XPlat C++ SDK specific changes
Fixed QoS search response when all servers time-out.
201027
Date: 2020-10-27
Supports the September 2nd PlayFab service release
Minor updates were made to APIs.
201014
Date: 2020-10-14
Supports the September 2nd PlayFab service release
(Also supports new methods in the Experimentation API which will appear in a near-future Service release)
PlayFab is committed to enable you to use our services for developing cross-platform and cross-device games
using various game engines and frameworks. To help us better focus on creating new features that you need, we
are opening the following SDKs for community contributions. If you have more questions or need support, go to
PlayFab community forum. This will be our last official update to the following SDKs:
https://github.com/PlayFab/Cocos2d-xSDK
https://github.com/PlayFab/Objective_C_SDK
https://github.com/PlayFab/PhpSdk
https://github.com/PlayFab/PythonSdk
200914
Date: 2020-09-14
Supports the September 2nd PlayFab service release
200901
Date: 2020-09-01
Supports the August 26th PlayFab service release
200817
Date: 2020-08-17
Supports the August 12th PlayFab service release
200805
Date: 2020-08-05
Supports the August 5 PlayFab service release
200730
Date: 2020-07-30
Supports the July 15 PlayFab service release
200713
Date: 2020-07-13
Supports the July 1 PlayFab service release
200615
Date: 2020-06-15
Supports the June 10 PlayFab service release
200602
Date: 2020-06-02
Supports the May 27 PlayFab service release
200518
Date: 2020-05-18
Supports the May 13 PlayFab service release
UnitySDK specific changes:
PlayFab SDK no longer sets Application.runInBackground = true
Game Developers are responsible for verifying API calls during app focus change or before shutdown,
are successful
XPlat C++ SDK specific changes
In the CURL HTTP implementation, more CURL error states are monitored and processed
The Event Pipeline feature now uses and supports the background thread feature
When TitleId is not set, API methods now throw real-time exceptions synchronously, rather than reporting
the issue in synchronous or threaded callbacks
200422
Date: 2020-04-22
NodeSDK Update:
Hotfix
Fixed an issue where recent NPM packages were missing a critical file, and could not be imported
Fixed an issue where some type definitions were incorrectly set to "Number" rather than proper types
200421
Date: 2020-04-21
SDK's support the PlayFab Service as of 2020-04-21. Service release notes available here
200402
Date: 2020-04-02
API Changes
Insights:
Please see our new Insights feature!
200330
Date: 2020-03-30
API Changes
Authentication:
Added new LoginIdentityProviders for Apple and Nintendo
Multiplayer Server:
Added new BuildRegion management functions DeleteBuildRegion and UpdateBuildRegion
UnrealMarketplacePlugin:
Added new Mac build helper scripts
XPlat C++ SDK specific changes
Fixed some threading issues for the PlayFabEventPipeline
UnrealMarketPlacePlugin specific changes
Security bug fixes
200303
Date: 2020-03-03
API Changes:
server.UnlinkXboxAccountRequest no longer requires the XboxToken to be unlinked
The Experiments feature and API have been released
See our Blog Post for more details
New Methods
client.LoginWithApple
client.LinkApple
client.UnlinkApple
200220
Date: 2020-02-20
New
Automation - We released a new Visual Studio Code extension for PlayFab. You can find the source code in
Github.
Cpp Gsdk- Breaking change
Due to thread safety concerns, the signatures of the following methods were modified:
200218
Date: 2020-02-18
API & Documentation Changes:
New api methods:
admin.CreateInsightsScheduledScalingTask
multiplayer.GetMultiplayerSessionLogsBySessionId
New feature and methods:
A new mechanism for Cloud Script: Azure functions, can now be used in PlayFab
Feature Documentation
List of New Methods:
cloudscript.ExecuteFunction
cloudscript.ListFunctions
cloudscript.ListHttpFunctions
cloudscript.ListQueuedFunctions
cloudscript.PostFunctionResultForEntityTriggeredAction
cloudscript.PostFunctionResultForFunctionExecution
cloudscript.PostFunctionResultForScheduledTask
cloudscript.RegisterHttpFunction
cloudscript.RegisterQueuedFunction
cloudscript.UnregisterFunction
Api method changes:
Region request parameter is no longer required for multiplayer.GetMultiplayerServerLogs
CSharpSdk specific changes:
Overhaul and improve the QoS ping calculation for PlayFab Multiplayer
200213
Date: 2020-02-13
PlayFab's Multiplayer Servers introduces an auto scaling enhancement named Dynamic Standby that monitors
standby server threshold levels and dynamically activates increased provisioning of game servers so that
demand can be met at scale. This feature feature adds a new object to the Multiplayer programming interface
called "DynamicStandby" object. The Dynamic Standby object is an optional property of the BuildRegionParams
object.
Dynamic Standby is an advanced game server feature and editing the settings from its default values should be
done with caution. Configuring Dynamic Standby can be accomplished in the Game Manager Developers' portal
or programmatically editing properties of the Dynamic Standby object. To learn more about Dynamic Standby,
visit its user guide in the PlayFab Multiplayer Servers online documentation.
200128
Date: 2020-01-28
Multiplayer Server Event Changes:
We are introducing a change to the Multiplayer Server event naming convention in efforts to unify our event
names with that of the rest of PlayFab event names. Additionally, we are making these changes in advance of the
Multiplayer Server feature becoming Public Preview. The changes are:
Multiplayer Server event names will be updated to use PascalCasing
Multiplayer Server events will no longer be sent in the legacy v1 PlayStream event format; only v2
PlayStream event format will be supported
These two changes represent breaking changes, particularly for developers who take a dependency on non-
right casing of names or PlayStream v1 of Multiplayer Server events. These changes are not breaking for
developers who leverage event names in the Game Manager UI (cloud script, insights, rules, or scheduled tasks).
This change will take effect Wednesday February 26, 2020 at 10:00 AM PST. Please adjust your code for these
changes before the change date.
Format Changes
Generally, PlayFab Events have the format similar to:
{
'Event Name':'my_event'
'Payload':
{
'prop1':1
'prop2':2
'camelcase':3
}
}
The fundamental format change are that properties in the events Payload object will be updated to use
PascalCasing for consistency with other PlayStream events. Therefore, the new property names will meet the
following format:
{
'Event Name':'my_event'
'Payload':
{
'Prop1':1
'Prop2':2
'CamelCase':3
}
}
Observe that the property names of Multiplayer server events are now updated to use PascalCasing.
This change will impact customers who process Multiplayer server events in (a) Kusto queries or (b) PlayFab
cloud scripts. Lastly, if a customer leverages the PlayFab Event Archive feature (currently in public preview), the
properties of Multiplayer server events exported will also be formatted in PascalCasing.
Schema Changes
The second change introduced are that Multiplayer server events will only be delivered in PlayStream v2 format
and no longer the legacy PlayStream v1 format.
PlayFab currently supports two event schemas.
Generally, PlayFab API's generate events in either PlayStream V1 format or PlayStream V2 format. For example,
APIs that grant player items generated a PlayStream V1 event. Whereas APIs that grant entity items generated a
PlayStream V2 event.
Because the Multiplayer Servers launched in public preview at or near the same time PlayStream V2 was
introduced, the Multiplayer Server feature supported both PlayStream V1 and V2 formats. Meaning, every
Multiplayer Server API call generated two events; one in V1 and V2 format.
To remove duplication, Multiplayer server events in the 'com.playfab.events.multiplayer.servers' namespace are
being deprecated. Events in the 'playfab.servers' namespace will be continue to be supported.
To distinguish between Multiplayer Server events of V1 and V2 format, examine the namespace property of the
event. The namespace is specified in the 3rd column of the table above. The JSON representation resembles the
following:
{
'FullName':
{
'Namespace':'abc',
'Name':'xyz'
}
}
200121
Date: 2020-01-21
API & Documentation Changes:
PlayFab API Documentation site has been fully migrated to https://docs.microsoft.com/gaming/playfab/
Most api.playfab.com links have been converted to their equivalent docs.microsoft.com links
Most original links redirect to the new site properly
Let us know in the forums if any old links don't work
New api methods:
multiplayer.ListServerBackfillTicketsForPlayer
multiplayer.GetServerBackfillTicket
multiplayer.CreateServerBackfillTicket
multiplayer.CancelServerBackfillTicket
multiplayer.CancelAllServerBackfillTicketsForPlayer
server.UnlinkPSNAccount
server.LinkPSNAccount
LuaSdk specific changes:
Minor login bugfix
PhpSdk specific changes:
Minor syntax fix for strict correctness
UnitySDK specific changes:
Update the GitHub repro and project structure.
Moving the Unity EdEx package from (UnityEditorExtensions)
[https://github.com/PlayFab/UnityEditorExtensions] to (UnitySdk)
[https://github.com/PlayFab/UnitySDK/blob/master/Packages/PlayFabEditorExtensions.unitypackage]
In the future, we will also be phasing out the separate UnityEditorExtensions repo
PlayFab Release Notes 2019
5/24/2022 • 5 minutes to read • Edit Online
191218
Last SDK publish of 2019!
API Changes:
New methods: GetMultiplayerServerLogs and UntagContainerImage
Many minor bug fixes across most SDKs including: ActionScriptSdk, CloudScript, CSharpSdk, UnitySDK,
UnrealSDK
NodeSDK specific changes:
[Minor breaking change] Error situations now throw error() objects instead of plain strings
UnitySDK specific changes:
Created asmdef files for Unity to de-couple PlayFab from the Unity runtime DLL
Verified working on Unity: 5.6.Latest, and all versions from 2017.1.Latest to 2019.3.Latest
UnrealSDK specific changes:
Added support for Unreal 4.24
Verified working on 4.22, 4.23, 4.24
XplatCppSdk specific changes:
This release has minor breaking changes, that will require some code changes in your project
Please see our upgrade guide
(Breaking change - All Customers) Some PlayFabSettings variables have been moved
Requires minor code changes for all customers. Please see our upgrade guide
Major fixes to instance-API data isolation, which includes some signature and usage changes
Requires customer code changes if you used instance-API's,
C++ syntax improvements (for const correctness and pointer vs references)
Minimal chance of customer code adjustments
Major fixes to timestamps on all platforms
Requires customer code changes if you read or write timestamps in the PlayFab API, models, or
PlayFab timestamp utility methods
Most customers will only observe timestamps will be correct and threadsafe on all platforms now
Minor project updates and resolved warnings for most platform-specific projects/solutions
191122
Date: 2019-11-22
CSharpSdk specific hotfixes:
Fixed an issue where request authentication wasn't always applied properly when making API calls
Fixed some warnings
API calls from the main GUI thread will stutter the program (because this is an anti-pattern), but will no
longer deadlock the program
191121
Date: 2019-11-21
API Changes:
Error code documentation for many methods have been updated
CSharpSdk specific changes:
Removed hard coded references to SimpleJson, the default Json Serializer.
This will fix some issues when customers replace the default serializer with their own.
NodeSDK specific changes:
Minor updates to typescript definitions
Several locations that used to throw strings, now throw proper Errors
Phaser 3 compatibility fix
UnitySDK specific changes:
Removed hard coded references to SimpleJson, the default Json Serializer.
This will fix some issues when customers replace the default serializer with their own.
Verified working on Unity: 5.6.Latest, and all versions from 2017.1.Latest to 2019.2.Latest
UnrealSDK specific changes:
Verified working on 4.21, 4.22, 4.23
XplatCppSdk publish delayed:
We have some significant improvements and changing coming soon, but they're not finished. Consequently,
XPlat could not be published this release.
There will be new features, performance and signature improvements.
There will be very minor breaking changes, and an upgrade guide.
Stay tuned for next release!
191029
Date: 2019-10-29
API Changes:
TreatmentAssignment used in the client "Login With ..." method calls.
Minor bug fixes in XplatCppSdk
Minor PythonSDK bug fix
Some NodeSDK issues have been resolved
UnrealSDK specific changes:
Minor issue fix regarding required member variables in request containers
Verified working on 4.21, 4.22, 4.23
UnitySDK specific changes:
Verified working on Unity: 5.6.Latest, and all versions from 2017.1.Latest to 2019.2.Latest
191015
Date: 2019-10-15
API Changes:
Minor bug fixes in the XplatCppSdk- PlayFab enums should now be enum classes, therefore strict typing will
start to be enforced on PlayFab enums (see opensource cppCoreGuidelines on enum classes)
Profiles now have ExperimentVariants (PlayerProfiles and ProfilesAPI with updates to Admin and Server
API's)
Updating Client error messages for AccountNotFound
Events API added clarifying descriptions to what namespaces are allowed for custom PlayStream events
MultiplayerAPI added Aliases with CreateBuildAlias, DeleteBuildAlias, GetBuildAlias, UpdateBuildAlias
UnrealSDK specific changes:
Verified working on 4.21, 4.22, 4.23
UnitySDK specific changes:
Verified working on Unity: 5.6.Latest, and all versions from 2017.1.Latest to 2019.2.Latest
191001
Date: 2019-10-01
API Changes:
Minor bug fixes with Unity, we should no longer see benign errors when upgrading the SDK
Minor bug fixes with C++, nuget package should no longer require additional work to get lib_json working
Minor documentation description updates
UnrealSDK specific changes:
Verified working on 4.21, 4.22, 4.23
UnitySDK specific changes:
Verified working on Unity: 5.6.Latest, and all versions from 2017.1.Latest to 2019.2.Latest
190916
Date: 2019-09-16
API Changes:
Error code updates
UnrealSDK specific changes:
Minor build warning fixes
Updated for 4.23 compatibility
Verified working on 4.21, 4.22, 4.23
UnitySDK specific changes:
Verified working on Unity: 5.6.Latest, and all versions from 2017.1.Latest to 2019.1.Latest
190903
Date: 2019-09-03
API Changes:
Added GetStoreItems to the Server API
Various minor syntax bug fixes
UnrealSDK specific changes:
Verified working on 4.20, 4.21, 4.22
UnitySDK specific changes:
Verified working on Unity: 5.6.Latest, and all versions from 2017.1.Latest to 2019.1.Latest
190821
Date: 2019-08-21
API Changes:
[Authentication API]https://docs.microsoft.com/rest/api/playfab/authentication/authentication?) has a new
LoginIdentityProvider
Add CatalogVersion param to receipt validation APIs
PurchaseReceiptFulfillment - Receipt validation APIs return fulfilled items example Restore IOS Purchases
UnrealSDK specific changes:
Verified working on 4.20, 4.21, 4.22
UnitySDK specific changes:
Verified working on Unity: 5.6.Latest, and all versions from 2017.1.Latest to 2019.1.Latest
190717
Date: 2019-07-17
API Changes:
WriteTelemetry is now out of Beta as a public API
Multiplayer APIs have moved out of Beta to CSharpOnly
Minor API Error Code updates
UnrealSDK specific changes:
Verified working on 4.20, 4.21, 4.22
UnitySDK specific changes:
Verified working on Unity 5.6.Latest, and all versions from 2017.1.Latest to 2019.1.Latest
190625
Date: 2019-06-25
API Changes:
minor API changes
Authentication bug fixes
UnrealSDK specific changes:
Verified working on 4.20, 4.21, 4.22
UnitySDK specific changes:
Verified working on Unity 5.6.Latest, and all versions from 2017.1.Latest to 2019.1.Latest
190610
Date: 2019-06-10
API Changes:
Minor bug fixes
Authentication API Changes:
EntityLineage
ValidateEntityToken
190520
API Changes:
Minor bugfixes
UnrealSDK specific changes:
Verified working on 4.20, 4.21, 4.22
UnitySDK specific changes:
Verified working on Unity 5.6.Latest, and all versions from 2017.1.Latest to 2019.1.Latest
190509
Date: 2019-05-09
API Changes:
New Methods
multiplayer.GetTitleMultiplayerServersQuotas
server.AddGenericID
server.GetPlayFabIDsFromGenericIDs
server.LinkServerCustomId
server.RemoveGenericID
server.UnlinkServerCustomId
New Push Template Methods
The three new APIs for Push Notifications enable developers to Delete, Create, Save, and Send Push
Notification Templates
server.DeletePushNotificationTemplate
server.SavePushNotificationTemplate
server.SendPushNotificationFromTemplate
UnitySdk specific changes:
Verified working on 2019.1
CSharpSdk and XPlatCppSdk specific changes:
Minor bugfixes
190424
Date: 2019-04-24
API Changes:
]
Updated Error codes for the following APIs in the PlayFab API: Admin , Authentication , CloudScript ,
Groups , Matchmaker , and Multiplayer .
190410
Date: 2019-04-10
Profiles API Changes:
EntityStatisticValue
EntityStatisticChildValue
190312
Date: 2019-03-12
API Changes:
New [Multiplayer]https://docs.microsoft.com/rest/api/playfab/multiplayer/multiplayerserver?) APIs
190304
Date: 2019-03-04
API Changes:
Windows C++ SDK is now deprecated. We recommend using the XPlatCppSdk for any windows C++
development
190219
Date: 2019-02-19
Minor bug fixes
190205
Date: 2019-02-05
API Changes:
Updated obsolete documentation meta data
Added TypeString as an Alternate name for Type in most APIs
Added AddLocalizedNews to the Admin API
Added GetPlayFabIDsFromPSNAccountIDs to the Server API
190123
Date: 2019-01-23
API Changes:
Added another MatchmakingEntityInvalid reason - NoLeaderboardForStatistic
Added CurrentSer verStats to Multiplayer Models
Various bug fixes across Unity
Xbox xplat nugets are also available: https://www.nuget.org/packages/com.playfab.xplatxboxsdk.v141/
PlayFab Release Notes 2018
5/24/2022 • 8 minutes to read • Edit Online
181218
Date: 2018-12-18
XPlatCppSdk specific changes
XPlatCppSdk -SDK Breaking Change : Updated the folder structure for the XPlatCppSdk repo. If you are
using the SDK with project references, an update to vcxproj files path would be required.
Adding Xbox support to the XPlatCppSdk . Refer to the C++ quickstart for Xbox.
New API
Added PlayFabEventApi to support Heavyweight (low throughput) and Lightweight (high throughput)
custom events.
UnrealMarketplacePlugin specific changes
UnrealMarketplacePlugin
Adding support for Unreal Engine 4.21
181204
Date: 2018-12-04
XPlatCppSDK specific changes
XPlatCppSDK
Added support to build external dependencies.
Updated nuget composition. This is not a breaking change. Added binaries for the external
dependencies to the nuget and updated the properties sheet.
Bug fixes for QoSAPI .
CSharpSDK specific changes
CSharpSDK
Added .NET Standard 1.1/2.0 (plus .Net Core) support.
Updated nuget composition. The package now contains binaries for .Net Standard 1.1/2.0 and
portables also.
Migrated VS project files to VS 2017 standard.
UnitySDK specific changes
UnitySDK
SDK Breaking Change : The SimpleGet success callback signature has changed, and now must
accept a new single parameter of a byte[].
Added SimplePost .
181105
Date: 2018-11-05
API changes
PlayFab now supports login and account-linking with OpenID .
Additional XboxLive ID support, and enabling Xbox login via server.
In preparation for wider release of the service, we are rolling out PlayFab Multiplayer Servers 2.0 APIs. See
PlayFab Multiplayer Servers 2.0 (Thunderhead) for more information
181001
Date: 2018-10-01
API changes
A variety of deprecations have taken effect, and those elements have been removed from SDKs and
documentation.
Some Admin API methods related to unreleased features have been hidden.
server.DeleteUsers deprecation has taken effect.
A field deprecation for ServerHostname , spread across a variety of matchmaking related calls in admin,
client, matchmaker, and server APIs has taken effect. ServerIPV4Address is the replacement.
UnitySDK changes
Minor fixes/improvements to ScreenTime analytics.
All SDKs
The automated-build branch structure for GitHub repos is changing.
The normal customer facing branches, "versioned" and "master" will be unchanged.
180924
Date: 2018-09-24
API changes
Adding Metadata to the DeleteMasterPlayerAccountRequest Model.
Bug fixes in the Unreal Marketplace Plugin to expand supported versions.
180917
Date: 2018-09-17
API changes
The Server API method DeleteUsers is deprecated, and replaced with DeletePlayer
Unreal Marketplace Plugin:
Updated Marketplace Plugin to include our Blueprint interface.
New Unreal Engine quickstart guide
View in Unreal Marketplace
180906
Date: 2018-09-06
New API
Localization
New PlayStream event documentation
client_focus_change
client_session_start
player_device_info
180829
Date: 2018-08-29
API changes
renaming Entity.TypeString to Entity.Type .
renaming EmptyResult to [EmptyResponse].(
xref:titleid.playfabapi.com.groups.groups.removemembers#emptyresponse )
Renamed most Authentication function calls like GameServer to MutliplayerServer .
Admin.GetUserAccountInfo has more detailed platform information.
Objective C specific changes
Various bug fixes and refactors.
Changing AttributeInstallRequest to be API-specific.
Unreal Engine specific changes
Adding in UE marketplace plugin to SDK generator.
180809
Date: 2018-08-09
API group changes
We have separated the Entity API Group into multiple new API Groups.
This is a big SDK breaking change for anybody using the former Entity API.
See our Upgrade Guide!
(Please note, the links for blog and upgrade guide may not work yet, they're almost done.)
API changes
New API Methods:
The following APIs are released and visible in SDK, but the accompanying documentation isn't ready
yet:
client.LoginWithNintendoSwitchDeviceId
client.UnlinkNintendoSwitchDeviceId
server.GetPlayFabIDsFromNintendoSwitchDeviceIds
client.LoginWithFacebookInstantGamesId (not ready to use yet)
client.UnlinkFacebookInstantGamesId (not ready to use yet)
server.GetPlayFabIDsFromFacebookInstantGamesIds (not ready to use yet).
New PlayStream Events
title_hopper_config_updated event renamed to title_queue_config_updated
General changes
The parameter ServerAddress in many models has been deprecated in favor of the new
ServerIPV4Address .
180716
Date: 2018-07-16
UnitySDK changes
UnitySDK
Fixed minor issues with ScreenTime under some rare circumstances.
CSharpSDK changes
CSharpSDK
Added Plugin Manager API to C# SDK, to support optional custom implementations of JSON
Serializer and HTTP client.
UnrealCppSdk Changes: (UPDATED : This SDK has been deprecated. For the new unreal SDK,
please refer to UnrealMarketplaceSDK)
Unreal 4 C++ SDK is also published on Unreal Marketplace!
180710
Date: 2018-07-10
Unity hotfix release
Further refinements and optimizations to the ScreenTime events.
180709
Date: 2018-07-09
Hotfix release
Fixing some minor issues with last week's deployments.
Everything in last week's release notes should now actually work as promised.
180706
Date: 2018-07-06
API changes
New API Method:
entity.WriteEvents
UnitySdDK specific changes
UnitySdDK
Screen time tracking, described in the previous release is no longer Beta-only.
180705
Date: 2018-07-05
API changes
EntityAPI.ExecuteEntityCloudScript
PlayStreamEventModel.title_hopper_config_updated
180618
Date: 2018-06-18
API changes
Added new error codes in a variety of API methods.
Multiple entity-related PlayStream events now describe their EntityLineage.
180528
Date: 2018-05-28
API changes
New API Methods:
Admin.GetPlayedTitleList
Admin.DeleteMasterPlayerAccount
Admin.ExportMasterPlayerData
This is a part of the new GDPR launch. See our blog here
Updated Error codes in a variety of API methods
New PlayStream Event:
player_data_exported
180514
Date: 2018-05-14
XPlatCppSDK specific changes
XPlatCppSDK
Fixes in JSON serialization.
180507
Date: 2018-05-07
API changes
New API Method:
entity.GetProfiles
New PlayStream Events:
entity_executed_cloud_script
Updated API Method:
client.RegisterPlayFabUser now returns result.EntityToken
UnitySDK specific changes
UnitySDK
HttpWebRequest certificate validation security has been improved.
No longer default to ignoring all certificates.
Customers are expected to implement their own certificate validation, or call
PlayFab.Internal.PlayFabWebRequest.SkipCertificateValidation() .
180414
Date: 2018-04-14
UnrealCppSdk HotFix: (UPDATED : This SDK has been deprecated. For the new unreal SDK, please refer to
UnrealMarketplaceSDK)
Issues were discovered in the Entity API release for UnrealCppSdk. These are hot fixed, and the Entity API
should now work as expected.
180409
Date: 2018-04-09
API changes
HotFix:
Only the date was updated, not the major/minor version numbers.
Guilds:
client.GetAccountInfo.UserAccountInfo.UserTitleInfo.TitlePlayerAccount now contains the required
information to identify other players and add them to your guild/group.
The same information can also be found with admin.GetUserAccountInfo and
server.GetUserAccountInfo.
UnitySDK specific changes
UnitySDK
Performance improvement for default HTTP settings (UnityWWW), for long-running processes.
180403
Date: 2018-04-03
Unreal SDKs updated to support v4.17 thru 4.19
Removing support for UE 4.14 thru 4.16 (Please update!)
180329
Date: 2018-03-29
Unreal SDKs updated to support Entity APIs
Sorry for the delay!
This release still targets UE 4.17, and not 4.18 or 4.19. We are in-progress working on updating versions.
180316
Date: 2018-03-16
API changes
Entities! Blog! Quickstart Guide!
All Client login methods return Entity credentials if request.LoginTitlePlayerAccountEntity is set to true .
Guilds! Blog! Guide!
Error Codes for many API methods updated for accuracy (Dozens!).
New API methods
admin.RevokeInventoryItems and server.RevokeInventoryItems.
A whole new Entity API.
Many new Entity PlayStream Events (search for "entity" on linked page).
Most SDKs updated to support Entity APIs
Full Suppor t:
UnitySDK
JavaScriptSDK
ActionScriptSDK
CSharpSDK
NodeSDK
PostmanCollection
WindowsSDK
Cocos2d-xSDK
JavaSDK
LuaSdk (Including Corona and Defold)
PhpSdk
CloudScript
Will Suppor t Soon: Unreal Bp and Cpp. (Sorry - delayed due to technical difficulties!)
180213
Date: 2018-02-13
API changes
SendAccountRecoveryEmail now supports custom account recovery email templates when a custom account
recovery email template ID is passed in with the request parameters.
All Client Login Mechanisms can now optionally return Entity API credentials. (This is part of a coming-soon
feature.)
UnitySDK specific changes
UnitySDK
We are dropping support for older Unity versions, see our blog post.
Build files are now published using Unity version 2017.3.0f3.
180131
Date: 2018-01-31
JavaSDK changes
JavaSDK
Java is now published to Maven.
180129
Date: 2018-01-29
UnitySDK specific changes
UnitySDK
Fixing issues with compression.
It should be safe to re-enable compression for all versions and all platforms.
180123
Date: 2018-01-23
UnitySDK hotfix
UnitySDK
PlayFab UnitySDK had an issue with Unity version 2017.1.
See the forum post for details.
This has been resolved, PlayFab UnitySDK should work for all versions again.
180122
Date: 2018-01-22
API documentation update
Error codes updated on many API methods.
CSharpSDK and UnitySDK specific changes
CSharpSDK and UnitySDK
Adding a PlayFabException class, so that it's easier to catch PlayFab specific exceptions.
NodeSDK specific changes
NodeSDK
SDK Breaking Change: Require syntax for NodeSDK NPM package changed.
Major upgrade focused on NPM package.
Formerly require statements did not follow the NPM convention, requiring multiple nonstandard
require statements.
Now it requires a single require statement, and follows NPM conventions.
Major version number changed, this release is now 2.0.
1.x to 2.x Upgrade Guide.
CloudScript example
Added TypeScript definitions for the API Error exceptions.
180103
Date: 2018-01-03
LuaSDK specific updates
LuaSDK/Defold/Corona
Bug fix update.
Some platforms were producing a malformed URL which could not be resolved.
180102
Date: 2018-01-02
UnitySDK specific updates
UnitySDK
Bug fix update.
In order to avoid an issue with response headers, compression should be disabled for all device builds.
This update makes that possible.
Alternately, switching to Web Request will also avoid the issue.
A new HTTP option has been added for Unity versions > 2017.
PlayFab Release Notes 2017
5/24/2022 • 18 minutes to read • Edit Online
171204
Date: 2017-12-04
Unreal SDK changes (Cpp and Bp)
Updated both SDKs to Unreal 4.18.1 .
Older versions will still work, but require un-commenting #defines in the _.build.cs files.
171127
Date: 2017-11-27
API changes
An inventory feature allowing "Limited Edition" items is now released from beta.
This lets you define that only a fixed number of a particular itemId will be available in your game.
A virtual currency property has been removed from API methods that use "ProfileModel", as that
information was never actually provided or correct. It will return... someday.
New API methods
admin.CheckLimitedEditionItemAvailability
admin.IncrementLimitedEditionItemAvailability
client.GetPaymentToken
Used for XSolla specific payment processing
client.ReportDeviceInfo
This API method is not meant to be called directly. It is currently a built-in feature for Unity and
Lumberyard SDKs. It can be disabled with the API Policy. Additionally, we will be adding another
option soon to disable in the title settings page in Game Manager.
Updated API method error codes
client.AddOrUpdateContactEmail
client.GetLeaderboardAroundPlayer
client.LoginWithAndroidDeviceID
client.LoginWithCustomID
client.LoginWithIOSDeviceID
SDK specific updates
UnitySdk: We are now building all published unity package files with Unity 2017.2.0f3.
For testing, we internally updated to the latest for each major.minor version, from Unity 4.7.2f1 to 2017.1.2f1.
Unity Example Test Game Server: Fix applied to HttpHelper to fix SSL validation on SignalR requests.
ActionScriptSDK: AirSdk in example updated to v27.
Cocos2d-xSDK: We are still targeting 3.15.1, despite 3.16 Cocos release (stay tuned).
SdkTestingCloudScript and NodeSDK: Updated the example VS projects to support VS/msbuild 2017.
WindowsSDK: This will be the last build of the nuget package targeting Visual Studio 2013:
WindowsSdk VS 2013 Nuget Package
We are updating our automated build machines, and we won't be installing VS 2013 on the new ones.
The newer nuget package will continue to work on VS 2015 and 2017.
171106
Date: 2017-11-06
New API methods
admin.GetPlayerProfile
server.SendEmailFromTemplate
Updated PlayStream event
sent_email gains new fields: Body, and Subject.
All SDKs
MINOR SDK BREAKING CHANGE: ForgetClientCredentials() renamed to ForgetAllCredentials() .
This is part of a "coming soon" feature, which will be announced when complete.
171102
Date: 2017-11-02
New PlayFab feature
Send emails to your players, using templates.
New API methods
admin.ResetPassword
admin.GetPlayerIdFromAuthToken
client.AddOrUpdateContactEmail
client.RemoveContactEmail
server.SendCustomAccountRecoveryEmail
Documentation update
New list of error codes relevant to every PlayFab API call
Updated Error Codes for: client.LoginWithGoogleAccount, client.UpdatePlayerStatistics, server.ConsumeItem
New PlayStream events
auth_token_validated
player_updated_contact_email
sent_email
Unreal specific update
Our auto builder failed to publish the Unreal SDKs for build number 171016 and 171026. The issue with our
auto-builder has been resolved, and version 171026 has been published after the fact, and releases will
resume normally
Unity specific changes
MINOR BREAKING CHANGE: ForgetClientCredentials has been renamed to ForgetAllCredentials .
This is part of a new feature that will be coming soon. ForgetClientCredentials will be renamed to
ForgetAllCredentials in all SDKs over the next few releases.
171026
Date: 2017-10-26
API documentation changes
Updating error codes for API methods.
Many error codes that are universal to all API methods have been removed from the per-API-method list.
A new page will be made which describes universal error codes.
Removed Universal Codes:
InvalidParams
OverLimit
DataUpdateRateExceeded
AccountBanned
These errors (and others, to be published in a separate document), can be returned from any API method
and should be handled appropriately.
New error codes have been added to several dozen API methods, and a few false codes removed. The
error code lists should be much more accurate for method-specific error returns. This is still an ongoing
process, so there will be more updates.
Several API methods involving virtual currency can decrease the balance below zero. These have been
labeled appropriately.
API changes
New API methods:
admin.DeleteTitle
Hosted game servers support both IPv4 and IPv6 .
Custom game servers now support IPV6 . All newly started game server instances are assigned both
IPV4 and IPV6 addresses, which are displayed in the Game Manager Ser vers tab and returned by
the matchmaking APIs. Clients can connect to either the IPV4 or IPV6 address for the assigned server.
All API methods that return server addresses now return both options:
client.StartGame.StartGameResult
Game Manager changes
You can now delete titles using the new Admin/DeleteTitle API, or on the Game Manager studios page, as
shown below.
171016
Date: 2017-10-16
API changes
Added a parameter to server.SendPushNotification.SendPushNotificationRequest.PushNotificationPackage,
for iOS Badge.
Clarified the device-specific nature of various parameters.
New PlayStream events
player_started_purchase
player_paid_for_purchase
JavaScriptSDK specific changes
JavaScriptSDK
Our SDK now integrates with Phaser.io.
Read our tutorial Setting up PlayFab authentication in Phaser.io!
LuaSDK specific changes
LuaSDK
Our Lua publish pipeline has been fixed, and LuaSDK is being updated properly again.
UnitySdk specific changes
UnitySdk
A regression in Unity has been handled on our side, and should no longer affect PlayFab customers.
UnrealCppSdk specific changes: (UPDATED : This SDK has been deprecated. For the new unreal SDK, please
refer to UnrealMarketplaceSDK)
One of our customers has made an add-on plugin to our SDK which integrates the Unreal OnlineSubsystem
& the PlayFab SDK
You can check it out here.
Unicorn Battle example
Deleted PlayFab custom Push Plugin & Updated to FCM push messages.
170925
Date: 2017-09-05
API Changes
A handful of beta APIs that were never made public have been removed. This should not affect any current
customers or live titles.
We bypassed the default language-level header checks in our CloudScript engine. This means several
CloudScript http.request() headers that were formerly being rejected should now work.
Global Push Notification update
Please see our blog for details about the improvements to Push Notifications
New PlayStream events
player_device_info
Games using the latest UnitySDK can now see some basic analytics data about their customers. SnowFlake is
ideal for viewing and analyzing this information, but it's also available in the PlayStream Event History.
player_updated_membership
JavaScriptSDK specific changes
JavaScriptSDK
A handful of mini-features that exist in other SDKs have been added to JavaScriptSDK:
You can now inject extra headers into requests (removing one of the blockers for Double Encrypted
Logins with this SDK).
Added a new function: PlayFabClientSDK.ForgetClientCredentials()
This is a convenience function that allows you to reset the client after shutting down or logging out.
PlayFab.GenerateErrorReport()
This is a convenience function that converts the error-result from a failed PlayFab call into a single
complete description of how the call failed.
Added optional data relays into the PlayFab API requests:
result.customData
This is any contextual object you can attach to the request, which can provide context for the
result. For example, you can provide a local client-player object as the customData for an
UpdatePlayerStatistics call, and set the updated statistics on that player after the remote call
has succeeded.
result.request
The request for your API calls are now relayed to the result, which can provide context for the
result. For example, when you call UpdatePlayerStatistics , you can read the updated stats
from the request, when updating your local player object.
UnitySDK specific changes
UnitySDK
New experimental feature: This release of PlayFab UnitySDK now optionally allows you to see device
information for your players. Example information you can see is: memory, resolution, user-agent,
device-type, OS version, etc.
UnrealCppSdk specific changes: (UPDATED : This SDK has been deprecated. For the new unreal SDK, please
refer to UnrealMarketplaceSDK)
Updated to Unreal 4.17
Split apart into 3 separate plugins, each with different functionality
Pretty significant upgrades overall
170828
Date: 2017-08-28
Client API changes
client.GetCurrentGames.result.Games[i].GameServerState has been deprecated, and replaced with
GameServerStateEnum.
GameServerState was serialized as an integer, which was an error. The new field is a proper enum-string.
Other API changes
The following API methods have been deprecated on Admin and Server APIs.
GetActionsOnPlayersInSegmentTaskInstance - This has accidentally been labeled as deprecated, but
that was an error which will be reverted.
SendPushNotification can now specify TargetPlatforms
Added some clarifications for which parameters work on which platforms for SendPushNotificationRequest
(Using parameters not supported for a target platform is not recommended).
Added some info about Shared Group restrictions to the Shared Group documentation (specifically that they
can't be used for anything like Guilds).
Player Profiles can now store a player contact email address.
New PlayStream events
entity_created
entity_logged_in
170814
Date: 2017-08-14
API updates
server.GetFriendsList and client.GetFriendsList API methods now return a PlayerProfile for each of your
friends.
CSharpSdk specific updates
SDK now includes a file called NewtonSoftJsonWrapper.cs which will let you swap out our included
SimpleJson serializer with the NewtonSoft nuget package.
The file includes instructions on how to use it.
170807
Date: 2017-08-07
New API methods
admin.DeletePlayer
Deprecated API methods
These API methods never worked as fully and completely as they were supposed to. In an effort to clean this
up, we've started over, and built the new DeletePlayer API above, and these are deprecated:
admin.ResetUsers
admin.DeleteUsers
API updates
PlayerProfile (in Admin/Server/PlayStream) contains a new field ContactEmailAddresses , which contains
any email address info you may have saved about your players.
PlayStream events
New Event: auth_token_validated
New Event: player_removed_title
New Event: player_updated_contact_email
New Event: player_verified_contact_email
New Event: sent_email (Still in beta, but events are already public)
New Field in Event: player_realmoney_purchase.TransactionId
Lumber yardSdk changes:
UPGRADE WARNING: This SDK is no longer compatible with previous versions of Lumberyard.
This release of PlayFab LumberyardSdk no longer works with Lumberyard version 1.3. It has been upgraded
and now targets Lumberyard 1.9. We will very likely have it targeting 1.10 in the near future, but again
without backwards compatibility to 1.9 or earlier. See our blog for details.
UnrealCppSdk : (UPDATED : This SDK has been deprecated. For the new unreal SDK, please refer to
UnrealMarketplaceSDK).
This SDK has been discontinued, and will no longer be maintained. We will produce an upgrade guide so that
users can switch to the UnrealBlueprintSdk. Please see this blog for more details.
See our upgrade guide
Unreal SDK: (UPDATED : This SDK has been deprecated. For the new unreal SDK, please refer to
UnrealMarketplaceSDK)
The PlayFab UnrealBlueprintSdk is now rebranded as the "Unreal SDK"
Unreal SDK has been updated to 4.16, with some minor fixes
We're also removing support for older versions of Unreal, which require older versions of Visual Studio
We now support 4.14 thru 4.16
Your project may continue working for older versions of Visual Studio, but we can only support and test
Visual Studio 2015 and later
Read our blog for more info
Unity Editor Extensions
Fixed issues downloading and uploading CloudScript revisions.
Fixed issues for users whose system language uses non-ASCII letters.
170710
Date: 2017-07-10
API changes
An Enterprise feature for double-encrypted logins has been released from beta, and is now live.
New API methods:
admin.CreatePlayerSharedSecret
admin.DeletePlayerSharedSecret
admin.GetPlayerSharedSecrets
admin.SetPlayerSecret
admin.UpdatePlayerSharedSecret
client.GetTitlePublicKey
client.SetPlayerSecret
server.SetPlayerSecret
server.RegisterGameRequest has a new property: LobbyId, which will let you attempt to re-register an
existing game
server.SendPushNotificationRequest now accepts a new property: Package, which defines all of the advanced
Android push capabilities.
SDK breaking change
admin.SetupPushNotificationRequest.Platform is now defined as an enum instead of a string. This is not a
breaking change to the API (as enums are transmitted as strings), but it will require some users to convert
their strings to the enum values in their code.
Changes in all SDKs
Minor SDK Breaking Change: Most SDKs have lost an optional field in multiple requests called
UseSpecificVersion, which was an alternate way to define the adjacent Version field as null. Not all languages
have the capability to define an integer as null in the request, and this field was only meant to be useful in
relevant SDKs (Specifically Unreal). If you are using this field, just remove it, and set the adjacent Version field
to null when appropriate.
Unity EditorExtensions update
The flags panel has been updated.
ENABLE/DISABLE_IDFA flag can be toggled now.
Displays non-PlayFab flags, and allows you to remove them (use with caution, don't remove flags you need).
SDK Dependency updates
UnitySDK built, packaged, and tested with Unity2017.1.0f1.
Only trivial, non-breaking changes.
ActionScriptSDK tested with AirSDK v26.
SDK unchanged, example updated to target v26.
Cocos2d-xSDK built, and tested with Cocos 3.15.1.
Cocos 3.14->3.15 contained changes that broke our example, which in turn meant the example had to be
updated. The example still works with 3.13 thru 3.15, but the example probably won't work with older
versions of Cocos SDK unchanged, and should continue to work with most of the latest 3.X Cocos versions.
170612
Date: 2017-06-12
Documentation changes
Many small revisions to dozens of API methods for clarity
Several documentation-groupings, each which only contained a single API method, have been merged into a
single group called "Platform Specific Methods".
The "Matchmaking APIs" group has been renamed to "Matchmaking" to be consistent with other groups.
Many length-restricted string fields now describe the allowed ranges.
Changes in all SDKs
Lots of broken links in all SDK readme's have been updated and fixed.
UnitySDK specific changes
UnitySDK
We now support multiple versions of the Android API and Google Play Services. Read more details
here.
This concludes the planned changes to the Unity + Android Push-Plugin for now. Please let us know if
you have any additional requests here.
170530
Date: 2017-05-30
API changes
BREAKING CHANGE: In server.ReportPlayer, the titleId field in ReportPlayerServerRequest has been
immediately removed (not merely deprecated). All reports will now go to their own title, and cannot report
to another title.
This had to be a breaking change as it was otherwise a mild cross-title exploit. Contact us if you need
assistance with this change.
In client.ReportPlayer and server.ReportPlayer, result.Updated has been deprecated in both cases. It was
always true, and the API Call would always return an error if the player was over the report limit. This error
condition has been updated to be OverLimit to match other limits.
All login methods can now return a player profile object, if requested, which contains information previously
only available to leaderboard results.
New API methods
client.GetPlayerProfile and server.GetPlayerProfile
Returns information previously only available to leaderboard results.
Documentation
Small updates, several examples no longer contain information about deprecated fields.
ExecuteCloudScript return and log size limits defined.
New PlayStream events
gameserverhost_started
gameserverhost_stopped
player_set_profile_property
UnitySDK specific changes
UnitySDK
Our Android Push plugin has been overhauled.
Blog Post
New/Updated Guide
CSharpSDK specific changes
CSharpSDK
It is now possible to specify extra headers that will be injected into an API request.
This is an Enterprise-Only feature, specifically for double-encrypted login requests.
170508
Date: 2017-05-08
API changes
BREAKING CHANGE:
ExecuteCloudScript will not serialize the return value of your call, if it is too large.
ExecuteCloudScript will not serialize the logs for your call, if they are too large.
Under either of these conditions, the call will still return 200/successful, but the FunctionResult and/or Logs
properties will be null.
PlayStream event changes
player_vc_item_purchased and character_vc_item_purchased now contain a StoreId parameter indicating
which store was used to make a purchase.
New event:
title_profile_view_constraints_changed
CSharpSDK updates
CSharpSDK
Some unused source files in CSharpSDK have been deleted.
This should not affect any existing projects, or the Nuget package, as those files were not referenced
by the Visual Studio Solution.
Postman collection update
Several common request parameters now utilize environment variables.
Specifically, TitleId={{TitleId}}, PlayFabId={{PlayFabId}}, CharacterId={{CharacterId}}, and CatalogVersion=
{{PrimaryCatalogName}}
170424
Date: 2017-04-24
SDK hotfix release
JavaSDK Updates:
We now publish Jar files for the SDK, one for code, and one for Java docs, which you can import into
your Java project instead of copy-pasting code. Thanks to Will Iverson for helping us improve our
JavaSDK usability
UnityEditorExtensions updates:
We have resolved some install-time exceptions. Specifically it is no longer required that you restart
Unity after a first-time install.
Additionally, an issue where the Client API was sometimes disabled inappropriately is now fixed.
(edited)
UnrealCppSdk Updates: (UPDATED : This SDK has been deprecated. For the new unreal SDK, please refer
to UnrealMarketplaceSDK)
The titleId is now available from the Plugin interface
170411
Date: 2017-04-11
API changes
New Enterprise Feature: Additional login encryption
You can utilize the Policy API methods to enforce Login Calls can require a second layer of encryption
See: UpdatePolicy , specifically UpdatePolicyRequest.Statements.ApiConditions
This feature is still partially in beta, and activating it is not suggested (yet - Coming Soon!)
New PlayStream events
player_receipt_validation
UnitySDK specific changes
It is now possible to specify extra headers that will be injected into an API request (This is required for the
encrypted login calls above).
UnityEditorExtensions specific changes
Fixed a compile issue with Unity 5.6.
170406
Date: 2017-04-06
Hot Fix for Unity Android Push plugin
Fixed Android 7.0+ Crash Bug.
Fixed Android missing Large Icon support ( Lollipop + ).
Fixed Android Small Icon support on Android 7.0+ ( now supports _transparent.png ).
170403
Date: 2017-04-03
API changes
Client & Ser ver Leaderboard Methods: Get-Leaderboard methods (such as client.GetLeaderboard)
previously gained new non-nullable parameters Version and UseSpecificVersion. The requirement that they
were non-nullable was an API-breaking change. We have updated these properties to be fully optional.
Client API: The Items field of GetPurchaseResult will be deprecated: This portion of the result is often
incorrect or incomplete. It will eventually be replaced with a fully functional parameter.
New PlayStream events
player_display_name_filtered
Unreal Specific Changes: (UPDATED : This SDK has been deprecated. For the new Unreal SDK, please refer to
UnrealMarketplaceSDK)
UnrealCppSdk: An issue where PlayFab settings such as TitleId were lost when publishing a build has been
fixed. Both SDKs have been tested and verified working with Unreal 4.15
JavaSDK specific changes
JavaSDK
JavaSDK folder structure and testing has been restructured.
The internal folder structure of the repo has changed a bit to accommodate Maven best practices.
Dependencies are now Maven controlled and no longer included with the SDK.
Our internal automated testing has been converted to Maven command line.
Our SDK is NOT available on Maven Central, as that effort has faltered. There is no ETA for completion
at this time.
UnitySDK specific changes
UnitySDK
Internal Unity version for testing and building asset bundles updated to 5.6.0. Our Unity SDK remains
compatible with all versions of Unity from 4.7 thru 5.6.
A compile issue with UnityEditorExtensions in Unity 5.6 has been fixed.
170223
Date: 2017-02-22
API changes
PlayFab leaderboards now store an avatar url for every player. This can be used to reference a player image
for leaderboard entries.
All leaderboard APIs can now fetch a specific version of the leaderboard. This is for titles which are set to use
Resetting Leaderboards.
Leaderboard entries now contain the PlayerProfile which can be used to display more detailed leaderboards
without additional API calls
PlayFab can now authenticate clients using Windows Hello and validate Windows store receipts
New APIs
Client/UpdateAvatarUrl
Client/RegisterWithWindowsHello
Client/GetWindowsHelloChallenge
Client/LoginWithWindowsHello
Client/LinkWindowsHello
Client/UnlinkWindowsHello
Client/ValidateWindowsStoreReceipt
Server/SetFriendTags
New PlayStream events
player_changed_avatar
WindowsSDK specific changes
Added some missing null checks to the JSON serializer.
All SDKs
Minor additions to the testTitleData format. This only applies to the Example-Test projects that come with
SDKs.
170130
Date: 2017-01-29
Breaking changes
The folder structure for JavaScriptSDK and NodeSDK has been changed with today's major release. This may
result in some broken connections for your project when you upgrade. (File names and file contents have not
changed. New TypeScript files now exist, which did not exist before.)
API changes
Added clarifying documentation to CDN APIs. Specifically mentioning that the CDN is not part of our free
service.
Google login fixes (Blog Post Pending).
New PlayStream events
developer_logged_in
developer_registered
studio_created
studio_user_added
studio_user_invited
studio_user_removed
JavaScriptSDK specific changes
JavaScriptSDK
Release day for a major upgrade! Version number updated to 1.0.
TypeScript integration!
Repository cleanup: Separating the sdk files from the example files.
Our example project has been converted to TypeScript.
See our blog!
NodeSDK specific changes
NodeSDK
Release day for a major upgrade! Version number updated to 1.0
TypeScript integration!
Our example project has been converted to TypeScript
See our blog!
CloudScript examples
Release of a new example repository.
TypeScript integration!
See our blog!
And new repository!
We will be expanding this repository over time.
UnitySDK specific changes
UnitySDK
Fixed an issue where where JsonWrapper did not work as expected in all cases.
See our forum post for details: https://community.playfab.com/questions/7599/cloudscript-
getplayercombinedinfo-little-problem.html
All of the following deprecated wrapper classes have been removed in favor of
PlayFab.Json.JsonWrapper :
PlayFab.Json.JsonConvert (Use PlayFab.Json.JsonWrapper )
PlayFab.Json.SimpleJson (Use PlayFab.Json.JsonWrapper or PlayFab.Json.PlayFabSimpleJson )
PlayFab.SimpleJson (Use PlayFab.Json.JsonWrapper or PlayFab.Json.PlayFabSimpleJson )
Repeating a note from 160627, UnityEngine.SimpleJson is an empty namespace in the
UnityEngine.dll , and that makes it necessary for us to not use that identifier.
170109
Date: 2017-01-08
Breaking changes
Libs in older versions of WindowsSDK have been removed, and must be re-created in Visual Studio. Those
libs never worked in vs2015, so it's highly suggested you just update to the latest WindowsSDK, published
last week.
API changes
Fixed typos in documentation.
All SDKs
New Getting Started Guides
SDKGenerator specific changes
SDKGenerator
The ActionScriptSDK build script was inconsistent from the other SDKs. The SDKGenerator commands
that build ActionScriptSDK have been simplified to match other SDKs. (No changes to the SDK itself.)
UnitySdk specific changes
UnitySdk
Some public elements in PlayFabSettings have gained Obsolete tags:
PlayFabSettings.PlayFabSharedSettings PlayFabSettings.DefaultPlayFabApiUrl
PlayFabSettings.GetSharedSettingsObject() PlayFabSettings.ProductionEnvironmentUrl
170102
Date: 2017-01-01
API changes
Client/GetUserCombinedInfo has transitioned to fully obsolete, and has been removed from the SDK and
documentation.
Cocos2d-xSDK specific changes
Cocos2d-xSDK
Fixed a crash when a PlayFab API returns an invalid response.
Resolved some compiler warnings.
Added unit tests for lambda callback functions in our test example project.
UnitySDK specific changes
UnitySDK
We have internally updated to Unity 5.5, and our .unitypackage files are built using this version
As always, we continue to support all Unity versions 4.7 and higher.
Added static constructors to many static classes, in order to solidify the initialization sequence in
Mono2x compiler. This should resolve some of the PlayFabSharedSettings issues we've been
seeing in iOS.
IDFA/ADID will now work properly for Unity 5.6 beta.
KNOWN ISSUE: Unity 5.6 beta builds do not work on Windows Ser ver (OS ), which includes
PlayFab game-server hosting. Please contact Unity if this affects you.
WindowsSDK specific changes
Release day for a major upgrade!
Blog Post: Windows SDK Update Released
Upgrade Guide: PlayFab WindowsSdk v0.x -> v1.x Upgrade guide
PlayFab Release Notes 2016
5/24/2022 • 23 minutes to read • Edit Online
161121
Date: 2016-11-20
API changes
Each Client API can now be individually enabled or disabled.
See our blog post for details.
We are releasing a new feature called Scheduled Tasks.
See our blog post for details: (Coming soon).
New APIs
Client API Policy APIs
Admin/GetPolicy
Admin/UpdatePolicy
Scheduled Tasks
Admin/AbortTaskInstance
Admin/CreateActionsOnPlayersInSegmentTask
Admin/CreateCloudScriptTask
Admin/DeleteTask
Admin/GetActionsOnPlayersInSegmentTaskInstance
Admin/GetCloudScriptTaskInstance
Admin/GetTasks
Admin/RunTask
Admin/UpdateTask
New PlayStream event
title_permission_policy_changed
WindowsSDK specific changes
A new overhauled WindowsSDK will be published next week.
See our blog post for a brief description.
If you are interested in previewing the upcoming changes, post here:
https://community.playfab.com/questions/3973/windowsc-sdk-vs2015-support.html
161108
Date: 2016-11-07
HOTFIX
Version 1.0 of the overhauled CSharpSDK increased the .Net version requirement from 4.0 to 4.6. This was not
intended. This hotfix removes the 4.6 only features, so that it will once again build on .Net 4.0 or higher.
161107
Date: 2016-11-06
API changes
Shared
CatalogItem
InitialLimitedEditionCount ( out of beta ) If IsLImitedEdition is true , then this determines amount of the
item initially available. Note that this field is ignored if the catalog item already existed in this catalog, or the
field is less than 1.
Player display name uniqueness is now optional.
Player display name returned as Photon "Nickname" when players connect to Photon Cloud.
Ser ver API
RedeemCouponRequest
Added: CharacterId
Optional identifier for the Character that should receive the item. If null , item is added to the player.
UpdatePlayerStatisticsRequest
Added: ForceUpdate
Indicates whether the statistics provided should be set, regardless of the aggregation method
set on the statistic. Default is false .
New PlayStream events
Player_photon_session_authenticated
Title_secret_key_changed
Title_api_settings_changed
SDK changes
CSharpSDK Specific Changes:
Major CSharp upgrade
161031
Date: 2016-10-30
Unreal Blueprints hotfix release (UPDATED : This SDK has been deprecated. For the new unreal SDK, please
refer to UnrealMarketplaceSDK)
UnrealBlueprintSDK upgrade warning : There was a naming conflict between Android and the PlayFab
"SourceType" enum. As a result, we've had to rename this blueprint-enum. This breaks any
Client/GetStoreItems or Admin/GetStoreItems PlayFab-api-nodes. The upgrade process in-editor is to
delete and re-create each affected blueprint node.
UnrealBlueprintSDK Specific Changes:
Fixed a minor bug where certain errors would not report correctly
Fixed a name conflict that prevented making Android builds (ESourceType)
161017
Date: 2016-10-16
Deprecation changes
Client/GetUserCombinedInfo has transitioned from Proposed to Deprecated , which means most SDKs using
this will now throw an error. Please transition to Client/GetPlayerCombinedInfo.
Deprecated APIs from this patch note: 160822 have transitioned from deprecated to obsolete, according to
this blog: Deprecation Visibility and thus, those APIs have been removed from the newest version of the
SDKs. If you update your SDK, you must now transition to the new replacement APIs.
Password in the Admin UserCredentials object has been deprecated. You no longer need to know your user's
password to call the Admin/ResetUsers method.
UnitySdk breaking changes
UnitySdk
If you are using reflection on PlayFab API-model types, you will have to convert your reflection logic
from properties to fields (See UnitySdk Specific Changes below).
API changes
New PlayStream events:
gamelobby_started
gamelobby_ended
Client/AttributeInstall request has deprecated Android_Id and converted to Adid . All SDKs have had
some internal login hooks updated to account for this. This is not a breaking change, because it was
always intended to use Google-AdvertisingId (Adid), and using the Android DeviceId here would not
have worked properly. This change is merely for clarity and consistency
For the GitHub add-on, revisions to CloudScript will no longer immediately go live. Instead a new
revision will be made, and you make it live via Game Manager
The default helloWorld CloudScript function described in this doc: CloudScript quickstart was out of
date. Updated the document to more closely match the current version (This is only relevant to new
title creation)
API Server bug fixes
Fixed a 500 error in Server/ExecuteCloudScript: PlayFabId is now a mandatory parameter (Formerly it would
error if it wasn't provided)
Fixed a 500 error in Server/GetSharedGroupData: SharedGroupId is now a mandatory parameter (Formerly
it would error if it wasn't provided)
Fixed a 500 error in Server/AddSharedGroupMembers: PlayFabIds is now a mandatory parameter (Formerly
it would error if it wasn't provided)
Fixed a 500 error in Server/RemoveSharedGroupMembers: PlayFabIds is now a mandatory parameter
(Formerly it would error if it wasn't provided)
Fixed a 500 error in Server/DeleteSharedGroup: SharedGroupId is now a mandatory parameter (Formerly it
would error if it wasn't provided)
LuaSDK specific changes
LuaSDK
Better identification headers for Corona vs Defold.
UnitySDK specific changes
UnitySDK
Model properties have been converted to fields so they display better in the Unity Inspector (where
relevant).
Fixed a bug where if a CloudScript function returns a primitive, it will now be properly deserialized
and returned as FunctionResult (Formerly it would have been null).
The PaperTrail package has been fixed: UnityPlayFabPaperTrail.unitypackage
SDKGenerator specific changes
SDKGenerator
SDKGenerator can additionally read Api-Specs from Api-Server or GitHub, allowing customers to
build their custom SDKs in-sync with PlayFab api-server, and with fewer steps and dependencies.
161003
Date: 2016-10-02
API changes
New APIs
Client/GetTime
Server/GetTime
Google OAuth upgraded to v3
Improved search results on our documentation site: PlayFab Documentation.
SDK global changes
Revised documentation for examples in SDKs, and provided better explanations of how to use our testing
tools:
https://github.com/PlayFab/SDKGenerator/blob/master/JenkinsConsoleUtility/testTitleData.md
https://github.com/PlayFab/SDKGenerator/blob/master/JenkinsConsoleUtility/readme.md
LuaSdk specific changes
LuaSdk
Corona Plugins are now available from the Corona Marketplace.
Client Plugin: https://marketplace.coronalabs.com/plugin/playfab-client
Server Plugin: https://marketplace.coronalabs.com/plugin/playfab-server
Combo Plugin: https://marketplace.coronalabs.com/plugin/playfab-combo
Corona Readme: https://github.com/PlayFab/LuaSdk/tree/master/Corona
UnitySDK specific changes
UnitySDK
UnitySDK V0 repository is being retired. Everybody should please update to UnitySDK V2 available on
our download page.
IDFA and AdvertisingId will work properly on Unity 5.5 beta versions.
CloudScript functions that return a primitive, such as an integer, will now deserialize correctly
Minor improvements to Unity Compression, it should now be safe to enable compression in the
PlayFabSharedSettings scriptable object.
WindowsSDK specific problems
The .lib files published with this repo are now bigger than the GitHub max file-size limit.
The latest version does not have updated lib files, and we've begun looking at alternatives.
160919
Date: 2016-09-18
New APIs for payments
We are expanding our Payments API to include a standard way to refund and dispute purchases.
Admin/RefundPurchase
Admin/ResolvePurchaseDispute A few friend-based APIs have been copied from the Client to
the Ser ver :
Server/GetFriendLeaderboard
Server/AddFriend
Server/GetFriendsList
Server/RemoveFriend
Small improvements to the Matchmaking ability of our Server API
Server/RegisterGame
Server/DeregisterGame
Server/SetGameServerInstanceTags
Server/RefreshGameServerInstanceHeartbeat
Cocos2d-xSDK specific changes
Cocos2d-xSDK
Cocos sample updated triggering a rebuild of the example project. This should still work as previously
designed, as only cosmetic changes were applied.
UnitySDK specific changes
UnitySDK
Minor fixes in unity game server, to reflect API changes.
JavaScriptSDK specific changes
JavaScriptSDK
Test-example updated to use CDN.
160912
Date: 2016-09-11
Unity and CSharp upgrade warning
The deprecation warnings described below have gone into effect. Deprecated APIs will now throw compiler
errors when possible. Likewise, the documentation for those APIs have been filtered from the main
documentation.
API changes
New APIs
Admin/GetAllActionGroups
Server/GetAllActionGroups
160829
Date: 2016-08-28
API changes
New APIs
Client/GetPlayerTags
Server/AddPlayerTag
Server/GetPlayerTags
Server/RemovePlayerTag
Admin/AddPlayerTag
Admin/GetPlayerTags
Admin/RemovePlayerTag
We have introduced segment tags, which provide a way of directly putting players into particular segments. You
can now add one or more segment tags to each player. And then, when creating a segment, you can define the
segment based on the segment tag.
One intended use for Segment Tags is for integration with external analytics providers, like Appuri. The external
analytics provider can perform its own advanced segmentation, such as "Likely to Churn", and then set a tag on
players that match that segment. All current deprecation changes have been released. Please see our blog post
for details: https://playfab.com/deprecation-visibility/
Cocos2d-xSDK specific changes
Cocos2d-xSDK
Special thanks to Max Muthig from Forest Ring Games for the following update:
Added support for lambda callback functions (formerly only static functions were allowed).
PostmanCollection specific changes
PostmanCollection
Added a header to all API methods which will help our servers track SDK usage. (This header already
exists on all other SDKs).
UnitySDK specific changes
UnitySDK
We are pleased to announce the initial public beta release of our latest tool: Unity Editor Extensions.
This plugin provides an easy-to-use interface for configuring and managing the PlayFab SDK. All Unity
developers are encouraged to check out EdEx; There has never been an easier time to sign up and get
started developing.
Added an alternate implementation of ExecuteCloudScript which automatically parses
FunctionResult into a target type, using a generic parameter.
Failure cases in API methods are improved: Some cases that threw exceptions now properly report
back to the error-callback (such as Web-Requests with no internet connection), and other cases report
better information to the error-callback.
UnrealBlueprintSdk specific changes: (UPDATED : This SDK has been deprecated. For the new unreal SDK,
please refer to UnrealMarketplaceSDK)
Fixed an issue where APIs containing an optional list field in the request would not post the request properly
to the server. (Such as GetPlayerStatistics)
SDKGenerator specific changes
SDKGenerator
Updated documentation, and an example project to better document for PlayFab users how to create
their own SDKs for our API.
160822
Date: 2016-08-21
Global upgrade warning
Some SDKs have gained warnings for APIs that have become deprecated. If you see these warnings, please
resolve them ASAP, and migrate to the indicated replacement APIs. Many of these APIs will be removed from the
SDK within the next couple of months. There is a blog post about this here.
Deprecation notices
Admin Fields
UpdateCloudScriptRequest.Version
Client Fields
GetPlayFabIDsFromSteamIDsRequest.SteamIDs
SendAccountRecoveryEmailRequest.PublisherId
SteamPlayFabIdPair.SteamId
Client DataTypes
GetCloudScriptUrlRequest
GetCloudScriptUrlResult
GetFriendLeaderboardAroundCurrentUserRequest
GetFriendLeaderboardAroundCurrentUserResult
GetLeaderboardAroundCurrentUserRequest
GetLeaderboardAroundCurrentUserResult
GetUserCombinedInfoRequest
GetUserCombinedInfoResult
GetUserStatisticsRequest
GetUserStatisticsResult
LogEventRequest
LogEventResult
UpdateUserStatisticsRequest
UpdateUserStatisticsResult
Client APIs
GetUserCombinedInfo
GetFriendLeaderboardAroundCurrentUser
GetLeaderboardAroundCurrentUser
GetUserStatistics
UpdateUserStatistics
LogEvent
GetCloudScriptUrl
RunCloudScript
Ser ver Fields
GetPlayFabIDsFromSteamIDsRequest.SteamIDs
SteamPlayFabIdPair.SteamId
Ser ver DataTypes
GetUserStatisticsRequest
GetUserStatisticsResult
LogEventRequest
LogEventResult
UpdateUserStatisticsRequest
UpdateUserStatisticsResult
Ser ver APIs
GetUserStatistics
UpdateUserStatistics
LogEvent
API changes
New APIs
Admin/BanUsers
Admin/GetUserBans
Admin/RevokeAllBansForUser
Admin/RevokeBans
Admin/UpdateBans
Admin/DeleteStore
Server/BanUsers
Server/GetUserBans
Server/RevokeAllBansForUser
Server/RevokeBans
Server/UpdateBans
Server/GetRandomResultTables
New PlayStream events
player_tag_added
player_tag_removed
title_catalog_updated
title_store_updated
Global SDK changes
The example projects provided with the SDKs have all been updated, and no longer use deprecated APIs.
Several SDKs have compiler warnings and/or comments that describe deprecated elements of the API.
The PostmanCollection internal format changed slightly. It will be less convenient to have multiple future
versions of our PostmanCollection loaded at the same time (You'll get a warning about duplicate IDs).
ActionScriptSDK specific changes
ActionScriptSDK
Updated Adobe AirSdk in the example project from version 18 to 22.
160815
Date: 2016-08-14
Unreal upgrade warning
Required syntax changes for upgrading Unreal 4.12 Best described by ZKShao in the pull request which helped
resolve the problems: https://github.com/PlayFab/UnrealCppSdk/pull/32
API changes
Minor documentation updates.
New PlayStream events:
player_statistic_deleted
player_unlinked_account
UnrealCppSdk & UnrealBlueprintSdk specific changes: (UPDATED : These SDKs have been deprecated.
For the new unreal SDK, please refer to UnrealMarketplaceSDK)
Updated to support Unreal 4.12
Sadly, this requires dropping support for Unreal 4.11.x, due to conflicting requirements
Support for Unreal 4.9 is maintained
UnitySDK specific changes
UnitySDK
Pre-Alpha release of a live-connection: Subscribe your custom game servers to live PlayStream events
using SignalR
Game-servers can begin testing with registering callbacks to PlayStream events, and react in real-time
PlayFabSDK no longer requires permissions on Android. (WP8 and iOS still requires internet in build
settings)
Phasing in deprecation warnings for APIs are out of date.
These will later become deprecation errors, and will eventually be removed from the sdk.
Some bug fixes for compression
PlayFabSdk now works in Unity 5.0
Fixed specific devices on specific older unity versions, and expanded internal testing
Updated UUnit test framework to display correctly when an async test times out
Our asset bundles are built with Unity 5.4
160801
Date: 2016-07-31
API changes
New APIs
RemoveVirtualCurrencyTypes
GetAllSegments
GetPlayerSegments
GetPlayersInSegment
GetPlayerCombinedInfo
GetAllSegments
GetPlayerSegments
GetPlayersInSegment
New PlayStream Events
session_started
session_ended
Minor documentation updates.
160726
Date: 2016-07-25
UnitySDK hotfix changes
UnitySDK
Fixes for specific Devices on older Unity versions.
Fix for specific AdminApi model classes which were being labeled as PlayFabResultCommon instead of
PlayFabRequestCommon .
Known Issue: When using PlayFab UnitySdk, Google advertisingID and iOS IDFA no longer attribute
correctly for Unity versions before 5.3.
The easiest fix is to upgrade your Unity3D version, but we will try to restore this in a later release of
our SDK.
160725
Date: 2016-07-24
API changes
New PlayStream Event
display_name_filtered (documentation available soon).
Some API examples have been updated.
Lots of minor documentation updates.
UnitySDK specific changes
UnitySDK
Introduced a PlayFabRequestCommon base-class , which does compile-time type-checking for
request objects passed to the API (This should not affect any users unless they're using non-
standard request objects).
Fixed a null-reference bug in startup that some users have reported.
Fixed an issue with ProductionEnvironmentUrl in the PlayFabSharedSettings ScriptableObject that
some users have reported.
160721
Date: 2016-07-20
UnitySDK hotfix changes
UnitySDK
Unity 4.7 works again, within the limitations of that version
A bunch of small high-visibility fixes that have been noticed by many in the community have been
fixed.
UnitySDK V2 was promised to have full Windows Phone/Universal support (as well as other
platforms like consoles). We're happy to say that all known issues have finally been fixed for all
known platforms, and the PlayFab UnitySdk should work everywhere.
Due to an unexpected side-effect in Unity, we won't be able to apply the HideAndDontSave flag to
the PlayFab Http Object. Details Here.
We have added a set of extension functions to reflection, which make both standard C# and
.NetCore C# do the same thing with the same lines of code, when possible. This extension it is not
meant to be a complete solution for all possible reflection inconsistencies between those
platforms.
160714
Date: 2016-07-13
UnitySDK upgrade warning
UnitySDK
We have released a new major revision for UnitySDK. Please visit our Upgrade Guide (UPDATE : The
UPGRADE Guide is obsolete).
API changes
You can now set CustomData on an item when granting it via the Admin Api: GrantItemsToUsers,
specifically: ItemGrant.
Twitch login integration! and APIs:
LoginWithTwitch
LinkTwitch
UnlinkTwitch
GetPlayFabIDsFromTwitchIDs
New PlayStream Events:
title_exceeded_limit
title_limit_changed
title_requested_limit_change
LumberyardSDK specific changes
Updated to Lumberyard 1.3
UnitySDK specific changes
UnitySDK
A new major revision of UnitySdk is going to be released very soon (hopefully today).
The original UnitySdk will be available here for a limited time [UPDATE: Old link removed].
Version 2 of the UnitySdk is currently available here: UnitySDKV2Beta [UPDATE: Old link removed],
and will become the new UnitySdk soon [UPDATE: Done].
160705
Date: 2016-07-04
API changes
New API
GetPlayerCombinedInfo
Lots of updated descriptions.
All login calls have been updated to optionally return the GetPlayerCombinedInfo results.
GetUserCombinedInfo API will be deprecated in favor of GetPlayerCombinedInfo in the near future.
A JsonProperty attribute has been added to SimpleJson and supports alternate naming of
fields/properties, and omitting nulls from the serialized json.
TimeSpans serialized with the default PlayFab SimpleJson strategy will now serialize as a float number of
seconds. Formerly, they would serialize as structs which wasn't supported by the API or any cross-
platform options.
Support for certain platforms (EG: consoles, iOS) that build using Mono2x mode will not be supported
until https://github.com/PlayFab/UnitySDKV2Beta goes live.
Support for Windows Universal will not be supported until https://github.com/PlayFab/UnitySDKV2Beta
goes live.
See this blog post for more details: https://playfab.com/new-and-improved-unity-sdk-beta-preview/
(standalone and android work correctly and are supported for all options)
All platforms that can utilize IL2CPP are supported in that mode.
This version was initially launched with an issue where compression did not always work. It was hot-fixed
on July-8. Initial downloads before this date may have compression issues, which can be solved by
updating, or by disabling compression: (PlayFabSettings.CompressApiData = false;)
160627
Date: 2016-06-26
UnitySDK upgrade warning
UnitySDK
has been renamed to PlayFab.Internal.PlayFabUtil . The "Util" name is
PlayFab.Internal.Util
very common and exists in the root level for many projects, which causes name conflicts for those
customers.
When updating PlayFab-UnitySdk, you may see some deprecation warnings if you are using
PlayFab's implementation of SimpleJson. Please resolve these at your leisure.
API changes
New Admin APIs
GetTitleInternalData
SetTitleInternalData
New PlayStream events
character_consumed_item
character_created
character_inventory_item_added
character_statistic_changed
character_vc_item_purchased
character_virtual_currency_balance_changed
player_redeemed_coupon
UnitySDK specific changes
UnitySDK
Known issues: Windows Store apps, and non-IL2CPP build options do not work yet. Stay tuned for a
blog post about these issues and our new repository: UnitySDKV2Beta [UPDATE: Old link removed].
We discovered a name-conflict with the core UnityEngine DLL, specifically an empty namespace
called SimpleJson . As such, we've had to rename and reorganize our JSON classes... again. Many
apologies.
160613
Date: 2016-06-12
Global SDK upgrade warning
PlayFabSettings and PlayFabVersion: These files and their contents have been merged into PlayFabSettings.
If you were previously referencing the PlayFabVersion variables, update to the same/very-similar variable in
PlayFabSettings.
API changes
New API
SetGameServerInstanceData
Bug fix for APIs:
Server/SetGameServerInstanceState
Client/GetCurrentGames
SDK global changes
Please note that RunCloudScript has been deprecated since March 2016, and will be removed from the
sdks in the near future. Please convert to ExecuteCloudScript asap.
Please stay tuned for a blog post about an internal testing system we call Jenkernaught. Our example
projects contain some changes oriented towards deeper testing to improve sdk stability and reliability.
Some specifics:
All testing and examples for CloudScript have been updated to ExecuteCloudScript, since RunCloudScript
is deprecated.
All testing and examples for successful login have been updated to LoginWithCustomID , to make internal
testing easier.
Cocos2d-xSDK specific changes
Cocos2d-xSDK
MultitypeVar can contain a PlayFabBaseModel for the purposes of writing request objects. It still
cannot receive an arbitrary json object for results.
Initial versioned release.
UnrealBlueprintSdk specific changes: (UPDATED : This SDK has been deprecated. For the new unreal SDK,
please refer to UnrealMarketplaceSDK)
Removed version info from a bunch of header-comments to avoid spammy check ins (So, this is the last
spammy check in)
A missing http header is now provided.
160606
Date: 2016-06-05
Global SDK upgrade warning
For consistency across all sdks, the sdkRevision variable was renamed to sdkVersion (ActionScriptSDK,
JavaSDK, UnitySdk). If you were accessing sdkRevision , switch to sdkVersion .
API changes
Some documentation updates, and improved error notifications.
SDK global changes
More steps towards the deprecation of RunCloudScript , so customers should plan to migrate to
ExecuteCloudScript for live projects.
Internally, we are halfway through a push to improve testing multi-platform testing for all sdks.
SDKGenerator users may find references to Jenkernaught and buildIdentifier . Jenkernaught is the
code-name for the tech that enables this improved platform testing. buildIdentifier is a new variable in
all sdks indicating the specific PlayFab-Jenkins job which generated a particular sdk version.
There will be blog-post describing what the Jenkernaught does, and more detailed test-framework
changes omitted from here, so stay tuned.
ActionScriptSDK specific changes
ActionScriptSDK
Jenkernaught -related ASyncUnitTest framework changes in the example/testing project.
160523
Date: 2016-05-22
Global SDK upgrade warning
Various APIs that save versioned data (UserData, CharacterData, and others) have had a datatype change from
int to uint. This will require some users to remove/alter some casting where our api was formerly inconsistent.
Some developers may need to change some local variables from int to uint.
UnrealBlueprintSdk upgrade warning: There was a naming conflict between xcode and some of the playfab
enums. As a result, we've had to revise the blueprint-enums again, which breaks all PlayFab-api-nodes using
enums. The upgrade process in-editor is to delete and re-create each affected blueprint node (they will throw in-
editor-compiler warnings if they're affected). (UPDATED : This SDK has been deprecated. For the new unreal SDK,
please refer to UnrealMarketplaceSDK)
API changes
There were some DataVersion vars which were set to an inconsistent datatype (int and uint in various
APIs). All of these have been changed to uint for consistency.
Some additional options have been added to APIs related to Matchmaking.
The matchmaker now takes an additional parameter ( StartNewIfNoneFound ), which allows titles to
determine whether a new server should spin up if no results are found in the matchmaking process. By
default, StartNewIfNoneFound is true , meaning that a new session will be created if one cannot be found
which matches the requirements. This allows titles with skill-based matchmaking to potentially "loosen"
the requirements for a match, to get players with skill levels at the far ends of the bell curve into games
more quickly.
Updated the custom game server logic with GameInstanceState , which determines whether the game
session is available for matchmaking. Games which are Closed are not available for matchmaking,
allowing developers to create game sessions which are specific to a group of players, as well as to
prevent post-start joins of a game session in progress. By default, game servers start in an Open state.
New API: SetGameServerInstanceState call can be used by the server to set its state, and StartOpen
has been added to the GameModeInfo used in calls to ModifyMatchmakerGameModes , to allow specifying
whether sessions in a game mode start as Open (the default) or Closed .
UnrealBlueprintSdk specific changes: (UPDATED : This SDK has been deprecated. For the new unreal SDK,
please refer to UnrealMarketplaceSDK)
Internal SDK updates that make it easier to execute and handle API calls from C++.
Added an internal testing suite which allows thorough verification of PlayFab functionality on all target
devices. (Example project only, not the core plugin)
A bunch of C++ code cleanup, and improvements on logging and warnings.
Resolved a concurrency problem with multiple synchronous api calls for Blueprints and C++ calls.
160502
Date: 2016-05-01
Global SDK upgrade warning
If you were previously setting the ConfirmationMessage and ForceLink fields, simply remove them.
API changes
New Admin API:
SetStoreSegmentOverrides (UPDATE : This API has been removed)
Some deprecated and internal fields are no longer published with the SDK: ConfirmationMessage and
ForceLink.
UnrealBlueprintSdk specific changes: (UPDATED : This SDK has been deprecated. For the new unreal SDK,
please refer to UnrealMarketplaceSDK)
Revised the readme and the example project to use a simpler login process, and the new simpler
ExecuteCloudScript method.
When there is an api error, the details of that error will report more accurately and display better debug
information.
We are removing the "Beta" flagging from Unreal sdks, they are now a full member of our SDK collection,
with full support and quality checks.
160425
Date: 2016-04-24
UnrealBlueprintSdk Upgrade warning: Many blueprint-api-calls which have enum fields will have to be
updated to utilize the enum dropdown. The old value will be lost, and must be re-set. This affects dozens of
PlayFab blueprint nodes. (UPDATED : This SDK has been deprecated. For the new unreal SDK, please refer to
UnrealMarketplaceSDK)
API changes
Lots of documentation updates.
Fixed typo in AndroidDevicePushNotificationRegistrationRequest .
New server API:
EvaluateRandomResultTable
Cocos2d-xSDK specific changes
Cocos2d-xSDK
Cocos SDK has been overhauled.
New testing framework, internal Http functionality has been converted.
Android, iOS, and Win32 platforms are all working.
Lots of other small fixes and improvements.
UnrealBlueprintSdk specific changes: (UPDATED : This SDK has been deprecated. For the new unreal SDK,
please refer to UnrealMarketplaceSDK)
UnrealBlueprintSdk is nearing the end of its limited-support Beta period. As such, there will be some
potentially breaking changes in the next few releases.
There are data fields in the Api-specification defined as enums. Formerly, UnrealBlueprintSdk displayed these
fields as arbitrary strings, and the user was expected to input the correct option. This has been fixed. All these
fields have been converted to be enum-dropdowns in the blueprints.
160414
Date: 2016-04-13
API changes
PlayStream APIs are now available in the SDKs.
Some documentation revisions.
UnitySDK specific changes
UnitySDK
More automated testing to improve stability of SDKs (and some associated bug fixes)
Specifically, a new PlayStream test and making tests more consistent across all sdks.
160328
Date: 2016-03-27
API changes
Minor incremental improvements to the new Resettable-Leaderboards and other Player-Statistics tweaks.
Minor revisions in the way that CloudScript is uploaded via Admin-API.
Continuing to revise and define API limits and overage definitions where needed.
"PlayFabId" input has been removed from the documentation on a few client APIs, which never used that
value.
Lots of minor documentation updates.
New ExecuteCloudScript API, which replaces the older pattern of GetCloudScriptUrl+RunCloudScript .
This should make it easier for novice users to call CloudScript correctly.
Cocos2d-xSDK specific changes
Cocos2d-xSDK
Project folder structure updated to be consistent across all platforms.
This fixes the issue where iOS build would fail to import some code files.
Cocos is now tested and working for Win32 and iOS.
UnitySDK specific changes
UnitySDK
Fixing inconsistent #define options which led to errors with ReadAllText function.
Known Issue (not resolved): SimpleJson does not serialize correctly when using the Player Setting
Scripting Back end option: Mono2x . Until this is fixed, please use IL2CPP if possible.
(A similar issue may be present when building for PlayStation®.)
160307
Date: 2016-03-06
API changes
Added Server.GetPlayFabIDsFromSteamIDs .
Fixed a minor bug in Server.GetPlayerStatistics .
UnitySDK specific changes
UnitySDK
Minor SDK refactoring for building to multiple targets.
WindowsSDK & Cocos2d-xSDK specific changes
WindowsSDK & Cocos2d-xSDK
Minor SDK refactoring for building to multiple targets.
Renamed several types to be more consistent with other SDKs.
SDK additions
Amazon's LumberyardSdk now available!
160222
Date: 2016-02-21
API changes
Added Server.GetPlayFabIDsFromSteamIDs .
Fixed a minor bug in Server.GetPlayerStatistics .
Fixed a minor bug in Server.UpdatePlayerStatistics .
CSharpSDK specific changes
CSharpSDK
Updated Helper Function Signatures in the testing harness.
Updated Server CloudScript Helper classes.
UnitySDK specific changes
UnitySDK
Updated Helper Function Signatures in the testing harness.
Added structural changes to switch our internal JSON serializer from JSON.net to SimpleJson (This is
an effort to enable Universal Windows Builds).
160215
Date: 2016-02-14
API changes
Resettable Leaderboards and Player Statistics are now live.
GetPlayFabIDsFromSteamIDs accepts and returns string IDs for languages that cannot handle ulong values.
Minor changes to support Parse migrations.
Minor documentation adjustments.
160208
Date: 2016-02-07
API changes
SteamID types updated from Uint32 to Uint64 .
Added APIs
server.UnlockContainerInstance
server.UnlockContainerItem
server.UnlockContainerItem
server.UnlockContainerInstance
Added admin.StatisticResetIntervalOption for use in resetable leaderboards.
UnitySdk specific changes
UnitySdk
Modified the project folder structure a bit, which may cause some file conflicts. Please see this forum
post for details.
160201
Date: 2016-01-31
API changes
New APIs
server.ConsumeItem
SteamID types updated from Uint64 to Uint32 .
GetContentListResult ItemCounts updated from Int64 to Int32 .
UnitySDK specific changes
UnitySDK
Added a new event callback system for monitoring PlayFab API requests and responses.
160125
Date: 2016-01-24
API changes
New APIs
Client.GetPlayFabIDsFromKongregateIDs
Client.GetCharacterStatistics
Client.UpdateCharacterStatistics
Server.RevokeInventoryItem
Fixed typo in PurchaseItem___ -> PurchaseItem___ .
Updated UserAccountInfo to contain additional account details.
UnrealBlueprintSdk specific changes: (UPDATED : This SDK has been deprecated. For the new unreal SDK,
please refer to UnrealMarketplaceSDK)
Fixed a Client issue that prevented subsequent calls after login from working.
160118
Date: 2016-01-17
API changes
New leaderboard apis are available:
GetLeaderboardAroundPlayer
GetFriendLeaderboardAroundPlayer
Old leaderboard apis are deprecated:
GetFriendLeaderboardAroundCurrentUser
GetLeaderboardAroundCurrentUser
Lots of minor documentation improvements.
ActionScriptSDK specific changes
ActionScriptSDK
Fixed an issue where errorDetails where not accessible in error-callbacks.
JavaSDK specific changes
JavaSDK
AndroidStudioExample : The Android advertisingId is automatically fetched and sent to PlayFab when
appropriate (and only when appropriate).
UnitySDK specific changes
UnitySDK
Deleted some internal testing systems (DemoScene folder) from the public SDK.
We are prototyping new samples and event systems. Some of the underlying SDK changes are visible
in the diff, but none of it is accessible yet. Stay tuned as it's almost done.
An alternate version of the unit-tests are available on the client, with client-only api calls.
Cocos2d-xSDK & WindowsSDK/C++ specific changes
Cocos2d-xSDK & WindowsSDK/C++
Updated both to use RapidJson 1.0.2 (C++ syntax and code where relevant)
Some other fixes, including IOS
courtesy of https://mingle-games.com/
PlayFab Release Notes 2015
5/24/2022 • 8 minutes to read • Edit Online
151221
Date: 2015-12-20
JavaSDK specific changes
JavaSDK
Google advertisingId is now automatically fetched appropriately when required.
NodeSDK specific changes
NodeSDK
0.7.151210 release has been hot-fixed with a minor bug fix.
151210
Date: 2015-12-08
API changes
Revamped APIs for PlayerStatistic .
Xbox authentication.
PS4 authentication.
Minor documentation improvements.
SDKGenerator revamped, code cleanup in generator and all SDKs, better client/server SDK-separation.
New automated tests in all SDKs for upcoming features.
WindowsSDK/C++/Cocos2d-xSDK specific changes
WindowsSDK/C++/Cocos2d-xSDK
The structure of the SDK has changed. Users that update from an older version will need to do a bit
more work than usual.
UnitySDK specific changes
UnitySDK
Google adver tisingId and iOS IDFA will be automatically fetched appropriately in the next release.
Specific Hotfix (Dec 11, 2015)
UnitySDK
Google adver tisingId and iOS IDFA are now automatically fetched appropriately when required.
151130
Date: 2015-11-29
API changes
LoginWithGameCenter - This was previously published and now being un-hidden.
GetLeaderboardAroundUser - Some issues with returning the correct number of results have been fixed.
GetFriendLeaderboardAroundUser - New API method that acts like GetLeaderboardAroundUser , except restricts
leaderboard results to the current player's friend list.
General Login - New data is being returned for all login results. This is still in prototype, and not fully
functional yet. Stay tuned!
151123
Date: 2015-11-22
API changes
The Steam error message response has been improved.
Updated automated testing systems for SDKs.
Minor documentation updates.
ActionScriptSDK specific changes
ActionScriptSDK
Fixed a minor typo in the test-debug output.
Cocos2d-xSDK specific changes
Cocos2d-xSDK
The example project is being built with a newer version of cocos. 3.7 -> 3.8.1.
JavaSDK specific changes
JavaSDK
Re-arranged the file structure to be more web-standard.
Added a client-only AndroidStudio example project.
Minor changes to confirm this example builds and works.
Some customization to the Client/Server/Combo files to more closely match each purpose, without
extra variables/functions.
General cleanup.
PostmanCollection specific changes
PostmanCollection
Fixing server/admin authentication issues.
UnitySDK specific changes
UnitySDK
Manifest cleanup in Android Plugin.
151116
Date: 2015-11-15
API changes
Documentation updates.
The format for the version numbering has slightly changed.
PostmanCollection specific changes
PostmanCollection
Initial release of Postman Versioned Collection.
151109
Date: 2015-11-08
API changes
Some data usage caps are enforced better, and reported better when broken.
Minor documentation changes.
New API-RedeemCouponRequest:
RedeemCoupon API Documentation
Fix issue with Steam item ID's needing to be numeric strings.
Improved error reporting for OpenGraph products.
Added third party request utilities to track error rates and response times from third party APIs such as
Google Play and Facebook.
WindowsSDK specific changes
UserData , CharacterData , ItemCustomData , SharedGroupData , as well as Read-Only and Server-Only variants,
can now be deleted by using the KeysToRemove field in the Data-Update Request objects.
151026
Date: 2015-10-25
API changes
Lots of improvements behind the scenes, but none are public-facing.
API_Specs contains much more information that can be used to generate more complete documentation
and examples in the future.
Greatly sped up granting of large sets of items.
151019
Date: 2015-10-18
API changes
Several API descriptions have been updated.
Several SeeAlso links have been updated.
The FailedByUber transaction-error has been deprecated, and
The FailedByPlayFab transaction-error replaces it.
Improved studio management in Game Manager.
Added real time metric counters for API call rates, sizes and timing.
UnitySDK specific changes
UnitySDK
Removing support for Unity 4.x. All future updates will only be supported with Unity 5.x or higher:
Unity Blog.
Clean up of files that should no longer exist in the Client-SDK.
Clean up of editor-dropdown options, and fixing the documentation links.
First pass at in-depth PlayFab API usage examples. These are not polished for general release, but
experienced users may be interested in looking at an early version.
Updated Android GCM plugin to improve usability:
Added comments where appropriate.
Renamed variables to better reflect their use.
Functionality:
Fixed an issue that caused a null ref when not properly instantiated.
Fixed an issue that was hiding the public methods when built for the Android target.
151012
Date: 2015-10-11
API changes
Removed ability to delete VC definitions in Game Manager to match APIs.
Added back end code to support atomic increment/decrement.
Changed custom data versions to use new atomic increments.
Fixed issue where user's VC would roll over if passing Int32 max. Now VC is capped to Int32 max.
Added support for case sensitive VC names to prevent rare issue.
151005
Date: 2015-10-04
API changes
Fixed PSN issue not properly using proxies.
Added character inventory management to Game Manager.
150928
Date: 2015-09-27
API changes
Client/Ser ver-API : GetCharacterInventory can return a new error type: CharacterNotFound .
Admin-API : RevokeInventoryItemRequest can operate on a character-inventory by providing a Character ID
in the request.
All : Very minor API documentation updates.
Bypass cache when GetUserData API calls specified filtering keys.
Added optional Character ID to revoke item API calls.
Fixed versioned data calls returning null instead of empty.
Changed APIs to restrict virtual currency names to 2 characters.
ActionScriptSDK specific changes
ActionScriptSDK
Initial release of ActionScript Versioned SDK.
Cocos2d-xSDK specific changes
Cocos2d-xSDK
Added a CloudScript test.
CSharpSDK specific changes
CSharpSDK
Minor updates to unit-testing framework.
Added a CloudScript test.
JavaSDK specific changes
JavaSDK
CloudScript fixes, added a CloudScript JUnit test.
Better error-reporting for bad/failed api calls.
UnitySDK specific changes
UnitySDK
Minor updates to unit-testing framework.
Added a CloudScript test.
Fixes to Android push-notifications.
WindowsSDK/C++ specific changes
Added a CloudScript test.
150921
Date: 2015-09-20
API changes
All-APIs : Minor function-documentation changes.
All-APIs : CatalogItem gains an optional parameter linked to Facebook purchasing.
Client and Ser ver API : VC recharge times are added to GetCharacterInventoryResult .
Client-API : LinkFacebookAccountRequest gains an optional parameter to override old connections.
Client-API : LinkKongregateAccountRequest and LoginWithKongregateRequest parameters are fixed.
Removed [a-zA-Z0-9] regex for character names.
Improved internal error handling to prevent returning unhelpful server errors.
Added tests to verify CDN APIs work as described.
Changed AddFriend API, to prevent you from adding yourself as a friend.
Fixed issue where AddFriend server API always returned an error.
Updated push notification internal code to report better errors from the remote push service.
Fixed error counts in API usage report which would not report some errors on the summary but would show
them in the details.
Added rate limiting to CloudScript and added ability for CloudScript -> PlayFab API calls to bypass rate
limiter
150908
Date: 2015-09-07
API changes
Some APIs returned a UserisNotValid error, this error has been renamed to AccountNotFound .
Better integration for matching PlayFab IDs and Facebook IDs, and matching them to the same account.
Server API's now define the client GetTitleNews API.
Feature not configured errors separated into more specific errors such as Facebook not configured .
Improved errors around Paypal API exceptions.
Fixed issues with coupon creation.
UnitySDK specific changes
UnitySDK
Fixed some IOS build issues.
Slight documentation improvements.
Android GCM fixes/updates.
150901
Date: 2015-08-31
API changes
New Client API :
ListUsersCharacters
ConsumeItemRequest takes an optional CharacterId parameter.
PurchaseItemRequest takes an optional CharacterId parameter.
UnlockContainerItemRequest takes an optional CharacterId parameter.
PurchaseItem can now return a new error type, CharacterNotFound , when a CharacterId is provided.
UnlockContainerItem function documentation updated.
Client and Ser ver : GetCharacterInventoryRequest parameter, PlayFabId , is now optional.
Added tracking of identity provider across login history.
UnitySDK specific changes
UnitySDK
New meta files
Cocos2d-xSDK specific changes
Cocos2d-xSDK
Android project should now compile.
Android project defaults to x86 processor, but can easily be switched to armeabi, or other processors
in Application.mk .
WindowsSDK specific changes
Compression has been disabled as it was having problems.
JavaScriptSDK specific changes
JavaScriptSDK
Overhauled – Not compatible with previous releases, so please beware!
150824
Date: 2015-08-23
API changes
Updated some descriptions for API-documentation.
GetUserInventoryResult contains new optional parameters: PlayFabId , CharacterId .
GetCharacterStatisticsResult contains new optional parameters: PlayFabId , CharacterId .
When calling GetTitleData return, all title data instead of none when no filter keys are provided.
Refactored code around Facebook login and payments to unify API calls to Facebook.
Added GetAllUsersCharacters API.
UnitySDK specific changes
UnitySDK
Error callback contains better information if you attempt to make API calls with no internet access.
WindowsSDK specific changes
Compiling for Android no longer throws errors (but doesn't work yet when executed).
150817 iOS
Date: 2015-08-16
API changes
Fixed issue with CloudScript admin APIs returning inappropriate error codes.
Added support for custom ID authentication.
Fixed server error when granting items that included a drop table that had been deleted before we added
drop table validation.
Internally rebuilt code around iTunes and Google Play receipt validation.
Improved handling of invalid JSON in API requests.
Fixed issue caused by stacking past Int32 max (now stacks are capped at Int32 max).
SDK specific changes
Initial release of versioned SDKs.
150810
Date: 2015-08-09
API changes
Added cross domain settings for APIs.
Added base for new title monitoring services.
Added Kongregate API key to title secret keys editor in Game Manager.
Updated SDK generator to account for interfaces and inheritance.
Fixed JSON upload/download of drop tables in Game Manager.
Added unit test coverage to documentation generator.
Added retry for iTunes receipt validation when a web error has occurred.
Added support for Facebook payments.
Added currency conversion service.
150727
Date: 2015-07-26
API changes
Improved random number generator used to generate IDs.
Added catch for Base64 decoding errors when validation Google Play receipts.
150720
Date: 2015-07-19
API changes
Added PayPal payment provider support for purchases.
Removed CatalogVersion from GetUserInventory API call.
Added Kongragate Authentication APIs.
150713
Date: 2015-07-12
API changes
Added audit log entries for terminating games and lobbies from Game Manager.
Fixed issue where the Store Index would not be updated when a Store was modified.
Added internal utility to migrate a studio across publishers.
Added switch to enable viewing beta features in doc site.
Updated retention report to generate calendar week cohorts.
Added PlayFab IDs to Top Spenders Report instead of just user names.
Fixed Game Manager audit log to show user's display name or email.
Added User Title Data editors to Game Manager.
150706
Date: 2015-07-05
API changes
Fixed errors on APIs that used string arrays, where the client passed in null or empty values for a list of
PlayFab IDs.
150629
Date: 2015-06-28
API changes
Added ability to flag APIs as Beta.
Fixed issue with stacking not always performing properly.
REST API overview
5/24/2022 • 2 minutes to read • Edit Online
Welcome to the PlayFab REST API reference. Here you will find reference material and gain insight into how our
APIs work. Each API reference is broken down into several different sections.
Endpoint
The endpoint is the HTTP URL that you can make API requests against. It is preceded with a REST method type
(eg. GET, POST). In addition, the titleId must be replaced with your game titleId.
Example:
POST https://[titleId].playfabapi.com/Client/LoginWithCustomID
Request Body
The request body is the object model that is sent as (JSON) to our API service. These models will contain
properties that need to be sent along with your API as the payload. Some properties will be flagged as
required , while others are optional .
Responses
The API service will either return a 200 OK with a JSON payload that can be deserialized as a model. In the
below example, Login API calls deserialize into a type of LoginResult.
If the response fails for any reason, a 400 Bad Request is received. This could mean the API service is returning
information about a bad request. Often, this could be missing parameters in your API call or a number of other
reasons. The ApiErrorWrapper object contains valuable information about the error including error codes, error
details and error messages from the server.
Security
Each API has some form of security that needs to be passed in the header of each request. See this section to
know what needs to be defined. Sometimes this is a session ticket from a login request or it could be your title
secret key if you are making server api requests.
Model Definitions
Each response from the API service can contain one or more Models in the response. These are located below
the ApiErrorWrapper and each model is represented in the same document as the API. Each model is also linked
in the response parent model. You can also visit the Definitions section in each API page to see a list of Models
supported by the API.
Event Model Definitions
The PlayStream Event Model reference contains the models of the automatically generated PlayStream event
types. Each event type has a set of properties that are included as part of event's data wherever it is sent.
Real-time notifications for Lobby and Matchmaking
APIs
5/24/2022 • 2 minutes to read • Edit Online
IMPORTANT
This feature is currently in public preview. It is provided to give you an early look at an upcoming feature, and to allow you
to provide feedback while it is still in development.
NOTE
Using Lobby, Matchmaking, and real-time notifications directly with REST and SignalR APIs is significantly more complex
than using client SDKs such as the Lobby C++ SDK and Matchmaking C++ SDK, and should only be done if the SDKs
don't meet your needs.
The Lobby and Matchmaking services offer a real-time notifications feature, which enables individual game
clients to subscribe to receive notifications from these services. Game clients subscribe for notifications over a
persistent SignalR WebSocket connection. To learn more about the scenario as a whole, see the conceptual
documentation for Lobby and Matchmaking real-time notifications.
To use this feature, game clients will first need to implement a SignalR client that connects to the SignalR Hub
for real-time notifications. Once connected, the clients can subscribe to resources they would like to receive
notifications for.
See also
Real-time notifications SignalR Hub
Subscribing to resources
Real-time notifications SignalR Hub
5/24/2022 • 2 minutes to read • Edit Online
IMPORTANT
This feature is currently in public preview. It is provided to give you an early look at an upcoming feature, and to allow you
to provide feedback while it is still in development.
NOTE
Using Lobby, Matchmaking, and real-time notifications directly with REST and SignalR APIs is significantly more complex
than using client SDKs such as the Lobby C++ SDK and Matchmaking C++ SDK, and should only be done if the SDKs
don't meet your needs.
The real-time notifications feature for Lobby and Matchmaking services works through a SignalR service, which
exposes a SignalR Hub. This SignalR Hub can be used by game clients to receive messages about resources they
subscribed to.
NOTE
1. SignalR client implementations expect the URL to omit the /negotiate portion of this path (ex: HubConnection
should created to a URL that ends in ...playfabapi.com/pubsub ).
2. The auth headers required to call this API can be passed to the SignalR client via HttpConnectionOptions as seen on
this method.
3. The only encoding the hub currently supports is JSON encoding.
Subscribing to resources
Once a session has been started with StartOrRecoverSession, you can use the connection handle returned to
start subscribing to resources and receiving messages.
APIs
Client methods
NAME DESC RIP T IO N
Server methods
NAME DESC RIP T IO N
See also
Subscribing to resources
Real-time notifications for Lobby and Matchmaking APIs
Subscribing to resources
5/24/2022 • 2 minutes to read • Edit Online
IMPORTANT
This feature is currently in public preview. It is provided to give you an early look at an upcoming feature, and to allow you
to provide feedback while it is still in development.
NOTE
Using Lobby, Matchmaking, and real-time notifications directly with REST and SignalR APIs is significantly more complex
than using client SDKs such as the Lobby C++ SDK and Matchmaking C++ SDK, and should only be done if the SDKs
don't meet your needs.
After the client connects to the SignalR Hub, and calls StartOrRecoverSession to receive a Connection Handle , it's
ready to subscribe to topics and receive messages. When subscribing to Lobby or Matchmaking resources, the
client will need to provide the Connection Handle that they received when starting the session. For more
information about starting and managing a session, see the SignalR Hub overview.
To manage resource subscriptions with the services that publish notifications, see:
See also
Real-time notifications SignalR Hub
Real-time notifications for Lobby and Matchmaking APIs
ReceiveMessage
5/24/2022 • 2 minutes to read • Edit Online
IMPORTANT
This feature is currently in public preview. It is provided to give you an early look at an upcoming feature, and to allow you
to provide feedback while it is still in development.
NOTE
Using Lobby, Matchmaking, and real-time notifications directly with REST and SignalR APIs is significantly more complex
than using client SDKs such as the Lobby C++ SDK and Matchmaking C++ SDK, and should only be done if the SDKs
don't meet your needs.
ReceiveMessage(Message message)
TIP
This is a SignalR client method. See documentation on exposing client methods in a SignalR client, which will be invoked
by the server.
Parameters
Message
See also
Type Message
Client method ReceiveSubscriptionChangeMessage
Real-time notifications SignalR Hub
Real-time notifications for Lobby and Matchmaking APIs
ReceiveSubscriptionChangeMessage
5/24/2022 • 2 minutes to read • Edit Online
IMPORTANT
This feature is currently in public preview. It is provided to give you an early look at an upcoming feature, and to allow you
to provide feedback while it is still in development.
NOTE
Using Lobby, Matchmaking, and real-time notifications directly with REST and SignalR APIs is significantly more complex
than using client SDKs such as the Lobby C++ SDK and Matchmaking C++ SDK, and should only be done if the SDKs
don't meet your needs.
Receives SubscriptionChangeMessages, so the client will know when its subscription status changes. This
message indicates that a request to subscribe or unsubscribe has finished processing.
ReceiveSubscriptionChangeMessage(SubscriptionChangeMessage subscriptionChangeMessage)
TIP
This is a SignalR client method. See documentation on exposing client methods in a SignalR client, which will be invoked
by the server.
Parameters
SubscriptionChangeMessage
See also
Type SubscriptionChangeMessage
Client method ReceiveMessage
Real-time notifications SignalR Hub
Real-time notifications for Lobby and Matchmaking APIs
AddEntityToSession
5/24/2022 • 2 minutes to read • Edit Online
IMPORTANT
This feature is currently in public preview. It is provided to give you an early look at an upcoming feature, and to allow you
to provide feedback while it is still in development.
NOTE
Using Lobby, Matchmaking, and real-time notifications directly with REST and SignalR APIs is significantly more complex
than using client SDKs such as the Lobby C++ SDK and Matchmaking C++ SDK, and should only be done if the SDKs
don't meet your needs.
For scenarios where multiple entities are signed in to the same device. Add an additional entity to the session,
other than the entity that started the session. This will allow the client to receive messages for multiple local
entities on a shared session.
TIP
This is a SignalR server method. See documentation on calling server methods from a SignalR client.
Parameters
SharedSessionRequest
Return value
SharedSessionResponse
See also
Server method RemoveEntityFromSession.
Real-time notifications SignalR Hub
Real-time notifications for Lobby and Matchmaking APIs
EndSession
5/24/2022 • 2 minutes to read • Edit Online
IMPORTANT
This feature is currently in public preview. It is provided to give you an early look at an upcoming feature, and to allow you
to provide feedback while it is still in development.
NOTE
Using Lobby, Matchmaking, and real-time notifications directly with REST and SignalR APIs is significantly more complex
than using client SDKs such as the Lobby C++ SDK and Matchmaking C++ SDK, and should only be done if the SDKs
don't meet your needs.
TIP
This is a SignalR server method. See documentation on calling server methods from a SignalR client.
Parameters
EndSessionRequest
Return value
EndSessionResponse
See also
Server method StartOrRecoverSession.
Real-time notifications SignalR Hub
Real-time notifications for Lobby and Matchmaking APIs
RemoveEntityFromSession
5/24/2022 • 2 minutes to read • Edit Online
IMPORTANT
This feature is currently in public preview. It is provided to give you an early look at an upcoming feature, and to allow you
to provide feedback while it is still in development.
NOTE
Using Lobby, Matchmaking, and real-time notifications directly with REST and SignalR APIs is significantly more complex
than using client SDKs such as the Lobby C++ SDK and Matchmaking C++ SDK, and should only be done if the SDKs
don't meet your needs.
Remove an additional entity that was added to the session with AddEntityToSession.
TIP
This is a SignalR server method. See documentation on calling server methods from a SignalR client.
Parameters
SharedSessionRequest
Return value
SharedSessionResponse
See also
Server method AddEntityToSession
Real-time notifications SignalR Hub
Real-time notifications for Lobby and Matchmaking APIs
StartOrRecoverSession
5/24/2022 • 2 minutes to read • Edit Online
IMPORTANT
This feature is currently in public preview. It is provided to give you an early look at an upcoming feature, and to allow you
to provide feedback while it is still in development.
NOTE
Using Lobby, Matchmaking, and real-time notifications directly with REST and SignalR APIs is significantly more complex
than using client SDKs such as the Lobby C++ SDK and Matchmaking C++ SDK, and should only be done if the SDKs
don't meet your needs.
Starts a session.
The client must call this method to start the session and obtain the Connection Handle representing it. The client
must store this Connection Handle to later use to create subscriptions for the session.
TIP
This is a SignalR server method. See documentation on calling server methods from a SignalR client.
Parameters
StartOrRecoverSessionRequest
Return value
StartOrRecoverSessionResponse
See also
Server method EndSession
Real-time notifications SignalR Hub
Real-time notifications for Lobby and Matchmaking APIs
EndSessionRequest
5/24/2022 • 2 minutes to read • Edit Online
IMPORTANT
This feature is currently in public preview. It is provided to give you an early look at an upcoming feature, and to allow you
to provide feedback while it is still in development.
NOTE
Using Lobby, Matchmaking, and real-time notifications directly with REST and SignalR APIs is significantly more complex
than using client SDKs such as the Lobby C++ SDK and Matchmaking C++ SDK, and should only be done if the SDKs
don't meet your needs.
{
"traceParent": "00-84678fd69ae13e41fce1333289bcf482-22d157fb94ea4827-01"
}
Members
traceParent string
A valid W3C TraceContext TraceParent Header.
Example: 00-84678fd69ae13e41fce1333289bcf482-22d157fb94ea4827-01
See also
Type EndSessionResponse
Server method EndSession
Real-time notifications SignalR Hub
Real-time notifications for Lobby and Matchmaking APIs
EndSessionResponse
5/24/2022 • 2 minutes to read • Edit Online
IMPORTANT
This feature is currently in public preview. It is provided to give you an early look at an upcoming feature, and to allow you
to provide feedback while it is still in development.
NOTE
Using Lobby, Matchmaking, and real-time notifications directly with REST and SignalR APIs is significantly more complex
than using client SDKs such as the Lobby C++ SDK and Matchmaking C++ SDK, and should only be done if the SDKs
don't meet your needs.
{
"status": "Success",
"traceId": "00-84678fd69ae13e41fce1333289bcf482-22d157fb94ea4827-01"
}
Members
status string
The status of the response. See all possible ResponseStatus values here.
Example: Success
traceId string
A W3C TraceContext trace-id. The client should log this field so it can be included if you need to send a bug
report to the PlayFab team.
Example: 4bf92f3577b34da6a3ce929d0e0e4736
See also
Type EndSessionRequest
Server method EndSession
Real-time notifications SignalR Hub
Real-time notifications for Lobby and Matchmaking APIs
Message
5/24/2022 • 2 minutes to read • Edit Online
IMPORTANT
This feature is currently in public preview. It is provided to give you an early look at an upcoming feature, and to allow you
to provide feedback while it is still in development.
NOTE
Using Lobby, Matchmaking, and real-time notifications directly with REST and SignalR APIs is significantly more complex
than using client SDKs such as the Lobby C++ SDK and Matchmaking C++ SDK, and should only be done if the SDKs
don't meet your needs.
{
"topic": "Opaque~Topic~String~6183258",
"payload":
"eyJsb2JieUlkIjoiODEyNDZmY2ItMWVmNy00ZmU1LTliYzctZTg3MjBiNmFjNWIxIiwibG9iYnlDaGFuZ2VzIjpbeyJjaGFuZ2VOdW1iZXI
iOjEsIm1lbWJlclRvTWVyZ2UiOnsibWVtYmVyRW50aXR5Ijp7IlR5cGUiOiJ0aXRsZV9wbGF5ZXJfYWNjb3VudCIsIklkIjoiOTgxRDU5MTc
wRTI4NEE3MiJ9fX1dfQ==",
"traceId": "4bf92f3577b34da6a3ce929d0e0e4736"
}
Members
topic string
A topic string, matching the topic string returned when subscribing to resources. This field allows the client to
keep track of which messages are for which resources they subscribed to.
Example: Opaque~Topic~String~6183258
payload string
The payload of the message.
Example:
eyJsb2JieUlkIjoiODEyNDZmY2ItMWVmNy00ZmU1LTliYzctZTg3MjBiNmFjNWIxIiwibG9iYnlDaGFuZ2VzIjpbeyJjaGFuZ2VOdW1iZXIiOjEsIm1lbWJlclRvTWVyZ2UiOnsibWVtYmVyRW50aXR5Ijp7IlR5cGUiOiJ0aX
traceId string
A W3C TraceContext trace-id. The client should log this field so it can be included if you need to send a bug
report to the PlayFab team.
Example: 4bf92f3577b34da6a3ce929d0e0e4736
See also
Client method ReceiveMessage
Real-time notifications SignalR Hub
Real-time notifications for Lobby and Matchmaking APIs
Response Status
5/24/2022 • 2 minutes to read • Edit Online
IMPORTANT
This feature is currently in public preview. It is provided to give you an early look at an upcoming feature, and to allow you
to provide feedback while it is still in development.
NOTE
Using Lobby, Matchmaking, and real-time notifications directly with REST and SignalR APIs is significantly more complex
than using client SDKs such as the Lobby C++ SDK and Matchmaking C++ SDK, and should only be done if the SDKs
don't meet your needs.
Possible values for the status member of SignalR server method responses.
Values
VA L UE DESC RIP T IO N
Success
TooManyRequests The individual client or title all-up has exceeded its request
rate limit, and the request was throttled. The request can be
retried a few times with exponential backoff.
See also
Type EndSessionResponse
Type SharedSessionResponse
Type StartOrRecoverSessionResponse
Real-time notifications SignalR Hub
Real-time notifications for Lobby and Matchmaking APIs
SharedSessionRequest
5/24/2022 • 2 minutes to read • Edit Online
IMPORTANT
This feature is currently in public preview. It is provided to give you an early look at an upcoming feature, and to allow you
to provide feedback while it is still in development.
NOTE
Using Lobby, Matchmaking, and real-time notifications directly with REST and SignalR APIs is significantly more complex
than using client SDKs such as the Lobby C++ SDK and Matchmaking C++ SDK, and should only be done if the SDKs
don't meet your needs.
{
"entityType": "title_player_account",
"entityId": "6C6B908A2B5B9A4",
"traceParent": "00-84678fd69ae13e41fce1333289bcf482-22d157fb94ea4827-01"
}
Members
entityType string
The type of the entity to add to the session. Currently we only accept title_player_account .
Example: title_player_account
entityId string
The ID of the entity to add to the session.
Example: 6C6B908A2B5B9A4
traceParent string
A valid W3C TraceContext TraceParent Header.
Example: 00-84678fd69ae13e41fce1333289bcf482-22d157fb94ea4827-01
See also
Type SharedSessionResponse
Server method AddEntityToSession
Server method RemoveEntityFromSession
Real-time notifications SignalR Hub
Real-time notifications for Lobby and Matchmaking APIs
SharedSessionResponse
5/24/2022 • 2 minutes to read • Edit Online
IMPORTANT
This feature is currently in public preview. It is provided to give you an early look at an upcoming feature, and to allow you
to provide feedback while it is still in development.
NOTE
Using Lobby, Matchmaking, and real-time notifications directly with REST and SignalR APIs is significantly more complex
than using client SDKs such as the Lobby C++ SDK and Matchmaking C++ SDK, and should only be done if the SDKs
don't meet your needs.
{
"entityCount": "2",
"status": "Success",
"traceId": "4bf92f3577b34da6a3ce929d0e0e4736"
}
Members
entityCount number optional
The number of entities currently in the shared session. This number can't exceed 8 .
Example: 2
status string
The status of the response. See all possible ResponseStatus values here.
Example: Success
traceId string
A W3C TraceContext trace-id. The client should log this field so it can be included if you need to send a bug
report to the PlayFab team.
Example: 4bf92f3577b34da6a3ce929d0e0e4736
See also
Type SharedSessionRequest
Server method AddEntityToSession
Server method RemoveEntityFromSession
Real-time notifications SignalR Hub
Real-time notifications for Lobby and Matchmaking APIs
StartOrRecoverSessionRequest
5/24/2022 • 2 minutes to read • Edit Online
IMPORTANT
This feature is currently in public preview. It is provided to give you an early look at an upcoming feature, and to allow you
to provide feedback while it is still in development.
NOTE
Using Lobby, Matchmaking, and real-time notifications directly with REST and SignalR APIs is significantly more complex
than using client SDKs such as the Lobby C++ SDK and Matchmaking C++ SDK, and should only be done if the SDKs
don't meet your needs.
{
"oldConnectionHandle": "1.Y2VudHJhbC11c35sb2NhbGhvc3R+QkxVV1pYSEwwZkF0b1o5WUR2MV9vQQ==",
"traceParent": "00-84678fd69ae13e41fce1333289bcf482-22d157fb94ea4827-01"
}
Members
oldConnectionHandle string optional
If recovering a session due to unexpected disconnection, subscriptions can be recovered by providing the
newConnectionHandle from the last session's StartOrRecoverSessionResponse.
Example: 1.Y2VudHJhbC11c35sb2NhbGhvc3R+QkxVV1pYSEwwZkF0b1o5WUR2MV9vQQ==
traceParent string
A valid W3C TraceContext TraceParent Header.
Example: 00-84678fd69ae13e41fce1333289bcf482-22d157fb94ea4827-01
See also
Type StartOrRecoverSessionResponse
Server method StartOrRecoverSession
Real-time notifications SignalR Hub
Real-time notifications for Lobby and Matchmaking APIs
StartOrRecoverSessionResponse
5/24/2022 • 2 minutes to read • Edit Online
IMPORTANT
This feature is currently in public preview. It is provided to give you an early look at an upcoming feature, and to allow you
to provide feedback while it is still in development.
NOTE
Using Lobby, Matchmaking, and real-time notifications directly with REST and SignalR APIs is significantly more complex
than using client SDKs such as the Lobby C++ SDK and Matchmaking C++ SDK, and should only be done if the SDKs
don't meet your needs.
{
"newConnectionHandle": "1.Y2VudHJhbC11c35sb2NhbGhvc3R+QkxVV1pYSEwwZkF0b1o5WUR2MV9vQQ==",
"recoveredTopics": ["Opaque~Topic~String~6183258", "Another~Opaque~Topic~String~843156"],
"status": "Success",
"traceId": "4bf92f3577b34da6a3ce929d0e0e4736"
}
Members
newConnectionHandle string
An opaque string Connection Handle .
The client doesn't need to concern itself with the contents of the connection handle. The client must acquire it
when starting a new session and pass it in requests to subscribe to resources.
If there's an unexpected disconnection with the SignalR server, subscriptions can be recovered on a new
connection by providing it as the oldConnectionHandle when calling StartOrRecoverSessionRequest.
Example: 1.Y2VudHJhbC11c35sb2NhbGhvc3R+QkxVV1pYSEwwZkF0b1o5WUR2MV9vQQ==
status string
The status of the response. See all possible ResponseStatus values here.
Example: Success
traceId string
A W3C TraceContext trace-id. The client should log this field so it can be included if you need to send a bug
report to the PlayFab team.
Example: 4bf92f3577b34da6a3ce929d0e0e4736
See also
Type StartOrRecoverSessionRequest
Server method StartOrRecoverSession
Real-time notifications SignalR Hub
Real-time notifications for Lobby and Matchmaking APIs
SubscriptionChangeMessage
5/24/2022 • 2 minutes to read • Edit Online
IMPORTANT
This feature is currently in public preview. It is provided to give you an early look at an upcoming feature, and to allow you
to provide feedback while it is still in development.
NOTE
Using Lobby, Matchmaking, and real-time notifications directly with REST and SignalR APIs is significantly more complex
than using client SDKs such as the Lobby C++ SDK and Matchmaking C++ SDK, and should only be done if the SDKs
don't meet your needs.
{
"entityType": "title_player_account",
"entityId": "6C6B908A2B5B9A4",
"topic": "Opaque~Topic~String~6183258",
"status": "SubscribeSuccess",
"unsubscribeReason": "ResourceOwningServiceDefinedReason",
"traceId": "4bf92f3577b34da6a3ce929d0e0e4736"
}
Members
entityType string
The type of the entity whose subscription changed. Clients may only care about this field if they added multiple
entities to the same session.
Example: title_player_account
entityId string
The ID of the entity whose subscription changed. Clients may only care about this field if they added multiple
entities to the same session.
Example: 6C6B908A2B5B9A4
topic string
A topic string, matching the topic string returned when subscribing to resources. This field allows the client to
keep track of which messages are for which resources they subscribed to.
Example: Opaque~Topic~String~6183258
status string
The status of the subscription change.
P O SSIB L E VA L UES DESC RIP T IO N
traceId string
A W3C TraceContext trace-id. The client should log this field so it can be included if you need to send a bug
report to the PlayFab team.
Example: 4bf92f3577b34da6a3ce929d0e0e4736
See also
Client method ReceiveSubscriptionChangeMessage
Real-time notifications SignalR Hub
Real-time notifications for Lobby and Matchmaking APIs
Party C/C++ API overview
5/24/2022 • 5 minutes to read • Edit Online
Classes
C L A SS DESC RIP T IO N
PartyManager The primary management class for interacting with the Party
library.
Callbacks
C ALLBAC K DESC RIP T IO N
Structures
ST RUC T URE DESC RIP T IO N
PartyTranslation A translation.
State changes
STAT E C H A N GE DESC RIP T IO N
STAT E C H A N GE DESC RIP T IO N
Enumerations
EN UM ERAT IO N DESC RIP T IO N
PartyTextChatFilterLevel The level of filtering that will apply to incoming text chat
when text moderation is enabled with
PartyLocalChatControl::SetTextChatOptions.
EN UM ERAT IO N DESC RIP T IO N
Syntax
class PartyAudioManipulationSinkStream
Public Methods
NAME DESC RIP T IO N
Requirements
Header : Party.h
See also
Party members
PartyAudioManipulationSinkStream::GetConfiguration
5/24/2022 • 2 minutes to read • Edit Online
Syntax
PartyError GetConfiguration(
PartyAudioManipulationSinkStreamConfiguration* configuration
)
Parameters
configuration PartyAudioManipulationSinkStreamConfiguration*
output
The stream configuration.
Return value
PartyError
c_partyErrorSuccess if the call succeeded or an error code otherwise. The human-readable form of the error
code can be retrieved via PartyManager::GetErrorMessage().
Remarks
The stream configuration matches the configuration provided to the configuration method used to create this
stream.
Requirements
Header : Party.h
See also
PartyAudioManipulationSinkStream
PartyLocalChatControl::ConfigureAudioManipulationCaptureStream
PartyLocalChatControl::ConfigureAudioManipulationRenderStream
PartyAudioManipulationSinkStream::GetFormat
5/24/2022 • 2 minutes to read • Edit Online
Syntax
PartyError GetFormat(
PartyAudioFormat* format
)
Parameters
format PartyAudioFormat*
output
The format of the buffers that will be submitted to PartyAudioManipulationSinkStream::SubmitBuffer().
Return value
PartyError
c_partyErrorSuccess if the call succeeded or an error code otherwise. The human-readable form of the error
code can be retrieved via PartyManager::GetErrorMessage().
Remarks
If a format is specified in the configuration provided by PartyAudioManipulationSinkStream::GetConfiguration(),
this format will match. Otherwise, this format will be the most efficient format automatically selected by the
library.
Requirements
Header : Party.h
See also
PartyAudioManipulationSinkStream
PartyLocalChatControl::ConfigureAudioManipulationCaptureStream
PartyLocalChatControl::ConfigureAudioManipulationRenderStream
PartyAudioManipulationSinkStream::SubmitBuffer
PartyAudioManipulationSinkStream::GetConfiguration
PartyAudioManipulationSinkStream::SubmitBuffer
5/24/2022 • 2 minutes to read • Edit Online
Submits audio to be processed by this sink. Depending on the type of sink, this audio may be transmitted to
other chat controls or rendered to the audio output.
Syntax
PartyError SubmitBuffer(
const PartyDataBuffer* buffer
)
Parameters
buffer PartyDataBuffer*
The audio buffer. Typically this audio buffer is generated by retrieving the next buffer available from each
incoming source stream, and then processing and mixing each buffer based on game logic. This buffer must
have the format format specified by PartyAudioManipulationSinkStream::GetFormat().
Return value
PartyError
c_partyErrorSuccess if the call succeeded or an error code otherwise. The human-readable form of the error
code can be retrieved via PartyManager::GetErrorMessage().
Remarks
Every 40ms, the next 40 ms of audio from this stream will be processed. To prevent audio hiccups, buffers for
audio that should be heard continuously should be submitted to this stream at a constant rate.
When applying chat permissions and determining which chat controls should receive audio, audio submitted to
a capture sink via this method is treated as microphone audio.
Requirements
Header : Party.h
See also
PartyAudioManipulationSinkStream
PartyChatPermissionOptions
PartyAudioManipulationSinkStream::GetCustomContext
5/24/2022 • 2 minutes to read • Edit Online
Retrieves the app's private, custom pointer-sized context value previously associated with this stream object.
Syntax
PartyError GetCustomContext(
void** customContext
)
Parameters
customContext void**
output, may return nullptr
The output custom context.
Return value
PartyError
c_partyErrorSuccess if the call succeeded or an error code otherwise. The human-readable form of the error
code can be retrieved via PartyManager::GetErrorMessage().
Remarks
If no custom context has been set yet, the value pointed to by customContext is set to nullptr.
Requirements
Header : Party.h
See also
PartyAudioManipulationSinkStream
PartyAudioManipulationSinkStream::SetCustomContext
PartyAudioManipulationSinkStream::SetCustomContext
5/24/2022 • 2 minutes to read • Edit Online
Configures an optional, custom pointer-sized context value with this stream object.
Syntax
PartyError SetCustomContext(
void* customContext
)
Parameters
customContext void*
optional
An arbitrary, pointer-sized value to store with the network object.
Return value
PartyError
c_partyErrorSuccess if the call succeeded or an error code otherwise. The human-readable form of the error
code can be retrieved via PartyManager::GetErrorMessage().
Remarks
The custom context is typically used as a "shortcut" that simplifies accessing local, title-specific memory
associated with the network without requiring a mapping lookup. The value is retrieved using the
GetCustomContext() method.
Any configured value is treated as opaque by the library, and is only valid on the local device; it is not
transmitted over the network.
Requirements
Header : Party.h
See also
PartyAudioManipulationSinkStream
PartyAudioManipulationSinkStream::GetCustomContext
PartyAudioManipulationSourceStream
5/24/2022 • 2 minutes to read • Edit Online
The management class for obtaining audio from an audio source stream.
Syntax
class PartyAudioManipulationSourceStream
Public Methods
NAME DESC RIP T IO N
ReturnBuffer Tells the library it can reclaim memory associated with this
buffer.
Requirements
Header : Party.h
See also
Party members
PartyAudioManipulationSourceStream::GetConfiguration
5/24/2022 • 2 minutes to read • Edit Online
Syntax
PartyError GetConfiguration(
PartyAudioManipulationSourceStreamConfiguration* configuration
)
Parameters
configuration PartyAudioManipulationSourceStreamConfiguration*
output
The stream configuration.
Return value
PartyError
c_partyErrorSuccess if the call succeeded or an error code otherwise. The human-readable form of the error
code can be retrieved via PartyManager::GetErrorMessage().
Remarks
The stream configuration matches the configuration provided to the call to
PartyChatControl::ConfigureAudioManipulationVoiceStream() used to create this stream.
Requirements
Header : Party.h
See also
PartyAudioManipulationSourceStream
PartyChatControl::ConfigureAudioManipulationVoiceStream
PartyAudioManipulationSourceStream::GetFormat
5/24/2022 • 2 minutes to read • Edit Online
Syntax
PartyError GetFormat(
PartyAudioFormat* format
)
Parameters
format PartyAudioFormat*
output
The format of the buffers that will be provided by PartyAudioManipulationSourceStream::GetNextBuffer().
Return value
PartyError
c_partyErrorSuccess if the call succeeded or an error code otherwise. The human-readable form of the error
code can be retrieved via PartyManager::GetErrorMessage().
Remarks
If a format is specified in the configuration provided by
PartyAudioManipulationSourceStream::GetConfiguration(), this format will match. Otherwise, this format will be
the most efficient format automatically selected by the library.
Requirements
Header : Party.h
See also
PartyAudioManipulationSourceStream
PartyChatControl::ConfigureAudioManipulationVoiceStream
PartyAudioManipulationSourceStream::GetNextBuffer
PartyAudioManipulationSourceStream::GetConfiguration
PartyAudioManipulationSourceStream::GetAvailableBufferCount
5/24/2022 • 2 minutes to read • Edit Online
Retrieves the total number of buffers available to retrieve from this stream via
PartyAudioManipulationSourceStream::GetNextBuffer().
Syntax
PartyError GetAvailableBufferCount(
uint32_t* count
)
Parameters
count uint32_t*
output
The output count of available buffers.
Return value
PartyError
c_partyErrorSuccess if the call succeeded or an error code otherwise. The human-readable form of the error
code can be retrieved via PartyManager::GetErrorMessage().
Remarks
This can be useful if the caller prefers to send audio through their pipeline in batches of buffers. Because this
buffer count is limited by the max audio queue size specified via
PartyChatControl::ConfigureAudioManipulationVoiceStream(), callers should give their audio processing
pipeline ample time to process the buffers and return them to
PartyAudioManipulationSourceStream::ReturnBuffer() to prevent dropped audio.
Requirements
Header : Party.h
See also
PartyAudioManipulationSourceStream
PartyAudioManipulationSourceStream::GetNextBuffer
5/24/2022 • 2 minutes to read • Edit Online
Syntax
PartyError GetNextBuffer(
PartyMutableDataBuffer* buffer
)
Parameters
buffer PartyMutableDataBuffer*
output
The output buffer. If no buffer is available, the PartyMutableDataBuffer's bufferByteCount field will be 0 and its
buffer field will be nullptr.
Return value
PartyError
c_partyErrorSuccess if the call succeeded or an error code otherwise. The human-readable form of the error
code can be retrieved via PartyManager::GetErrorMessage().
Remarks
When voice activity is detected, a new buffer will be available every 40 ms. Otherwise, no buffers will be
available. Buffers retrieved by this method must be returned to the library via
PartyAudioManipulationSourceStream::ReturnBuffer() when they are done being used.
A mutable data buffer is provided so that the app can optionally modify the audio in place.
Requirements
Header : Party.h
See also
PartyAudioManipulationSourceStream
PartyAudioManipulationSourceStream::GetFormat
PartyAudioManipulationSourceStream::ReturnBuffer
PartyAudioManipulationSourceStream::ReturnBuffer
5/24/2022 • 2 minutes to read • Edit Online
Tells the library it can reclaim memory associated with this buffer.
Syntax
PartyError ReturnBuffer(
void* buffer
)
Parameters
buffer void*
input not valid afterwards
The buffer to return, which is the buffer field of a PartyDataBuffer previously retrieved from this source stream
PartyAudioManipulationSourceStream::GetNextBuffer().
Return value
PartyError
c_partyErrorSuccess if the call succeeded or an error code otherwise. The human-readable form of the error
code can be retrieved via PartyManager::GetErrorMessage().
Requirements
Header : Party.h
See also
PartyAudioManipulationSourceStream
PartyAudioManipulationSourceStream::GetNextBuffer
PartyAudioManipulationSourceStream::GetCustomContext
5/24/2022 • 2 minutes to read • Edit Online
Retrieves the app's private, custom pointer-sized context value previously associated with this stream object.
Syntax
PartyError GetCustomContext(
void** customContext
)
Parameters
customContext void**
output, may return nullptr
The output custom context.
Return value
PartyError
c_partyErrorSuccess if the call succeeded or an error code otherwise. The human-readable form of the error
code can be retrieved via PartyManager::GetErrorMessage().
Remarks
If no custom context has been set yet, the value pointed to by customContext is set to nullptr.
Requirements
Header : Party.h
See also
PartyAudioManipulationSourceStream
PartyAudioManipulationSourceStream::SetCustomContext
PartyAudioManipulationSourceStream::SetCustomContext
5/24/2022 • 2 minutes to read • Edit Online
Configures an optional, custom pointer-sized context value with this stream object.
Syntax
PartyError SetCustomContext(
void* customContext
)
Parameters
customContext void*
optional
An arbitrary, pointer-sized value to store with the network object.
Return value
PartyError
c_partyErrorSuccess if the call succeeded or an error code otherwise. The human-readable form of the error
code can be retrieved via PartyManager::GetErrorMessage().
Remarks
The custom context is typically used as a "shortcut" that simplifies accessing local, title-specific memory
associated with the network without requiring a mapping lookup. The value is retrieved using the
GetCustomContext() method.
Any configured value is treated as opaque by the library, and is only valid on the local device; it is not
transmitted over the network.
Requirements
Header : Party.h
See also
PartyAudioManipulationSourceStream
PartyAudioManipulationSourceStream::GetCustomContext
PartyChatControl
5/24/2022 • 2 minutes to read • Edit Online
Syntax
class PartyChatControl
Public Methods
NAME DESC RIP T IO N
GetEntityId Gets the PlayFab Entity ID of the user associated with this
chat control.
Requirements
Header : Party.h
See also
Party members
PartyLocalChatControl
PartyChatControl::GetLocal
5/24/2022 • 2 minutes to read • Edit Online
Syntax
PartyError GetLocal(
PartyLocalChatControl** localChatControl
)
Parameters
localChatControl PartyLocalChatControl**
library-allocated output, may return nullptr
The local version of this chat control object, or nullptr if this is not a local chat control.
Return value
PartyError
c_partyErrorSuccess if the call succeeded or an error code otherwise. The human-readable form of the error
code can be retrieved via PartyManager::GetErrorMessage().
Requirements
Header : Party.h
See also
PartyChatControl
PartyChatControl::GetDevice
5/24/2022 • 2 minutes to read • Edit Online
Syntax
PartyError GetDevice(
PartyDevice** device
)
Parameters
device PartyDevice**
library-allocated output
The output device this chat control is associated with.
Return value
PartyError
c_partyErrorSuccess if the call succeeded or an error code otherwise. The human-readable form of the error
code can be retrieved via PartyManager::GetErrorMessage().
Requirements
Header : Party.h
See also
PartyChatControl
PartyChatControl::GetEntityId
5/24/2022 • 2 minutes to read • Edit Online
Gets the PlayFab Entity ID of the user associated with this chat control.
Syntax
PartyError GetEntityId(
PartyString* entityId
)
Parameters
entityId PartyString*
library-allocated output
The output Entity ID.
Return value
PartyError
c_partyErrorSuccess if the call succeeded or an error code otherwise. The human-readable form of the error
code can be retrieved via PartyManager::GetErrorMessage().
Remarks
The memory for the Entity ID string remains valid for the life of the chat control, which is until its
PartyChatControlDestroyedStateChange and/or PartyDestroyChatControlCompletedStateChange, depending on
the type of destruction that occurred, has been provided via PartyManager::StartProcessingStateChanges() and
all state changes referencing the chat control have been returned to
PartyManager::FinishProcessingStateChanges().
Requirements
Header : Party.h
See also
PartyChatControl
PartyChatControl::GetNetworks
5/24/2022 • 2 minutes to read • Edit Online
Syntax
PartyError GetNetworks(
uint32_t* networkCount,
PartyNetworkArray* networks
)
Parameters
networkCount uint32_t*
output
The output number of networks to which this chat control is connected.
networks PartyNetworkArray*
library-allocated output array of size *networkCount
A library-allocated output array containing the networks to which this chat control is connected.
Return value
PartyError
c_partyErrorSuccess if the call succeeded or an error code otherwise. The human-readable form of the error
code can be retrieved via PartyManager::GetErrorMessage().
Remarks
Once a PartyChatControlLeftNetworkStateChange has been provided by
PartyManager::StartProcessingStateChanges(), the network will no longer be present in the array returned by
this method.
The memory for the returned array is invalidated whenever the title calls
PartyManager::StartProcessingStateChanges() or PartyNetwork::ConnectChatControl() returns success.
Requirements
Header : Party.h
See also
PartyChatControl
PartyNetwork::ConnectChatControl
PartyNetwork::DisconnectChatControl
PartyChatControlLeftNetworkStateChange
PartyChatControl::GetCustomContext
5/24/2022 • 2 minutes to read • Edit Online
Retrieves the app's private, custom pointer-sized context value previously associated with this chat control
object.
Syntax
PartyError GetCustomContext(
void** customContext
)
Parameters
customContext void**
output, may return nullptr
The output custom context.
Return value
PartyError
c_partyErrorSuccess if retrieving the custom context succeeded or an error code otherwise. The human-
readable form of the error code can be retrieved via PartyManager::GetErrorMessage().
Remarks
If no custom context has been set yet, the value pointed to by customContext is set to nullptr.
Requirements
Header : Party.h
See also
PartyChatControl
PartyChatControl::SetCustomContext
PartyChatControl::SetCustomContext
5/24/2022 • 2 minutes to read • Edit Online
Configures an optional, custom pointer-sized context value with this chat control object.
Syntax
PartyError SetCustomContext(
void* customContext
)
Parameters
customContext void*
optional
An arbitrary, pointer-sized value to store with the chat control object.
Return value
PartyError
c_partyErrorSuccess if configuring the custom context succeeded or an error code otherwise. The human-
readable form of the error code can be retrieved via PartyManager::GetErrorMessage().
Remarks
The custom context is typically used as a "shortcut" that simplifies accessing local, title-specific memory
associated with the chat control without requiring a mapping lookup. The value is retrieved using the
GetCustomContext() method.
Any configured value is treated as opaque by the library, and is only valid on the local device; it is not
transmitted over the network.
Requirements
Header : Party.h
See also
PartyChatControl
PartyChatControl::GetCustomContext
PartyChatControl::ConfigureAudioManipulationVoiceStream
5/24/2022 • 2 minutes to read • Edit Online
Queues an asynchronous operation to configure the audio manipulation voice stream associated with this chat
control.
Syntax
PartyError ConfigureAudioManipulationVoiceStream(
PartyAudioManipulationSourceStreamConfiguration* configuration,
void* asyncIdentifier
)
Parameters
configuration PartyAudioManipulationSourceStreamConfiguration*
optional
The stream configuration.
asyncIdentifier void*
optional
An optional, app-defined, pointer-sized context value that can be used to associate the completion state change
with this call.
Return value
PartyError
c_partyErrorSuccess if the call succeeded or an error code otherwise. The human-readable form of the error
code can be retrieved via PartyManager::GetErrorMessage().
Remarks
If the configuration is non-null, an audio manipulation voice stream will be created for this chat control. Such a
stream redirects output for the voice audio associated with this chat control; instead of the library automatically
handling the voice audio and routing it, the app can use the source stream to retrieve the voice audio and route
it via game logic. If the configuration is null, and a voice stream has previously been configured, the voice
stream will be destroyed.
Upon completion of the asynchronous operation, when a non-null configuration was specified, a voice stream
for this chat control can be queried via PartyChatControl::GetAudioManipulationVoiceStream(). Completion is
indicated by a PartyConfigureAudioManipulationVoiceStreamCompletedStateChange.
Platform support and supported formats
This function is only supported on Windows and Xbox. Calls on other platforms will fail.
Channel mask 0 0
Channel count 1 1
Requirements
Header : Party.h
See also
PartyChatControl
PartyChatControl::GetAudioManipulationVoiceStream
5/24/2022 • 2 minutes to read • Edit Online
Retrieves the audio manipulation voice stream associated with this chat control.
Syntax
PartyError GetAudioManipulationVoiceStream(
PartyAudioManipulationSourceStream** sourceStream
)
Parameters
sourceStream PartyAudioManipulationSourceStream**
library-allocated output
The source stream.
Return value
PartyError
c_partyErrorSuccess if the call succeeded or an error code otherwise. The human-readable form of the error
code can be retrieved via PartyManager::GetErrorMessage().
Remarks
If this is a local chat control, the stream represents the voice audio detected by the local audio input. Audio
provided by this stream will have already been preprocessed with Voice Activity Detection (VAD) and Automatic
Gain Control (AGC). Audio will only be provided when voice activity is detected. Typically, the app will retrieve
audio from this stream via PartyAudioManipulationSourceStream::GetNextBuffer(), process the audio using app
logic, and then submit the audio back to the library. The audio is submitted back to the library by retrieving the
voice sink stream via PartyLocalChatControl::GetAudioManipulationCaptureStream() and then submitting the
buffer via PartyAudioManipulationSinkStream::SubmitBuffer().
Audio retrieved via this stream will not have been transcribed via speech-to-text for voice chat transcription.
Audio that is submitted to a sink stream via PartyAudioManipulationSinkStream::SubmitBuffer() will be
transcribed, if transcription options configured via PartyLocalChatControl::SetTranscriptionOptions indicates that
audio associated the sink's chat control should be.
If this a remote chat control, the stream represents the chat control's incoming voice audio. Typically, the app will
retrieve audio from the voice streams associated with all remote chat controls via
PartyAudioManipulationSourceStream::GetNextBuffer(), process and mix each buffer into a single audio stream,
and then submit the mixed stream to be rendered by each appropriate sink stream. Each render stream can be
retrieved via PartyLocalChatControl::GetAudioManipulationRenderStream().
Requirements
Header : Party.h
See also
PartyChatControl
PartyDevice
5/24/2022 • 2 minutes to read • Edit Online
Syntax
class PartyDevice
Public Methods
NAME DESC RIP T IO N
Requirements
Header : Party.h
See also
Party members
PartyLocalDevice
PartyDevice::GetLocal
5/24/2022 • 2 minutes to read • Edit Online
Syntax
PartyError GetLocal(
PartyLocalDevice** localDevice
)
Parameters
localDevice PartyLocalDevice**
library-allocated output, may return nullptr
The output local version of this device object, or nullptr if this is not a local device.
Return value
PartyError
c_partyErrorSuccess if the call succeeded or an error code otherwise. The human-readable form of the error
code can be retrieved via PartyManager::GetErrorMessage().
Requirements
Header : Party.h
See also
PartyDevice
PartyDevice::GetChatControls
5/24/2022 • 2 minutes to read • Edit Online
Syntax
PartyError GetChatControls(
uint32_t* chatControlCount,
PartyChatControlArray* chatControls
)
Parameters
chatControlCount uint32_t*
output
The output number of chat controls on this device.
chatControls PartyChatControlArray*
library-allocated output array of size *chatControlCount
A library-allocated output array containing the chat controls on this device.
Return value
PartyError
c_partyErrorSuccess if the call succeeded or an error code otherwise. The human-readable form of the error
code can be retrieved via PartyManager::GetErrorMessage().
Remarks
Once a PartyChatControlDestroyedStateChange has been provided by
PartyManager::StartProcessingStateChanges(), the chat control will no longer be present in the array returned
by this method.
The memory for the returned array is invalidated whenever the title calls
PartyManager::StartProcessingStateChanges(). If this is the local device, the memory for the array is also
invalidated when PartyLocalDevice::CreateChatControl() returns success.
Requirements
Header : Party.h
See also
PartyDevice
PartyLocalDevice::CreateChatControl
PartyLocalDevice::DestroyChatControl
PartyChatControlDestroyedStateChange
PartyDevice::GetCustomContext
5/24/2022 • 2 minutes to read • Edit Online
Retrieves the app's private, custom pointer-sized context value previously associated with this device object.
Syntax
PartyError GetCustomContext(
void** customContext
)
Parameters
customContext void**
output, may return nullptr
The output custom context.
Return value
PartyError
c_partyErrorSuccess if retrieving the custom context succeeded or an error code otherwise. The human-
readable form of the error code can be retrieved via PartyManager::GetErrorMessage().
Remarks
If no custom context has been set yet, the value pointed to by customContext is set to nullptr.
Requirements
Header : Party.h
See also
PartyDevice
PartyDevice::SetCustomContext
PartyDevice::SetCustomContext
5/24/2022 • 2 minutes to read • Edit Online
Configures an optional, custom pointer-sized context value with this device object.
Syntax
PartyError SetCustomContext(
void* customContext
)
Parameters
customContext void*
optional
An arbitrary, pointer-sized value to store with the device object.
Return value
PartyError
c_partyErrorSuccess if configuring the custom context succeeded or an error code otherwise. The human-
readable form of the error code can be retrieved via PartyManager::GetErrorMessage().
Remarks
The custom context is typically used as a "shortcut" that simplifies accessing local, title-specific memory
associated with the device without requiring a mapping lookup. The value is retrieved using the
GetCustomContext() method.
Any configured value is treated as opaque by the library, and is only valid on the local device; it is not
transmitted over the network.
Requirements
Header : Party.h
See also
PartyDevice
PartyDevice::GetCustomContext
PartyEndpoint
5/24/2022 • 2 minutes to read • Edit Online
Syntax
class PartyEndpoint
Public Methods
NAME DESC RIP T IO N
GetEntityId Gets the PlayFab Entity ID of the user associated with this
endpoint.
Requirements
Header : Party.h
See also
Party members
PartyLocalEndpoint
PartyEndpoint::GetLocal
5/24/2022 • 2 minutes to read • Edit Online
Syntax
PartyError GetLocal(
PartyLocalEndpoint** localEndpoint
)
Parameters
localEndpoint PartyLocalEndpoint**
library-allocated output, may return nullptr
The output local version of this endpoint object, or nullptr if this is not a local endpoint.
Return value
PartyError
c_partyErrorSuccess if the call succeeded or an error code otherwise. The human-readable form of the error
code can be retrieved via PartyManager::GetErrorMessage().
Requirements
Header : Party.h
See also
PartyEndpoint
PartyEndpoint::GetEntityId
5/24/2022 • 2 minutes to read • Edit Online
Gets the PlayFab Entity ID of the user associated with this endpoint.
Syntax
PartyError GetEntityId(
PartyString* entityId
)
Parameters
entityId PartyString*
library-allocated output, may return nullptr
The output Entity ID of ther user associated with this endpoint, or nullptr.
Return value
PartyError
c_partyErrorSuccess if the call succeeded or an error code otherwise. The human-readable form of the error
code can be retrieved via PartyManager::GetErrorMessage().
Remarks
If this endpoint is not associated with a user, entityId is set to nullptr.
The memory for the Entity ID string remains valid for the life of the endpoint, which is until its
PartyEndpointDestroyedStateChange and/or PartyDestroyEndpointCompletedStateChange, depending on the
type of destruction that occurred, has been provided via PartyManager::StartProcessingStateChanges() and all
state changes referencing the endpoint have been returned to PartyManager::FinishProcessingStateChanges().
Requirements
Header : Party.h
See also
PartyEndpoint
PartyEndpoint::GetNetwork
5/24/2022 • 2 minutes to read • Edit Online
Syntax
PartyError GetNetwork(
PartyNetwork** network
)
Parameters
network PartyNetwork**
library-allocated output
The output network associated with this endpoint.
Return value
PartyError
c_partyErrorSuccess if the call succeeded or an error code otherwise. The human-readable form of the error
code can be retrieved via PartyManager::GetErrorMessage().
Requirements
Header : Party.h
See also
PartyEndpoint
PartyEndpoint::GetDevice
5/24/2022 • 2 minutes to read • Edit Online
Syntax
PartyError GetDevice(
PartyDevice** device
)
Parameters
device PartyDevice**
library-allocated output
The output device associated with this endpoint.
Return value
PartyError
c_partyErrorSuccess if the call succeeded or an error code otherwise. The human-readable form of the error
code can be retrieved via PartyManager::GetErrorMessage().
Requirements
Header : Party.h
See also
PartyEndpoint
PartyEndpoint::GetUniqueIdentifier
5/24/2022 • 2 minutes to read • Edit Online
Syntax
PartyError GetUniqueIdentifier(
uint16_t* uniqueIdentifier
)
Parameters
uniqueIdentifier uint16_t*
output
The output unique identifier.
Return value
PartyError
c_partyErrorSuccess if the call succeeded or an error code otherwise. The human-readable form of the error
code can be retrieved via PartyManager::GetErrorMessage().
Remarks
This identifier is unique within the endpoint's network and is consistent across all endpoints in a network. It is
intended to be used as a compact option for titles to refer to specific endpoints in
PartyLocalEndpoint::SendMessage() data buffers without much bandwidth overhead or the need to manually
negotiate identifiers. This identifier is not unique across networks.
For local endpoints, this method will fail until the PartyEndpointCreatedStateChange has been provided by
PartyManager::StartProcessingStateChanges(). For remote endpoints, this method will always succeed.
All devices in a network will agree on a given endpoint's unique identifier, but different devices may not see the
same endpoints at a given moment. For example, it's possible for endpoint A to send a message to endpoint B
that references a newly-created endpoint C's unique identifier, but that message between A and B may arrive
before the PartyEndpointCreatedStateChange for endpoint C is generated on endpoint B's device.
Requirements
Header : Party.h
See also
PartyEndpoint
PartyEndpointCreatedStateChange
PartyNetwork::FindEndpointByUniqueIdentifier
PartyEndpoint::GetCustomContext
5/24/2022 • 2 minutes to read • Edit Online
Retrieves the app's private, custom pointer-sized context value previously associated with this endpoint object.
Syntax
PartyError GetCustomContext(
void** customContext
)
Parameters
customContext void**
output, may return nullptr
The output custom context.
Return value
PartyError
c_partyErrorSuccess if retrieving the custom context succeeded or an error code otherwise. The human-
readable form of the error code can be retrieved via PartyManager::GetErrorMessage().
Remarks
If no custom context has been set yet, the value pointed to by customContext is set to nullptr.
Requirements
Header : Party.h
See also
PartyEndpoint
PartyEndpoint::SetCustomContext
PartyEndpoint::SetCustomContext
5/24/2022 • 2 minutes to read • Edit Online
Configures an optional, custom pointer-sized context value with this endpoint object.
Syntax
PartyError SetCustomContext(
void* customContext
)
Parameters
customContext void*
optional
An arbitrary, pointer-sized value to store with the endpoint object.
Return value
PartyError
c_partyErrorSuccess if configuring the custom context succeeded or an error code otherwise. The human-
readable form of the error code can be retrieved via PartyManager::GetErrorMessage().
Remarks
The custom context is typically used as a "shortcut" that simplifies accessing local, title-specific memory
associated with the endpoint without requiring a mapping lookup. The value is retrieved using the
GetCustomContext() method.
Any configured value is treated as opaque by the library, and is only valid on the local device; it is not
transmitted over the network.
Requirements
Header : Party.h
See also
PartyEndpoint
PartyEndpoint::GetCustomContext
PartyInvitation
5/24/2022 • 2 minutes to read • Edit Online
Syntax
class PartyInvitation
Public Methods
NAME DESC RIP T IO N
GetCreatorEntityId Gets the PlayFab Entity ID of the user that created this
invitation or nullptr if this invitation was generated as part of
a PartyManager::CreateNewNetwork() operation.
Requirements
Header : Party.h
See also
Party members
PartyManager::CreateNewNetwork
PartyNetwork::CreateInvitation
PartyNetwork::AuthenticateLocalUser
PartyInvitationConfiguration
PartyInvitation::GetCreatorEntityId
5/24/2022 • 2 minutes to read • Edit Online
Gets the PlayFab Entity ID of the user that created this invitation or nullptr if this invitation was generated as part
of a PartyManager::CreateNewNetwork() operation.
Syntax
PartyError GetCreatorEntityId(
PartyString* entityId
)
Parameters
entityId PartyString*
library-allocated output, may return nullptr
The output Entity ID of the user that created this invitation, or nullptr.
Return value
PartyError
c_partyErrorSuccess if the call succeeded or an error code otherwise. The human-readable form of the error
code can be retrieved via PartyManager::GetErrorMessage().
Requirements
Header : Party.h
See also
PartyInvitation
PartyInvitation::GetInvitationConfiguration
5/24/2022 • 2 minutes to read • Edit Online
Syntax
PartyError GetInvitationConfiguration(
const PartyInvitationConfiguration** configuration
)
Parameters
configuration PartyInvitationConfiguration**
library-allocated output
The output configuration of this invitation.
Return value
PartyError
c_partyErrorSuccess if the call succeeded or an error code otherwise. The human-readable form of the error
code can be retrieved via PartyManager::GetErrorMessage().
Remarks
The memory for the PartyInvitationConfiguration and all memory it references are valid for the lifetime of the
invitation object.
Requirements
Header : Party.h
See also
PartyInvitation
PartyInvitationConfiguration
PartyInvitation::GetCustomContext
5/24/2022 • 2 minutes to read • Edit Online
Retrieves the app's private, custom pointer-sized context value previously associated with this invitation object.
Syntax
PartyError GetCustomContext(
void** customContext
)
Parameters
customContext void**
output, may return nullptr
The output custom context.
Return value
PartyError
c_partyErrorSuccess if retrieving the custom context succeeded or an error code otherwise. The human-
readable form of the error code can be retrieved via PartyManager::GetErrorMessage().
Remarks
If no custom context has been set yet, the value pointed to by customContext is set to nullptr.
Requirements
Header : Party.h
See also
PartyInvitation
PartyInvitation::SetCustomContext
PartyInvitation::SetCustomContext
5/24/2022 • 2 minutes to read • Edit Online
Configures an optional, custom pointer-sized context value with this invitation object.
Syntax
PartyError SetCustomContext(
void* customContext
)
Parameters
customContext void*
optional
An arbitrary, pointer-sized value to store with the invitation object.
Return value
PartyError
c_partyErrorSuccess if configuring the custom context succeeded or an error code otherwise. The human-
readable form of the error code can be retrieved via PartyManager::GetErrorMessage().
Remarks
The custom context is typically used as a "shortcut" that simplifies accessing local, title-specific memory
associated with the invitation without requiring a mapping lookup. The value is retrieved using the
GetCustomContext() method.
Any configured value is treated as opaque by the library, and is only valid on the local device; it is not
transmitted over the network.
Requirements
Header : Party.h
See also
PartyInvitation
PartyInvitation::GetCustomContext
PartyLocalChatControl
5/24/2022 • 2 minutes to read • Edit Online
The management class for chat operations related to the local device.
Syntax
class PartyLocalChatControl : public PartyChatControl
Public Methods
NAME DESC RIP T IO N
GetLocalUser Gets the local user associated with this local chat control.
SetPermissions Sets the chat permissions between the local chat control and
a target chat control.
GetAvailableTextToSpeechProfiles Gets the text to speech profiles for this chat control.
GetTextToSpeechProfile Gets the profile that was last configured from a successfully
completed SetTextToSpeechProfile() operation for a specified
type of text-to-speech operation.
NAME DESC RIP T IO N
SetTextChatOptions Configures the text chat options associated with text chat for
this chat control.
GetTextChatOptions Provides the text chat options associated with text chat for
this chat control.
GetAudioRenderVolume Provides the volume setting for audio received from a target
chat control that will be used for the local chat control.
GetAudioInputMuted Provides whether the user's audio input is in the mute state.
SetIncomingAudioMuted Configures whether the incoming audio from the target chat
control, in relation to the local chat control, is muted.
GetIncomingAudioMuted Provides whether the incoming audio from the target chat
control, in relation to the local chat control, has previously
been muted.
Requirements
Header : Party.h
See also
Party members
PartyChatControl
PartyChatControl::GetLocal
PartyLocalChatControl::GetLocalUser
5/24/2022 • 2 minutes to read • Edit Online
Gets the local user associated with this local chat control.
Syntax
PartyError GetLocalUser(
PartyLocalUser** localUser
)
Parameters
localUser PartyLocalUser**
library-allocated output
The output local user.
Return value
PartyError
c_partyErrorSuccess if the call succeeded or an error code otherwise. The human-readable form of the error
code can be retrieved via PartyManager::GetErrorMessage().
Requirements
Header : Party.h
See also
PartyLocalChatControl
PartyLocalChatControl::SetPermissions
5/24/2022 • 2 minutes to read • Edit Online
Sets the chat permissions between the local chat control and a target chat control.
Syntax
PartyError SetPermissions(
const PartyChatControl* targetChatControl,
PartyChatPermissionOptions chatPermissionOptions
)
Parameters
targetChatControl PartyChatControl*
The target chat control.
chatPermissionOptions PartyChatPermissionOptions
The chat permission options.
Return value
PartyError
c_partyErrorSuccess if the call succeeded or an error code otherwise. The human-readable form of the error
code can be retrieved via PartyManager::GetErrorMessage().
Remarks
Chat permissions allow you to control incoming and outgoing voice communication, as well as incoming text
communication, between any pair of chat controls. The chat permissions should be configured to reflect your
target scenario. For example, if the target chat control is a member of the same team, you'd likely allow audio in
both directions. If the target chat control is a member of an opposing team, you likely wouldn't allow audio in
either direction. Regardless of team, you might allow receiving text.
The target chat control must be remote. The default permission is PartyChatPermissionOptions::None.
This setting is local only. If a local chat control is configured to send audio to a remote chat control, no audio will
be sent to the remote chat control unless the remote chat control has also been configured to receive audio
from the local chat control in their instance of the library. Similarly, if a local chat control is configured to receive
audio from a remote chat control, no audio will be received from the remote chat control unless the remote chat
control has also been configured to send audio to the local chat control in their instance of the library. Therefore,
both chat controls must agree that the communication is allowed; one chat control can't force another to accept
or transmit undesired chat.
There is no permission associated with sending chat text because each call to SendText() requires an explicit list
of target chat controls. Including or omitting a target is equivalent to granting or denying send permission for
that text message. The target still must have set PartyChatPermissionOptions::ReceiveText in their instance of the
library for it to actually be delivered.
The Party library does not enforce platform restrictions tied to the user's identity, such as a platform setting that
restricts chat to "friends only". Platform restrictions should be considered when configuring the chat
permissions between two chat controls.
Requirements
Header : Party.h
See also
PartyLocalChatControl
PartyLocalChatControl::GetPermissions
5/24/2022 • 2 minutes to read • Edit Online
Gets the voice communication relationship between the local chat control and a target chat control.
Syntax
PartyError GetPermissions(
const PartyChatControl* targetChatControl,
PartyChatPermissionOptions* chatPermissionOptions
)
Parameters
targetChatControl PartyChatControl*
The target chat control.
chatPermissionOptions PartyChatPermissionOptions*
output
The output chat permission options.
Return value
PartyError
c_partyErrorSuccess if the call succeeded or an error code otherwise. The human-readable form of the error
code can be retrieved via PartyManager::GetErrorMessage().
Requirements
Header : Party.h
See also
PartyLocalChatControl
PartyLocalChatControl::SendText
5/24/2022 • 2 minutes to read • Edit Online
Syntax
PartyError SendText(
uint32_t targetChatControlCount,
PartyChatControlArray targetChatControls,
PartyString chatText,
uint32_t dataBufferCount,
const PartyDataBuffer* dataBuffers
)
Parameters
targetChatControlCount uint32_t
The number of target chat controls in the targetChatControls array.
targetChatControls PartyChatControlArray
input array of size targetChatControlCount
Remarks
Sending chat text to local chat controls is not currently supported. If the array of target chat controls includes
any local targets, this call will synchronously fail.
There is no guaranteed translation, localization, or offensive language filtering of the text content; the chat text
string will be presented with the text as is.
The text string will only be delivered to target chat controls that have configured their own instances to receive
text messages from the local chat control via PartyLocalChatControl::SetPermissions().
If a target chat control is not connected to at least one network in common with the source chat control, the text
string will not be delivered. This is possible if there are two local chat controls. A target chat control connected to
one of the local chat controls may not be connected to all other local chat controls.
The PartyDataBuffer structures in the dataBuffers array are for auxiliary data associated with the chat text, such
as metadata indicating the color that should be used to render the text or a binary blob containing image data
for an icon to render along with the chat text. For sending game data that is unrelated to text chat, see
PartyLocalEndpoint::SendMessage(), a messaging option that exposes finer control over message transmission
behavior.
Callers provide 0 or more PartyDataBuffer structures in the dataBuffers array. The memory that the structures
reference does not have to be contiguous, making it easy to have a fixed header buffer followed by a variable
payload, for example. The buffers will be assembled in order, transmitted, and delivered to the targeted chat
controls as a single contiguous data block, separate from the chat text, in a PartyChatTextReceivedStateChange.
The Party library does not expend bandwidth transmitting metadata to describe the original PartyDataBuffer
segmentation.
Requirements
Header : Party.h
See also
PartyLocalChatControl
PartyChatTextReceivedStateChange
PartyLocalChatControl::SetAudioInput
5/24/2022 • 2 minutes to read • Edit Online
Configures the preferred microphone or recording device that the chat control will use for audio input.
Syntax
PartyError SetAudioInput(
PartyAudioDeviceSelectionType audioDeviceSelectionType,
PartyString audioDeviceSelectionContext,
void* asyncIdentifier
)
Parameters
audioDeviceSelectionType PartyAudioDeviceSelectionType
If PartyAudioDeviceSelectionType::None is specified, the audio input will be cleared. If
PartyAudioDeviceSelectionType::SystemDefault is specified, the Party library will attempt to use the system's
default communication device. If PartyAudioDeviceSelectionType::PlatformUserDefault is specified, the Party
library will attempt to use the default communication device associated with audioDeviceSelectionContext . If
PartyAudioDeviceSelectionType::Manual is specified, the Party library will attempt to use the communication
device whose device identifier matches. Note that this is not supported on iOS or Android.
audioDeviceSelectionContext .
audioDeviceSelectionContext PartyString
optional
When using PartyAudioDeviceSelectionType::None or PartyAudioDeviceSelectionType::SystemDefault,
audioDeviceSelectionContext will be ignored. When using PartyAudioDeviceSelectionType::PlatformUserDefault,
audioDeviceSelectionContext must be the non-null, non-empty platform-specific user context that the chat
control should use when selecting the audio device. When using PartyAudioDeviceSelectionType::Manual,
audioDeviceSelectionContext must be the non-null, non-empty identifier of the audio device that the chat
control should use.
asyncIdentifier void*
optional
An optional, app-defined, pointer-sized context value that can be used to associate the completion state change
with this call.
Return value
PartyError
c_partyErrorSuccess if the asynchronous operation to set the audio input began, or an error code otherwise. If
this method fails, no related state changes will be generated. The human-readable form of the error code can be
retrieved via PartyManager::GetErrorMessage().
Remarks
This method queues an asynchronous operation to configure the preferred recording device associated with this
local chat control. If the method succeeds, a PartyLocalChatAudioInputChangedStateChange will be provided by
PartyManager::StartProcessingStateChanges() with details about the input device status and a
PartySetChatAudioInputCompletedStateChange will be provided upon completion of the operation, indicating
success or failure. After completion, an additional PartyLocalChatAudioInputChangedStateChange will be
provided each time the audio device status changes, such as due to device removal.
If the specified device isn't present, the chat control will subscribe to audio device changes and use the device
when it does appear.
When using the PlatformUserDefault option on the Xbox platform, the Xbox User Identifier (XUID) must be
passed as the audioDeviceSelectionContext value.
Requirements
Header : Party.h
See also
PartyLocalChatControl
PartyLocalChatControl::GetAudioInput
PartyLocalChatControl::SetAudioOutput
PartyLocalChatControl::GetAudioInput
5/24/2022 • 2 minutes to read • Edit Online
Provides the preferred microphone or recording device that the chat control has been configured to use for
audio input.
Syntax
PartyError GetAudioInput(
PartyAudioDeviceSelectionType* audioDeviceSelectionType,
PartyString* audioDeviceSelectionContext,
PartyString* deviceId
)
Parameters
audioDeviceSelectionType PartyAudioDeviceSelectionType*
output
An output value indicating the selection type that was used to select the provided deviceId .
audioDeviceSelectionContext PartyString*
library-allocated output
When using PartyAudioDeviceSelectionType::None or PartyAudioDeviceSelectionType::SystemDefault,
audioDeviceSelectionContext will be empty. When using PartyAudioDeviceSelectionType::PlatformUserDefault
or PartyAudioDeviceSelectionType::Manual, audioDeviceSelectionContext will be the value provided in a
previous call to SetAudioInput(). The memory for the string remains valid until the next
PartyLocalChatAudioInputChangedStateChange is provided via PartyManager::StartProcessingStateChanges() or
the chat control is destroyed.
deviceId PartyString*
library-allocated output
An output value indicating the selected audio input device's identifier. The memory for the string remains valid
until the next PartyLocalChatAudioInputChangedStateChange is provided via
PartyManager::StartProcessingStateChanges() or the chat control is destroyed.
Return value
PartyError
c_partyErrorSuccess if the call succeeded or an error code otherwise. The human-readable form of the error
code can be retrieved via PartyManager::GetErrorMessage().
Remarks
An empty device identifier string indicates that no input has been selected.
Requirements
Header : Party.h
See also
PartyLocalChatControl
PartyLocalChatControl::SetAudioInput
PartyLocalChatControl::GetAudioOutput
PartyLocalChatControl::SetAudioOutput
5/24/2022 • 2 minutes to read • Edit Online
Configures the preferred speakers or headset device that the chat control will use for audio output.
Syntax
PartyError SetAudioOutput(
PartyAudioDeviceSelectionType audioDeviceSelectionType,
PartyString audioDeviceSelectionContext,
void* asyncIdentifier
)
Parameters
audioDeviceSelectionType PartyAudioDeviceSelectionType
If PartyAudioDeviceSelectionType::None is specified, the audio output will be cleared. If
PartyAudioDeviceSelectionType::SystemDefault is specified, the Party library will attempt to use the system's
default communication device. If PartyAudioDeviceSelectionType::PlatformUserDefault is specified, the Party
library will attempt to use the default communication device associated with audioDeviceSelectionContext . If
PartyAudioDeviceSelectionType::Manual is specified, the Party library will attempt to use the communication
device whose device identifier matches audioDeviceSelectionContext .
audioDeviceSelectionContext PartyString
optional
When using PartyAudioDeviceSelectionType::None or PartyAudioDeviceSelectionType::SystemDefault,
audioDeviceSelectionContext will be ignored. When using PartyAudioDeviceSelectionType::PlatformUserDefault,
audioDeviceSelectionContext must be the non-null, non-empty platform-specific user context that the chat
control should use when selecting the audio device. When using PartyAudioDeviceSelectionType::Manual,
audioDeviceSelectionContext must be the non-null, non-empty identifier of the audio device that the chat
control should use.
asyncIdentifier void*
optional
An optional, app-defined, pointer-sized context value that can be used to associate the completion state change
with this call.
Return value
PartyError
c_partyErrorSuccess if the asynchronous operation to set the audio output began, or an error code otherwise. If
this method fails, no related state changes will be generated. The human-readable form of the error code can be
retrieved via PartyManager::GetErrorMessage().
Remarks
This method queues an asynchronous operation to configure the preferred speakers or headset device
associated with this local chat control. If the method succeeds, a
PartyLocalChatAudioOutputChangedStateChange will be provided by
PartyManager::StartProcessingStateChanges() with details about the output device status and a
PartySetChatAudioOutputCompletedStateChange will be provided upon completion of the operation, indicating
success or failure. After completion, an additional PartyLocalChatAudioOutputChangedStateChange will be
provided each time the audio device status changes, such as due to device removal.
If the specified device isn't present, the chat control will subscribe to audio device changes and use the device
when it does appear.
When using the PlatformUserDefault option on the Xbox platform, the Xbox User Identifier (XUID) must be
passed as the audioDeviceSelectionContext value.
Requirements
Header : Party.h
See also
PartyLocalChatControl
PartyLocalChatControl::GetAudioOutput
PartyLocalChatControl::SetAudioInput
PartyLocalChatControl::GetAudioOutput
5/24/2022 • 2 minutes to read • Edit Online
Provides the preferred speakers or headset device that the chat control has been configured to use for audio
output.
Syntax
PartyError GetAudioOutput(
PartyAudioDeviceSelectionType* audioDeviceSelectionType,
PartyString* audioDeviceSelectionContext,
PartyString* deviceId
)
Parameters
audioDeviceSelectionType PartyAudioDeviceSelectionType*
output
An output value indicating the selection type that was used to select the provided deviceId .
audioDeviceSelectionContext PartyString*
library-allocated output
When using PartyAudioDeviceSelectionType::None or PartyAudioDeviceSelectionType::SystemDefault,
audioDeviceSelectionContext will be empty. When using PartyAudioDeviceSelectionType::PlatformUserDefault
or PartyAudioDeviceSelectionType::Manual, audioDeviceSelectionContext will be the value provided in a
previous call to SetAudioOutput(). The memory for the string remains valid until the next
PartyLocalChatAudioOutputChangedStateChange is provided via PartyManager::StartProcessingStateChanges()
or the chat control is destroyed.
deviceId PartyString*
library-allocated output
An output value indicating the selected audio output device's identifier. The memory for the string remains valid
until the next PartyLocalChatAudioOutputChangedStateChange is provided via
PartyManager::StartProcessingStateChanges() or the chat control is destroyed.
Return value
PartyError
c_partyErrorSuccess if the call succeeded or an error code otherwise. The human-readable form of the error
code can be retrieved via PartyManager::GetErrorMessage().
Remarks
An empty device identifier string indicates that no output has been selected.
Requirements
Header : Party.h
See also
PartyLocalChatControl
PartyLocalChatControl::SetAudioOutput
PartyLocalChatControl::GetAudioInput
PartyLocalChatControl::PopulateAvailableTextToSpeechProfiles
5/24/2022 • 2 minutes to read • Edit Online
Populates the local chat control's list of supported text to speech profiles.
Syntax
PartyError PopulateAvailableTextToSpeechProfiles(
void* asyncIdentifier
)
Parameters
asyncIdentifier void*
optional
An optional, app-defined, pointer-sized context value that can be used to associate the completion state change
with this call.
Return value
PartyError
c_partyErrorSuccess if the asynchronous operation began, or an error code otherwise. If this method fails, no
related state changes will be generated. The human-readable form of the error code can be retrieved via
PartyManager::GetErrorMessage().
Remarks
This is an asynchronous operation; a PartyPopulateAvailableTextToSpeechProfilesCompletedStateChange will be
provided via PartyManager::StartProcessingStateChanges() on completion.
Requirements
Header : Party.h
See also
PartyLocalChatControl
PartyLocalChatControl::GetAvailableTextToSpeechProfiles
PartyLocalChatControl::SetTextToSpeechProfile
PartyLocalChatControl::GetTextToSpeechProfile
PartyLocalChatControl::GetAvailableTextToSpeechProfiles
5/24/2022 • 2 minutes to read • Edit Online
Syntax
PartyError GetAvailableTextToSpeechProfiles(
uint32_t* profileCount,
PartyTextToSpeechProfileArray* profiles
)
Parameters
profileCount uint32_t*
output
The output number of available profiles.
profiles PartyTextToSpeechProfileArray*
library-allocated output array of size *profileCount
A library-allocated output array containing the available profiles.
Return value
PartyError
c_partyErrorSuccess if the call succeeded or an error code otherwise. The human-readable form of the error
code can be retrieved via PartyManager::GetErrorMessage().
Remarks
This method synchronously returns the result cached by the last successful
PopulateAvailableTextToSpeechProfiles() operation.
The returned array is only valid until the next call to PartyManager::StartProcessingStateChanges().
Requirements
Header : Party.h
See also
PartyLocalChatControl
PartyLocalChatControl::PopulateAvailableTextToSpeechProfiles
PartyLocalChatControl::SetTextToSpeechProfile
5/24/2022 • 2 minutes to read • Edit Online
Syntax
PartyError SetTextToSpeechProfile(
PartySynthesizeTextToSpeechType type,
PartyString profileIdentifier,
void* asyncIdentifier
)
Parameters
type PartySynthesizeTextToSpeechType
The type of text-to-speech operations for which the specified profile should be used.
profileIdentifier PartyString
The identifier of the profile that text-to-speech operations of the specified type should use.
asyncIdentifier void*
optional
An optional, app-defined, pointer-sized context value that can be used to associate the completion state change
with this call.
Return value
PartyError
c_partyErrorSuccess if the asynchronous operation to set the text to speech profile began, or an error code
otherwise. If this method fails, no related state changes will be generated. The human-readable form of the error
code can be retrieved via PartyManager::GetErrorMessage().
Remarks
The profile provided will be used for all subsequent calls to SynthesizeTextToSpeech() that specify the same
value for type . No profile will be configured until SetTextToSpeechProfile() is called at least once. Thus, this
method must be called at least once before any calls to SynthesizeTextToSpeech() can succeed.
This method accepts a profile identifier to indicate the profile selection so that titles may either pass in the result
of PartyTextToSpeechProfile::GetIdentifier() or provide a profile identifier cached from a previous Party library
session.
Multiple SetTextToSpeechProfile() operations can be initiated, and they will be asynchronously queued. Each
operation will be processed and completed in order.
See also
PartyLocalChatControl
PartyLocalChatControl::GetTextToSpeechProfile
PartyLocalChatControl::GetTextToSpeechProfile
5/24/2022 • 2 minutes to read • Edit Online
Gets the profile that was last configured from a successfully completed SetTextToSpeechProfile() operation for a
specified type of text-to-speech operation.
Syntax
PartyError GetTextToSpeechProfile(
PartySynthesizeTextToSpeechType type,
PartyTextToSpeechProfile** profile
)
Parameters
type PartySynthesizeTextToSpeechType
The type of text-to-speech operations for which the profile should be retrieved.
profile PartyTextToSpeechProfile**
library-allocated output, may return nullptr
The output profile. The profile may be nullptr if none has been set for the specified type. The pointer is only valid
until the next call to PartyManager::StartProcessingStateChanges().
Return value
PartyError
c_partyErrorSuccess if the call succeeded or an error code otherwise. The human-readable form of the error
code can be retrieved via PartyManager::GetErrorMessage().
Remarks
If no profile has been successfully configured for the specified type of text-to-speech operation, the retrieved
profile will be null.
Requirements
Header : Party.h
See also
PartyLocalChatControl
PartyLocalChatControl::SetTextToSpeechProfile
PartyLocalChatControl::SynthesizeTextToSpeech
5/24/2022 • 2 minutes to read • Edit Online
Generates text-to-speech audio that is used to either displace the microphone audio associated with this chat
control or render directly to the chat control's audio output.
Syntax
PartyError SynthesizeTextToSpeech(
PartySynthesizeTextToSpeechType type,
PartyString textToSynthesize,
void* asyncIdentifier
)
Parameters
type PartySynthesizeTextToSpeechType
Remarks
SynthesizeTextToSpeech() cannot be called for a particular type until a text-to-speech profile has been
configured for the specified type via SetTextToSpeechProfile().
SynthesizeTextToSpeech() can be called immediately after configuring a text-to-speech profile via a call to
SetTextToSpeechProfile() with the same type . In such a case, the text-to-speech operation will be queued behind
the completion of the SetTextToSpeechProfile() operation.
Requirements
Header : Party.h
See also
PartyLocalChatControl
PartyLocalChatControl::SetTextToSpeechProfile
PartyLocalChatControl::GetLanguage
5/24/2022 • 2 minutes to read • Edit Online
Syntax
PartyError GetLanguage(
PartyString* languageCode
)
Parameters
languageCode PartyString*
library-allocated output
The output BCP 47 language code used by the chat control future communication. The memory for the string
remains valid until the chat control is destroyed.
Return value
PartyError
c_partyErrorSuccess if the call succeeded or an error code otherwise. The human-readable form of the error
code can be retrieved via PartyManager::GetErrorMessage().
Remarks
The language is used as the spoken language associated with this chat control for transcription and the target
language for incoming translations. If the language code specified is en-US, for instance, the input audio to this
chat control will be treated as the English (United States) language and transcribed as such. If translation is
enabled via either SetTranscriptionOptions() or SetTextChatOptions(), the incoming voice chat transcriptions
and/or text chat will be translated to English (United States).
The language code should be in BCP 47 format; supported language codes are enumerated at
https://docs.microsoft.com/azure/cognitive-services/speech-service/language-support. Specifying an
unsupported or invalid language code will not cause this method to fail, but will result in failure to generate
transcriptions associated with this chat control. The language code can be queried via GetLanguage().
Requirements
Header : Party.h
See also
PartyLocalChatControl
PartyLocalDevice::CreateChatControl
PartyLocalChatControl::SetTranscriptionOptions
PartyLocalChatControl::SetTranscriptionOptions
5/24/2022 • 2 minutes to read • Edit Online
Configures the transcription options associated with voice chat audio for this chat control.
Syntax
PartyError SetTranscriptionOptions(
PartyVoiceChatTranscriptionOptions options,
void* asyncIdentifier
)
Parameters
options PartyVoiceChatTranscriptionOptions
Options associated with voice chat transcription, such as which chat controls should generate transcriptions for
the local chat control, and whether those transcriptions should be translated to the local chat control's language.
asyncIdentifier void*
optional
An optional, app-defined, pointer-sized context value that can be used to associate the completion state change
with this call.
Return value
PartyError
c_partyErrorSuccess if the asynchronous operation to set the transcription options began, or an error code
otherwise. If this method fails, no related state changes will be generated. The human-readable form of the error
code can be retrieved via PartyManager::GetErrorMessage().
Remarks
Transcription is the process of generating strings representing spoken phrases in voice chat. The options
specified via options specify the chat controls that should generate these transcription strings, which are
subsequently provided to the local chat control via PartyVoiceChatTranscriptionReceivedStateChanges.
Only chat controls configured to use a language that supports transcription, via
PartyLocalDevice::CreateChatControl(), will provide transcriptions.
Requirements
Header : Party.h
See also
PartyLocalChatControl
PartyLocalChatControl::GetTranscriptionOptions
5/24/2022 • 2 minutes to read • Edit Online
Provides the transcription options associated with voice chat audio for this chat control.
Syntax
PartyError GetTranscriptionOptions(
PartyVoiceChatTranscriptionOptions* options
)
Parameters
options PartyVoiceChatTranscriptionOptions*
output
Options associated with voice chat transcription, such as whether it should be enabled only for the local chat
control, remote chat controls, or none.
Return value
PartyError
c_partyErrorSuccess if the call succeeded or an error code otherwise. The human-readable form of the error
code can be retrieved via PartyManager::GetErrorMessage().
Remarks
Transcription is the process of generating strings representing spoken phrases in voice chat. The options
specified via options specify the chat controls that should generate these transcription strings, which are
subsequently provided to the local chat control via PartyVoiceChatTranscriptionReceivedStateChanges.
Only chat controls configured to use a language that supports transcription, via
PartyLocalDevice::CreateChatControl(), will provide transcriptions.
Requirements
Header : Party.h
See also
PartyLocalChatControl
PartyLocalChatControl::SetTextChatOptions
5/24/2022 • 2 minutes to read • Edit Online
Configures the text chat options associated with text chat for this chat control.
Syntax
PartyError SetTextChatOptions(
PartyTextChatOptions options,
void* asyncIdentifier
)
Parameters
options PartyTextChatOptions
Options associated with text chat, such as whether incoming text chat should be translated.
asyncIdentifier void*
optional
An optional, app-defined, pointer-sized context value that can be used to associate the completion state change
with this call.
Return value
PartyError
c_partyErrorSuccess if the asynchronous operation to set the chat text options began, or an error code
otherwise. If this method fails, no related state changes will be generated. The human-readable form of the error
code can be retrieved via PartyManager::GetErrorMessage().
Requirements
Header : Party.h
See also
PartyLocalChatControl
PartyLocalChatControl::GetTextChatOptions
5/24/2022 • 2 minutes to read • Edit Online
Provides the text chat options associated with text chat for this chat control.
Syntax
PartyError GetTextChatOptions(
PartyTextChatOptions* options
)
Parameters
options PartyTextChatOptions*
output
Options associated with text chat.
Return value
PartyError
c_partyErrorSuccess if the call succeeded or an error code otherwise. The human-readable form of the error
code can be retrieved via PartyManager::GetErrorMessage().
Requirements
Header : Party.h
See also
PartyLocalChatControl
PartyLocalChatControl::SetAudioRenderVolume
5/24/2022 • 2 minutes to read • Edit Online
Configures the volume setting for audio received from a target chat control that will be used for the local chat
control.
Syntax
PartyError SetAudioRenderVolume(
const PartyChatControl* targetChatControl,
float volume
)
Parameters
targetChatControl PartyChatControl*
The target chat control.
volume float
The volume.
Return value
PartyError
c_partyErrorSuccess if the call succeeded or an error code otherwise. The human-readable form of the error
code can be retrieved via PartyManager::GetErrorMessage().
Remarks
The volume is a fractional percentage between 0.0 (quietest possible) and 1.0 (the standard chat volume).
Requirements
Header : Party.h
See also
PartyLocalChatControl
PartyLocalChatControl::GetAudioRenderVolume
5/24/2022 • 2 minutes to read • Edit Online
Provides the volume setting for audio received from a target chat control that will be used for the local chat
control.
Syntax
PartyError GetAudioRenderVolume(
const PartyChatControl* targetChatControl,
float* volume
)
Parameters
targetChatControl PartyChatControl*
The target chat control.
volume float*
output
The volume.
Return value
PartyError
c_partyErrorSuccess if the call succeeded or an error code otherwise. The human-readable form of the error
code can be retrieved via PartyManager::GetErrorMessage().
Remarks
The volume is a fractional percentage between 0.0 (quietest possible) and 1.0 (the standard chat volume).
Requirements
Header : Party.h
See also
PartyLocalChatControl
PartyLocalChatControl::SetAudioInputMuted
5/24/2022 • 2 minutes to read • Edit Online
Syntax
PartyError SetAudioInputMuted(
PartyBool muted
)
Parameters
muted PartyBool
Remarks
Muting determines whether audio data will be captured from the chat control's audio input and sent to the
appropriate chat controls according to the configured relationships. When the audio input is muted, no audio
data will be captured, regardless of the relationships that have been configured. Muting does not stop outgoing
text messages or audio that has been generated by a call to SynthesizeTextToSpeech().
Requirements
Header : Party.h
See also
PartyLocalChatControl
PartyLocalChatControl::GetAudioInputMuted
5/24/2022 • 2 minutes to read • Edit Online
Syntax
PartyError GetAudioInputMuted(
PartyBool* muted
)
Parameters
muted PartyBool*
output
True if muted, false otherwise.
Return value
PartyError
c_partyErrorSuccess if the call succeeded or an error code otherwise. The human-readable form of the error
code can be retrieved via PartyManager::GetErrorMessage().
Remarks
Muting determines whether audio data will be captured from the chat control's audio input and sent to the
appropriate chat controls according to the configured relationships. When the audio input is muted, no audio
data will be captured, regardless of the relationships that have been configured. Muting does not stop outgoing
text messages or audio that has been generated by a call to SynthesizeTextToSpeech().
Requirements
Header : Party.h
See also
PartyLocalChatControl
PartyLocalChatControl::SetIncomingAudioMuted
5/24/2022 • 2 minutes to read • Edit Online
Configures whether the incoming audio from the target chat control, in relation to the local chat control, is
muted.
Syntax
PartyError SetIncomingAudioMuted(
const PartyChatControl* targetChatControl,
PartyBool muted
)
Parameters
targetChatControl PartyChatControl*
The target chat control.
muted PartyBool
True to mute, false otherwise.
Return value
PartyError
c_partyErrorSuccess if the call succeeded or an error code otherwise. The human-readable form of the error
code can be retrieved via PartyManager::GetErrorMessage().
Remarks
Audio muting determines whether incoming voice audio from the target chat control will be rendered to the
local chat control.
Requirements
Header : Party.h
See also
PartyLocalChatControl
PartyLocalChatControl::GetIncomingAudioMuted
5/24/2022 • 2 minutes to read • Edit Online
Provides whether the incoming audio from the target chat control, in relation to the local chat control, has
previously been muted.
Syntax
PartyError GetIncomingAudioMuted(
const PartyChatControl* targetChatControl,
PartyBool* muted
)
Parameters
targetChatControl PartyChatControl*
The target chat control.
muted PartyBool*
output
True if muted, false otherwise.
Return value
PartyError
c_partyErrorSuccess if the call succeeded or an error code otherwise. The human-readable form of the error
code can be retrieved via PartyManager::GetErrorMessage().
Remarks
Audio muting determines whether incoming voice audio from the target chat control will be rendered to the
local chat control.
Requirements
Header : Party.h
See also
PartyLocalChatControl
PartyLocalChatControl::SetIncomingTextMuted
5/24/2022 • 2 minutes to read • Edit Online
Configures whether the incoming text messages from the target chat control, in relation to the local chat control,
is muted.
Syntax
PartyError SetIncomingTextMuted(
const PartyChatControl* targetChatControl,
PartyBool muted
)
Parameters
targetChatControl PartyChatControl*
The target chat control.
muted PartyBool
True to mute, false otherwise.
Return value
PartyError
c_partyErrorSuccess if the call succeeded or an error code otherwise. The human-readable form of the error
code can be retrieved via PartyManager::GetErrorMessage().
Remarks
Chat text muting determines whether incoming chat text messages from the target chat control will be provided
to the local chat control.
Requirements
Header : Party.h
See also
PartyLocalChatControl
PartyLocalChatControl::GetIncomingTextMuted
5/24/2022 • 2 minutes to read • Edit Online
Provides whether the incoming text messages from the target chat control, in relation to the local chat control,
has previously been muted.
Syntax
PartyError GetIncomingTextMuted(
const PartyChatControl* targetChatControl,
PartyBool* muted
)
Parameters
targetChatControl PartyChatControl*
The target chat control.
muted PartyBool*
output
True if muted, false otherwise.
Return value
PartyError
c_partyErrorSuccess if the call succeeded or an error code otherwise. The human-readable form of the error
code can be retrieved via PartyManager::GetErrorMessage().
Remarks
Chat text muting determines whether incoming chat text messages from the target chat control will be provided
to the local chat control.
Requirements
Header : Party.h
See also
PartyLocalChatControl
PartyLocalChatControl::GetLocalChatIndicator
5/24/2022 • 2 minutes to read • Edit Online
Provides a chat indicator specifying the audio state of the local chat control.
Syntax
PartyError GetLocalChatIndicator(
PartyLocalChatControlChatIndicator* chatIndicator
)
Parameters
chatIndicator PartyLocalChatControlChatIndicator*
output
The chat indicator.
Return value
PartyError
c_partyErrorSuccess if the call succeeded or an error code otherwise. The human-readable form of the error
code can be retrieved via PartyManager::GetErrorMessage().
Remarks
This indicator is intended to assist UI iconic representation so that users can determine whether their voice
audio is being captured and, if not, then why not.
This value changes frequently and is typically polled every graphics frame.
Requirements
Header : Party.h
See also
PartyLocalChatControl
PartyLocalChatControl::GetChatIndicator
5/24/2022 • 2 minutes to read • Edit Online
Provides a chat indicator specifying the audio state of a target chat control in relation to the local chat control.
Syntax
PartyError GetChatIndicator(
const PartyChatControl* targetChatControl,
PartyChatControlChatIndicator* chatIndicator
)
Parameters
targetChatControl PartyChatControl*
The target chat control.
chatIndicator PartyChatControlChatIndicator*
output
The chat indicator.
Return value
PartyError
c_partyErrorSuccess if the call succeeded or an error code otherwise. The human-readable form of the error
code can be retrieved via PartyManager::GetErrorMessage().
Remarks
This indicator is intended to assist UI iconic representation so that users can determine why they're hearing/
seeing what they are ("who's that talking?"), or why not.
This value changes frequently and is typically polled every graphics frame.
Requirements
Header : Party.h
See also
PartyLocalChatControl
PartyLocalChatControl::ConfigureAudioManipulationCaptureStream
5/24/2022 • 2 minutes to read • Edit Online
Syntax
PartyError ConfigureAudioManipulationCaptureStream(
PartyAudioManipulationSinkStreamConfiguration* configuration,
void* asyncIdentifier
)
Parameters
configuration PartyAudioManipulationSinkStreamConfiguration*
optional
The stream configuration.
asyncIdentifier void*
optional
An optional, app-defined, pointer-sized context value that can be used to associate the completion state change
with this call.
Return value
PartyError
c_partyErrorSuccess if the call succeeded or an error code otherwise. The human-readable form of the error
code can be retrieved via PartyManager::GetErrorMessage().
Remarks
If the configuration is non-null, a capture stream will be created for this chat control. Such a stream acts as the
voice input for this chat control that is sent to all other chat controls to which this chat control is configured to
communicate. If the configuration is null, and a capture stream has previously been configured, the capture will
be destroyed.
Upon completion of the asynchronous operation, when a non-null configuration was specified, a capture stream
for this chat control can be queried via PartyLocalChatControl::GetAudioManipulationCaptureStream().
Completion is indicated by a PartyConfigureAudioManipulationCaptureStreamCompletedStateChange.
Platform support and supported formats
This function is only supported on Windows and Xbox. Calls on other platforms will fail.
F O RM AT O P T IO N SUP P O RT ED VA L UE
Channel mask 0
Channel count 1
Interleaved false
Requirements
Header : Party.h
See also
PartyLocalChatControl
PartyLocalChatControl::GetAudioManipulationCaptureStream
5/24/2022 • 2 minutes to read • Edit Online
Retrieves the audio manipulation capture stream associated with this chat control.
Syntax
PartyError GetAudioManipulationCaptureStream(
PartyAudioManipulationSinkStream** stream
)
Parameters
stream PartyAudioManipulationSinkStream**
library-allocated output
The output stream.
Return value
PartyError
c_partyErrorSuccess if the call succeeded or an error code otherwise. The human-readable form of the error
code can be retrieved via PartyManager::GetErrorMessage().
Remarks
This stream represents acts as the associated chat control's audio input, i.e. the audio that will be treated as the
local chat control's voice and sent to other chat controls. Typically, the app will retrieve audio from the voice
manipulation stream stream via PartyAudioManipulationSourceStream::GetNextBuffer(), process the audio using
app logic, and then submit the audio back to the library via this stream.
Requirements
Header : Party.h
See also
PartyLocalChatControl
PartyLocalChatControl::ConfigureAudioManipulationRenderStream
5/24/2022 • 2 minutes to read • Edit Online
Syntax
PartyError ConfigureAudioManipulationRenderStream(
PartyAudioManipulationSinkStreamConfiguration* configuration,
void* asyncIdentifier
)
Parameters
configuration PartyAudioManipulationSinkStreamConfiguration*
optional
The stream configuration.
asyncIdentifier void*
optional
An optional, app-defined, pointer-sized context value that can be used to associate the completion state change
with this call.
Return value
PartyError
c_partyErrorSuccess if the call succeeded or an error code otherwise. The human-readable form of the error
code can be retrieved via PartyManager::GetErrorMessage().
Remarks
If the configuration is non-null, an audio manipulation render stream will be created for this chat control. Such a
stream acts as the render pipeline for audio that will be rendered to this chat control. If the configuration is null,
and a stream has previously been configured, the stream will be destroyed.
Upon completion of the asynchronous operation, when a non-null configuration was specified, a render stream
for this chat control can be queried via PartyLocalChatControl::GetAudioManipulationRenderStream().
Completion is indicated by a PartyConfigureAudioManipulationRenderStreamCompletedStateChange.
Platform support and supported formats
This function is only supported on Windows and Xbox. Calls on other platforms will fail.
F O RM AT O P T IO N SUP P O RT ED VA L UE( S)
Samples per second Any value between 8 kHz and 48 kHz, inclusive.
Requirements
Header : Party.h
See also
PartyLocalChatControl
PartyLocalChatControl::GetAudioManipulationRenderStream
5/24/2022 • 2 minutes to read • Edit Online
Retrieves the manipulation render stream associated with this chat control.
Syntax
PartyError GetAudioManipulationRenderStream(
PartyAudioManipulationSinkStream** stream
)
Parameters
stream PartyAudioManipulationSinkStream**
library-allocated output
The output stream.
Return value
PartyError
c_partyErrorSuccess if the call succeeded or an error code otherwise. The human-readable form of the error
code can be retrieved via PartyManager::GetErrorMessage().
Remarks
This stream represents the audio that will be rendered to the chat control's audio output. Typically, the app will
retrieve audio from the voice streams associated with all remote chat controls via
PartyAudioManipulationSourceStream::GetNextBuffer(), process and mix each buffer into a single audio stream,
and then submit the mixed stream to be rendered by each appropriate render stream. Each render stream can
be retrieved via PartyLocalChatControl::GetAudioManipulationRenderStream().
Requirements
Header : Party.h
See also
PartyLocalChatControl
PartyLocalDevice
5/24/2022 • 2 minutes to read • Edit Online
Syntax
class PartyLocalDevice : public PartyDevice
Public Methods
NAME DESC RIP T IO N
Requirements
Header : Party.h
See also
Party members
PartyDevice
PartyManager::GetLocalDevice
PartyLocalDevice::CreateChatControl
5/24/2022 • 2 minutes to read • Edit Online
Queues an asynchronous operation to create a local chat control for the specified user.
Syntax
PartyError CreateChatControl(
const PartyLocalUser* localUser,
PartyString languageCode,
void* asyncIdentifier,
PartyLocalChatControl** localChatControl
)
Parameters
localUser PartyLocalUser*
The local user for the new local chat control.
languageCode PartyString
optional
The optional language to use.
asyncIdentifier void*
optional
An optional, app-defined, pointer-sized context value that can be used to associate the completion state change
with this call.
localChatControl PartyLocalChatControl**
optional, library-allocated output
The optional, output local chat control.
Return value
PartyError
c_partyErrorSuccess if the asynchronous operation to create a chat control began, or an error code otherwise. If
this method fails, no related state changes will be generated. The human-readable form of the error code can be
retrieved via PartyManager::GetErrorMessage().
Remarks
If this method returns success, a PartyCreateChatControlCompletedStateChange will be generated to provide
the result of the asynchronous operation. If the asynchronous operation succeeds, a
PartyChatControlCreatedStateChange will be generated. If the operation fails, a
PartyChatControlDestroyedStateChange will be generated. This method itself does not make the chat control
visible to any remote devices. To announce this chat control to remote devices, the title should call
PartyNetwork::ConnectChatControl().
On successful return, this method invalidates the memory for any array previously returned by
PartyManager::GetChatControls() or PartyDevice::GetChatControls() for the local device, as it synchronously
adds the new chat control to the arrays. PartyManager::StartProcessingStateChanges() also invalidates the
memory for these arrays. The returned localChatControl object will be valid until a
PartyChatControlDestroyedStateChange has been generated and all state changes referencing the object have
been returned to PartyManager::FinishProcessingStateChanges().
The language associated with this chat control can optionally be specified via the languageCode parameter. If no
language is specified, the user's default, as determined by the platform, will be used. The language is used as the
spoken the language associated with this chat control for transcription and the target language for incoming
translations. If the language code specified is en-US, for instance, the input audio to this chat control will be
treated as the English (United States) language and transcribed as such. If translation is enabled via either
PartyLocalChatControl::SetTranscriptionOptions() or PartyLocalChatControl::SetTextChatOptions(), the incoming
voice chat transcriptions and/or text chat will be translated to English (United States).
The language code should be in BCP 47 format; supported language codes are enumerated at
https://docs.microsoft.com/azure/cognitive-services/speech-service/language-support. Specifying an
unsupported or invalid language code will not cause this method to fail, but will result in failure to generate
transcriptions associated with this chat control. The language code used with this method can be queried via
PartyLocalChatControl::GetLanguage().
Requirements
Header : Party.h
See also
PartyLocalDevice
PartyCreateChatControlCompletedStateChange
PartyChatControlCreatedStateChange
PartyChatControlDestroyedStateChange
PartyManager::GetChatControls
PartyDevice::GetChatControls
PartyNetwork::ConnectChatControl
PartyLocalChatControl::GetLanguage
PartyLocalChatControl::SetTranscriptionOptions
PartyLocalChatControl::SetTranscriptionOptions
PartyLocalDevice::DestroyChatControl
5/24/2022 • 2 minutes to read • Edit Online
Syntax
PartyError DestroyChatControl(
PartyLocalChatControl* localChatControl,
void* asyncIdentifier
)
Parameters
localChatControl PartyLocalChatControl*
The local chat control to destroy.
asyncIdentifier void*
optional
An optional, app-defined, pointer-sized context value that can be used to associate the completion state change
with this call.
Return value
PartyError
c_partyErrorSuccess if the asynchronous operation to destroy the chat control began, or an error code
otherwise. If this method fails, no related state changes will be generated. The human-readable form of the error
code can be retrieved via PartyManager::GetErrorMessage().
Remarks
This method queues an asynchronous attempt to destroy a local chat control. A
PartyDestroyChatControlCompletedStateChange will be provided upon completion of the operation, indicating
success or failure. Before successful completion of the operation, the local chat control will be disconnected from
all networks it was previously connected to (each indicated by a PartyChatControlLeftNetworkStateChange).
Memory for the local chat control will remain valid until all state changes referencing the chat control have been
returned to PartyManager::FinishProcessingStateChanges().
Requirements
Header : Party.h
See also
PartyLocalDevice
PartyDestroyChatControlCompletedStateChange
PartyChatControlDestroyedStateChange
PartyChatControlLeftNetworkStateChange
PartyLocalEndpoint
5/24/2022 • 2 minutes to read • Edit Online
Syntax
class PartyLocalEndpoint : public PartyEndpoint
Public Methods
NAME DESC RIP T IO N
GetLocalUser Gets the local user associated with this local endpoint.
GetEndpointStatistics Gets one or more statistic counter values for the specified
target endpoints.
Requirements
Header : Party.h
See also
Party members
PartyEndpoint
PartyEndpoint::GetLocal
PartyLocalEndpoint::GetLocalUser
5/24/2022 • 2 minutes to read • Edit Online
Syntax
PartyError GetLocalUser(
PartyLocalUser** localUser
)
Parameters
localUser PartyLocalUser**
library-allocated output, may return nullptr
The output local user associated with this local endpoint, or nullptr.
Return value
PartyError
c_partyErrorSuccess if the call succeeded or an error code otherwise. The human-readable form of the error
code can be retrieved via PartyManager::GetErrorMessage().
Remarks
If this endpoint is not associated with a user, localUser is set to nullptr.
Requirements
Header : Party.h
See also
PartyLocalEndpoint
PartyLocalEndpoint::SendMessage
5/24/2022 • 5 minutes to read • Edit Online
Syntax
PartyError SendMessage(
uint32_t targetEndpointCount,
PartyEndpointArray targetEndpoints,
PartySendMessageOptions options,
const PartySendMessageQueuingConfiguration* queuingConfiguration,
uint32_t dataBufferCount,
const PartyDataBuffer* dataBuffers,
void* messageIdentifier
)
Parameters
targetEndpointCount uint32_t
The number of target endpoints in the targetEndpoints array. May be zero to broadcast to all remote endpoints
in the network. A device that receives a broadcast message will have the target endpoint fields of the
PartyEndpointMessageReceivedStateChange populated with all of the device's local endpoints.
targetEndpoints PartyEndpointArray
input array of size targetEndpointCount
The targetEndpointCount entry array of target PartyEndpoint object pointers to which the message should be
sent. This is ignored when targetEndpointCount is zero.
options PartySendMessageOptions
Zero or more option flags describing how to send the message.
queuingConfiguration PartySendMessageQueuingConfiguration*
optional
An optional structure describing how the message should behave while locally queued and waiting for an
opportunity to transmit. May be nullptr to use default queuing behavior.
dataBufferCount uint32_t
The number of buffer structures provided in the dataBuffers array. Must be greater than 0.
dataBuffers PartyDataBuffer*
input array of size dataBufferCount
The dataBufferCount entry array of PartyDataBuffer structures describing the message payload to send.
messageIdentifier void*
optional
An opaque, caller-specific context pointer the Party library will include in any state changes referring to this
message. It is not interpreted or transmitted remotely. May be nullptr if no message identification context is
needed.
Return value
PartyError
c_partyErrorSuccess if enqueuing the message for transmission succeeded or an error code otherwise. If this
method fails, no related state changes will be generated. The human-readable form of the error code can be
retrieved via PartyManager::GetErrorMessage().
Remarks
Sending messages to local endpoints is not currently supported. If the array of target endpoints includes any
local targets, this call will synchronously fail.
If the array of target endpoints is specified as having zero entries, then the message is broadcast to all remote
endpoints currently in the network.
Callers provide 1 or more PartyDataBuffer structures in the dataBuffers array. The memory that the structures
reference does not have to be contiguous, making it easy to have a fixed header buffer followed by a variable
payload, for example. The buffers will be assembled in order, transmitted, and delivered to the targeted
endpoints as a single contiguous data block in a PartyEndpointMessageReceivedStateChange. The Party library
does not expend bandwidth transmitting metadata to describe the original PartyDataBuffer segmentation.
By default, the buffers described in the caller's dataBuffers array are copied to an allocated buffer before
SendMessage() returns. Specifying PartySendMessageOptions::DontCopyDataBuffers will avoid this extra copy
step and instead require the caller to keep the memory specified in each buffer valid and unmodified until a
PartyDataBuffersReturnedStateChange returns ownership of the memory to the caller. The PartyDataBuffer
structures themselves do not need to remain valid after the SendMessage() call returns, only the memory that
they reference.
Messages may not be transmitted to target endpoints right away based on factors such as connection quality
and receiver responsiveness. The local send queue will grow if you are sending faster than the connection to an
endpoint is estimated to currently support. This increases memory usage and may result in increases in
perceived message latency, so callers are strongly recommended to monitor and manage the local send queues.
You can retrieve information about the send queue using PartyLocalEndpoint::GetEndpointStatistics(). You can
manage the send queue by reducing the size and/or frequency of sending, by using the queuingConfiguration
optional settings to configure timeouts that automatically expire messages that have been queued for too long,
or by using PartyLocalEndpoint::CancelMessages() to explicitly remove some or all queued messages.
When this method returns success, the message has begun transmitting or has successfully been enqueued for
future transmission. In particular, a successful return from this method does not imply that the message was
successfully delivered to any recipients. The Party API does not currently provide a way to track the delivery and
processing of individual messages. The PartyNetwork::GetNetworkStatistics() and GetEndpointStatistics()
methods can be used to query aggregate statistics for the network as a whole or for an individual local
endpoint, respectively.
The Party library automatically fragments and reassembles large messages that exceed the maximum size
supported by the environment so that callers are not required to manage this. However, there is a small amount
of overhead associated with fragmentation. Callers that are able to send smaller messages or otherwise
naturally break up large state payloads efficiently themselves may wish to do so.
If SendMessage() is invoked with a zero entry target endpoint array prior to successfully authenticating a first
user into the network, then even though no remote endpoints have been reported via
PartyEndpointCreatedStateChange state changes (and therefore known to exist in the network), the message will
still be queued. Once the first user has successfully authenticated and this sending local endpoint has been
successfully created, the queued message will then target all remote endpoints that exist in the network at that
later time. Because the future state of the network and the set of ultimately receiving endpoints isn't known at
SendMessage() time in this case, titles should exercise caution regarding what content is placed in such deferred
broadcast messages, or simply refrain from submitting them at all until this local device and endpoint are fully
participating in the network.
Requirements
Header : Party.h
See also
PartyLocalEndpoint
PartySendMessageOptions
PartySendMessageQueuingConfiguration
PartyDataBuffersReturnedStateChange
PartyEndpointMessageReceivedStateChange
PartyNetwork::GetNetworkStatistics
PartyLocalEndpoint::GetEndpointStatistics
PartyLocalEndpoint::FlushMessages
PartyLocalEndpoint::FlushMessages
5/24/2022 • 2 minutes to read • Edit Online
Forces all queued messages to the specified endpoints from this local endpoint to be sent as soon as possible
regardless of their coalesce settings.
Syntax
PartyError FlushMessages(
uint32_t targetEndpointCount,
PartyEndpointArray targetEndpoints
)
Parameters
targetEndpointCount uint32_t
This parameter is currently ignored. The number of target endpoints in the targetEndpoints array.
targetEndpoints PartyEndpointArray
input array of size targetEndpointCount
This parameter is currently ignored. A targetEndpointCount entry array of target PartyEndpoint object pointers.
Messages from this local endpoint, up through and including the most recent message to any endpoint in the
array, will be transmitted as soon as possible.
Return value
PartyError
c_partyErrorSuccess if flushing messages succeeded or an error code otherwise. The human-readable form of
the error code can be retrieved via PartyManager::GetErrorMessage().
Remarks
When PartySendMessageOptions::CoalesceOpportunistically or
PartySendMessageOptions::AlwaysCoalesceUntilFlushed is specified in a call to SendMessage(), the message
may not be transmitted immediately and instead be combined with other messages. This coalescing can
improve bandwidth efficiency at the potential expense of perceived latency. This method allows the title to
manually force such coalesced messages to begin transmitting as soon as possible.
Currently this method ignores the targetEndpoints parameter and forces all queued messages from this local
endpoint to be transmitted as soon as possible.
Requirements
Header : Party.h
See also
PartyLocalEndpoint
PartyLocalEndpoint::SendMessage
PartySendMessageOptions
PartyLocalEndpoint::GetEndpointStatistics
5/24/2022 • 2 minutes to read • Edit Online
Gets one or more statistic counter values for the specified target endpoints.
Syntax
PartyError GetEndpointStatistics(
uint32_t targetEndpointCount,
PartyEndpointArray targetEndpoints,
uint32_t statisticCount,
const PartyEndpointStatistic* statisticTypes,
uint64_t* statisticValues
)
Parameters
targetEndpointCount uint32_t
The number of target endpoints in the targetEndpoints array. May be 0 to retrieve statistics for all endpoints
currently in the network, including this local one.
targetEndpoints PartyEndpointArray
input array of size targetEndpointCount
The targetEndpointCount entry array of target PartyEndpoint object pointers for which statistics should be
retrieved. This is ignored when targetEndpointCount is zero.
statisticCount uint32_t
The number of statistics in the input statisticTypes array and to be written in the statisticValues output
array. This must be at least 1.
statisticTypes PartyEndpointStatistic*
input array of size statisticCount
The statisticCount entry input array of unique PartyEndpointStatistic types to retrieve.
statisticValues uint64_t*
output array of size statisticCount
The statisticCount entry output array where the statistic values should be written. Each statistic value will be
written at the same entry index corresponding to where the requested PartyEndpointStatistic appears in the
statisticTypes input array.
Return value
PartyError
c_partyErrorSuccess if retrieving the endpoint statistics succeeded or an error code otherwise. The human-
readable form of the error code can be retrieved via PartyManager::GetErrorMessage().
Remarks
This method is used to retrieve performance counters, queue lengths, historical usage metrics, or other
statistical information recorded between this local endpoint and a target endpoint.
Alternatively, multiple target endpoints can be provided, or a zero-entry array to retrieve statistics for all target
endpoints currently in the network, including this local one. If multiple target endpoints are requested, then the
values returned are the combined statistics for those endpoints. The particular method used to combine
multiple endpoint statistics into a single value depends on and is described by the specific PartyEndpointStatistic
type.
A given PartyEndpointStatistic type may appear in any order in the statisticTypes array, but must not be
specified more than once. Each corresponding statistic value will be written to the statisticValues array in the
same order.
The returned statistic values are always the most current ones available. There is no guarantee they will report
the same value from one GetEndpointStatistics() call to the next, even if there were no intervening calls to
PartyManager::StartProcessingStateChanges() or PartyManager::FinishProcessingStateChanges().
Requirements
Header : Party.h
See also
PartyLocalEndpoint
PartyEndpointStatistic
PartyNetwork::GetNetworkStatistics
PartyLocalUser
5/24/2022 • 2 minutes to read • Edit Online
Syntax
class PartyLocalUser
Public Methods
NAME DESC RIP T IO N
UpdateEntityToken Updates the PlayFab Entity Token associated with this local
user, for use in future authenticated operations.
Requirements
Header : Party.h
See also
Party members
PartyManager::CreateLocalUser
PartyManager::GetLocalUsers
PartyManager::DestroyLocalUser
PartyManager::CreateNewNetwork
PartyNetwork::AuthenticateLocalUser
PartyNetwork::RemoveLocalUser
PartyNetwork::CreateInvitation
PartyNetwork::RevokeInvitation
PartyNetwork::CreateEndpoint
PartyLocalDevice::CreateChatControl
PartyLocalUser::GetEntityId
5/24/2022 • 2 minutes to read • Edit Online
Syntax
PartyError GetEntityId(
PartyString* entityId
)
Parameters
entityId PartyString*
library-allocated output
The output Entity ID.
Return value
PartyError
c_partyErrorSuccess if the call succeeded or an error code otherwise. The human-readable form of the error
code can be retrieved via PartyManager::GetErrorMessage().
Remarks
The retrieved Entity ID is identical to the Entity ID provided by the title via PartyManager::CreateLocalUser().
The memory for the Entity ID string remains valid for the life of the local user, which is until its
PartyDestroyLocalUserCompletedStateChange has been provided via
PartyManager::StartProcessingStateChanges() and all state changes referencing the local user have been
returned to PartyManager::FinishProcessingStateChanges().
Requirements
Header : Party.h
See also
PartyLocalUser
PartyManager::CreateLocalUser
PartyLocalUser::UpdateEntityToken
5/24/2022 • 2 minutes to read • Edit Online
Updates the PlayFab Entity Token associated with this local user, for use in future authenticated operations.
Syntax
PartyError UpdateEntityToken(
PartyString titlePlayerEntityToken
)
Parameters
titlePlayerEntityToken PartyString
The PlayFab Entity Token to associate with the local user.
Return value
PartyError
c_partyErrorSuccess if the call succeeded or an error code otherwise. The human-readable form of the error
code can be retrieved via PartyManager::GetErrorMessage().
Remarks
This method takes a PlayFab Entity Token as titlePlayerEntityToken . No synchronous validation is performed
on this value. When the library performs operations that require user authentication or authorization, such as
creating a network, authenticating into a network, or performing speech-to-text transcription, the Party service
will validate that the token is valid, is not expired, is associated with the same Entity ID that was provided to the
PartyManager::CreateLocalUser() call, and is authorized to perform the operation. If these conditions aren't met,
the operation will fail.
A PlayFab Entity Token can be obtained from the output of a PlayFab login operation and then provided as input
to this method. The token must be associated with a PlayFab Entity of type title_player_account , which, for
most developers, represents the "player" in the most traditional way.
The provided titlePlayerEntityToken must have been acquired using the same Title ID that was passed to
PartyManager::Initialize().
The Party library makes a copy of the supplied PlayFab Entity Token for use in subsequent operations that
require authentication or authorization of the local user, such as PartyManager::CreateNewNetwork() or
PartyNetwork::AuthenticateLocalUser(). If the token provided to this call is expired or otherwise invalid,
operations that require a valid token will fail. A new, valid token can be provided to the Party library by another
call to this method.
The caller is responsible for monitoring the expiration of the entity token provided to this method and
PartyManager::CreateLocalUser(). When the token is nearing or past the expiration time a new token should be
obtained by performing a PlayFab login operation and provided to the Party library by calling this method. It is
recommended to acquire a new token when the previously supplied token is halfway through its validity period.
On platforms that may enter a low power state or otherwise cause the application to pause execution for a long
time, preventing the token from being refreshed before it expires, the token should be checked for expiration
once execution resumes.
Requirements
Header : Party.h
See also
PartyLocalUser
PartyManager::GetErrorMessage
PartyManager::CreateLocalUser
PartyManager::CreateNewNetwork
PartyNetwork::AuthenticateLocalUser
PartyLocalUser::GetCustomContext
5/24/2022 • 2 minutes to read • Edit Online
Retrieves the app's private, custom pointer-sized context value previously associated with this local user object.
Syntax
PartyError GetCustomContext(
void** customContext
)
Parameters
customContext void**
output, may return nullptr
The output custom context.
Return value
PartyError
c_partyErrorSuccess if retrieving the custom context succeeded or an error code otherwise. The human-
readable form of the error code can be retrieved via PartyManager::GetErrorMessage().
Remarks
If no custom context has been set yet, the value pointed to by customContext is set to nullptr.
Requirements
Header : Party.h
See also
PartyLocalUser
PartyLocalUser::SetCustomContext
PartyLocalUser::SetCustomContext
5/24/2022 • 2 minutes to read • Edit Online
Configures an optional, custom pointer-sized context value with this local user object.
Syntax
PartyError SetCustomContext(
void* customContext
)
Parameters
customContext void*
optional
An arbitrary, pointer-sized value to store with the player object.
Return value
PartyError
c_partyErrorSuccess if configuring the custom context succeeded or an error code otherwise. The human-
readable form of the error code can be retrieved via PartyManager::GetErrorMessage().
Remarks
The custom context is typically used as a "shortcut" that simplifies accessing local, title-specific memory
associated with the local user without requiring a mapping lookup. The value is retrieved using the
GetCustomContext() method.
Any configured value is treated as opaque by the library, and is only valid on the local device; it is not
transmitted over the network.
Requirements
Header : Party.h
See also
PartyLocalUser
PartyLocalUser::GetCustomContext
PartyManager
5/24/2022 • 2 minutes to read • Edit Online
The primary management class for interacting with the Party library.
Syntax
class PartyManager
Public Methods
NAME DESC RIP T IO N
GetRegions Gets an array containing the set of regions for which your
title is configured, along with round trip latency information.
Remarks
Only a single instance of the class is permitted.
Requirements
Header : Party.h
See also
Party members
PartyManager::GetSingleton
5/24/2022 • 2 minutes to read • Edit Online
Syntax
PartyManager& GetSingleton(
)
Parameters
Return value
PartyManager&
The PartyManager singleton instance.
Requirements
Header : Party.h
See also
PartyManager
PartyManager::SetOption
5/24/2022 • 2 minutes to read • Edit Online
Syntax
PartyError SetOption(
void* object,
PartyOption option,
const void* value
)
Parameters
object void*
optional
The Party library object that may be required as context for different PartyOption values.
option PartyOption
The Party library option to configure.
value void*
optional
A pointer to the value used to override option . If value is null, the option will be reset to its default value.
Return value
PartyError
c_partyErrorSuccess if the call succeeded or an error code otherwise.
Requirements
Header : Party.h
See also
PartyManager
PartyOption
PartyManager::GetOption
PartyManager::GetOption
5/24/2022 • 2 minutes to read • Edit Online
Syntax
PartyError GetOption(
const void* object,
PartyOption option,
void* value
)
Parameters
object void*
optional
The Party library object that may be required as context for different PartyOption values.
option PartyOption
The Party library option to retrieve.
value void*
output
An output value to fill with the current option setting. If this option has not yet been overridden by a call to
PartyManager::SetOption(), this method will retrieve that option's default value.
Return value
PartyError
c_partyErrorSuccess if the call succeeded or an error code otherwise.
Requirements
Header : Party.h
See also
PartyManager
PartyOption
PartyManager::SetOption
PartyManager::GetErrorMessage
5/24/2022 • 2 minutes to read • Edit Online
Syntax
PartyError GetErrorMessage(
PartyError error,
PartyString* errorMessage
)
Parameters
error PartyError
An error code.
errorMessage PartyString*
library-allocated output
The output, human-readable error message. The memory for the returned string remains valid for the lifetime
of the process.
Return value
PartyError
c_partyErrorSuccess if the call succeeded or an error code otherwise.
Remarks
These error messages are not localized and are only intended for developers, i.e. these error messages are not
intended to be shown to users via UI.
Requirements
Header : Party.h
See also
PartyManager
PartyManager::SerializeNetworkDescriptor
5/24/2022 • 2 minutes to read • Edit Online
Serializes a network descriptor structure into an opaque string that is safe to communicate over title and
platform-specific communication channels.
Syntax
PartyError SerializeNetworkDescriptor(
const PartyNetworkDescriptor* networkDescriptor,
char* serializedNetworkDescriptorString
)
Parameters
networkDescriptor PartyNetworkDescriptor*
The network descriptor to serialize.
serializedNetworkDescriptorString char*
output string buffer of size c_maxSerializedNetworkDescriptorStringLength+1
The output buffer to which the serialized network descriptor string is written. The serialized network descriptor
string will never contain non-ASCII, control, or other characters that would require JSON or XML escaping.
Return value
PartyError
c_partyErrorSuccess if the descriptor is serializable and was successfully serialized, or an error code otherwise.
Remarks
A network descriptor contains all the information required for a device to connect to the network to which the
descriptor is associated. serializedNetworkDescriptorString is the serialized form of the descriptor specified by
networkDescriptor and is safe to communicate over title and platform-specific communication channels. The
string may be up to c_maxSerializedNetworkDescriptorStringLength characters long, not including the null
terminator, and will never contain non-ASCII, control, or other characters that would require JSON or XML
escaping.
This method will fail if the network descriptor is not serializable. For example, the descriptor provided
synchronously by a call to CreateNewNetwork() is not serializable because it does not contain enough
information for a remote client to connect to the new network. The network descriptor changes and becomes
serializable when the PartyCreateNewNetworkCompletedStateChange is provided and indicates success. The
updated network descriptor is provided as a field in the PartyCreateNewNetworkCompletedStateChange. Once
connected to the network, the descriptor can be retrieved using PartyNetwork::GetNetworkDescriptor().
PartyNetworkDescriptors work in tandem with PartyInvitations to facilitate inviting remote users to join the
network. First, obtain the network descriptor via PartyNetwork::GetNetworkDescriptor() and serialize it via
SerializeNetworkDescriptor(). Next, create an invitation via PartyNetwork::CreateInvitation() or query for a
preexisting invitation via PartyNetwork::GetInvitations() and obtain the invitation's identifier from its
configuration via PartyInvitation::GetInvitationConfiguration(). Last, include both the serialized network
descriptor and the invitation identifier in the payload of the platform-specific invite mechanism. When the
remote user receives the invite, they deserialize the network descriptor from the platform-invite payload via
DeserializeNetworkDescriptor() and pass the deserialized descriptor to ConnectToNetwork(). After connecting,
the remote user joins by authenticating into the network via PartyNetwork::AuthenticateLocalUser() with the
invitation identifier in the platform-invite payload.
Requirements
Header : Party.h
See also
PartyManager
PartyManager::DeserializeNetworkDescriptor
PartyNetwork::GetNetworkDescriptor
PartyManager::ConnectToNetwork
PartyInvitation
PartyNetwork::CreateInvitation
PartyNetwork::GetInvitations
PartyInvitation::GetInvitationConfiguration
PartyNetwork::AuthenticateLocalUser
PartyManager::DeserializeNetworkDescriptor
5/24/2022 • 2 minutes to read • Edit Online
Deserializes a network descriptor structure from an opaque string serialized via a prior call to
SerializeNetworkDescriptor().
Syntax
PartyError DeserializeNetworkDescriptor(
PartyString serializedNetworkDescriptorString,
PartyNetworkDescriptor* networkDescriptor
)
Parameters
serializedNetworkDescriptorString PartyString
The serialized network descriptor string.
networkDescriptor PartyNetworkDescriptor*
output
The output network descriptor. serializedNetworkDescriptorString .
Return value
PartyError
c_partyErrorSuccess if the descriptor string is a valid serialized network descriptor string and was successfully
deserialized, or an error code otherwise.
Remarks
The resulting networkDescriptor can be used to connect to a network via ConnectToNetwork().
Requirements
Header : Party.h
See also
PartyManager
PartyManager::SerializeNetworkDescriptor
PartyManager::ConnectToNetwork
PartyManager::SetMemoryCallbacks
5/24/2022 • 2 minutes to read • Edit Online
Optionally configures the memory allocation and freeing callbacks the Party library should use.
Syntax
PartyError SetMemoryCallbacks(
PartyAllocateMemoryCallback allocateMemoryCallback,
PartyFreeMemoryCallback freeMemoryCallback
)
Parameters
allocateMemoryCallback PartyAllocateMemoryCallback
A pointer to the custom allocation callback to use.
freeMemoryCallback PartyFreeMemoryCallback
A pointer to the custom freeing callback to use.
Return value
PartyError
c_partyErrorSuccess if the call succeeded or an error code otherwise. The human-readable form of the error
code can be retrieved via GetErrorMessage().
Remarks
This method allows the title to install custom memory allocation functions in order to service all requests by the
Party library for new memory buffers instead of using its default allocation functions.
To use this method, it must be called before any other Party method except for
PartyManager::GetMemoryCallbacks(). This method cannot be called again for the lifetime of this process.
Requirements
Header : Party.h
See also
PartyManager
PartyAllocateMemoryCallback
PartyFreeMemoryCallback
PartyManager::GetMemoryCallbacks
PartyManager::GetMemoryCallbacks
5/24/2022 • 2 minutes to read • Edit Online
Retrieves the memory allocation and freeing callbacks the Party library is using.
Syntax
PartyError GetMemoryCallbacks(
PartyAllocateMemoryCallback* allocateMemoryCallback,
PartyFreeMemoryCallback* freeMemoryCallback
)
Parameters
allocateMemoryCallback PartyAllocateMemoryCallback*
output
A place to store a pointer to the memory allocation callback currently used.
freeMemoryCallback PartyFreeMemoryCallback*
output
A place to store a pointer to the memory freeing callback currently used.
Return value
PartyError
c_partyErrorSuccess if the call succeeded or an error code otherwise. The human-readable form of the error
code can be retrieved via GetErrorMessage().
Remarks
This retrieves the memory allocation functions servicing requests by the Party library for new memory.
This method does not require the Initialize() method to have been called first.
Requirements
Header : Party.h
See also
PartyManager
PartyAllocateMemoryCallback
PartyFreeMemoryCallback
PartyManager::SetMemoryCallbacks
PartyManager::SetProfilingCallbacksForMethodEntryExit
5/24/2022 • 2 minutes to read • Edit Online
Optionally configures the profiling event callbacks the Party library will make when entering or exiting
instrumented methods.
Syntax
PartyError SetProfilingCallbacksForMethodEntryExit(
PartyProfilingMethodEntranceCallback profilingMethodEntranceCallback,
PartyProfilingMethodExitCallback profilingMethodExitCallback
)
Parameters
profilingMethodEntranceCallback PartyProfilingMethodEntranceCallback
optional
The callback to be made when the Party library enters an internal method which is instrumented for profiling.
profilingMethodExitCallback PartyProfilingMethodExitCallback
optional
The callback to be made when the Party library is about to exit an internal method which is instrumented for
profiling.
Return value
PartyError
c_partyErrorSuccess if the call succeeded or an error code otherwise. The human-readable form of the error
code can be retrieved via GetErrorMessage().
Remarks
This method allows the title to install custom profiling callback functions in order to record and visualize Party
library performance metrics in external profiling tools.
This method can only be called when the Party library is uninitialized. Calling while Party is initialized will fail
and return an error.
Setting an optional callback equal to nullptr will cause the Party library to not make any profiling callbacks for
that event type.
In order to minimize the impact of profiling on title performance, callbacks for these events should be kept as
lightweight as possible, as they are expected to fire hundreds or thousands of times per second.
This method is only supported on the Windows, Xbox One XDK, and Microsoft Game Core versions of the
library. Calls on other platforms will fail.
Requirements
Header : Party.h
See also
PartyManager
PartyProfilingMethodEntranceCallback
PartyProfilingMethodExitCallback
PartyManager::GetProfilingCallbacksForMethodEntryExit
PartyManager::GetProfilingCallbacksForMethodEntryExit
5/24/2022 • 2 minutes to read • Edit Online
Retrieves the profiling event callbacks the Party library is configured to use when entering or exiting
instrumented methods.
Syntax
PartyError GetProfilingCallbacksForMethodEntryExit(
PartyProfilingMethodEntranceCallback* profilingMethodEntranceCallback,
PartyProfilingMethodExitCallback* profilingMethodExitCallback
)
Parameters
profilingMethodEntranceCallback PartyProfilingMethodEntranceCallback*
library-allocated output, may return nullptr
A pointer to the callback made when the Party library enters an internal method which is instrumented for
profiling.
profilingMethodExitCallback PartyProfilingMethodExitCallback*
library-allocated output, may return nullptr
A pointer to the callback made when the Party library is about to exit an internal method which is instrumented
for profiling.
Return value
PartyError
c_partyErrorSuccess if the call succeeded or an error code otherwise. The human-readable form of the error
code can be retrieved via GetErrorMessage().
Remarks
This method retrieves the profiling callback functions the Party library is calling for the instrumented event
types.
A callback equal to nullptr indicates that the Party library will not make any profiling callbacks for that event
type.
This method is only supported on the Windows, Xbox One XDK, and Microsoft Game Core versions of the
library. Calls on other platforms will fail.
Requirements
Header : Party.h
See also
PartyManager
PartyProfilingMethodEntranceCallback
PartyProfilingMethodExitCallback
PartyManager::SetProfilingCallbacksForMethodEntryExit
PartyManager::SetThreadAffinityMask
5/24/2022 • 2 minutes to read • Edit Online
Optionally configures the processor on which internal Party library threads will run.
Syntax
PartyError SetThreadAffinityMask(
PartyThreadId threadId,
uint64_t threadAffinityMask
)
Parameters
threadId PartyThreadId
Remarks
This method enables the title to configure the processor affinity for internal Party library threads of a given type.
On Windows, the Audio type affects both library's directly-owned threads and threads owned by XAudio2. For
more information, see PartyThreadId.
This method may be called at any time before or after Initialize() and will take effect immediately. Thread
processor settings are persisted across calls to Cleanup() and Initialize(). When there are more than 64 cores
present, this method always applies to processor group 0.
In order to specify any processor, pass c_anyProcessor as the threadAffinityMask parameter. This is also the
default value the Party library will use if this method is never called.
Requirements
Header : Party.h
See also
PartyManager
PartyThreadId
PartyManager::GetThreadAffinityMask
PartyManager::GetThreadAffinityMask
5/24/2022 • 2 minutes to read • Edit Online
Retrieves the current set of processors on which internal Party library threads will run or are running as an
affinity mask.
Syntax
PartyError GetThreadAffinityMask(
PartyThreadId threadId,
uint64_t* threadAffinityMask
)
Parameters
threadId PartyThreadId
The type of internal Party library thread for which processor affinity should be retrieved.
threadAffinityMask uint64_t*
output
The output affinity mask for this type of Party library thread.
Return value
PartyError
c_partyErrorSuccess if the call succeeded or an error code otherwise. The human-readable form of the error
code can be retrieved via GetErrorMessage().
Remarks
This retrieves the current processor affinity for internal Party library threads of a given type.
This method does not require Initialize() to have been called first.
A reported value of c_anyProcessor written to threadAffinityMask indicates that the thread is free to run on any
processor.
Requirements
Header : Party.h
See also
PartyManager
PartyThreadId
PartyManager::SetThreadAffinityMask
PartyManager::SetWorkMode
5/24/2022 • 2 minutes to read • Edit Online
Configures the work mode of the Party library processing task associated with threadId .
Syntax
PartyError SetWorkMode(
PartyThreadId threadId,
PartyWorkMode workMode
)
Parameters
threadId PartyThreadId
Remarks
If the work mode is set as PartyWorkMode::Automatic, the processing task associated with threadId is handled
internally by the Party library. If the work mode is configured as PartyWorkMode::Manual, the title must instead
perform the processing task associated with threadId via periodic calls to DoWork().
This method can only be called when the Party library is uninitialized. Calling while initialized will fail and return
an error.
Configuration of the work mode associated with threadId persists across subsequent calls to Cleanup() and
Initialize().
Requirements
Header : Party.h
See also
PartyManager
PartyManager::GetWorkMode
PartyManager::DoWork
PartyManager::GetWorkMode
5/24/2022 • 2 minutes to read • Edit Online
Retrieves the current work mode of the Party library's internal processing task associated with threadId .
Syntax
PartyError GetWorkMode(
PartyThreadId threadId,
PartyWorkMode* workMode
)
Parameters
threadId PartyThreadId
Requirements
Header : Party.h
See also
PartyManager
PartyManager::SetWorkMode
PartyManager::DoWork
PartyManager::Initialize
5/24/2022 • 2 minutes to read • Edit Online
Syntax
PartyError Initialize(
PartyString titleId
)
Parameters
titleId PartyString
Remarks
This must be called before any other method, aside from the static methods GetSingleton(),
SetMemoryCallbacks(), GetMemoryCallbacks(), SetThreadAffinityMask(), GetThreadAffinityMask(),
SerializeNetworkDescriptor(), DeserializeNetworkDescriptor(), SetWorkMode(), and GetWorkMode(). Initialize()
cannot be called again without a subsequent Cleanup() call.
It is recommended for apps using the Xbox One XDK version of the Party library to wait until the platform is
ready for networking operations before calling this method. Please refer to the XDK documentation about
networking and secure device associations best practices for more information.
Apps using the Microsoft Game Core version of the Party library will need to wait for the Game Core
Networking stack to be initialized prior to calling this method. Determining the status of the network stack can
be done using the Game Core XNetworkingGetConnectivityHint API.
Apps using the Microsoft Game Core version of the Party library must listen for app state notifications via the
RegisterAppStateChangeNotification API. When the app is suspended, the app must call
PartyManager::Cleanup(). When the app is resumed, the title must wait for the Game Core networking stack to
ready and then re-initialize the Party library by calling PartyManager::Initialize().
The provided titleId must be the same Title ID used to acquire the PlayFab Entity IDs and Entity Tokens that
will be passed to CreateLocalUser().
Requirements
Header : Party.h
See also
PartyManager
PartyManager::CreateLocalUser
PartyManager::Cleanup
PartyManager::GetSingleton
PartyManager::SetMemoryCallbacks
PartyManager::GetMemoryCallbacks
PartyManager::SetThreadAffinityMask
PartyManager::GetThreadAffinityMask
PartyManager::SerializeNetworkDescriptor
PartyManager::DeserializeNetworkDescriptor
PartyManager::Cleanup
5/24/2022 • 2 minutes to read • Edit Online
Immediately reclaims all resources associated with all Party library objects.
Syntax
PartyError Cleanup(
)
Parameters
Return value
PartyError
c_partyErrorSuccess if the call succeeded or an error code otherwise. The human-readable form of the error
code can be retrieved via GetErrorMessage().
Remarks
If local users were participating in a PartyNetwork, they are removed ungracefully (it appears to remote devices
as if network connectivity to this device has been lost), so best practice is to call PartyNetwork::LeaveNetwork()
first on all networks returned from a call to GetNetworks() and wait for the corresponding
PartyLeaveNetworkCompletedStateChange to have the local users exit any existing PartyNetworks gracefully.
This method is not thread-safe and may not be called concurrently with other non-static Party library methods.
After calling this method, all Party library state is invalidated.
Titles using the Microsoft Game Core version of the Party library must listen for app state notifications via the
RegisterAppStateChangeNotification API. When the app is suspended, the title must call
PartyManager::Cleanup(). When the app is resumed, the title must wait for the Game Core networking stack to
be ready and then re-initialize the Party library by calling PartyManager::Initialize().
Requirements
Header : Party.h
See also
PartyManager
PartyManager::Initialize
PartyNetwork::LeaveNetwork
PartyManager::GetNetworks
PartyManager::StartProcessingStateChanges
5/24/2022 • 2 minutes to read • Edit Online
Retrieves an array of all PartyStateChanges to process since the last such call.
Syntax
PartyError StartProcessingStateChanges(
uint32_t* stateChangeCount,
PartyStateChangeArray* stateChanges
)
Parameters
stateChangeCount uint32_t*
output
The output number of PartyStateChange entries for the title to handle in the stateChanges array.
stateChanges PartyStateChangeArray*
library-allocated output array of size *stateChangeCount
A library-allocated output array of all PartyStateChange entries for the title to handle and then pass to
FinishProcessingStateChanges().
Return value
PartyError
c_partyErrorSuccess if the call succeeded or an error code otherwise. The human-readable form of the error
code can be retrieved via GetErrorMessage().
Remarks
This method provides the Party library an opportunity to synchronize state with remote devices or services, and
retrieves a list of all changes currently available for the title since the last call to this method. The title should use
the provided array of 0 or more changes to update its own state or UI, and then call
FinishProcessingStateChanges() with them in a timely manner.
Party library state exposed by the library can change during this call, so you must be thread-safe in your use of
it. For example, invoking StartProcessingStateChanges() on your UI thread at the same time a separate worker
thread is looping through the list of endpoints returned by PartyNetwork::GetEndpoints() may result in crashes
because StartProcessingStateChanges() can alter the memory associated with the endpoint list.
StartProcessingStateChanges() should be called frequently-- at least once per graphics frame. It's designed to
execute and return quickly such that it can be called on your main UI thread with negligible impact. For best
results, you should also minimize the time you spend handling state changes before calling
FinishProcessingStateChanges().
See also
PartyManager
PartyStateChange
PartyManager::FinishProcessingStateChanges
PartyManager::FinishProcessingStateChanges
5/24/2022 • 2 minutes to read • Edit Online
Syntax
PartyError FinishProcessingStateChanges(
uint32_t stateChangeCount,
PartyStateChangeArray stateChanges
)
Parameters
stateChangeCount uint32_t
The number of changes, provided in the list specified by stateChanges , previously returned by
StartProcessingStateChanges() that have now been handled by the title.
stateChanges PartyStateChangeArray
input array of size stateChangeCount
The array of changes previously returned by StartProcessingStateChanges() that have now been handled by the
title.
Return value
PartyError
c_partyErrorSuccess if the call succeeded or an error code otherwise. The human-readable form of the error
code can be retrieved via GetErrorMessage().
Remarks
This method informs the Party library that the state changes reported by a previous call to
StartProcessingStateChanges() have now been handled by the title, so their associated resources can be
reclaimed. You may call FinishProcessingStateChanges() with any number of state changes. Each state change
returned by StartProcessingStateChanges() must be returned to FinishProcessingStateChanges() exactly once,
but may be returned out of order and may be interleaved with state changes from other calls to
StartProcessingStateChanges(). Even if state changes are held across subsequent calls to
StartProcessingStateChanges(), the Party library state returned by all getters will advance and may no longer
reflect the same state that the held state changes refer to.
Any resources associated with a specific state change are guaranteed to stay valid until the state change is
returned to FinishProcessingStateChanges().
For best results, you should minimize the time you spend handling state changes before calling
FinishProcessingStateChanges().
Requirements
Header : Party.h
See also
PartyManager
PartyStateChange
PartyManager::StartProcessingStateChanges
PartyManager::DoWork
5/24/2022 • 2 minutes to read • Edit Online
Syntax
PartyError DoWork(
PartyThreadId threadId
)
Parameters
threadId PartyThreadId
Remarks
This method will fail and return an error if the work mode of threadId has not previously been set to
PartyWorkMode::Manual via a call to SetWorkMode(). Additionally, on the Windows, Xbox One XDK, and
Microsoft Game Core versions of the library, this method will fail and return an error if the title thread calling
this method does not exist in a COM multithreaded apartment when threadId is PartyThreadId::Networking.
By default, the Party library will internally manage the processing task associated with threadId . However, if the
work mode of threadId is configured as PartyWorkMode::Manual via a call to SetWorkMode(), the title must
periodically call this method to perform the processing task instead.
The processing task associated with threadId dictates the frequency at which this method should be called. The
processing task associated with PartyThreadId::Audio should be performed every 40ms, while the processing
task associated with PartyThreadId::Networking should be performed every 50 to 100ms. Internally, processing
tasks will attempt to handle small variations in timing, but issues will arise if timing strays too far from what is
expected (e.g. audio stutter, network state desynchronization).
For more information on processing task types and timing expectations, see PartyThreadId.
Requirements
Header : Party.h
See also
PartyManager
PartyManager::SetWorkMode
PartyManager::GetWorkMode
PartyManager::GetRegions
5/24/2022 • 2 minutes to read • Edit Online
Gets an array containing the set of regions for which your title is configured, along with round trip latency
information.
Syntax
PartyError GetRegions(
uint32_t* regionCount,
const PartyRegion** regions
)
Parameters
regionCount uint32_t*
output
The output number of regions provided in regions .
regions PartyRegion**
library-allocated output array of size *regionCount
Remarks
The array provided by this method is not populated until the first PartyRegionsChangedStateChange is provided.
Each subsequent PartyRegionsChangedStateChange indicates an update to this set of regions. Background
operations to populate this set begin when Initialize() is called and, if this set hasn't yet been successfully
populated, when CreateNewNetwork() is called.
The array will be sorted in order of increasing latency. Latency for a region is defined as the end-to-end time it
takes to send a UDP datagram to the PlayFab Quality of Service beacon for that region and receive a response.
The library will measure latency for each region several times in order to calculate high fidelity results.
A latency equivalent to UINT32_MAX indicates that the region is supported but latency information could not be
determined, either due to failures internal to the library or a ping timeout was reached without receiving a
response from the beacon. This can be used for diagnostic purposes (a UINT32_MAX latency to every region
likely indicates a local configuration problem) or used to filter out regions that are unlikely to be viable during
region selection.
The returned names in the PartyRegion structures are not localized to the current user's language, and showing
the strings directly in UI is not recommended outside of troubleshooting.
You shouldn't assume the set of regions returned will remain the same over the life of your title. The PlayFab
Party library will automatically take advantage of additions and changes to available regions over time to
continually improve the experience for end users.
After internally retrieving the set of regions, the worst-case time for failing latency measurements to every
region would be approximately 500 milliseconds multiplied by the number of regions, but measurements are
actually performed in parallel to reduce the overall duration. Successful latency measurement time varies by
network environment. Currently most devices worldwide successfully complete the entire measurement process
in 2.2 seconds or less, and 95% of devices successfully complete in less than 6 seconds. This may increase
slightly over time as additional regions are introduced.
Requirements
Header : Party.h
See also
PartyManager
PartyRegionsChangedStateChange
PartyManager::CreateNewNetwork
PartyManager::CreateNewNetwork
5/24/2022 • 6 minutes to read • Edit Online
Syntax
PartyError CreateNewNetwork(
const PartyLocalUser* localUser,
const PartyNetworkConfiguration* networkConfiguration,
uint32_t regionCount,
const PartyRegion* regions,
const PartyInvitationConfiguration* initialInvitationConfiguration,
void* asyncIdentifier,
PartyNetworkDescriptor* networkDescriptor,
char* appliedInitialInvitationIdentifier
)
Parameters
localUser PartyLocalUser*
The local user to which the network creation and relay allocation is attributed.
networkConfiguration PartyNetworkConfiguration*
Network configuration properties such as max user count and max device count. These properties last for the
lifetime of the network and cannot be changed.
regionCount uint32_t
The number of regions provided in the array of preferred regions specified via regions . If this is zero, the
library will use all regions in which the title is configured, ordered by lowest round trip latency from this device.
regions PartyRegion*
The array of preferred regions in which the network should be created. The network will be created in the first
available region.
initialInvitationConfiguration PartyInvitationConfiguration*
optional
An optionally specified configuration for the initial invitation.
If this value is null, then default configuration values will be used. By default, PlayFab Party will generate a
unique invitation identifier for the title, the revocability will be PartyInvitationRevocability::Anyone, and the
PlayFab Entity ID list will be empty, allowing any user to join using the invitation.
If a configuration is provided, the title may optionally specify the identifier on the configuration. If the identifier
is nullptr or an empty string, the PlayFab Party library will generate an identifier for the title. It is guaranteed that
this generated identifier will be different from all identifiers that the PlayFab Party library will generate for all
future invitations on this network across all devices. Titles may specify their own identifier by providing a non-
null, non-empty value in the configuration. If the title specifies the identifier, it is the title's responsibility to
ensure that this identifier does not collide with the identifiers of future invitations created on this network via
PartyNetwork::CreateInvitation() on any device.
If a configuration is provided and the list of PlayFab Entity IDs is empty, all users will be allowed to join using the
new invitation.
asyncIdentifier void*
optional
An optional, app-defined, pointer-sized context value that can be used to associate the completion state change
with this call.
networkDescriptor PartyNetworkDescriptor*
optional output
The optional, output network descriptor that can be used to immediately queue a connection of the local device
to the newly created network via ConnectToNetwork().
appliedInitialInvitationIdentifier char*
optional output string buffer of size c_maxInvitationIdentifierStringLength+1
The optional, output buffer to which the initial invitation's identifier is written. If initialInvitationConfiguration
has been provided with a non-null, non-empty identifier, then this buffer will be filled with the same identifier. If
an initial configuration was not provided or the provided configuration had an empty or null identifier, the
PlayFab Party library will generate one and return it to the title in this buffer.
Return value
PartyError
c_partyErrorSuccess if the asynchronous operation to create a new network began, or an error code otherwise.
If this method fails, no related state changes will be generated. The human-readable form of the error code can
be retrieved via GetErrorMessage().
Remarks
A PartyNetwork is a set of devices, such as Xbox One consoles and PCs, that are connected via a client-server
topology to a transparent cloud relay server. Each device in the network contains a collection of endpoints
associated with the network; directed messages can be sent from an endpoint on the local device to any set of
endpoints, or broadcast to all endpoints. This method queues an attempt to allocate a relay, thus creating a new
network, on behalf of the user represented by localUser but does not connect the local device to the network.
If no devices connect to the network within ten minutes of the relay's creation, it will shut down. The network
will stay active indefinitely while at least one device is connected, migrating to a new relay if required. If no
devices are connected to the network, the relay will become inactive and shut down after one minute of
inactivity.
The local device can queue an attempt to connect to the new network by immediately passing
networkDescriptor to ConnectToNetwork(). Using this descriptor with SerializeNetworkDescriptor() will result in
failure because the descriptor does not contain enough information for a remote device to connect to the
network. The network descriptor changes and becomes serializable when the
PartyCreateNewNetworkCompletedStateChange is provided and indicates success. The updated network
descriptor is provided as a field in the PartyCreateNewNetworkCompletedStateChange. Once connected to the
network, the descriptor can be retrieved using PartyNetwork::GetNetworkDescriptor().
The network is created in the first available region using the order specified in regions . If none of the specified
regions are available, the network will not be created. Specifying 0 for regionCount defaults to using all regions
in which the title is configured, ordered by lowest latency to this device.
Note that the default region selection only includes latency measurements from this device and not from any
other devices. Titles that have a set of participants for the session known up front should implement
functionality to gather measurements from all devices prior to creating the network and construct a new
regions array ordered by lowest aggregate latency for the whole group.
For titles that support join-in-progress, the region with the best overall latency for the group of connected
participants may change as devices join and leave. Titles should take advantage of Party's support for being
connected to multiple networks simultaneously to migrate devices seamlessly to a network created in a region
with better aggregate latency for the group. The title can gather region latency measurements via messages
over the original Party network or information uploaded to an external roster service, create a new Party
network in a region with lower aggregate latency, and instruct all devices to connect to the more favorable
network and disconnect from the original one.
The initial invitation for the newly created network will not be owned by any user. Therefore calling
PartyInvitation::GetCreatorEntityId() will return nullptr for the initial invitation. As well, the initial invitation for
the newly created network will persist for the lifetime of the network until specifically revoked via
PartyNetwork::RevokeInvitation(). New invitations can be created for the network via
PartyNetwork::CreateInvitation() by local users that are authenticated into the network, and those invitations will
persist until their creating local users are removed from the network. Users join the network via
PartyNetwork::AuthenticateLocalUser() by providing the identifier of an invitation that was successfully created,
has not been revoked, and allows them to join.
Retrying on failure
When CreateNewNetwork() fails asynchronously, a PartyCreateNewNetworkCompletedStateChange is provided
by StartProcessingStateChanges indicating the result. The operation may be retried after a delay, depending on
the PartyStateChangeResult provided.
InternetConnectivityError Retry with a small delay of no less than 10 seconds. For your
app, it may be more appropriate to display the error to the
user immediately, rather than retrying automatically.
UserNotAuthorized This result can mean that the user's entity token was invalid,
expired, or that the user was not authorized for other
reasons. Retry no more than one time, and only after getting
a new entity token for the user and calling
PartyLocalUser::UpdateEntityToken().
RESULT RET RY B EH AVIO R
FailedToBindToLocalUdpSocket This result means that the library couldn't bind to the local
UDP socket specified in the
PartyOption::LocalUdpSocketBindAddress option. The title
must clean up its instance of the library, update the
PartyOption::LocalUdpSocketBindAddress option to a valid,
available bind address, and re-initialize the library.
Requirements
Header : Party.h
See also
PartyManager
PartyCreateNewNetworkCompletedStateChange
PartyManager::ConnectToNetwork
PartyNetwork::AuthenticateLocalUser
PartyNetwork::LeaveNetwork
PartyNetwork::RevokeInvitation
PartyNetwork::CreateInvitation
PartyInvitation
PartyInvitationConfiguration
PartyManager::ConnectToNetwork
5/24/2022 • 2 minutes to read • Edit Online
Syntax
PartyError ConnectToNetwork(
const PartyNetworkDescriptor* networkDescriptor,
void* asyncIdentifier,
PartyNetwork** network
)
Parameters
networkDescriptor PartyNetworkDescriptor*
The descriptor associated with the network to which a connection will be established.
asyncIdentifier void*
optional
An optional, app-defined, pointer-sized context value that can be used to associate the completion state change
with this call.
network PartyNetwork**
optional, library-allocated output
The optional, output network object.
Return value
PartyError
c_partyErrorSuccess if the asynchronous operation to connect to a new network began, or an error code
otherwise. If this method fails, no related state changes will be generated. The human-readable form of the error
code can be retrieved via GetErrorMessage().
Remarks
This method queues an asynchronous attempt to connect to the network associated with networkDescriptor by
negotiating and establishing a secure DTLS connection from the local device to the transparent cloud relay
server. A PartyConnectToNetworkCompletedStateChange will be provided upon completion of the
asynchronous operation, indicating success or failure. On success, the local device will have established a
connection to the transparent cloud relay server. On failure, a PartyNetworkDestroyedStateChange will be
generated. No other devices will become visible, and the local device will not be visible to any remote devices,
until at least one local user is successfully authenticated via PartyNetwork::AuthenticateLocalUser().
After the device successfully connects to the network, it must authenticate into the network via
PartyNetwork::AuthenticateLocalUser(). If the device is connected to the network but unauthenticated for more
than one minute, the device will be disconnected and a PartyNetworkDestroyedStateChange will be generated.
This will occur regardless of whether the device never authenticated or lost authentication after calling
PartyNetwork::RemoveLocalUser().
This method optionally provides network as output that can immediately be used to perform asynchronous
network operations, such as PartyNetwork::CreateInvitation() and PartyNetwork::CreateEndpoint(). These
asynchronous operations will be internally queued until the connection completes, at which point they will be
processed. This network will also be provided on the resulting PartyConnectToNetworkCompletedStateChange
where it will be fully connected and associated with the provided asyncIdentifier .
On successful return, this method invalidates the memory for any array previously returned by GetNetworks(),
as it synchronously adds the new network to the array. StartProcessingStateChanges() also invalidates the
memory for the array. The returned network object will be valid until a PartyNetworkDestroyedStateChange has
been generated and all state changes referencing the object have been returned to
FinishProcessingStateChanges().
Retrying on failure
When ConnectToNetwork() fails asynchronously, a PartyConnectToNetworkCompletedStateChange is provided
by StartProcessingStateChanges() indicating the result. The operation may be retried after a delay, depending on
the PartyStateChangeResult provided.
InternetConnectivityError Retry with a small delay of no less than 10 seconds. For your
app, it may be more appropriate to display the error to the
user immediately, rather than retrying automatically.
FailedToBindToLocalUdpSocket This result means that the library couldn't bind to the local
UDP socket specified in the
PartyOption::LocalUdpSocketBindAddress option. The title
must clean up its instance of the library, update the
PartyOption::LocalUdpSocketBindAddress option to a valid,
available bind address, and re-initialize the library.
Requirements
Header : Party.h
See also
PartyManager
PartyConnectToNetworkCompletedStateChange
PartyNetworkDestroyedStateChange
PartyNetworkConfiguration
PartyManager::CreateNewNetwork
PartyManager::GetNetworks
PartyNetwork::AuthenticateLocalUser
PartyNetwork::RemoveLocalUser
PartyNetwork::CreateInvitation
PartyNetwork::RevokeInvitation
PartyNetwork::CreateEndpoint
PartyNetwork::LeaveNetwork
PartyManager::GetLocalDevice
5/24/2022 • 2 minutes to read • Edit Online
Syntax
PartyError GetLocalDevice(
PartyLocalDevice** localDevice
)
Parameters
localDevice PartyLocalDevice**
library-allocated output
The output local device.
Return value
PartyError
c_partyErrorSuccess if the call succeeded or an error code otherwise. The human-readable form of the error
code can be retrieved via GetErrorMessage().
Remarks
The local device represents the physical device on which the title is executing, such as an Xbox One or PC. Once
the library is initialized, this method will always succeed in returning a local device. The local device will also
appear in the device list of any network to which the local device has connected via ConnectToNetwork().
Requirements
Header : Party.h
See also
PartyManager
PartyManager::CreateLocalUser
5/24/2022 • 2 minutes to read • Edit Online
Creates a local user object that is used to represent a local user when performing networking and chat
operations.
Syntax
PartyError CreateLocalUser(
PartyString entityId,
PartyString titlePlayerEntityToken,
PartyLocalUser** localUser
)
Parameters
entityId PartyString
Remarks
This method takes a PlayFab Entity ID as entityId and a PlayFab Entity Token as titlePlayerEntityToken . No
synchronous validation is performed on these values except that the length of entityId is less than or equal to
c_maxEntityIdStringLength . When the library performs operations that require user authentication or
authorization, such as creating a network, authenticating into a network, or performing speech-to-text
transcription, the Party service will validate that the token is valid, is not expired, is associated with the Entity ID
provided, and is authorized to perform the operation. If these conditions aren't met, the operation will fail.
A PlayFab Entity ID and Entity Token can be obtained from the output of a PlayFab login operation and then
provided as input to this method. The PlayFab Entity ID must be of type title_player_account , which, for most
developers, represents the "player" in the most traditional way.
The provided entityId and titlePlayerEntityToken must have been acquired using the same Title ID that was
passed to Initialize().
The Party library makes a copy of the supplied PlayFab Entity Token for use in subsequent operations that
require authentication or authorization of the local user, such as CreateNewNetwork() or
PartyNetwork::AuthenticateLocalUser(). If the token provided to this call is expired or otherwise invalid,
operations that require a valid token will fail. A new, valid token can be provided to the Party library via a call to
PartyLocalUser::UpdateEntityToken().
The caller is responsible for monitoring the expiration of the entity token provided to this method and
PartyLocalUser::UpdateEntityToken(). When the token is nearing or past the expiration time a new token should
be obtained by performing a PlayFab login operation and provided to the Party library by calling
PartyLocalUser::UpdateEntityToken(). It is recommended to acquire a new token when the previously supplied
token is halfway through its validity period. On platforms that may enter a low power state or otherwise cause
the application to pause execution for a long time, preventing the token from being refreshed before it expires,
the token should be checked for expiration once execution resumes.
Only c_maxLocalUsersPerDeviceCount PartyLocalUser objects may exist simultaneously at any given time. This
method will synchronously fail if creating another local user would exceed that limit.
On successful return, this method invalidates the memory for any array previously returned by GetLocalUsers(),
as it synchronously adds the new user to the array. StartProcessingStateChanges() also invalidates the memory
for the array. The returned localUser object will be valid until a PartyDestroyLocalUserCompletedStateChange
has been generated and all state changes referencing the object have been returned to
FinishProcessingStateChanges().
Requirements
Header : Party.h
See also
PartyManager
PartyDestroyLocalUserCompletedStateChange
PartyManager::Initialize
PartyManager::GetLocalUsers
PartyManager::DestroyLocalUser
PartyManager::CreateNewNetwork
PartyNetwork::AuthenticateLocalUser
PartyNetwork::RemoveLocalUser
PartyNetwork::CreateInvitation
PartyNetwork::RevokeInvitation
PartyNetwork::CreateEndpoint
PartyLocalUser::UpdateEntityToken
PartyLocalDevice::CreateChatControl
PartyManager::DestroyLocalUser
5/24/2022 • 2 minutes to read • Edit Online
Syntax
PartyError DestroyLocalUser(
const PartyLocalUser* localUser,
void* asyncIdentifier
)
Parameters
localUser PartyLocalUser*
The local user to destroy.
asyncIdentifier void*
optional
An optional, app-defined, pointer-sized context value that can be used to associate the completion state change
with this call.
Return value
PartyError
c_partyErrorSuccess if the operation to destroy the local user started or an error code otherwise. If this method
fails, no related state changes will be generated. The human-readable form of the error code can be retrieved via
GetErrorMessage().
Remarks
This method queues an asynchronous operation to destroy a local user. A
PartyDestroyLocalUserCompletedStateChange will be provided upon completion of the operation, indicating
success or failure. Before successful completion of the operation, the local user will be removed from all
networks it has authenticated into (each indicated by a PartyLocalUserRemovedStateChange) and any local chat
control associated with the user will be destroyed (indicated by a PartyChatControlDestroyedStateChange).
Memory for the local user will remain valid until all state changes referencing the local user have been returned
to PartyManager::FinishProcessingStateChanges().
Requirements
Header : Party.h
See also
PartyManager
PartyDestroyLocalUserCompletedStateChange
PartyChatControlDestroyedStateChange
PartyLocalUserRemovedStateChange
PartyManager::GetLocalUsers
PartyManager::GetLocalUsers
5/24/2022 • 2 minutes to read • Edit Online
Syntax
PartyError GetLocalUsers(
uint32_t* userCount,
PartyLocalUserArray* localUsers
)
Parameters
userCount uint32_t*
output
The output number of local users provided in localUsers .
localUsers PartyLocalUserArray*
library-allocated output array of size *userCount
Remarks
Once a PartyDestroyLocalUserCompletedStateChange has been provided by
PartyManager::StartProcessingStateChanges(), the local user will no longer be present in the array returned by
this method.
The memory for the returned array is invalidated whenever the title calls
PartyManager::StartProcessingStateChanges() or CreateLocalUser() returns success.
Requirements
Header : Party.h
See also
PartyManager
PartyManager::CreateLocalUser
PartyManager::DestroyLocalUser
PartyDestroyLocalUserCompletedStateChange
PartyManager::GetNetworks
5/24/2022 • 2 minutes to read • Edit Online
Gets an array of all networks to which the local device is connected or connecting.
Syntax
PartyError GetNetworks(
uint32_t* networkCount,
PartyNetworkArray* networks
)
Parameters
networkCount uint32_t*
output
The output number of networks to which the local device is connected or connecting provided in networks .
networks PartyNetworkArray*
library-allocated output array of size *networkCount
A library-allocated output array containing the networks to which the local device is connected or connecting.
Return value
PartyError
c_partyErrorSuccess if the call succeeded or an error code otherwise. The human-readable form of the error
code can be retrieved via GetErrorMessage().
Remarks
Once a PartyNetworkDestroyedStateChange has been provided by
PartyManager::StartProcessingStateChanges(), the network will no longer be present in the array returned by
this method.
The memory for the returned array is invalidated whenever the title calls
PartyManager::StartProcessingStateChanges() or ConnectToNetwork() returns success.
Requirements
Header : Party.h
See also
PartyManager
PartyManager::ConnectToNetwork
PartyNetwork::LeaveNetwork
PartyNetworkDestroyedStateChange
PartyManager::GetChatControls
5/24/2022 • 2 minutes to read • Edit Online
Gets an array that contains a combined list of all chat controls on the local device and all remote devices.
Syntax
PartyError GetChatControls(
uint32_t* chatControlCount,
PartyChatControlArray* chatControls
)
Parameters
chatControlCount uint32_t*
output
The output number of chat controls provided in chatControls .
chatControls PartyChatControlArray*
library-allocated output array of size *chatControlCount
A library-allocated output array containing the list of all chat controls.
Return value
PartyError
c_partyErrorSuccess if the call succeeded or an error code otherwise. The human-readable form of the error
code can be retrieved via GetErrorMessage().
Remarks
Once a PartyChatControlDestroyedStateChange has been provided by
PartyManager::StartProcessingStateChanges(), the chat control will no longer be present in the array returned
by this method.
The memory for the returned array is invalidated whenever the title calls
PartyManager::StartProcessingStateChanges() or PartyLocalDevice::CreateChatControl() returns success.
Requirements
Header : Party.h
See also
PartyManager
PartyLocalDevice::CreateChatControl
PartyLocalDevice::DestroyChatControl
PartyChatControlDestroyedStateChange
PartyNetwork
5/24/2022 • 2 minutes to read • Edit Online
Represents a network.
Syntax
class PartyNetwork
Public Methods
NAME DESC RIP T IO N
GetNetworkConfiguration Gets the network configuration which was set when creating
the network.
GetNetworkStatistics Gets one or more statistic counter values for the network.
GetDeviceConnectionType Retrieves the type of connection used by the local device for
transmitting messages or chat data to the specified target
device in this network.
Requirements
Header : Party.h
See also
Party members
PartyNetwork::AuthenticateLocalUser
5/24/2022 • 4 minutes to read • Edit Online
Queues an asynchronous operation to authenticate the specified local user into the network.
Syntax
PartyError AuthenticateLocalUser(
const PartyLocalUser* localUser,
PartyString invitationIdentifier,
void* asyncIdentifier
)
Parameters
localUser PartyLocalUser*
The local user to authenticate into the network.
invitationIdentifier PartyString
The identifier of the invitation that allows the localUser to authenticate into the network.
asyncIdentifier void*
optional
An optional, app-defined, pointer-sized context value that can be used to associate the completion state change
with this call.
Return value
PartyError
c_partyErrorSuccess if the asynchronous operation to authenticate the local user began, or an error code
otherwise. If this method fails, no related state changes will be generated. The human-readable form of the error
code can be retrieved via PartyManager::GetErrorMessage().
Remarks
While any device with the appropriate network descriptor can establish a connection to the network, no useful
actions can be performed, and no useful information can be gleaned, without first authenticating a local user on
the device into the network. As such, authentication is an important security measure to ensure the integrity of
the network and the privacy of the devices and users participating in the network. To authenticate a user is to
have the transparent cloud relay server validate the user's identity and that the user is allowed to join the
network.
Upon successful completion of the asynchronous operation started by this call, a user is considered
authenticated into the network. Completion is indicated by the
PartyAuthenticateLocalUserCompletedStateChange. Successful authentication requires that the local user's
PlayFab Entity Token is valid and is associated with the local user's PlayFab Entity ID. Successful authentication
also requires that the provided invitation allows the provided local user to join the network. Authentication will
fail if authenticating the provided user would violate one of the limits in the network's configuration. These
requirements are enforced by the transparent cloud relay server. If the asynchronous operation fails, the
PartyAuthenticateLocalUserCompletedStateChange will provide a diagnostic result and error detail, and a
PartyLocalUserRemovedStateChange will be generated. Because being connected to a network with no
authenticated users is not a useful state outside of transition periods, the Party library will automatically
disconnect a device that does not have an authenticated user for an extended period.
Users need an invitationIdentifier to call this method and authenticate into the network. Most commonly this
means that another device will have to share the identifier of the initial invitation generated via
PartyManager::CreateNewNetwork() or share the identifier of an invitation it has generated via
CreateInvitation().
User authentication also determines device authentication. A device is considered authenticated into the
network if at least one local user is authenticated into the network. If a device is authenticated into the network,
it will be visible to all other authenticated devices. If a device is connected to the network but not authenticated,
no remote devices, endpoints, or chat controls, will be visible. Similarly, the device will not be visible to any other
devices connected to the network.
Once this method is called, all other methods that queue asynchronous operations but require the local user or
local device to be authenticated into the network can be called. Such operations will be queued until completion
of the authentication operation. Once the authentication operation completes, the queued operations will be
processed. If the authentication operation failed, the queued operations will also fail and their respective
completion state changes will indicate such.
If the local device enters a state in which there are no authenticated users and no authentication operations in
progress, then all endpoints, including those that are not fully created, will be destroyed automatically. This will
be signaled by PartyEndpointDestroyedStateChanges.
On successful return, this method invalidates the memory for any array previously returned by
PartyNetwork::GetLocalUsers(), as it synchronously adds the new user to the array.
PartyManager::StartProcessingStateChanges() also invalidates the memory for the array.
This method will fail if the specified localUser is in the process of authenticating into the network, is already
authenticated into the network, is authenticated but in the process of being removed due to a previous call to
PartyNetwork::RemoveLocalUser(), or if the device overall is in the process of becoming unauthenticated due to
its last authenticated user being removed from the network.
Retrying on failure
If the PartyAuthenticateLocalUserCompletedStateChange associated with the completion of this call indicates a
failure, the operation may be retried after a delay. The proper retry behavior depends on the
PartyStateChangeResult provided in the state change.
InternetConnectivityError Retry with a small delay of no less than 10 seconds. For your
app, it may be more appropriate to display the error to the
user immediately, rather than retrying automatically.
UserNotAuthorized This result can mean that the user's entity token was invalid,
expired, or that the user was not authorized for other
reasons. It could also mean that specified invitation is no
longer valid, or the invitation does not contain this user.
Retry no more than one time, and only after getting a new
entity token for the user and calling
PartyLocalUser::UpdateEntityToken().
FailedToBindToLocalUdpSocket This result means that the library couldn't bind to the local
UDP socket specified in the
PartyOption::LocalUdpSocketBindAddress option. The title
must clean up its instance of the library, update the
PartyOption::LocalUdpSocketBindAddress option to a valid,
available bind address, and re-initialize the library.
Requirements
Header : Party.h
See also
PartyNetwork
PartyAuthenticateLocalUserCompletedStateChange
PartyEndpointDestroyedStateChange
PartyLocalUserRemovedStateChange
PartyNetworkConfiguration
PartyManager::CreateLocalUser
PartyNetwork::RemoveLocalUser
PartyNetwork::GetLocalUsers
PartyManager::CreateNewNetwork
PartyNetwork::CreateInvitation
PartyNetwork::RemoveLocalUser
5/24/2022 • 2 minutes to read • Edit Online
Syntax
PartyError RemoveLocalUser(
const PartyLocalUser* localUser,
void* asyncIdentifier
)
Parameters
localUser PartyLocalUser*
The local user to remove from the network.
asyncIdentifier void*
optional
An optional, app-defined, pointer-sized context value that can be used to associate the completion state change
with this call.
Return value
PartyError
c_partyErrorSuccess if the asynchronous operation to remove the local user began, or an error code otherwise.
If this method fails, no related state changes will be generated. The human-readable form of the error code can
be retrieved via PartyManager::GetErrorMessage().
Remarks
Upon completion of the asynchronous operation, a user is no longer considered authenticated into the network.
Completion is indicated by a PartyRemoveLocalUserCompletedStateChange. The asynchronous operation will
always succeed, and a PartyLocalUserRemovedStateChange will always be provided before the
PartyRemoveLocalUserCompletedStateChange. Before successful completion of the operation, all endpoints
associated with that user will be destroyed (each indicated by a PartyEndpointDestroyedStateChange) and all
chat controls associated with that user will be disconnected from the network (each indicated by a
PartyChatControlLeftNetworkStateChange).
When all local users are removed from the network, the device is no longer considered authenticated. All
endpoints are destroyed and all remote devices will appear to leave the network, because they are no longer
visible to the local device. Similarly, all remote devices will see the local device as having left the network. The
device will not immediately be disconnected and can again be authenticated by a new call to
AuthenticateLocalUser(). However, because being connected to a network with no authenticated users is not a
useful state outside of transition periods, the Party library will automatically disconnect a device that is
unauthenticated for more than one minute.
This method will fail if the specified localUser is already in the process of being removed from the network due
to a previous call to this method.
Requirements
Header : Party.h
See also
PartyNetwork
PartyRemoveLocalUserCompletedStateChange
PartyEndpointDestroyedStateChange
PartyChatControlLeftNetworkStateChange
PartyNetwork::AuthenticateLocalUser
PartyNetwork::GetLocalUsers
PartyNetwork::CreateInvitation
5/24/2022 • 3 minutes to read • Edit Online
Syntax
PartyError CreateInvitation(
const PartyLocalUser* localUser,
const PartyInvitationConfiguration* invitationConfiguration,
void* asyncIdentifier,
PartyInvitation** invitation
)
Parameters
localUser PartyLocalUser*
The local user that owns the invitation in the network. If this local user leaves the network for any reason the
invitation will be automatically revoked.
invitationConfiguration PartyInvitationConfiguration*
optional
An optionally specified configuration for the newly created invitation.
If this value is null, the default configuration values will be used. By default, PlayFab Party will generate a unique
invitation identifier for the title, the revocability will be PartyInvitationRevocability::Creator, and the PlayFab
Entity ID list will be empty, allowing any user to join using the invitation.
If a configuration is provided, the title may optionally specify the identifier on the configuration. If the identifier
is nullptr or an empty string, the PlayFab Party library will generate an identifier for the title. It is guaranteed that
this generated identifier will be different from all identifiers that the PlayFab Party library has already generated
for invitations on this network across all devices. Titles may specify their own identifier by providing a non-null,
non-empty value in the configuration. If the title specifies the identifier, it is the title's responsibility to ensure
that this identifier does not collide with the identifiers of other invitations created on this network via
PartyManager::CreateNewNetwork() or CreateInvitation() on any device. If the title attempts to create an
invitation with an identifier that would collide with a pre-existing invitation, then the operation will fail
asynchronously and the title will receive a PartyInvitationDestroyedStateChange followed by a
PartyCreateInvitationCompletedStateChange with a failure result.
If a configuration is provided and the list of PlayFab Entity IDs is empty, all users will be allowed to join using the
new invitation.
asyncIdentifier void*
An optional, app-defined, pointer-sized context value that can be used to associate the completion state change
with this call.
invitation PartyInvitation**
optional, library-allocated output
The optional, output invitation that may immediately be used to queue user authentications on a network via
AuthenticateLocalUser().
Return value
PartyError
c_partyErrorSuccess if the asynchronous operation to create an invitation began, or an error code otherwise. If
this method fails, no related state changes will be generated. The human-readable form of the error code can be
retrieved via PartyManager::GetErrorMessage().
Remarks
To join a network, a user must provide an invitation to AuthenticateLocalUser().
This method queues an asynchronous attempt to create an invitation for the network. A
PartyCreateInvitationCompletedStateChange will be provided upon completion of the asynchronous operation,
indicating success or failure. On success, a PartyInvitationCreatedStateChange will have been generated
beforehand to indicate that the transparent cloud relay server is ready to accept authentications using the
invitation's identifier. On failure, a PartyInvitationDestroyedStateChange will have been generated beforehand to
indicate that the invitation object is no longer valid and will no longer be queryable via GetInvitations().
The lifetime of the invitation is tied to the owning local user's membership in the network, therefore localUser
must be authenticated or in the process of authenticating. If localUser leaves the network for any reason the
invitation will be automatically revoked and subsequent attempts to use that invitation's identifier to join the
network will fail until a new invitation is created using that identifier.
Invitations created with this method will only be queryable via GetInvitations() on the local device where the
invitation was created.
On successful return, this method invalidates the memory for any array previously returned by GetInvitations(),
as it synchronously adds the new invitation to the array. PartyManager::StartProcessingStateChanges() also
invalidates the memory for the array. The returned invitation object will be valid until a
PartyInvitationDestroyedStateChange has been generated and all state changes referencing the object have
been returned to PartyManager::FinishProcessingStateChanges().
Requirements
Header : Party.h
See also
PartyNetwork
PartyInvitationRevocability
PartyNetwork::AuthenticateLocalUser
PartyInvitationCreatedStateChange
PartyCreateInvitationCompletedStateChange
PartyInvitationDestroyedStateChange
PartyManager::CreateNewNetwork
PartyNetwork::RevokeInvitation
5/24/2022 • 2 minutes to read • Edit Online
Syntax
PartyError RevokeInvitation(
const PartyLocalUser* localUser,
PartyInvitation* invitation,
void* asyncIdentifier
)
Parameters
localUser PartyLocalUser*
The local user attempting to revoke the invitation.
invitation PartyInvitation*
The invitation to revoke.
asyncIdentifier void*
An optional, app-defined, pointer-sized context value that can be used to associate the completion state change
with this call.
Return value
PartyError
c_partyErrorSuccess if the asynchronous operation to revoke the invitation began, or an error code otherwise. If
this method fails, no related state changes will be generated. The human-readable form of the error code can be
retrieved via PartyManager::GetErrorMessage().
Remarks
Titles may revoke an invitation to prevent further users from authenticating into a network using the invitation's
identifier.
This method queues an asynchronous attempt to revoke an invitation from the network. A
PartyRevokeInvitationCompletedStateChange will be provided upon completion of the asynchronous operation,
indicating success or failure. On success, a PartyInvitationDestroyedStateChange will have been generated
beforehand with PartyDestroyedReason::Requested, to indicate that the network will no longer accept
authentications using the invitation's identifier until a new invitation is created with that same identifier. It also
indicates that the invitation will no longer be queryable via GetInvitations().
This operation will only succeed if the invitation was created with its revocability specified such that the
localUser on the local device may revoke the invitation. This might not be the case if the revocability is set to
PartyInvitationRevocability::Creator and the localUser is authenticated on a different device than the creator or
if the localUser refers to a different user than the creator.
Requirements
Header : Party.h
See also
PartyNetwork
PartyRevokeInvitationCompletedStateChange
PartyInvitationDestroyedStateChange
PartyNetwork::GetInvitations
5/24/2022 • 2 minutes to read • Edit Online
Syntax
PartyError GetInvitations(
uint32_t* invitationCount,
PartyInvitationArray* invitations
)
Parameters
invitationCount uint32_t*
output
An output value indicating the number of invitations provided in invitations .
invitations PartyInvitationArray*
library-allocated output array of size *invitationCount
A library-allocated output array containing the invitations that have been created for the network.
Return value
PartyError
c_partyErrorSuccess if the call succeeded or an error code otherwise. The human-readable form of the error
code can be retrieved via PartyManager::GetErrorMessage().
Remarks
The array is backed by the library's internal memory. The array is only valid until the next call to either
CreateInvitation() or PartyManager::StartProcessingStateChanges().
A new invitation is exposed to the local device whenever the local device calls CreateInvitation() or a
PartyInvitationCreatedStateChange is provided via PartyManager::StartProcessingStateChanges().
Invitations created via CreateInvitation() will only be exposed to the local device. The initial invitation will be
exposed to all devices in the network via a PartyInvitationCreatedStateChange.
Requirements
Header : Party.h
See also
PartyNetwork
PartyManager::CreateNewNetwork
PartyNetwork::CreateInvitation
PartyNetwork::RevokeInvitation
PartyInvitationCreatedStateChange
PartyInvitationDestroyedStateChange
PartyNetwork::CreateEndpoint
5/24/2022 • 3 minutes to read • Edit Online
Syntax
PartyError CreateEndpoint(
const PartyLocalUser* localUser,
uint32_t propertyCount,
const PartyString* keys,
const PartyDataBuffer* values,
void* asyncIdentifier,
PartyLocalEndpoint** localEndpoint
)
Parameters
localUser PartyLocalUser*
optional
An optional local user to associate as the owner of this endpoint. When this endpoint becomes visible on remote
devices, the user's identifier will be tied to this endpoint. The endpoint will be destroyed if the user becomes
unauthenticated because they were voluntarily removed via RemoveLocalUser() or kicked via
PartyNetwork::KickUser().
propertyCount uint32_t
The number of properties in the input keys and values arrays. Property bags are currently unimplemented.
This parameter must be zero.
keys PartyString*
optional input array of size propertyCount
The propertyCount entry array of property bag keys. The nth key in this array maps to the nth value in the
values array. Property bags are currently unimplemented. This parameter must be nullptr.
values PartyDataBuffer*
optional input array of size propertyCount
The propertyCount entry array of property bag values. The nth value in this array is mapped by the nth key in
the keys array. Property bags are currently unimplemented. This parameter must be nullptr.
asyncIdentifier void*
optional
An optional, app-defined, pointer-sized context value that can be used to associate the completion state change
with this call.
localEndpoint PartyLocalEndpoint**
optional, library-allocated output
The optional, output local endpoint object on which to queue endpoint operations.
Return value
PartyError
c_partyErrorSuccess if the asynchronous operation to create the endpoint began, or an error code otherwise. If
this method fails, no related state changes will be generated. The human-readable form of the error code can be
retrieved via PartyManager::GetErrorMessage().
Remarks
This method queues an asynchronous attempt to create an endpoint associated with the local device on this
network. A PartyCreateEndpointCompletedStateChange will be provided upon completion of the operation,
indicating success or failure. On success, a PartyEndpointCreatedStateChange will be generated, and the
endpoint will be fully created, connected to the network, and visible to all authenticated devices in the network.
On failure, a PartyEndpointDestroyedStateChange will be generated.
This method optionally provides localEndpoint as output that can immediately be used to perform
asynchronous endpoint operations, such as PartyLocalEndpoint::SendMessage() and
PartyLocalEndpoint::SetSharedProperties(). These asynchronous operations will be internally queued until the
endpoint creation completes, at which point they will be processed. PartyEndpoint::GetUniqueIdentifier() will
return a failure until the endpoint creation completes. This localEndpoint will also be provided in the resulting
PartyCreateEndpointCompletedStateChange.
A local user may optionally be provided as the owner of an endpoint. If an owning local user is provided, it must
be authenticated into the network or in the process of authenticating into the network. If its authentication fails,
the endpoint creation will consequently fail as well. If the owning local user is removed from the network while
this endpoint exists, the endpoint will be automatically destroyed. This will be signaled via a
PartyEndpointDestroyedStateChange.
If the local device enters a state in which there are no authenticated users and no authentication operations in
progress, then all endpoints, including those that are not fully created, will be destroyed automatically. This will
be signaled by PartyEndpointDestroyedStateChanges.
On successful return, this method invalidates the memory for any array previously returned by GetEndpoints(),
as it synchronously adds the new endpoint to the array. PartyManager::StartProcessingStateChanges() also
invalidates the memory for the array. The returned localEndpoint object will be valid until a
PartyEndpointDestroyedStateChange has been generated and all state changes referencing the object have been
returned to PartyManager::FinishProcessingStateChanges().
The property bag is a collection of title-specific values associated with an endpoint. The initial property bag is
queryable as soon as the endpoint becomes visible.
The property bag is currently unimplemented. propertyCount must be zero and both keys and values must
be nullptr.
Requirements
Header : Party.h
See also
PartyNetwork
PartyCreateEndpointCompletedStateChange
PartyEndpointCreatedStateChange
PartyEndpointDestroyedStateChange
PartyNetworkDestroyedStateChange
PartyNetworkConfiguration
PartyNetwork::GetEndpoints
PartyLocalEndpoint::SendMessage
PartyEndpoint::GetUniqueIdentifier
PartyEndpoint::GetEntityId
PartyNetwork::AuthenticateLocalUser
PartyNetwork::RemoveLocalUser
PartyNetwork::DestroyEndpoint
5/24/2022 • 2 minutes to read • Edit Online
Syntax
PartyError DestroyEndpoint(
PartyLocalEndpoint* localEndpoint,
void* asyncIdentifier
)
Parameters
localEndpoint PartyLocalEndpoint*
The local endpoint to begin destroying.
asyncIdentifier void*
optional
An optional, app-defined, pointer-sized context value that can be used to associate the completion state change
with this call.
Return value
PartyError
c_partyErrorSuccess if the asynchronous operation to destroy the endpoint began, or an error code otherwise.
If this method fails, no related state changes will be generated. The human-readable form of the error code can
be retrieved via PartyManager::GetErrorMessage().
Remarks
This method queues an asynchronous operation to destroy an endpoint associated with the local device on this
network. A PartyDestroyEndpointCompletedStateChange will be provided upon completion of the operation,
indicating success or failure. On success, the endpoint is no longer connected to the network or visible to any
devices. Memory for the endpoint will remain valid until all state changes referencing the endpoint have been
returned to PartyManager::FinishProcessingStateChanges().
If this call returns success, asynchronous endpoint destruction has begun and methods that attempt to send
data from this local endpoint to the Party network, such as PartyLocalEndpoint::SendMessage() and
PartyLocalEndpoint::FlushMessages(), will fail. Methods that retrieve cached state, such as
PartyEndpoint::GetCustomContext() and PartyEndpoint::GetEntityId(), will continue to succeed.
When the local device begins destroying an endpoint, every remote device will be alerted via a
PartyEndpointDestroyedStateChange. Those remote devices have the opportunity to send the destructing
endpoint any final messages they wish before returning the PartyEndpointDestroyedStateChange to
PartyManager::FinishProcessingStateChanges(). By returning the PartyEndpointDestroyedStateChange, the
remote device acknowledges the endpoint's destruction and may no longer target the endpoint in
PartyLocalEndpoint::SendMessage() calls. Because the endpoint will not be able to complete its destruction on
the local device until all remote devices have acknowledged it, it is recommended to return this state change as
quickly as possible. If the remote device does not return the PartyEndpointDestroyedStateChange within two
seconds, the remote device will automatically acknowledge the endpoint destruction and the endpoint will no
longer be targetable in PartyLocalEndpoint::SendMessage() calls. The destructing endpoint can receive
PartyEndpointMessageReceivedStateChanges up until all remote devices have acknowledged the endpoint's
destruction, which is indicated by a PartyEndpointDestroyedStateChange generated on the local device.
Requirements
Header : Party.h
See also
PartyNetwork
PartyDestroyEndpointCompletedStateChange
PartyEndpointDestroyedStateChange
PartyEndpointMessageReceivedStateChange
PartyLocalEndpoint::SendMessage
PartyEndpoint::GetCustomContext
PartyEndpoint::GetEntityId
PartyNetwork::LeaveNetwork
5/24/2022 • 2 minutes to read • Edit Online
Syntax
PartyError LeaveNetwork(
void* asyncIdentifier
)
Parameters
asyncIdentifier void*
optional
An optional, app-defined, pointer-sized context value that can be used to associate the completion state change
with this call.
Return value
PartyError
c_partyErrorSuccess if the asynchronous operation to leave the network began, or an error code otherwise. If
this method fails, no related state changes will be generated. The human-readable form of the error code can be
retrieved via PartyManager::GetErrorMessage().
Remarks
This method queues an asynchronous operation to gracefully leave the network. A
PartyLeaveNetworkCompletedStateChange will be provided upon completion of the operation, indicating
success or failure. Memory for the network will remain valid until all state changes referencing the network have
been returned to PartyManager::FinishProcessingStateChanges().
Before successful completion of the operation, all in-flight inbound and outbound traffic to and from all local
endpoints on this device will be delivered, state changes will be generated on this device showing all local and
remote endpoints being destroyed (each indicated by a PartyEndpointDestroyedStateChange), all chat controls
being disconneced from this network (each indicated by a PartyChatControlLeftNetworkStateChange), all
remote devices leaving the network (each indicated by a PartyRemoteDeviceLeftNetworkStateChange), and all
local users being removed from this network (each indicated by a PartyLocalUserRemovedStateChange).
This object will be valid until a PartyNetworkDestroyedStateChange has been generated and all state changes
referencing the object have been returned to PartyManager::FinishProcessingStateChanges().
Requirements
Header : Party.h
See also
PartyNetwork
PartyNetworkDestroyedStateChange
PartyEndpointDestroyedStateChange
PartyChatControlLeftNetworkStateChange
PartyRemoteDeviceLeftNetworkStateChange
PartyLocalUserRemovedStateChange
PartyNetwork::GetEndpoints
5/24/2022 • 2 minutes to read • Edit Online
Syntax
PartyError GetEndpoints(
uint32_t* endpointCount,
PartyEndpointArray* endpoints
)
Parameters
endpointCount uint32_t*
output
The output number of PartyEndpoint entries in the endpoints array.
endpoints PartyEndpointArray*
library-allocated output array of size *endpointCount
Remarks
This method gets all endpoints currently associated with the network and visible to the local device.
All local endpoints that have successfully been created or are in the process of being created will be present in
endpoints . All remote endpoints that have been successfully created will also be present.
The memory for the returned array is invalidated whenever the title calls
PartyManager::StartProcessingStateChanges() or CreateEndpoint() returns success.
Requirements
Header : Party.h
See also
PartyNetwork
PartyEndpointCreatedStateChange
PartyEndpointDestroyedStateChange
PartyNetwork::CreateEndpoint
PartyNetwork::FindEndpointByUniqueIdentifier
5/24/2022 • 2 minutes to read • Edit Online
Finds the endpoint with the corresponding network-unique identifier in this network, if it exists.
Syntax
PartyError FindEndpointByUniqueIdentifier(
uint16_t uniqueIdentifier,
PartyEndpoint** endpoint
)
Parameters
uniqueIdentifier uint16_t
The network-unique identifier of an endpoint.
endpoint PartyEndpoint**
library-allocated output
The output endpoint with a network-unique identifier matching uniqueIdentifier .
Return value
PartyError
c_partyErrorSuccessif an endpoint with a matching identifier was found on this network or an error code
otherwise. The human-readable form of the error code can be retrieved via PartyManager::GetErrorMessage().
Remarks
This method returns an error if the endpoint is not valid on the local device, that is, if the
PartyEndpointCreatedStateChange for the endpoint associated with uniqueIdentifier has not yet been
provided by PartyManager::StartProcessingStateChanges() or if the PartyEndpointDestroyedStateChange has
been generated and all state changes referencing the endpoint have been returned to
PartyManager::FinishProcessingStateChanges().
All devices in a network will agree on a given endpoint's unique identifier, but different devices may not see the
same endpoints at a given moment. For example, it's possible for endpoint A to send a message to endpoint B
that references a newly-created endpoint C's unique identifier, but that message between A and B may arrive
before the PartyEndpointCreatedStateChange for endpoint C is generated on endpoint B's device. In that
situation, this method will return an error when called on endpoint B's device because endpoint C is not yet
known on that device.
Requirements
Header : Party.h
See also
PartyNetwork
PartyEndpoint::GetUniqueIdentifier
PartyEndpointCreatedStateChange
PartyEndpointDestroyedStateChange
PartyNetwork::GetDevices
5/24/2022 • 2 minutes to read • Edit Online
Syntax
PartyError GetDevices(
uint32_t* deviceCount,
PartyDeviceArray* devices
)
Parameters
deviceCount uint32_t*
output
The output number of devices in this network.
devices PartyDeviceArray*
library-allocated output array of size *deviceCount
Remarks
Once a PartyRemoteDeviceLeftNetworkStateChange has been provided by
PartyManager::StartProcessingStateChanges(), the remote device will no longer be present in the array returned
by this method. The local device is always in the array.
The memory for the returned array is invalidated whenever the title calls
PartyManager::StartProcessingStateChanges().
Requirements
Header : Party.h
See also
PartyNetwork
PartyRemoteDeviceLeftNetworkStateChange
PartyNetwork::GetLocalUsers
5/24/2022 • 2 minutes to read • Edit Online
Gets an array containing the local users that are authenticated or authenticating into the network.
Syntax
PartyError GetLocalUsers(
uint32_t* userCount,
PartyLocalUserArray* localUsers
)
Parameters
userCount uint32_t*
output
An output value indicating the number of users provided in localUsers .
localUsers PartyLocalUserArray*
library-allocated output array of size *userCount
A library-allocated output array containing the local users that are authenticated or authenticating into the
network.
Return value
PartyError
c_partyErrorSuccess if the call succeeded or an error code otherwise. The human-readable form of the error
code can be retrieved via PartyManager::GetErrorMessage().
Remarks
Once a PartyLocalUserRemovedStateChange has been provided by
PartyManager::StartProcessingStateChanges(), the local user will no longer be present in the array returned by
this method.
The memory for the returned array is invalidated whenever the title calls
PartyManager::StartProcessingStateChanges() or AuthenticateLocalUser() returns success.
Requirements
Header : Party.h
See also
PartyNetwork
PartyNetwork::AuthenticateLocalUser
PartyNetwork::RemoveLocalUser
PartyLocalUserRemovedStateChange
PartyNetwork::GetNetworkDescriptor
5/24/2022 • 2 minutes to read • Edit Online
Syntax
PartyError GetNetworkDescriptor(
PartyNetworkDescriptor* networkDescriptor
)
Parameters
networkDescriptor PartyNetworkDescriptor*
output
The output network descriptor.
Return value
PartyError
c_partyErrorSuccess if the call succeeded or an error code otherwise. The human-readable form of the error
code can be retrieved via PartyManager::GetErrorMessage().
Remarks
A network descriptor contains all the information required for a device to connect to the network to which the
descriptor is associated. PartyManager::SerializeNetworkDescriptor() can be used to get the serialized form of
the descriptor, which is safe to exchange over title and platform-specific communication channels. However, the
network descriptor provided by this call is not serializable until the asynchronous creation operation associated
with this network successfully completes, signaled by a PartyCreateNewNetworkCompletedStateChange with a
success result code.
PartyNetworkDescriptors work in tandem with PartyInvitations to facilitate inviting remote users to join the
network. First, obtain the network descriptor via GetNetworkDescriptor() and serialize it via
PartyManager::SerializeNetworkDescriptor(). Next, create an invitation via CreateInvitation() or query for a
preexisting invitation via GetInvitations() and obtain the invitation's identifier from its configuration via
PartyInvitation::GetInvitationConfiguration(). Last, include both the serialized network descriptor and the
invitation identifier in the payload of the platform-specific invite mechanism. When the remote user receives the
invite, they deserialize the network descriptor from the platform-invite payload via
PartyManager::DeserializeNetworkDescriptor() and pass the deserialized descriptor to
PartyManager::ConnectToNetwork(). After connecting, the remote user joins by authenticating into the network
via AuthenticateLocalUser() with the invitation identifier in the platform-invite payload.
Requirements
Header : Party.h
See also
PartyNetwork
PartyCreateNewNetworkCompletedStateChange
PartyManager::CreateNewNetwork
PartyManager::SerializeNetworkDescriptor
PartyManager::DeserializeNetworkDescriptor
PartyManager::ConnectToNetwork
PartyInvitation
PartyNetwork::CreateInvitation
PartyNetwork::GetInvitations
PartyInvitation::GetInvitationConfiguration
PartyNetwork::AuthenticateLocalUser
PartyNetwork::GetNetworkConfiguration
5/24/2022 • 2 minutes to read • Edit Online
Gets the network configuration which was set when creating the network.
Syntax
PartyError GetNetworkConfiguration(
const PartyNetworkConfiguration** networkConfiguration
)
Parameters
networkConfiguration PartyNetworkConfiguration**
library-allocated output
The output network configuration.
Return value
PartyError
c_partyErrorSuccess if the call succeeded or an error code otherwise. The human-readable form of the error
code can be retrieved via PartyManager::GetErrorMessage().
Remarks
This method returns an error until PartyManager::StartProcessingStateChanges() provides a
PartyNetworkConfigurationMadeAvailableStateChange.
Requirements
Header : Party.h
See also
PartyNetwork
PartyNetworkConfigurationMadeAvailableStateChange
PartyNetwork::ConnectChatControl
5/24/2022 • 2 minutes to read • Edit Online
Syntax
PartyError ConnectChatControl(
PartyLocalChatControl* chatControl,
void* asyncIdentifier
)
Parameters
chatControl PartyLocalChatControl*
The chat control to connect to this network.
asyncIdentifier void*
optional
An optional, app-defined, pointer-sized context value that can be used to associate the completion state change
with this call.
Return value
PartyError
c_partyErrorSuccess if the asynchronous operation to connect the chat control began, or an error code
otherwise. If this method fails, no related state changes will be generated. The human-readable form of the error
code can be retrieved via PartyManager::GetErrorMessage().
Remarks
On successful return, this method invalidates the memory for any array previously returned by
GetChatControls() or PartyChatControl::GetNetworks() for chatControl , as it synchronously updates those
arrays. PartyManager::StartProcessingStateChanges() also invalidates the memory for those arrays.
Requirements
Header : Party.h
See also
PartyNetwork
PartyNetwork::DisconnectChatControl
5/24/2022 • 2 minutes to read • Edit Online
Syntax
PartyError DisconnectChatControl(
PartyLocalChatControl* chatControl,
void* asyncIdentifier
)
Parameters
chatControl PartyLocalChatControl*
The chat control to disconnect from this network.
asyncIdentifier void*
optional
An optional, app-defined, pointer-sized context value that can be used to associate the completion state change
with this call.
Return value
PartyError
c_partyErrorSuccess if the asynchronous operation to disconnect the chat control began, or an error code
otherwise. If this method fails, no related state changes will be generated. The human-readable form of the error
code can be retrieved via PartyManager::GetErrorMessage().
Requirements
Header : Party.h
See also
PartyNetwork
PartyNetwork::GetChatControls
5/24/2022 • 2 minutes to read • Edit Online
Syntax
PartyError GetChatControls(
uint32_t* chatControlCount,
PartyChatControlArray* chatControls
)
Parameters
chatControlCount uint32_t*
output
The output number of chat controls in this network.
chatControls PartyChatControlArray*
library-allocated output array of size *chatControlCount
A library-allocated output array containing the chat controls in this network.
Return value
PartyError
c_partyErrorSuccess if the call succeeded or an error code otherwise. The human-readable form of the error
code can be retrieved via PartyManager::GetErrorMessage().
Remarks
Once a PartyChatControlLeftNetworkStateChange has been generated for a chat control by
PartyManager::StartProcessingStateChanges(), the chat control will no longer be present in the array returned
by this method.
The memory for the returned array is invalidated whenever the title calls
PartyManager::StartProcessingStateChanges() or ConnectChatControl() returns success.
Requirements
Header : Party.h
See also
PartyNetwork
PartyNetwork::ConnectChatControl
PartyNetwork::DisconnectChatControl
PartyChatControlLeftNetworkStateChange
PartyNetwork::GetNetworkStatistics
5/24/2022 • 2 minutes to read • Edit Online
Syntax
PartyError GetNetworkStatistics(
uint32_t statisticCount,
const PartyNetworkStatistic* statisticTypes,
uint64_t* statisticValues
)
Parameters
statisticCount uint32_t
The number of statistics in the input statisticTypes array and to be written in the statisticValues output
array. This must be at least 1.
statisticTypes PartyNetworkStatistic*
input array of size statisticCount
The statisticCount entry input array of unique PartyNetworkStatistic types to retrieve.
statisticValues uint64_t*
output array of size statisticCount
The statisticCount entry output array where the statistic values should be written. Each statistic value will be
written at the same entry index corresponding to where the requested PartyNetworkStatistic appears in the
statisticTypes input array.
Return value
PartyError
c_partyErrorSuccess if retrieving the network statistics succeeded or an error code otherwise. The human-
readable form of the error code can be retrieved via PartyManager::GetErrorMessage().
Remarks
This method is used to retrieve performance counters, queue lengths, historical usage metrics, or other
statistical information recorded for this network.
A given PartyNetworkStatistic type may appear in any order in the statisticTypes array, but must not be
specified more than once. Each corresponding statistic value will be written to the statisticValues array in the
same order.
The returned statistic values are always the most current ones available. There is no guarantee they will report
the same value from one GetNetworkStatistics() call to the next, even if there were no intervening calls to
PartyManager::StartProcessingStateChanges() or PartyManager::FinishProcessingStateChanges().
Requirements
Header : Party.h
See also
PartyNetwork
PartyNetworkStatistic
PartyLocalEndpoint::GetEndpointStatistics
PartyNetwork::GetCustomContext
5/24/2022 • 2 minutes to read • Edit Online
Retrieves the app's private, custom pointer-sized context value previously associated with this network object.
Syntax
PartyError GetCustomContext(
void** customContext
)
Parameters
customContext void**
output, may return nullptr
The output custom context.
Return value
PartyError
c_partyErrorSuccess if retrieving the custom context succeeded or an error code otherwise. The human-
readable form of the error code can be retrieved via PartyManager::GetErrorMessage().
Remarks
If no custom context has been set yet, the value pointed to by customContext is set to nullptr.
Requirements
Header : Party.h
See also
PartyNetwork
PartyNetwork::SetCustomContext
PartyNetwork::SetCustomContext
5/24/2022 • 2 minutes to read • Edit Online
Configures an optional, custom pointer-sized context value with this network object.
Syntax
PartyError SetCustomContext(
void* customContext
)
Parameters
customContext void*
optional
An arbitrary, pointer-sized value to store with the network object.
Return value
PartyError
c_partyErrorSuccess if configuring the custom context succeeded or an error code otherwise. The human-
readable form of the error code can be retrieved via PartyManager::GetErrorMessage().
Remarks
The custom context is typically used as a "shortcut" that simplifies accessing local, title-specific memory
associated with the network without requiring a mapping lookup. The value is retrieved using the
GetCustomContext() method.
Any configured value is treated as opaque by the library, and is only valid on the local device; it is not
transmitted over the network.
Requirements
Header : Party.h
See also
PartyNetwork
PartyNetwork::GetCustomContext
PartyNetwork::GetDeviceConnectionType
5/24/2022 • 2 minutes to read • Edit Online
Retrieves the type of connection used by the local device for transmitting messages or chat data to the specified
target device in this network.
Syntax
PartyError GetDeviceConnectionType(
const PartyDevice* targetDevice,
PartyDeviceConnectionType* deviceConnectionType
)
Parameters
targetDevice PartyDevice*
The device whose connection type should be retrieved.
deviceConnectionType PartyDeviceConnectionType*
output
The output device connection type.
Return value
PartyError
c_partyErrorSuccess if retrieving the connection type succeeded or an error code otherwise. The human-
readable form of the error code can be retrieved via PartyManager::GetErrorMessage().
Remarks
Connection types are determined when devices first authenticate an initial user into the network. If this network
permitted direct peer-to-peer connectivity via the PartyNetworkConfiguration::directPeerConnectivityOptions
field, neither device had excluded such connectivity via the
PartyOption::LocalDeviceDirectPeerConnectivityOptionsMask option, and a direct peer connection was
successfully established at that time, then this function will report a value of
PartyDeviceConnectionType::DirectPeerConnection. Otherwise it will report
PartyDeviceConnectionType::RelayServer. The value will not change for as long as the target PartyDevice object
remains in this network, even if PartyNetwork::RemoveLocalUser() is called for that initially authenticating user.
If the target device is the local device, PartyDeviceConnectionType::DirectPeerConnection will always be reported
regardless of PartyNetworkConfiguration settings or
PartyOption::LocalDeviceDirectPeerConnectivityOptionsMask option.
If the target device object is not participating in this network, an error is returned.
If the local device is participating in additional networks with the target device object, you should not assume
that calling this same function on those other network objects will report the same value.
Requirements
Header : Party.h
See also
PartyNetwork
PartyDeviceConnectionType
PartyNetworkConfiguration
PartyOption::LocalDeviceDirectPeerConnectivityOptionsMask
PartyTextToSpeechProfile
5/24/2022 • 2 minutes to read • Edit Online
Syntax
class PartyTextToSpeechProfile
Public Methods
NAME DESC RIP T IO N
Requirements
Header : Party.h
See also
Party members
PartyLocalChatControl::PopulateAvailableTextToSpeechProfiles
PartyLocalChatControl::GetAvailableTextToSpeechProfiles
PartyLocalChatControl::SetTextToSpeechProfile
PartyLocalChatControl::GetTextToSpeechProfile
PartyTextToSpeechProfile::GetIdentifier
5/24/2022 • 2 minutes to read • Edit Online
Syntax
PartyError GetIdentifier(
PartyString* identifier
)
Parameters
identifier PartyString*
library-allocated output
The output unique identifier. The memory for the string remains valid for the lifetime of the profile.
Return value
PartyError
c_partyErrorSuccess if the call succeeded or an error code otherwise. The human-readable form of the error
code can be retrieved via PartyManager::GetErrorMessage().
Requirements
Header : Party.h
See also
PartyTextToSpeechProfile
PartyLocalChatControl::SetTextToSpeechProfile
PartyTextToSpeechProfile::GetName
5/24/2022 • 2 minutes to read • Edit Online
Syntax
PartyError GetName(
PartyString* name
)
Parameters
name PartyString*
library-allocated output
The output profile name. The memory for the string remains valid for the lifetime of the profile.
Return value
PartyError
c_partyErrorSuccess if the call succeeded or an error code otherwise. The human-readable form of the error
code can be retrieved via PartyManager::GetErrorMessage().
Remarks
This name is intended for use in title UI and logs, but is not localized.
Requirements
Header : Party.h
See also
PartyTextToSpeechProfile
PartyTextToSpeechProfile::GetLanguageCode
5/24/2022 • 2 minutes to read • Edit Online
Syntax
PartyError GetLanguageCode(
PartyString* languageCode
)
Parameters
languageCode PartyString*
library-allocated output
The output profile language. The memory for the string remains valid for the lifetime of the profile.
Return value
PartyError
c_partyErrorSuccess if the call succeeded or an error code otherwise. The human-readable form of the error
code can be retrieved via PartyManager::GetErrorMessage().
Requirements
Header : Party.h
See also
PartyTextToSpeechProfile
PartyTextToSpeechProfile::GetGender
5/24/2022 • 2 minutes to read • Edit Online
Syntax
PartyError GetGender(
PartyGender* gender
)
Parameters
gender PartyGender*
output
The output profile gender.
Return value
PartyError
c_partyErrorSuccess if the call succeeded or an error code otherwise. The human-readable form of the error
code can be retrieved via PartyManager::GetErrorMessage().
Requirements
Header : Party.h
See also
PartyTextToSpeechProfile
PartyTextToSpeechProfile::GetCustomContext
5/24/2022 • 2 minutes to read • Edit Online
Retrieves the app's private, custom pointer-sized context value previously associated with this profile.
Syntax
PartyError GetCustomContext(
void** customContext
)
Parameters
customContext void**
output, may return nullptr
The output custom context.
Return value
PartyError
c_partyErrorSuccess if retrieving the custom context succeeded or an error code otherwise. The human-
readable form of the error code can be retrieved via PartyManager::GetErrorMessage().
Remarks
If no custom context has been set yet, the value pointed to by customContext is set to nullptr.
Requirements
Header : Party.h
See also
PartyTextToSpeechProfile
PartyTextToSpeechProfile::SetCustomContext
PartyTextToSpeechProfile::SetCustomContext
5/24/2022 • 2 minutes to read • Edit Online
Syntax
PartyError SetCustomContext(
void* customContext
)
Parameters
customContext void*
optional
An arbitrary, pointer-sized value to store with the profile object.
Return value
PartyError
c_partyErrorSuccess if configuring the custom context succeeded or an error code otherwise. The human-
readable form of the error code can be retrieved via PartyManager::GetErrorMessage().
Remarks
The custom context is typically used as a "shortcut" that simplifies accessing local, title-specific memory
associated with the profile without requiring a mapping lookup. The value is retrieved using the
GetCustomContext() method.
Any configured value is treated as opaque by the library, and is only valid on the local device; it is not
transmitted over the network.
Requirements
Header : Party.h
See also
PartyTextToSpeechProfile
PartyTextToSpeechProfile::GetCustomContext
PartyAllocateMemoryCallback
5/24/2022 • 2 minutes to read • Edit Online
A callback invoked every time a new memory buffer must be dynamically allocated by the Party library.
Syntax
typedef
void* (*PartyAllocateMemoryCallback)(
size_t size,
uint32_t memoryTypeId
)
Parameters
size size_t
The size of the allocation to be made. This value will never be zero.
memoryTypeId uint32_t
An opaque identifier representing the Party library internal category of memory being allocated. This value
should be ignored.
Return value
Type: void*
A pointer to an allocated block of memory of the specified size, or nullptr if the allocation failed.
Remarks
This callback is optionally installed using the PartyManager::SetMemoryCallbacks() method.
The callback must allocate and return a pointer to a contiguous block of memory of the specified size that will
remain valid until the title's corresponding PartyFreeMemoryCallback is invoked to release it. If this is not
possible, the callback must return nullptr to fail the allocation. Memory allocation failures are sometimes
considered benign but will usually cause current Party library operation(s) to fail.
Every non-nullptr returned by this method will be subsequently passed to the corresponding
PartyFreeMemoryCallback once the memory is no longer needed.
Requirements
Header : Party.h
See also
Party members
PartyFreeMemoryCallback
PartyManager::SetMemoryCallbacks
PartyManager::GetMemoryCallbacks
PartyFreeMemoryCallback
5/24/2022 • 2 minutes to read • Edit Online
A callback invoked every time a previously allocated memory buffer is no longer needed by the Party library
and can be freed.
Syntax
typedef
void (*PartyFreeMemoryCallback)(
void* pointer,
uint32_t memoryTypeId
)
Parameters
pointer void*
Post_invalid
A pointer to a memory buffer previously allocated. This value will never be nullptr.
memoryTypeId uint32_t
An opaque identifier representing the Party library internal category of memory being freed. This value should
be ignored.
Return value
Type: void
The callback does not return a value.
Remarks
This callback is optionally installed using the PartyManager::SetMemoryCallbacks() method.
The callback is invoked whenever the Party library has finished using a memory buffer previously returned by
the title's corresponding PartyAllocateMemoryCallback, so that the title can free the memory buffer.
Requirements
Header : Party.h
See also
Party members
PartyAllocateMemoryCallback
PartyManager::SetMemoryCallbacks
PartyManager::GetMemoryCallbacks
PartyProfilingMethodEntranceCallback
5/24/2022 • 2 minutes to read • Edit Online
A callback invoked every time the Party library enters an instrumented method.
Syntax
typedef
void (*PartyProfilingMethodEntranceCallback)(
const PartyProfilingMethodEntranceEventData* eventData
)
Parameters
eventData PartyProfilingMethodEntranceEventData*
A constant pointer to a structure containing additional information which may be of use when profiling this
event. The data referenced by this pointer is guaranteed to be valid only for the duration the callback.
Return value
Type: void
The callback does not return a value.
Remarks
This callback is optionally installed using the PartyManager::SetProfilingCallbacksForMethodEntryExit() method,
which also details the types of profiled events available to a caller.
In order to minimize the impact of profiling on title performance, callbacks should be kept as lightweight as
possible as they are expected to fire hundreds or thousands of times per second.
Requirements
Header : Party.h
See also
Party members
PartyProfilingMethodEntranceEventData
PartyManager::SetProfilingCallbacksForMethodEntryExit
PartyManager::GetProfilingCallbacksForMethodEntryExit
PartyProfilingMethodExitCallback
5/24/2022 • 2 minutes to read • Edit Online
A callback invoked every time the Party library is about to exit an instrumented method.
Syntax
typedef
void (*PartyProfilingMethodExitCallback)(
const PartyProfilingMethodExitEventData* eventData
)
Parameters
eventData PartyProfilingMethodExitEventData*
A constant pointer to a structure containing additional information which may be of use when profiling this
event. The data referenced by this pointer is guaranteed to be valid only for the duration the callback.
Return value
Type: void
The callback does not return a value.
Remarks
This callback is optionally installed using the PartyManager::SetProfilingCallbacksForMethodEntryExit() method,
which also details the types of profiled events available to a caller.
In order to minimize the impact of profiling on title performance, callbacks should be kept as lightweight as
possible as they are expected to fire hundreds or thousands of times per second.
Requirements
Header : Party.h
See also
Party members
PartyProfilingMethodExitEventData
PartyManager::SetProfilingCallbacksForMethodEntryExit
PartyManager::GetProfilingCallbacksForMethodEntryExit
PartyAudioFormat
5/24/2022 • 2 minutes to read • Edit Online
Syntax
struct PartyAudioFormat {
uint32_t samplesPerSecond;
uint32_t channelMask;
uint16_t channelCount;
uint16_t bitsPerSample;
PartyAudioSampleType sampleType;
PartyBool interleaved;
}
Members
samplesPerSecond uint32_t
Specifies the sample frequency at which each channel should be played or recorded.
channelMask uint32_t
Overrides the assignment of channels in a multichannel audio stream to speaker positions.
channelCount uint16_t
Specifies the number of channels of audio data.
bitsPerSample uint16_t
Specifies the number of bits per sample. If this value is not byte-divisible, it will be assumed that the containing
sample type is padded with bits to make it byte-divisble.
sampleType PartyAudioSampleType
Specifies the sample type.
interleaved PartyBool
A flag representing whether the multichannel audio data is interleaved for multi-channel formats.
Requirements
Header : Party.h
See also
Party members
PartyAudioManipulationSinkStreamConfiguration
5/24/2022 • 2 minutes to read • Edit Online
Syntax
struct PartyAudioManipulationSinkStreamConfiguration {
PartyAudioFormat* format;
uint32_t maxTotalAudioBufferSizeInMilliseconds;
}
Members
format PartyAudioFormat*
may be nullptr
Optionally specifies the format of the audio that will be submitted to the sink stream.
If this value is nullptr, the sink stream will be configured to use the format most efficient for the library. The
format can be queried via PartyAudioManipulationSinkStream::GetFormat().
maxTotalAudioBufferSizeInMilliseconds uint32_t
The maximum total size of audio buffers that can concurrently exist for this queue, in milliseconds.
This defines the limit for the total amount of audio internally queued by the sink stream, but not yet processed
by the library. When this limit is reached, the sink stream will stop accepting additional buffers.
This value should be chosen based on how frequently the game will submit buffers to the sink stream and how
large those buffers will be. Because the library processes audio in 40 milliseconds intervals, the minimum is 40
milliseconds. Most games will find 200 milliseconds to be a reasonable value.
Requirements
Header : Party.h
See also
Party members
PartyLocalChatControl::ConfigureAudioManipulationCaptureStream
PartyLocalChatControl::ConfigureAudioManipulationRenderStream
PartyAudioManipulationSourceStreamConfiguration
5/24/2022 • 2 minutes to read • Edit Online
Syntax
struct PartyAudioManipulationSourceStreamConfiguration {
PartyAudioFormat* format;
uint32_t maxTotalAudioBufferSizeInMilliseconds;
}
Members
format PartyAudioFormat*
may be nullptr
Optionally specifies the format of the audio that should be produced by the source stream.
If this value is nullptr, the source stream will produce audio in the format most efficient for the library. The
format can be queried via PartyAudioManipulationSourceStream::GetFormat().
maxTotalAudioBufferSizeInMilliseconds uint32_t
The maximum total size of audio buffers that can concurrently exist for this queue, in milliseconds.
This defines the limit for the total amount of audio internally queued by the source stream, but not yet retrieved
via PartyAudioManipulationSourceStream::GetNextBuffer, plus the total amount of audio retrieved by the app,
but not yet returned to the library via PartyAudioManipulationSourceStream::ReturnBuffer. When this total is
reached, the source stream will stop producing additional buffers.
Because the library processes audio in 40 millisecond intervals, the effective maximum is the nearest multiple of
40 less than the specified maximum. The minimum is 40 milliseconds.
Requirements
Header : Party.h
See also
Party members
PartyChatControl::ConfigureAudioManipulationVoiceStream
PartyDataBuffer
5/24/2022 • 2 minutes to read • Edit Online
A data buffer.
Syntax
struct PartyDataBuffer {
const void* buffer;
uint32_t bufferByteCount;
}
Members
buffer const void*
buffer of size bufferByteCount bytes
The data buffer.
bufferByteCount uint32_t
The size of the buffer in bytes.
Requirements
Header : Party.h
See also
Party members
PartyInvitationConfiguration
5/24/2022 • 2 minutes to read • Edit Online
Syntax
struct PartyInvitationConfiguration {
PartyString identifier;
PartyInvitationRevocability revocability;
uint32_t entityIdCount;
const PartyString* entityIds;
}
Members
identifier PartyString
may be nullptr
The identifier of the invitation.
This value may only be nullptr when used as input to PartyManager::CreateNewNetwork() or
PartyNetwork::CreateInvitation().
The list of PlayFab Entity IDs that the invitation allows to authenticate into the network.
If this list is empty, all users are allowed to authenticate using the invitation's identifier.
Requirements
Header : Party.h
See also
Party members
PartyInvitation
PartyInvitationRevocability
PartyManager::CreateNewNetwork
PartyNetwork::CreateInvitation
PartyInvitation::GetInvitationConfiguration
PartyLocalUdpSocketBindAddressConfiguration
5/24/2022 • 2 minutes to read • Edit Online
Syntax
struct PartyLocalUdpSocketBindAddressConfiguration {
PartyLocalUdpSocketBindAddressOptions options;
uint16_t port;
}
Members
options PartyLocalUdpSocketBindAddressOptions
Optional flags describing how to interpret this UDP socket configuration.
port uint16_t
The specific port number to which the local UDP socket will be bound the next time Party is initialized.
In the Microsoft Game Core version of the Party library, a port value of 0 means that the Party library will select
the Game Core preferred local UDP multiplayer port unless the
PartyLocalUdpSocketBindAddressOptions::ExcludeGameCorePreferredUdpMultiplayerPort option flag is
specified in the options field. On all other versions of the Party library, a port value of 0 means the Party library
will let the system dynamically select a port that's available on all local IP address interfaces.
If this port value cannot be bound when the Party library is initialized, PartyManager::Initialize() will
synchronously return an error. The human-readable form of the error code can be retrieved via
PartyManager::GetErrorMessage().
The port should be specified in native host byte order. If your application also directly uses or is porting from its
own socket API calls, be aware that this natural byte ordering may therefore differ from the network byte order
used by socket address port numbers.
Remarks
This structure can be used together with PartyOption::LocalUdpSocketBindAddress to either override or query
the Party library's current configuration via PartyManager::SetOption() and PartyManager::GetOption()
respectively.
Requirements
Header : Party.h
See also
Party members
PartyOption::LocalUdpSocketBindAddress
PartyLocalUdpSocketBindAddressOptions
PartyManager::SetOption
PartyManager::GetOption
PartyMutableDataBuffer
5/24/2022 • 2 minutes to read • Edit Online
Syntax
struct PartyMutableDataBuffer {
void* buffer;
uint32_t bufferByteCount;
}
Members
buffer void*
buffer of size bufferByteCount bytes
The data buffer.
bufferByteCount uint32_t
The size of the buffer in bytes.
Requirements
Header : Party.h
See also
Party members
PartyNetworkConfiguration
5/24/2022 • 4 minutes to read • Edit Online
Syntax
struct PartyNetworkConfiguration {
uint32_t maxUserCount;
uint32_t maxDeviceCount;
uint32_t maxUsersPerDeviceCount;
uint32_t maxDevicesPerUserCount;
uint32_t maxEndpointsPerDeviceCount;
PartyDirectPeerConnectivityOptions directPeerConnectivityOptions;
}
Members
maxUserCount uint32_t
The maximum number of unique users allowed in the network.
This value must be greater than 0.
If a client would violate this limit by calling PartyNetwork::AuthenticateLocalUser(), the operation will fail
asynchronously and PartyAuthenticateLocalUserCompletedStateChange::result will be set to
PartyStateChangeResult::NetworkLimitReached.
maxDeviceCount uint32_t
The maximum number of devices allowed to connect to the network.
This value must be between 1 and c_maxNetworkConfigurationMaxDeviceCount inclusive.
If a client would violate this limit by calling PartyManager::ConnectToNetwork(), the operation will fail
asynchronously and PartyConnectToNetworkCompletedStateChange::result will be set to
PartyStateChangeResult::NetworkLimitReached.
maxUsersPerDeviceCount uint32_t
The maximum number of users allowed per device.
This value must be between 1 and c_maxLocalUsersPerDeviceCount inclusive.
If a client would violate this limit by calling PartyNetwork::AuthenticateLocalUser(), the operation will fail
asynchronously and PartyAuthenticateLocalUserCompletedStateChange::result will be set to
PartyStateChangeResult::NetworkLimitReached.
maxDevicesPerUserCount uint32_t
The maximum number of devices allowed per user.
This value must be greater than 0.
If a client would violate this limit by calling PartyNetwork::AuthenticateLocalUser(), the operation will fail
asynchronously and PartyAuthenticateLocalUserCompletedStateChange::result will be set to
PartyStateChangeResult::NetworkLimitReached.
maxEndpointsPerDeviceCount uint32_t
The maximum number of endpoints allowed per device.
This value must be between 0 and c_maxNetworkConfigurationMaxEndpointsPerDeviceCount inclusive.
If a client would violate this limit by calling PartyNetwork::CreateEndpoint() after the network configuration was
made available, the call to PartyNetwork::CreateEndpoint() will fail synchronously. If the client had already
queued a violating number of endpoint creations when the network configuration became available, the client
will be kicked from the network and a PartyNetworkDestroyedStateChange will be generated.
directPeerConnectivityOptions PartyDirectPeerConnectivityOptions
Whether and how to support direct peer-to-peer connection attempts among devices in the network.
As part of successfully authenticating an initial user into a network, a device may attempt to establish direct
peer-to-peer connections with other devices already participating in the network when permitted by these flags.
For attempts that are successful, endpoint messages and chat data between the devices will be transmitted
using those direct connections. For attempts that fail due to environmental incompatibilities between the
devices, all communication between those devices will be transmitted via transparent cloud relay servers
instead. If the devices aren't permitted to attempt direct peer connections by these flags, then they never
exchange IP address information and will always transmit endpoint messages and chat data via transparent
cloud relay servers.
You can determine whether the local device actually established a direct peer-to-peer connection to a specific
remote device by calling PartyNetwork::GetDeviceConnectionType().
Successful direct peer connectivity may provide lower latency between some devices, though attempting to
establish it also requires users to disclose their devices' IP addresses to others, which may be a concern for
privacy or for enabling malicious users to potentially attack peers' devices and Internet connections outside of
the title. It also may not be permitted on certain platforms for policy reasons. Be sure to use the appropriate
flags for your performance and security goals.
Besides the specific network's value configured here, the flags may optionally be further constrained by a device
for all networks into which it authenticates by using PartyManager::SetOption() to set
PartyOption::LocalDeviceDirectPeerConnectivityOptionsMask. All flags are evaluated using a bitwise AND
operation. That is, a particular flag is actually only in effect for a given network's pair of devices if it's enabled in
three places: this field for the network, and both devices' respective local mask options. Even if this field permits
direct peer connectivity of the relevant form, either device can unilaterally opt out of the IP address disclosure
and direct connection attempts between them by not enabling the flag in its local device mask option. The
PartyOption::LocalDeviceDirectPeerConnectivityOptionsMask value defaults to permitting all direct peer
connections enabled by networks, so you only need to configure it if you have device-specific requirements to
prevent some or all direct peer connectivity involving it.
To avoid excessive resource consumption, the Party library will also internally prevent any given device from
attempting to establish more than c_maxDirectPeerConnectionsPerDevice direct peer connections across all
networks in which it's currently participating, even if permitted by these flags. This doesn't affect the device's
ability to participate in large or multiple networks with additional remote devices. Communication with
additional devices will simply be transmitted via transparent cloud relay servers.
It's recommended that you don't actively enforce the availability of a direct peer-to-peer connection for any
given pair of devices (i.e., don't call PartyNetwork::LeaveNetwork() if PartyNetwork::GetDeviceConnectionType()
reports a value other than PartyDeviceConnectionType::DirectPeerConnection) since the specific underlying
transmission method in use doesn't alter the overall logical ability to communicate. If your game design has
stringent requirements for maximum message latency that encourage direct peer connectivity, it's better to take
action on the current concrete observations of that latency as reported by the
PartyEndpointStatistic::AverageDeviceRoundTripLatencyInMilliseconds statistic rather than make abstract
assumptions based on transmission mechanism. Otherwise you might continually hinder users trying to play
with the same set of friends who always need to use nearby transparent cloud relay servers due to
environmental factors beyond their control.
Requirements
Header : Party.h
See also
Party members
PartyNetwork::AuthenticateLocalUser
PartyAuthenticateLocalUserCompletedStateChange
PartyManager::ConnectToNetwork
PartyConnectToNetworkCompletedStateChange
PartyNetwork::CreateEndpoint
PartyNetworkDestroyedStateChange
PartyStateChangeResult
PartyDirectPeerConnectivityOptions
PartyNetworkDescriptor
5/24/2022 • 2 minutes to read • Edit Online
Syntax
struct PartyNetworkDescriptor {
char networkIdentifier[c_networkIdentifierStringLength + 1];
char regionName[c_maxRegionNameStringLength + 1];
uint8_t opaqueConnectionInformation[c_opaqueConnectionInformationByteCount];
}
Members
networkIdentifier char[c_networkIdentifierStringLength + 1]
A unique identifier for the network.
This identifier can be used to correlate locally observed PartyNetwork behavior with remote telemetry gathered
by the Party service and transparent cloud relay. It is recommended that this identifier be recorded alongside
any other information the title records to diagnose network behavior.
regionName char[c_maxRegionNameStringLength + 1]
The Azure region in which the network was created.
opaqueConnectionInformation uint8_t[c_opaqueConnectionInformationByteCount]
Connection information for the network used internally by the Party library.
Requirements
Header : Party.h
See also
Party members
PartyProfilingMethodEntranceEventData
5/24/2022 • 2 minutes to read • Edit Online
Syntax
struct PartyProfilingMethodEntranceEventData {
PartyString methodName;
}
Members
methodName PartyString
A string containing the fully qualified name of the method responsible for the callback.
Requirements
Header : Party.h
See also
Party members
PartyProfilingMethodEntranceCallback
PartyProfilingMethodExitEventData
5/24/2022 • 2 minutes to read • Edit Online
Syntax
struct PartyProfilingMethodExitEventData {
PartyString methodName;
}
Members
methodName PartyString
A string containing the fully qualified name of the method responsible for the callback.
Requirements
Header : Party.h
See also
Party members
PartyProfilingMethodExitCallback
PartyRegion
5/24/2022 • 2 minutes to read • Edit Online
Syntax
struct PartyRegion {
char regionName[c_maxRegionNameStringLength + 1];
uint32_t roundTripLatencyInMilliseconds;
}
Members
regionName char[c_maxRegionNameStringLength + 1]
The name of the Azure region, such as "eastus2".
This name is not localized to the current user's language, and showing the string directly in UI is not
recommended outside of troubleshooting.
roundTripLatencyInMilliseconds uint32_t
The round trip latency between the local device and the region's datacenter.
Requirements
Header : Party.h
See also
Party members
PartySendMessageQueuingConfiguration
5/24/2022 • 4 minutes to read • Edit Online
Optional configuration parameters for modifying local queuing behavior when sending a message.
Syntax
struct PartySendMessageQueuingConfiguration {
int8_t priority;
uint32_t identityForCancelFilters;
uint32_t timeoutInMilliseconds;
}
Members
priority int8_t
The priority of the locally queued message in relation to chat data or messages sent from other local endpoints.
priority must be a value between c_minSendMessageQueuingPriority and c_maxSendMessageQueuingPriority ,
inclusive. Higher numbers represent higher relative priority (will be transmitted first) over lower numbers. The
default when no PartySendMessageQueuingConfiguration structure is provided to
PartyLocalEndpoint::SendMessage() is c_defaultSendMessageQueuingPriority , which lies exactly in the middle of
the signed integer range (zero).
Send queue priority does not modify the order in which messages sent from a given local endpoint are
transmitted or delivered. It only affects the ordering of messages from different local endpoints, or between an
endpoint and internally transmitted chat data, which uses priority c_chatSendMessageQueuingPriority . The local
endpoint send queue that has the messages with the highest priority value will have its messages eligible for
transmission first. If all remaining messages queued by local endpoints are of equal priority, then the individual
messages will be eligible for transmission in the same order in which their PartyLocalEndpoint::SendMessage()
calls occurred.
One way to think of the behavior is that high priority messages automatically elevate the priority of all previous
messages from the same local endpoint to the same value to ensure timely delivery of the high priority
message but without breaking the sequential delivery expectations of the messages previously transmitted by
the local endpoint. Other local endpoints have their own send sequence, and thus have no such ordering
guarantees (though the Party library makes a best-effort attempt to preserve the ordering in which they were
originally sent where possible).
A message's send queue priority matters when there are more bytes to be sent than the connection can support
due to connection quality or receiver responsiveness. Sending more important messages as higher priority
ensures that they get the first opportunity to use the limited network resources. If you continue to send
messages faster than can successfully be transmitted, lower priority messages may get "starved" and the
associated local endpoint send queue will continue to grow. Be sure to manage such potential growth by
canceling extraneous messages with PartyLocalEndpoint::CancelMessages(), using the timeoutInMilliseconds
field to automatically time out messages that have been queued for too long, or simply reducing the size and/or
frequency of the PartyLocalEndpoint::SendMessage() calls.
identityForCancelFilters uint32_t
A caller-defined value to use when evaluating the message for applicability with cancel filter expressions.
This message identity value can have any caller-specific meaning and is not interpreted by the Party library
other than for use by PartyLocalEndpoint::CancelMessages() when evaluating whether the message matches the
optionally provided cancel filter expression.
Canceling messages can help prevent the local send queue from growing excessively when experiencing poor
network conditions. Canceling message identities that match certain filter expressions works well when you
have categories of messages that are regularly sent with the latest information and should replace any
previously queued out-of-date message that might still be awaiting a transmission opportunity. Canceling can
also be useful when you have an instance or category of opportunistic messages whose loss would not be fatal
and that aren't worth the bandwidth to try transmitting instead of more valuable queued messages.
This local identity value is not part of the transmitted data payload. It has no applicability once the message
begins transmitting and can no longer be removed from the local send queue by
PartyLocalEndpoint::CancelMessages().
timeoutInMilliseconds uint32_t
The maximum time, in milliseconds, that the message is permitted to remain in a Party-managed send queue
awaiting a transmission opportunity.
If the message has not started transmitting when this timeout elapses due to connection quality or receiver
responsiveness, the message will be aborted and removed from the queue without being sent.
A timeoutInMilliseconds value of zero indicates that there should be no timeout and that the message should
remain queued until it is either successfully transmitted, is explicitly canceled, or encounters some transmission
failure such as remote disconnection. Zero is the default when no PartySendMessageQueuingConfiguration
structure is provided to PartyLocalEndpoint::SendMessage().
Message send queue timeouts can help prevent send queues from growing excessively when experiencing poor
network conditions. They work well with messages that contain time-sensitive, periodic data where it would be a
waste of bandwidth to transmit ones that are stale because a newer complete replacement message is sent
regularly, and the loss of any individual one is not fatal.
This timeout value only affects Party-managed send queuing. It does not affect the time it takes to actually
transmit a message (environmental latency) nor alter how long to wait for the receiver to acknowledge the
transmission if applicable.
This timeout value is evaluated twice when sending to targets without direct peer connections: once for the
sending client's local send queues to the transparent cloud relay, affected by local environmental conditions and
transmission rates to the relay, and a second time on the relay itself, which may be forced to queue messages
before forwarding based on differing network conditions, transmission rates, or responsiveness of the remote
targets.
Requirements
Header : Party.h
See also
Party members
PartyLocalEndpoint::SendMessage
PartyTranslation
5/24/2022 • 2 minutes to read • Edit Online
A translation.
Syntax
struct PartyTranslation {
PartyStateChangeResult result;
PartyError errorDetail;
PartyString languageCode;
PartyTranslationReceivedOptions options;
PartyString translation;
}
Members
result PartyStateChangeResult
The translation string may be up to c_maxChatTextMessageLength characters long, not including the null
terminator. Truncation occurs if the translated string length would exceed that limit, which can happen due to
language differences even though the original string length is less than or equal to c_maxChatTextMessageLength .
In such a case, options will contain PartyTranslationReceivedOptions::Truncated. Truncation may occur at an
arbitrary point in the UTF-8 byte sequence and may not result in a complete, valid character or word. Strings are
always null terminated, even when truncated.
Requirements
Header : Party.h
See also
Party members
PartyAuthenticateLocalUserCompletedStateChange
5/24/2022 • 2 minutes to read • Edit Online
Syntax
struct PartyAuthenticateLocalUserCompletedStateChange : PartyStateChange {
PartyStateChangeResult result;
PartyError errorDetail;
PartyNetwork* network;
PartyLocalUser* localUser;
PartyString invitationIdentifier;
void* asyncIdentifier;
}
Members
result PartyStateChangeResult
Indicates that the authenticate local user operation Succeeded or provides the reason that it failed.
errorDetail PartyError
A diagnostic value providing additional troubleshooting information regarding any potential error condition.
The human-readable form of this error detail can be retrieved via PartyManager::GetErrorMessage().
network PartyNetwork*
The network used in the call associated with this state change.
localUser PartyLocalUser*
The local user provided to the call associated with this state change.
invitationIdentifier PartyString
The identifier of the invitation used to authenticate into the network.
asyncIdentifier void*
The async identifier provided to the call associated with this state change.
Requirements
Header : Party.h
See also
Party members
PartyNetwork::AuthenticateLocalUser
PartyChatControlCreatedStateChange
5/24/2022 • 2 minutes to read • Edit Online
Syntax
struct PartyChatControlCreatedStateChange : PartyStateChange {
PartyChatControl* chatControl;
}
Members
chatControl PartyChatControl*
The chat control that was created.
Requirements
Header : Party.h
See also
Party members
PartyLocalDevice::CreateChatControl
PartyChatControlDestroyedStateChange
5/24/2022 • 2 minutes to read • Edit Online
Syntax
struct PartyChatControlDestroyedStateChange : PartyStateChange {
PartyChatControl* chatControl;
PartyDestroyedReason reason;
PartyError errorDetail;
}
Members
chatControl PartyChatControl*
The chat control that was destroyed.
The memory remains valid until this state change is returned.
reason PartyDestroyedReason
The reason the chat control was destroyed.
errorDetail PartyError
A diagnostic value providing additional troubleshooting information regarding any potential error condition.
The human-readable form of this error detail can be retrieved via PartyManager::GetErrorMessage().
Requirements
Header : Party.h
See also
Party members
PartyLocalDevice::DestroyChatControl
PartyChatControlJoinedNetworkStateChange
5/24/2022 • 2 minutes to read • Edit Online
Syntax
struct PartyChatControlJoinedNetworkStateChange : PartyStateChange {
PartyNetwork* network;
PartyChatControl* chatControl;
}
Members
network PartyNetwork*
The network joined.
chatControl PartyChatControl*
The chat control that joined the network.
Requirements
Header : Party.h
See also
Party members
PartyNetwork::ConnectChatControl
PartyChatControlLeftNetworkStateChange
5/24/2022 • 2 minutes to read • Edit Online
Syntax
struct PartyChatControlLeftNetworkStateChange : PartyStateChange {
PartyDestroyedReason reason;
PartyError errorDetail;
PartyNetwork* network;
PartyChatControl* chatControl;
}
Members
reason PartyDestroyedReason
Requirements
Header : Party.h
See also
Party members
PartyNetwork::DisconnectChatControl
PartyChatTextReceivedStateChange
5/24/2022 • 2 minutes to read • Edit Online
Syntax
struct PartyChatTextReceivedStateChange : PartyStateChange {
PartyChatControl* senderChatControl;
uint32_t receiverChatControlCount;
PartyLocalChatControlArray receiverChatControls;
PartyString languageCode;
PartyString chatText;
uint32_t dataSize;
const void* data;
uint32_t translationCount;
PartyTranslation* translations;
PartyChatTextReceivedOptions options;
PartyString originalChatText;
PartyError errorDetail;
}
Members
senderChatControl PartyChatControl*
The chat control object that originated the text message.
receiverChatControlCount uint32_t
The number of local receiver chat controls to which the text message is addressed.
receiverChatControls PartyLocalChatControlArray
array of size receiverChatControlCount
The local receiver chat controls to which the text message is addressed.
languageCode PartyString
The language of the chat text.
The language will only be provided when translation to the local language is enabled. If translation isn't enabled,
or failure is encountered during translation, the language code will be an empty string.
The language code will be in BCP 47 format, such as en-US for English (United States). Supported language
codes are enumerated at https://docs.microsoft.com/azure/cognitive-services/speech-service/language-
support.
chatText PartyString
The received chat text.
The string may be up to c_maxChatTextMessageLength characters long, not including the null terminator.
When filtering is enabled, this text may not be the exact text sent by the remote user. The exact source text can be
retrieved from the originalChatText field.
dataSize uint32_t
The size of the data associated with this text message.
data const void*
buffer of size dataSize bytes
The data associated with this text message.
translationCount uint32_t
The number of translations associated with the chat text.
Translations will be provided if PartyTextChatOptions::TranslateToLocalLanguage had previously been specified
via PartyLocalChatControl::SetTextChatOptions() on a chat control local to this device. There may be more than
one translation if multiple local chat controls have enabled translation and the local chat controls have specified
different languages via PartyLocalDevice::CreateChatControl(). In that case, the app can compare the
languageCode field of each PartyTranslation in translations against the language code, obtained via
PartyLocalChatControl::GetLanguage(), for each local chat control in receiverChatControls to determine the
target local chat control for each translation.
translations PartyTranslation*
array of size translationCount
Requirements
Header : Party.h
See also
Party members
PartyLocalDevice::CreateChatControl
PartyLocalChatControl::SendText
PartyLocalChatControl::SetTextChatOptions
PartyConfigureAudioManipulationCaptureStreamCompletedStateChange
5/24/2022 • 2 minutes to read • Edit Online
Syntax
struct PartyConfigureAudioManipulationCaptureStreamCompletedStateChange : PartyStateChange {
PartyStateChangeResult result;
PartyError errorDetail;
PartyLocalChatControl* localChatControl;
PartyAudioManipulationSinkStreamConfiguration* configuration;
void* asyncIdentifier;
}
Members
result PartyStateChangeResult
Requirements
Header : Party.h
See also
Party members
PartyLocalChatControl::ConfigureAudioManipulationCaptureStream
PartyConfigureAudioManipulationRenderStreamCompletedStateChange
5/24/2022 • 2 minutes to read • Edit Online
Syntax
struct PartyConfigureAudioManipulationRenderStreamCompletedStateChange : PartyStateChange {
PartyStateChangeResult result;
PartyError errorDetail;
PartyLocalChatControl* localChatControl;
PartyAudioManipulationSinkStreamConfiguration* configuration;
void* asyncIdentifier;
}
Members
result PartyStateChangeResult
Requirements
Header : Party.h
See also
Party members
PartyLocalChatControl::ConfigureAudioManipulationRenderStream
PartyConfigureAudioManipulationVoiceStreamCompletedStateChange
5/24/2022 • 2 minutes to read • Edit Online
Syntax
struct PartyConfigureAudioManipulationVoiceStreamCompletedStateChange : PartyStateChange {
PartyStateChangeResult result;
PartyError errorDetail;
PartyChatControl* chatControl;
PartyAudioManipulationSourceStreamConfiguration* configuration;
void* asyncIdentifier;
}
Members
result PartyStateChangeResult
Requirements
Header : Party.h
See also
Party members
PartyChatControl::ConfigureAudioManipulationVoiceStream
PartyConnectChatControlCompletedStateChange
5/24/2022 • 2 minutes to read • Edit Online
Syntax
struct PartyConnectChatControlCompletedStateChange : PartyStateChange {
PartyStateChangeResult result;
PartyError errorDetail;
PartyNetwork* network;
PartyLocalChatControl* localChatControl;
void* asyncIdentifier;
}
Members
result PartyStateChangeResult
Requirements
Header : Party.h
See also
Party members
PartyNetwork::ConnectChatControl
PartyConnectToNetworkCompletedStateChange
5/24/2022 • 2 minutes to read • Edit Online
Syntax
struct PartyConnectToNetworkCompletedStateChange : PartyStateChange {
PartyStateChangeResult result;
PartyError errorDetail;
PartyNetworkDescriptor networkDescriptor;
void* asyncIdentifier;
PartyNetwork* network;
}
Members
result PartyStateChangeResult
Indicates that the connect to network operation Succeeded or provides the reason that it failed.
errorDetail PartyError
A diagnostic value providing additional troubleshooting information regarding any potential error condition.
The human-readable form of this error detail can be retrieved via PartyManager::GetErrorMessage().
networkDescriptor PartyNetworkDescriptor
The network descriptor provided to the call associated with this state change.
asyncIdentifier void*
The async identifier provided to the call associated with this state change.
network PartyNetwork*
The network that was connected to.
Requirements
Header : Party.h
See also
Party members
PartyManager::ConnectToNetwork
PartyCreateChatControlCompletedStateChange
5/24/2022 • 2 minutes to read • Edit Online
Syntax
struct PartyCreateChatControlCompletedStateChange : PartyStateChange {
PartyStateChangeResult result;
PartyError errorDetail;
PartyLocalDevice* localDevice;
PartyLocalUser* localUser;
PartyString languageCode;
void* asyncIdentifier;
PartyLocalChatControl* localChatControl;
}
Members
result PartyStateChangeResult
Indicates that the chat control creation operation Succeeded or provides the reason that it failed.
errorDetail PartyError
A diagnostic value providing additional troubleshooting information regarding any potential error condition.
The human-readable form of this error detail can be retrieved via PartyManager::GetErrorMessage().
localDevice PartyLocalDevice*
The local device used in the call associated with this state change.
localUser PartyLocalUser*
The local user provided to the call associated with this state change.
languageCode PartyString
The language code provided to the call associated with this state change.
asyncIdentifier void*
The async identifier provided to the call associated with this state change.
localChatControl PartyLocalChatControl*
The chat control that was created.
Requirements
Header : Party.h
See also
Party members
PartyLocalDevice::CreateChatControl
PartyCreateEndpointCompletedStateChange
5/24/2022 • 2 minutes to read • Edit Online
Syntax
struct PartyCreateEndpointCompletedStateChange : PartyStateChange {
PartyStateChangeResult result;
PartyError errorDetail;
PartyNetwork* network;
PartyLocalUser* localUser;
void* asyncIdentifier;
PartyLocalEndpoint* localEndpoint;
}
Members
result PartyStateChangeResult
Indicates that the create endpoint Succeeded or provides the reason that it failed.
errorDetail PartyError
A diagnostic value providing additional troubleshooting information regarding any potential error condition.
The human-readable form of this error detail can be retrieved via PartyManager::GetErrorMessage().
network PartyNetwork*
The network used in the call associated with this state change.
localUser PartyLocalUser*
may be nullptr
The local user provided to the call associated with this state change if one was provided.
asyncIdentifier void*
The async identifier provided to the call associated with this state change.
localEndpoint PartyLocalEndpoint*
The endpoint that was created.
Remarks
An associated PartyEndpointCreatedStateChange will be generated before this state change is generated.
Requirements
Header : Party.h
See also
Party members
PartyNetwork::CreateEndpoint
PartyCreateInvitationCompletedStateChange
5/24/2022 • 2 minutes to read • Edit Online
Syntax
struct PartyCreateInvitationCompletedStateChange : PartyStateChange {
PartyStateChangeResult result;
PartyError errorDetail;
PartyNetwork* network;
PartyLocalUser* localUser;
void* asyncIdentifier;
PartyInvitation* invitation;
}
Members
result PartyStateChangeResult
Indicates that the PartyNetwork::CreateInvitation() operation succeeded or provides the reason that it failed.
errorDetail PartyError
A diagnostic value providing additional troubleshooting information regarding any potential error condition.
The human-readable form of this error detail can be retrieved via PartyManager::GetErrorMessage().
network PartyNetwork*
The network used in the call associated with this state change.
localUser PartyLocalUser*
The local user that created the invitation.
asyncIdentifier void*
The async identifier provided to the call associated with this state change.
invitation PartyInvitation*
The invitation created for the network.
Requirements
Header : Party.h
See also
Party members
PartyNetwork::CreateInvitation
PartyCreateNewNetworkCompletedStateChange
5/24/2022 • 2 minutes to read • Edit Online
Syntax
struct PartyCreateNewNetworkCompletedStateChange : PartyStateChange {
PartyStateChangeResult result;
PartyError errorDetail;
PartyLocalUser* localUser;
PartyNetworkConfiguration networkConfiguration;
uint32_t regionCount;
const PartyRegion* regions;
void* asyncIdentifier;
PartyNetworkDescriptor networkDescriptor;
PartyString appliedInitialInvitationIdentifier;
}
Members
result PartyStateChangeResult
Indicates that the create new network operation Succeeded or provides the reason that it failed.
errorDetail PartyError
A diagnostic value providing additional troubleshooting information regarding any potential error condition.
The human-readable form of this error detail can be retrieved via PartyManager::GetErrorMessage().
localUser PartyLocalUser*
The local user provided to the call associated with this state change.
networkConfiguration PartyNetworkConfiguration
The network configuration provided to the call associated with this state change.
regionCount uint32_t
The number of regions provided to the call associated with this state change.
regions const PartyRegion*
The regions provided to the call associated with this state change.
asyncIdentifier void*
The async identifier provided to the call associated with this state change.
networkDescriptor PartyNetworkDescriptor
The network descriptor of the network that was created.
The regionName and opaqueConnectionInformation fields are only populated if the result field is
PartyStateChangeResult::Succeeded. The networkIdentifier field should always be populated. If the result field is
PartyStateChangeResult::Succeeded, this network descriptor is serializable via
PartyManager::SerializeNetworkDescriptor().
appliedInitialInvitationIdentifier PartyString
The identifier for the network's initial invitation.
Requirements
Header : Party.h
See also
Party members
PartyManager::CreateNewNetwork
PartyManager::SerializeNetworkDescriptor
PartyDataBuffersReturnedStateChange
5/24/2022 • 2 minutes to read • Edit Online
Syntax
struct PartyDataBuffersReturnedStateChange : PartyStateChange {
PartyNetwork* network;
PartyLocalEndpoint* localSenderEndpoint;
uint32_t dataBufferCount;
const PartyDataBuffer* dataBuffers;
void* messageIdentifier;
}
Members
network PartyNetwork*
The network on which the message was sent.
localSenderEndpoint PartyLocalEndpoint*
The local endpoint used to send the message.
dataBufferCount uint32_t
The number of data buffers.
dataBuffers const PartyDataBuffer*
array of size dataBufferCount
Remarks
This state change is only returned if the corresponding call to PartyLocalEndpoint::SendMessage() included the
PartySendMessageOptions::DontCopyDataBuffers option. This state change is returned once the data buffers
passed with this call are no longer in use by the library.
Requirements
Header : Party.h
See also
Party members
PartyLocalEndpoint::SendMessage
PartyDestroyChatControlCompletedStateChange
5/24/2022 • 2 minutes to read • Edit Online
Syntax
struct PartyDestroyChatControlCompletedStateChange : PartyStateChange {
PartyStateChangeResult result;
PartyError errorDetail;
PartyLocalDevice* localDevice;
PartyLocalChatControl* localChatControl;
void* asyncIdentifier;
}
Members
result PartyStateChangeResult
Indicates that the chat control destruction operation Succeeded or provides the reason that it failed.
errorDetail PartyError
A diagnostic value providing additional troubleshooting information regarding any potential error condition.
The human-readable form of this error detail can be retrieved via PartyManager::GetErrorMessage().
localDevice PartyLocalDevice*
The local device used in the call associated with this state change.
localChatControl PartyLocalChatControl*
The chat control that was destroyed.
The memory remains valid until this state change is returned.
asyncIdentifier void*
The async identifier provided to the call associated with this state change.
Requirements
Header : Party.h
See also
Party members
PartyLocalDevice::DestroyChatControl
PartyDestroyEndpointCompletedStateChange
5/24/2022 • 2 minutes to read • Edit Online
Syntax
struct PartyDestroyEndpointCompletedStateChange : PartyStateChange {
PartyStateChangeResult result;
PartyError errorDetail;
PartyNetwork* network;
PartyLocalEndpoint* localEndpoint;
void* asyncIdentifier;
}
Members
result PartyStateChangeResult
Indicates that the destroy endpoint operation Succeeded or provides the reason that it failed.
errorDetail PartyError
A diagnostic value providing additional troubleshooting information regarding any potential error condition.
The human-readable form of this error detail can be retrieved via PartyManager::GetErrorMessage().
network PartyNetwork*
The network used in the call associated with this state change.
localEndpoint PartyLocalEndpoint*
The endpoint provided to the call associated with this state change.
asyncIdentifier void*
The async identifier provided to the call associated with this state change.
Remarks
An associated PartyEndpointDestroyedStateChange will be generated before this state change is generated.
Requirements
Header : Party.h
See also
Party members
PartyNetwork::DestroyEndpoint
PartyDestroyLocalUserCompletedStateChange
5/24/2022 • 2 minutes to read • Edit Online
Syntax
struct PartyDestroyLocalUserCompletedStateChange : PartyStateChange {
PartyStateChangeResult result;
PartyError errorDetail;
PartyLocalUser* localUser;
void* asyncIdentifier;
}
Members
result PartyStateChangeResult
Indicates that the destroy local user operation Succeeded or provides the reason that it failed.
errorDetail PartyError
A diagnostic value providing additional troubleshooting information regarding any potential error condition.
The human-readable form of this error detail can be retrieved via PartyManager::GetErrorMessage().
localUser PartyLocalUser*
The local user provided to the call associated with this state change.
asyncIdentifier void*
The async identifier provided to the call associated with this state change.
Remarks
This PartyLocalUser will be removed from all dependent networks prior to this state change. All dependent
PartyEndpoint and PartyChatControl objects will be destroyed with reason
PartyDestroyedReason::UserRemoved prior to the PartyLocalUser being removed from its dependent networks.
Once this state change is returned to PartyManager::FinishProcessingStateChanges(), the PartyLocalUser object
memory will become invalid.
Requirements
Header : Party.h
See also
Party members
PartyManager::DestroyLocalUser
PartyDisconnectChatControlCompletedStateChange
5/24/2022 • 2 minutes to read • Edit Online
Syntax
struct PartyDisconnectChatControlCompletedStateChange : PartyStateChange {
PartyStateChangeResult result;
PartyError errorDetail;
PartyNetwork* network;
PartyLocalChatControl* localChatControl;
void* asyncIdentifier;
}
Members
result PartyStateChangeResult
Requirements
Header : Party.h
See also
Party members
PartyNetwork::DisconnectChatControl
PartyEndpointCreatedStateChange
5/24/2022 • 2 minutes to read • Edit Online
Syntax
struct PartyEndpointCreatedStateChange : PartyStateChange {
PartyNetwork* network;
PartyEndpoint* endpoint;
}
Members
network PartyNetwork*
The network of the endpoint that was created.
endpoint PartyEndpoint*
The endpoint that was created.
Requirements
Header : Party.h
See also
Party members
PartyEndpointDestroyedStateChange
5/24/2022 • 2 minutes to read • Edit Online
Syntax
struct PartyEndpointDestroyedStateChange : PartyStateChange {
PartyNetwork* network;
PartyEndpoint* endpoint;
PartyDestroyedReason reason;
PartyError errorDetail;
}
Members
network PartyNetwork*
The network of the endpoint that was destroyed.
endpoint PartyEndpoint*
The endpoint that was destroyed.
reason PartyDestroyedReason
The reason the endpoint was destroyed.
errorDetail PartyError
A diagnostic value providing additional troubleshooting information regarding any potential error condition.
The human-readable form of this error detail can be retrieved via PartyManager::GetErrorMessage().
Requirements
Header : Party.h
See also
Party members
PartyEndpointMessageReceivedStateChange
5/24/2022 • 2 minutes to read • Edit Online
Syntax
struct PartyEndpointMessageReceivedStateChange : PartyStateChange {
PartyNetwork* network;
PartyEndpoint* senderEndpoint;
uint32_t receiverEndpointCount;
PartyLocalEndpointArray receiverEndpoints;
PartyMessageReceivedOptions options;
uint32_t messageSize;
const void* messageBuffer;
}
Members
network PartyNetwork*
The network containing the endpoint on which the message was received.
senderEndpoint PartyEndpoint*
The endpoint which sent the message.
receiverEndpointCount uint32_t
The number of local endpoints to which the message was sent. This value will always be greater than zero. If the
sender specified an empty target endpoints array in the PartyLocalEndpoint::SendMessage() call that resulted in
this state change, receiverEndpointCount and receiverEndpoints will contain all local endpoints.
receiverEndpoints PartyLocalEndpointArray
array of size receiverEndpointCount
The local endpoints to which the message was sent. This array will never be empty. If the sender specified an
empty target endpoints array in the PartyLocalEndpoint::SendMessage() call that resulted in this state change,
receiverEndpointCount and receiverEndpoints will contain all local endpoints.
options PartyMessageReceivedOptions
The options used to send the message.
messageSize uint32_t
The size of the message in bytes.
messageBuffer const void*
buffer of size messageSize bytes
The message buffer.
Requirements
Header : Party.h
See also
Party members
PartyLocalEndpoint::SendMessage
PartyInvitationCreatedStateChange
5/24/2022 • 2 minutes to read • Edit Online
Syntax
struct PartyInvitationCreatedStateChange : PartyStateChange {
PartyNetwork* network;
PartyInvitation* invitation;
}
Members
network PartyNetwork*
The network of the invitation that was created.
invitation PartyInvitation*
The invitation that was created.
Upon receiving this state change, the invitation object will be queryable via PartyNetwork::GetInvitations().
Requirements
Header : Party.h
See also
Party members
PartyInvitationDestroyedStateChange
5/24/2022 • 2 minutes to read • Edit Online
Syntax
struct PartyInvitationDestroyedStateChange : PartyStateChange {
PartyNetwork* network;
PartyInvitation* invitation;
PartyDestroyedReason reason;
PartyError errorDetail;
}
Members
network PartyNetwork*
The network of the invitation that was destroyed.
invitation PartyInvitation*
The invitation that was destroyed.
Upon receiving this state change, the invitation object will no longer be queryable via
PartyNetwork::GetInvitations().
reason PartyDestroyedReason
The reason the invitation was destroyed.
If the invitation object was destroyed because it was explicitly revoked via PartyNetwork::RevokeInvitation() or
automatically revoked when the creating local user left the network, this value will be
PartyDestroyedReason::Requested. If the invitation object was destroyed because the local client is no longer
authenticated in the network, this value will be PartyDestroyedReason::DeviceLostAuthentication.
errorDetail PartyError
A diagnostic value providing additional troubleshooting information regarding any potential error condition.
The human-readable form of this error detail can be retrieved via PartyManager::GetErrorMessage().
Requirements
Header : Party.h
See also
Party members
PartyLeaveNetworkCompletedStateChange
5/24/2022 • 2 minutes to read • Edit Online
Syntax
struct PartyLeaveNetworkCompletedStateChange : PartyStateChange {
PartyStateChangeResult result;
PartyError errorDetail;
PartyNetwork* network;
void* asyncIdentifier;
}
Members
result PartyStateChangeResult
Indicates that the leave network operation Succeeded or provides the reason that it failed.
errorDetail PartyError
A diagnostic value providing additional troubleshooting information regarding any potential error condition.
The human-readable form of this error detail can be retrieved via PartyManager::GetErrorMessage().
network PartyNetwork*
The network used in call associated with this state change.
asyncIdentifier void*
The async identifier provided to the call associated with this state change.
Remarks
An associated PartyNetworkDestroyedStateChange will be generated before this state change is generated. The
network object network is only valid until this state change is returned to
PartyManager::FinishProcessingStateChanges().
Requirements
Header : Party.h
See also
Party members
PartyNetwork::LeaveNetwork
PartyLocalChatAudioInputChangedStateChange
5/24/2022 • 2 minutes to read • Edit Online
Syntax
struct PartyLocalChatAudioInputChangedStateChange : PartyStateChange {
PartyLocalChatControl* localChatControl;
PartyAudioInputState state;
PartyError errorDetail;
}
Members
localChatControl PartyLocalChatControl*
The local chat control which had an audio input state change.
state PartyAudioInputState
Indicates the new state of the audio input associated with the chat control.
errorDetail PartyError
A diagnostic value providing additional troubleshooting information regarding any potential error condition.
The human-readable form of this error detail can be retrieved via PartyManager::GetErrorMessage().
Requirements
Header : Party.h
See also
Party members
PartyLocalChatControl::SetAudioInput
PartyLocalChatAudioOutputChangedStateChange
5/24/2022 • 2 minutes to read • Edit Online
Syntax
struct PartyLocalChatAudioOutputChangedStateChange : PartyStateChange {
PartyLocalChatControl* localChatControl;
PartyAudioOutputState state;
PartyError errorDetail;
}
Members
localChatControl PartyLocalChatControl*
The local chat control which had an audio output state change.
state PartyAudioOutputState
Indicates the new state of the audio output associated with the chat control.
errorDetail PartyError
A diagnostic value providing additional troubleshooting information regarding any potential error condition.
The human-readable form of this error detail can be retrieved via PartyManager::GetErrorMessage().
Requirements
Header : Party.h
See also
Party members
PartyLocalChatControl::SetAudioOutput
PartyLocalUserRemovedStateChange
5/24/2022 • 2 minutes to read • Edit Online
Syntax
struct PartyLocalUserRemovedStateChange : PartyStateChange {
PartyNetwork* network;
PartyLocalUser* localUser;
PartyLocalUserRemovedReason removedReason;
}
Members
network PartyNetwork*
The network that the local user was removed from.
localUser PartyLocalUser*
The local user provided to the call associated with this state change.
removedReason PartyLocalUserRemovedReason
The reason the user was removed from the network.
Remarks
All PartyEndpoints depending on this user will have been destroyed prior to this state change being generated.
All PartyChatControls depending on this user will have left the network prior to this state change being
generated.
Requirements
Header : Party.h
See also
Party members
PartyNetwork::RemoveLocalUser
PartyManager::DestroyLocalUser
PartyNetworkConfigurationMadeAvailableStateChange
5/24/2022 • 2 minutes to read • Edit Online
Syntax
struct PartyNetworkConfigurationMadeAvailableStateChange : PartyStateChange {
PartyNetwork* network;
PartyNetworkConfiguration* networkConfiguration;
}
Members
network PartyNetwork*
The network where the network configuration was made available.
networkConfiguration PartyNetworkConfiguration*
The newly available network configuration.
Requirements
Header : Party.h
See also
Party members
PartyNetwork::GetNetworkConfiguration
PartyNetworkDescriptorChangedStateChange
5/24/2022 • 2 minutes to read • Edit Online
Syntax
struct PartyNetworkDescriptorChangedStateChange : PartyStateChange {
PartyNetwork* network;
}
Members
network PartyNetwork*
The network where the network descriptor changed.
Remarks
This state change is generated when the network descriptor of a network changes due to migration from one
server to another. Use PartyNetwork::GetNetworkDescriptor() to get the new network descriptor. The old
network descriptor is no longer guaranteed to be usable for connecting to the network, so any outstanding
external references to the old network descriptor (such as invitations sent over a social network) should be
updated.
Requirements
Header : Party.h
See also
Party members
PartyNetwork::GetNetworkDescriptor
PartyNetworkDestroyedStateChange
5/24/2022 • 2 minutes to read • Edit Online
Syntax
struct PartyNetworkDestroyedStateChange : PartyStateChange {
PartyDestroyedReason reason;
PartyError errorDetail;
PartyNetwork* network;
}
Members
reason PartyDestroyedReason
Requirements
Header : Party.h
See also
Party members
PartyPopulateAvailableTextToSpeechProfilesCompletedStateChange
5/24/2022 • 2 minutes to read • Edit Online
Syntax
struct PartyPopulateAvailableTextToSpeechProfilesCompletedStateChange : PartyStateChange {
PartyStateChangeResult result;
PartyError errorDetail;
PartyLocalChatControl* localChatControl;
void* asyncIdentifier;
}
Members
result PartyStateChangeResult
Requirements
Header : Party.h
See also
Party members
PartyLocalChatControl::PopulateAvailableTextToSpeechProfiles
PartyRegionsChangedStateChange
5/24/2022 • 2 minutes to read • Edit Online
Syntax
struct PartyRegionsChangedStateChange : PartyStateChange {
PartyStateChangeResult result;
PartyError errorDetail;
}
Members
result PartyStateChangeResult
Indicates whether a background operation to query the list of supported regions and the latency to each region
Succeeded, or provides the reason that it failed.
On success, the region list provided by PartyManager::GetRegions() will be populated with the results of the
operation. On failure, the region list provided by PartyManager::GetRegions() will be empty.
If the result is PartyStateChangeResult::FailedToBindToLocalUdpSocket, the library couldn't bind to the local UDP
socket specified in the PartyOption::LocalUdpSocketBindAddress option. The title must clean up its instance of
the library, update the PartyOption::LocalUdpSocketBindAddress option to a valid, available bind address, and
re-initialize the library.
errorDetail PartyError
A diagnostic value providing additional troubleshooting information regarding any potential error condition.
The human-readable form of this error detail can be retrieved via PartyManager::GetErrorMessage().
Requirements
Header : Party.h
See also
Party members
PartyManager::GetRegions
PartyRemoteDeviceCreatedStateChange
5/24/2022 • 2 minutes to read • Edit Online
Syntax
struct PartyRemoteDeviceCreatedStateChange : PartyStateChange {
PartyDevice* device;
}
Members
device PartyDevice*
Remarks
This state change indicates that the device was just created.
Requirements
Header : Party.h
See also
Party members
PartyRemoteDeviceDestroyedStateChange
5/24/2022 • 2 minutes to read • Edit Online
Syntax
struct PartyRemoteDeviceDestroyedStateChange : PartyStateChange {
PartyDevice* device;
}
Members
device PartyDevice*
Remarks
This state change is generated when device has left all networks.
Requirements
Header : Party.h
See also
Party members
PartyRemoteDeviceJoinedNetworkStateChange
5/24/2022 • 2 minutes to read • Edit Online
Syntax
struct PartyRemoteDeviceJoinedNetworkStateChange : PartyStateChange {
PartyDevice* device;
PartyNetwork* network;
}
Members
device PartyDevice*
Remarks
This state change indicates that the device has just joined the network.
Requirements
Header : Party.h
See also
Party members
PartyRemoteDeviceLeftNetworkStateChange
5/24/2022 • 2 minutes to read • Edit Online
Syntax
struct PartyRemoteDeviceLeftNetworkStateChange : PartyStateChange {
PartyDestroyedReason reason;
PartyError errorDetail;
PartyDevice* device;
PartyNetwork* network;
}
Members
reason PartyDestroyedReason
Remarks
This state change indicates that the device just left the network.
Requirements
Header : Party.h
See also
Party members
PartyRemoveLocalUserCompletedStateChange
5/24/2022 • 2 minutes to read • Edit Online
Syntax
struct PartyRemoveLocalUserCompletedStateChange : PartyStateChange {
PartyStateChangeResult result;
PartyError errorDetail;
PartyNetwork* network;
PartyLocalUser* localUser;
void* asyncIdentifier;
}
Members
result PartyStateChangeResult
Indicates that the remove local user operation Succeeded or provides the reason that it failed.
errorDetail PartyError
A diagnostic value providing additional troubleshooting information regarding any potential error condition.
The human-readable form of this error detail can be retrieved via PartyManager::GetErrorMessage().
network PartyNetwork*
The network used in the call associated with this state change.
localUser PartyLocalUser*
The local user provided to the call associated with this state change.
asyncIdentifier void*
The async identifier provided to the call associated with this state change.
Remarks
All PartyEndpoints and PartyChatControls depending upon this user will have been destroyed with reason
PartyDestroyedReason::UserRemoved before this state change is generated. If the user referenced by this state
change was the last authenticated user in the network, then all remaining PartyEndpoints on this device, which
at this point inherently consists of only endpoints associated with the last user or no user, will also have been
destroyed before this state change is generated. An associated PartyLocalUserRemovedStateChange will have
been generated before this state change is generated.
Requirements
Header : Party.h
See also
Party members
PartyChatControlDestroyedStateChange
PartyChatControlLeftNetworkStateChange
PartyEndpointDestroyedStateChange
PartyNetwork::RemoveLocalUser
PartyRevokeInvitationCompletedStateChange
5/24/2022 • 2 minutes to read • Edit Online
Syntax
struct PartyRevokeInvitationCompletedStateChange : PartyStateChange {
PartyStateChangeResult result;
PartyError errorDetail;
PartyNetwork* network;
PartyLocalUser* localUser;
PartyInvitation* invitation;
void* asyncIdentifier;
}
Members
result PartyStateChangeResult
Indicates that the PartyNetwork::RevokeInvitation() operation succeeded or provides the reason that it failed.
errorDetail PartyError
A diagnostic value providing additional troubleshooting information regarding any potential error condition.
The human-readable form of this error detail can be retrieved via PartyManager::GetErrorMessage().
network PartyNetwork*
The network used in the call associated with this state change.
localUser PartyLocalUser*
The local user used to revoke the invitation.
invitation PartyInvitation*
The revoked invitation.
asyncIdentifier void*
The async identifier provided to the call associated with this state change.
Requirements
Header : Party.h
See also
Party members
PartyNetwork::RevokeInvitation
PartySetChatAudioInputCompletedStateChange
5/24/2022 • 2 minutes to read • Edit Online
Syntax
struct PartySetChatAudioInputCompletedStateChange : PartyStateChange {
PartyStateChangeResult result;
PartyError errorDetail;
PartyLocalChatControl* localChatControl;
PartyAudioDeviceSelectionType audioDeviceSelectionType;
PartyString audioDeviceSelectionContext;
void* asyncIdentifier;
}
Members
result PartyStateChangeResult
Indicates that the audio input configuration operation Succeeded or provides the reason that it failed.
errorDetail PartyError
A diagnostic value providing additional troubleshooting information regarding any potential error condition.
The human-readable form of this error detail can be retrieved via PartyManager::GetErrorMessage().
localChatControl PartyLocalChatControl*
The chat control used in the call associated with this state change.
audioDeviceSelectionType PartyAudioDeviceSelectionType
The audio device selection type provided to the call associated with this state change.
audioDeviceSelectionContext PartyString
The device context provided to the call associated with this state change.
asyncIdentifier void*
The async identifier provided to the call associated with this state change.
Requirements
Header : Party.h
See also
Party members
PartyLocalChatControl::SetAudioInput
PartySetChatAudioOutputCompletedStateChange
5/24/2022 • 2 minutes to read • Edit Online
Syntax
struct PartySetChatAudioOutputCompletedStateChange : PartyStateChange {
PartyStateChangeResult result;
PartyError errorDetail;
PartyLocalChatControl* localChatControl;
PartyAudioDeviceSelectionType audioDeviceSelectionType;
PartyString audioDeviceSelectionContext;
void* asyncIdentifier;
}
Members
result PartyStateChangeResult
Indicates that the audio output configuration operation Succeeded or provides the reason that it failed.
errorDetail PartyError
A diagnostic value providing additional troubleshooting information regarding any potential error condition.
The human-readable form of this error detail can be retrieved via PartyManager::GetErrorMessage().
localChatControl PartyLocalChatControl*
The chat control used in the call associated with this state change.
audioDeviceSelectionType PartyAudioDeviceSelectionType
The audio device selection type provided to the call associated with this state change.
audioDeviceSelectionContext PartyString
The device context provided to the call associated with this state change.
asyncIdentifier void*
The async identifier provided to the call associated with this state change.
Requirements
Header : Party.h
See also
Party members
PartyLocalChatControl::SetAudioOutput
PartySetTextChatOptionsCompletedStateChange
5/24/2022 • 2 minutes to read • Edit Online
Syntax
struct PartySetTextChatOptionsCompletedStateChange : PartyStateChange {
PartyStateChangeResult result;
PartyError errorDetail;
PartyLocalChatControl* localChatControl;
PartyTextChatOptions options;
void* asyncIdentifier;
}
Members
result PartyStateChangeResult
Requirements
Header : Party.h
See also
Party members
PartyLocalChatControl::SetTranscriptionOptions
PartySetTextToSpeechProfileCompletedStateChange
5/24/2022 • 2 minutes to read • Edit Online
Syntax
struct PartySetTextToSpeechProfileCompletedStateChange : PartyStateChange {
PartyStateChangeResult result;
PartyError errorDetail;
PartyLocalChatControl* localChatControl;
PartySynthesizeTextToSpeechType type;
PartyString profileIdentifier;
void* asyncIdentifier;
}
Members
result PartyStateChangeResult
Remarks
At most, one PartySetTextToSpeechProfileCompletedStateChange object will be returned in any state change
batch from PartyManager::StartProcessingStateChanges().
Requirements
Header : Party.h
See also
Party members
PartyLocalChatControl::SetTextToSpeechProfile
PartySetTranscriptionOptionsCompletedStateChange
5/24/2022 • 2 minutes to read • Edit Online
Syntax
struct PartySetTranscriptionOptionsCompletedStateChange : PartyStateChange {
PartyStateChangeResult result;
PartyError errorDetail;
PartyLocalChatControl* localChatControl;
PartyVoiceChatTranscriptionOptions options;
void* asyncIdentifier;
}
Members
result PartyStateChangeResult
Requirements
Header : Party.h
See also
Party members
PartyLocalChatControl::SetTranscriptionOptions
PartyStateChange
5/24/2022 • 2 minutes to read • Edit Online
Syntax
struct PartyStateChange {
PartyStateChangeType stateChangeType;
}
Members
stateChangeType PartyStateChangeType
The specific type of the state change represented.
Use this field to determine which corresponding derived structure is represented by this PartyStateChange
structure header.
Remarks
PartyStateChange structures are reported by PartyManager::StartProcessingStateChanges() for the title to
handle and then promptly pass back via the PartyManager::FinishProcessingStateChanges() method.
The stateChangeType field indicates which kind of state change occurred, and this base structure should then be
cast to a more specific derived structure to retrieve additional event-specific information.
Requirements
Header : Party.h
See also
Party members
PartyManager::StartProcessingStateChanges
PartyManager::FinishProcessingStateChanges
PartySynthesizeTextToSpeechCompletedStateChange
5/24/2022 • 2 minutes to read • Edit Online
Syntax
struct PartySynthesizeTextToSpeechCompletedStateChange : PartyStateChange {
PartyStateChangeResult result;
PartyError errorDetail;
PartyLocalChatControl* localChatControl;
PartySynthesizeTextToSpeechType type;
PartyString textToSynthesize;
void* asyncIdentifier;
}
Members
result PartyStateChangeResult
Requirements
Header : Party.h
See also
Party members
PartyLocalChatControl::SynthesizeTextToSpeech
PartyVoiceChatTranscriptionReceivedStateChange
5/24/2022 • 3 minutes to read • Edit Online
Syntax
struct PartyVoiceChatTranscriptionReceivedStateChange : PartyStateChange {
PartyStateChangeResult result;
PartyError errorDetail;
PartyChatControl* senderChatControl;
uint32_t receiverChatControlCount;
PartyLocalChatControlArray receiverChatControls;
PartyAudioSourceType sourceType;
PartyString languageCode;
PartyString transcription;
PartyVoiceChatTranscriptionPhraseType type;
uint32_t translationCount;
PartyTranslation* translations;
}
Members
result PartyStateChangeResult
Indicates that the transcription operation Succeeded or provides the reason that it failed.
On success, the transcription field will be a string of non-zero length. On failure, the string will be empty.
Failure indicates that a transcription operation was attempted for the speaker but could not be completed. If
transcription is enabled at the request of the user associated with the chat control, and the transcription
messages are shown via UI, it is recommended that failures also be indicated to the user in order to provide
feedback as to whether transcriptions are pending or have failed.
errorDetail PartyError
A diagnostic value providing additional troubleshooting information regarding any potential error condition.
The human-readable form of this error detail can be retrieved via PartyManager::GetErrorMessage().
senderChatControl PartyChatControl*
The chat control object that originated the transcription message.
receiverChatControlCount uint32_t
The number of local receiver chat controls to which the transcription is addressed.
receiverChatControls PartyLocalChatControlArray
array of size receiverChatControlCount
The language code will be in BCP 47 format, such as en-US for English (United States). Supported language
codes are enumerated at https://docs.microsoft.com/azure/cognitive-services/speech-service/language-
support.
transcription PartyString
The transcribed voice chat text.
The string may be up to c_maxChatTextMessageLength characters long, not including the null terminator. The
string will always be empty when the result field indicates failures.
type PartyVoiceChatTranscriptionPhraseType
Indicates the phrase type of the text provided in the transcription field.
The type will always be PartyVoiceChatTranscriptionPhraseType::Final when the result field indicates failure.
translationCount uint32_t
The number of translations associated with the transcribed voice chat text.
Translations will be provided if PartyVoiceChatTranscriptionOptions::TranslateToLocalLanguage had previously
been specified via PartyLocalChatControl::SetTranscriptionOptions() on a chat control local to this device. There
may be more than one translation if multiple local chat controls have enabled translation and the local chat
controls have specified different languages via PartyLocalDevice::CreateChatControl(). In that case, the app can
compare the languageCode field of each PartyTranslation in translations against the language code, obtained
via PartyLocalChatControl::GetLanguage(), for each local chat control in receiverChatControls to determine the
target local chat control for each translation.
translations PartyTranslation*
array of size translationCount
A translation corresponding to the language for each chat control in receiverChatControls that has enabled
translation will be provided, even if the speaking chat control's language is the same as the local chat control's
language. In such a case, the transcription and translation strings will be identical.
Requirements
Header : Party.h
See also
Party members
PartyLocalDevice::CreateChatControl
PartyLocalChatControl::SetTranscriptionOptions
PartyAudioDeviceSelectionType
5/24/2022 • 2 minutes to read • Edit Online
Syntax
enum class PartyAudioDeviceSelectionType
{
None = 0,
SystemDefault = 1,
PlatformUserDefault = 2,
Manual = 3,
}
Constants
C O N STA N T DESC RIP T IO N
PlatformUserDefault Select audio device based on the platform and user settings.
Requirements
Header : Party.h
See also
Party members
PartyLocalChatControl::SetAudioInput
PartyLocalChatControl::SetAudioOutput
PartyAudioInputState
5/24/2022 • 2 minutes to read • Edit Online
Syntax
enum class PartyAudioInputState
{
NoInput = 0,
Initialized = 1,
NotFound = 2,
UserConsentDenied = 3,
UnsupportedFormat = 4,
AlreadyInUse = 5,
UnknownError = 6,
}
Constants
C O N STA N T DESC RIP T IO N
This can occur if the input was removed while in use. When
in this state, the chat control will subscribe to audio device
changes and use the specified input if it can be found at a
later time.
Requirements
Header : Party.h
See also
Party members
PartyAudioOutputState
5/24/2022 • 2 minutes to read • Edit Online
Syntax
enum class PartyAudioOutputState
{
NoOutput = 0,
Initialized = 1,
NotFound = 2,
UnsupportedFormat = 3,
AlreadyInUse = 4,
UnknownError = 5,
}
Constants
C O N STA N T DESC RIP T IO N
This can occur if the output was removed while in use. When
in this state, the chat control will subscribe to audio device
changes and use the specified output if it can be found at a
later time.
Requirements
Header : Party.h
See also
Party members
PartyAudioSampleType
5/24/2022 • 2 minutes to read • Edit Online
Syntax
enum class PartyAudioSampleType
{
Integer = 0,
Float = 1,
}
Constants
C O N STA N T DESC RIP T IO N
Requirements
Header : Party.h
See also
Party members
PartyAudioSourceType
5/24/2022 • 2 minutes to read • Edit Online
Syntax
enum class PartyAudioSourceType
{
Microphone = 0,
TextToSpeech = 1,
}
Constants
C O N STA N T DESC RIP T IO N
Requirements
Header : Party.h
See also
Party members
PartyChatControlChatIndicator
5/24/2022 • 2 minutes to read • Edit Online
Audio states for a target chat control in relation to a local chat control.
Syntax
enum class PartyChatControlChatIndicator
{
Silent = 0,
Talking = 1,
IncomingVoiceDisabled = 2,
IncomingCommunicationsMuted = 3,
NoRemoteInput = 4,
RemoteAudioInputMuted = 5,
}
Constants
C O N STA N T DESC RIP T IO N
IncomingVoiceDisabled The local chat control is not configured to receive audio from
the target chat control.
IncomingCommunicationsMuted The target chat control has been muted by the local chat
control.
NoRemoteInput The target chat control does not have an audio input.
RemoteAudioInputMuted The target chat control has an audio input but has muted it.
Requirements
Header : Party.h
See also
Party members
PartyChatPermissionOptions
5/24/2022 • 2 minutes to read • Edit Online
Options for defining the communication relationship between two chat controls.
Syntax
enum class PartyChatPermissionOptions
{
None = 0x0,
SendMicrophoneAudio = 0x1,
SendTextToSpeechAudio = 0x2,
SendAudio = SendMicrophoneAudio | SendTextToSpeechAudio,
ReceiveMicrophoneAudio = 0x4,
ReceiveTextToSpeechAudio = 0x8,
ReceiveAudio = ReceiveMicrophoneAudio | ReceiveTextToSpeechAudio,
ReceiveText = 0x10,
}
Constants
C O N STA N T DESC RIP T IO N
SendAudio All audio communication from the local chat control to the
target chat control is allowed.
ReceiveText Text communication from the target chat control to the local
chat control is allowed.
Requirements
Header : Party.h
See also
Party members
PartyChatTextReceivedOptions
5/24/2022 • 2 minutes to read • Edit Online
Syntax
enum class PartyChatTextReceivedOptions
{
None = 0x0,
FilteredOffensiveTerms = 0x1,
FilteredEntireMessage = 0x2,
FilteredDueToError = 0x4,
}
Constants
C O N STA N T DESC RIP T IO N
FilteredEntireMessage The incoming text chat was unable to filter specific terms,
and the entire text has been replaced by asterisks.
FilteredDueToError The incoming text was unable to be filtered, and the entire
text has been replaced by asterisks.
Requirements
Header : Party.h
See also
Party members
PartyChatTextReceivedStateChange
PartyDestroyedReason
5/24/2022 • 2 minutes to read • Edit Online
Syntax
enum class PartyDestroyedReason
{
Requested = 0,
Disconnected = 1,
Kicked = 2,
DeviceLostAuthentication = 3,
CreationFailed = 4,
}
Constants
C O N STA N T DESC RIP T IO N
Requirements
Header : Party.h
See also
Party members
PartyDeviceConnectionType
5/24/2022 • 2 minutes to read • Edit Online
The type of connection used for transmitting endpoint message or chat data to a device.
Syntax
enum class PartyDeviceConnectionType
{
RelayServer = 0,
DirectPeerConnection = 1,
}
Constants
C O N STA N T DESC RIP T IO N
Requirements
Header : Party.h
See also
Party members
PartyNetwork::GetDeviceConnectionType
PartyDirectPeerConnectivityOptions
5/24/2022 • 5 minutes to read • Edit Online
Flags controlling the attempted use of direct peer-to-peer connectivity among devices in a network.
Syntax
enum class PartyDirectPeerConnectivityOptions : int32_t
{
None = 0x0,
SamePlatformType = 0x1,
DifferentPlatformType = 0x2,
AnyPlatformType = SamePlatformType | DifferentPlatformType,
SameEntityLoginProvider = 0x4,
DifferentEntityLoginProvider = 0x8,
AnyEntityLoginProvider = SameEntityLoginProvider | DifferentEntityLoginProvider,
}
Constants
C O N STA N T DESC RIP T IO N
Note that this flag does not permit any direct peer-to-peer
connectivity attempts by itself. It must be combined with
one or both of the SameEntityLoginProvider and
DifferentEntityLoginProvider flags.
C O N STA N T DESC RIP T IO N
Note that this flag does not permit any direct peer-to-peer
connectivity attempts by itself. It must be combined with
one or both of the SameEntityLoginProvider and
DifferentEntityLoginProvider flags.
Note that this flag does not permit any direct peer-to-peer
connectivity attempts by itself. It must be combined with
one or both of the SamePlatformType and
DifferentPlatformType flags.
Note that this flag does not permit any direct peer-to-peer
connectivity attempts by itself. It must be combined with
one or both of the SamePlatformType and
DifferentPlatformType flags.
C O N STA N T DESC RIP T IO N
Remarks
As part of successfully authenticating an initial user into a network, a device may attempt to establish direct
peer-to-peer connections with other devices already participating in the network when permitted by these flags
declared in the network's PartyNetworkConfiguration structure. For attempts that are successful, endpoint
messages and chat data between the devices will be transmitted using those direct connections. For attempts
that fail due to environmental incompatibilities between the devices, all communication between those devices
will be transmitted via transparent cloud relay servers instead. If the devices aren't permitted to attempt direct
peer connections by these flags, then they never exchange IP address information and will always transmit
endpoint messages and chat data via transparent cloud relay servers.
You can determine whether the local device actually established a direct peer-to-peer connection to a specific
remote device by calling PartyNetwork::GetDeviceConnectionType().
Successful direct peer connectivity may provide lower latency between some devices, though attempting to
establish it also requires users to disclose their devices' IP addresses to others, which may be a concern for
privacy or for enabling malicious users to potentially attack peers' devices and Internet connections outside of
the title. It also may not be permitted on certain platforms for policy reasons. Be sure to use the appropriate
flags for your performance and security goals.
To avoid excessive resource consumption, the Party library will also internally prevent any given device from
attempting to establish more than c_maxDirectPeerConnectionsPerDevice direct peer connections across all
networks in which it's currently participating, even if permitted by these flags. This doesn't affect the device's
ability to participate in large or multiple networks with additional remote devices. Communication with
additional devices will simply be transmitted via transparent cloud relay servers.
It's recommended that you don't actively enforce the availability of a direct peer-to-peer connection for any
given pair of devices (i.e., don't call PartyNetwork::LeaveNetwork() if PartyNetwork::GetDeviceConnectionType()
reports a value other than PartyDeviceConnectionType::DirectPeerConnection) since the specific underlying
transmission method in use doesn't alter the overall logical ability to communicate. If your game design has
stringent requirements for maximum message latency that encourage direct peer connectivity, it's better to take
action on the current concrete observations of that latency as reported by the
PartyEndpointStatistic::AverageDeviceRoundTripLatencyInMilliseconds statistic rather than make abstract
assumptions based on transmission mechanism. Otherwise you might continually hinder users trying to play
with the same set of friends who always need to use nearby transparent cloud relay servers due to
environmental factors beyond their control.
Requirements
Header : Party.h
See also
Party members
PartyNetworkConfiguration
PartyOption::LocalDeviceDirectPeerConnectivityOptionsMask
PartyManager::SetOption
PartyEndpointStatistic::AverageDeviceRoundTripLatencyInMilliseconds
PartyLocalEndpoint::GetEndpointStatistics
PartyEndpointStatistic
5/24/2022 • 5 minutes to read • Edit Online
Syntax
enum class PartyEndpointStatistic
{
CurrentlyQueuedSendMessages = 0,
CurrentlyQueuedSendMessageBytes = 1,
CurrentlyActiveSendMessages = 2,
CurrentlyActiveSendMessageBytes = 3,
TimedOutSendMessages = 4,
TimedOutSendMessageBytes = 5,
CanceledSendMessages = 6,
CanceledSendMessageBytes = 7,
AverageDeviceRoundTripLatencyInMilliseconds = 8,
}
Constants
C O N STA N T DESC RIP T IO N
AverageDeviceRoundTripLatencyInMilliseconds The current moving average round trip latency ("ping time")
in milliseconds to the endpoint's owning device.
You can also determine the local device's average round trip
latency to the network's transparent cloud relay server by
using PartyNetwork::GetNetworkStatistics() to retrieve the
PartyNetworkStatistic::AverageRelayServerRoundTripLatencyI
nMilliseconds statistic.
Requirements
Header : Party.h
See also
Party members
PartyNetworkStatistic
PartySendMessageQueuingConfiguration
PartyLocalEndpoint::SendMessage
PartyLocalEndpoint::GetEndpointStatistics
PartyNetwork::GetNetworkStatistics
PartyGender
5/24/2022 • 2 minutes to read • Edit Online
Syntax
enum class PartyGender
{
Neutral = 0,
Female = 1,
Male = 2,
}
Constants
C O N STA N T DESC RIP T IO N
Requirements
Header : Party.h
See also
Party members
PartyTextToSpeechProfile
PartyInvitationRevocability
5/24/2022 • 2 minutes to read • Edit Online
Syntax
enum class PartyInvitationRevocability
{
Creator = 0,
Anyone = 1,
}
Constants
C O N STA N T DESC RIP T IO N
Requirements
Header : Party.h
See also
Party members
PartyNetwork::RevokeInvitation
PartyInvitation
PartyLocalUser
PartyLocalChatControlChatIndicator
5/24/2022 • 2 minutes to read • Edit Online
Syntax
enum class PartyLocalChatControlChatIndicator
{
Silent = 0,
Talking = 1,
AudioInputMuted = 2,
NoAudioInput = 3,
}
Constants
C O N STA N T DESC RIP T IO N
NoAudioInput Either no audio input has been specified for the local chat
control, or initializing the specified input failed.
Requirements
Header : Party.h
See also
Party members
PartyLocalUdpSocketBindAddressOptions
5/24/2022 • 2 minutes to read • Edit Online
Additional options to control how the Party library binds to the UDP socket specified by the
PartyLocalUdpSocketBindAddressConfiguration structure.
Syntax
enum class PartyLocalUdpSocketBindAddressOptions
{
None = 0x0,
ExcludeGameCorePreferredUdpMultiplayerPort = 0x1,
}
Constants
C O N STA N T DESC RIP T IO N
Requirements
Header : Party.h
See also
Party members
PartyLocalUdpSocketBindAddressConfiguration
PartyLocalUserRemovedReason
5/24/2022 • 2 minutes to read • Edit Online
Syntax
enum class PartyLocalUserRemovedReason
{
AuthenticationFailed = 0,
RemoveLocalUser = 1,
DestroyLocalUser = 2,
DestroyNetwork = 3,
}
Constants
C O N STA N T DESC RIP T IO N
RemoveLocalUser The local user is being removed because the title called
PartyNetwork::RemoveLocalUser().
DestroyLocalUser The local user is being removed because the title called
PartyManager::DestroyLocalUser().
Requirements
Header : Party.h
See also
Party members
PartyNetwork::AuthenticateLocalUser
PartyNetwork::RemoveLocalUser
PartyManager::DestroyLocalUser
PartyMessageReceivedOptions
5/24/2022 • 2 minutes to read • Edit Online
Syntax
enum class PartyMessageReceivedOptions : int32_t
{
None = 0x0000,
GuaranteedDelivery = 0x0001,
SequentialDelivery = 0x0002,
RequiredFragmentation = 0x0004,
}
Constants
C O N STA N T DESC RIP T IO N
RequiredFragmentation The message was larger than could fit in available space in a
single packet and needed to be split across multiple packets
for delivery.
See also
Party members
PartyEndpointMessageReceivedStateChange
PartyLocalEndpoint::SendMessage
PartyNetworkStatistic
5/24/2022 • 8 minutes to read • Edit Online
Syntax
enum class PartyNetworkStatistic
{
AverageRelayServerRoundTripLatencyInMilliseconds = 0,
SentProtocolPackets = 1,
SentProtocolBytes = 2,
RetriedProtocolPackets = 3,
RetriedProtocolBytes = 4,
DroppedProtocolPackets = 5,
ReceivedProtocolPackets = 6,
ReceivedProtocolBytes = 7,
CurrentlyQueuedSendMessages = 8,
CurrentlyQueuedSendMessageBytes = 9,
CurrentlyActiveSendMessages = 10,
CurrentlyActiveSendMessageBytes = 11,
TimedOutSendMessages = 12,
TimedOutSendMessageBytes = 13,
CanceledSendMessages = 14,
CanceledSendMessageBytes = 15,
}
Constants
C O N STA N T DESC RIP T IO N
AverageRelayServerRoundTripLatencyInMilliseconds The current moving average round trip latency ("ping time")
in milliseconds to the network's cloud relay server.
The reported value does not include the packet overhead for
Internet protocols (e.g., UDP, IP) or that of lower level media
over which the Party library internal protocol operates.
This statistic does not include the sizes of any retried packets
generated for HTTP web client operations that are used
internally by the Party library for some aspects of
authentication, management transactions, speech-to-text
transcription, and text-to-speech synthesis.
The reported value does not include the packet overhead for
Internet protocols (e.g., UDP, IP) or that of lower level media
over which the Party library internal protocol operates.
See also
Party members
PartyEndpointStatistic
PartySendMessageOptions
PartyNetwork::GetNetworkStatistics
PartyLocalEndpoint::SendMessage
PartyLocalEndpoint::GetEndpointStatistics
PartyOption
5/24/2022 • 3 minutes to read • Edit Online
Syntax
enum class PartyOption : uint32_t
{
LocalUdpSocketBindAddress = 0,
LocalDeviceDirectPeerConnectivityOptionsMask = 1,
TextChatFilterLevel = 2,
}
Constants
C O N STA N T DESC RIP T IO N
TextChatFilterLevel An option for fine-tuning the level that chat text will be
filtered at.
The filter level will apply to incoming chat text for all local
chat controls on the client. Filtering must be enabled with
PartyLocalChatControl::SetTextChatOptions for at least one
local chat control for this to have an effect on the chat text.
Requirements
Header : Party.h
See also
Party members
PartyManager::SetOption
PartyManager::GetOption
PartyLocalUdpSocketBindAddressConfiguration
PartyNetworkConfiguration
PartyDirectPeerConnectivityOptions
PartySendMessageOptions
5/24/2022 • 7 minutes to read • Edit Online
Syntax
enum class PartySendMessageOptions : int32_t
{
Default = 0x0000,
GuaranteedDelivery = 0x0001,
BestEffortDelivery = 0x0000,
SequentialDelivery = 0x0002,
NonsequentialDelivery = 0x0000,
CopyDataBuffers = 0x0000,
DontCopyDataBuffers = 0x0004,
CoalesceOpportunistically = 0x0000,
AlwaysCoalesceUntilFlushed = 0x0008,
RequireTimelyAcknowledgement = 0x0000,
AllowLazyAcknowledgement = 0x0010,
}
Constants
C O N STA N T DESC RIP T IO N
BestEffortDelivery Transmit the message best-effort and ignore any packet loss.
This option flag works well for state information that should
reach the destination in a particular sequence, even if that
means slightly less network efficiency and possibly waiting a
bit longer to receive it if there is packet loss or reordering by
the environment.
This option flag works well for messages that are safe to
process in any order or have their own inherent ordering
information already, and where you'd like maximum network
efficiency and lowest perceived latency.
DontCopyDataBuffers Informs the Party library to use the supplied data buffers
directly and that the caller will keep the memory valid until
the library no longer needs them.
Use this flag if you typically batch your network updates into
single, periodic messages that are not likely to be queued
around the same time as other messages and would not
gain bandwidth efficiency if delayed.
Even with this flag there are scenarios where the message
might begin transmitting without requiring an explicit
PartyLocalEndpoint::FlushMessages() call. This can occur
when there are other queued messages that are already
being transmitted for other reasons and there is room in the
packet to include this message. Similarly, when enough
message data bytes exist to send a full packet and no more
coalescence is possible, the packet will be sent. Calling
PartyLocalEndpoint::FlushMessages() when all messages
have already begun transmitting is benign.
C O N STA N T DESC RIP T IO N
Requirements
Header : Party.h
See also
Party members
PartySendMessageQueuingConfiguration
PartyDataBuffersReturnedStateChange
PartyLocalEndpoint::SendMessage
PartyLocalEndpoint::FlushMessages
PartyStateChangeResult
5/24/2022 • 2 minutes to read • Edit Online
Syntax
enum class PartyStateChangeResult
{
Succeeded = 0,
UnknownError = 1,
CanceledByTitle = 2,
InternetConnectivityError = 3,
PartyServiceError = 4,
NoServersAvailable = 5,
UserNotAuthorized = 6,
UserCreateNetworkThrottled = 7,
TitleNotEnabledForParty = 8,
NetworkLimitReached = 10,
NetworkNoLongerExists = 11,
VersionMismatch = 13,
LeaveNetworkCalled = 14,
FailedToBindToLocalUdpSocket = 15,
}
Constants
C O N STA N T DESC RIP T IO N
TitleNotEnabledForParty The title has not been enabled to use PlayFab Party. PlayFab
Party must be enabled in the PlayFab Game Manager.
VersionMismatch The operation failed because this version of the Party library
was incompatible with either the Party service or the Party
network.
FailedToBindToLocalUdpSocket The operation failed because the Party library was unable to
bind to the socket specified in the
PartyOption::LocalUdpSocketBindAddress option.
Requirements
Header : Party.h
See also
Party members
PartyStateChangeType
5/24/2022 • 6 minutes to read • Edit Online
Syntax
enum class PartyStateChangeType : uint32_t
{
RegionsChanged = 0,
DestroyLocalUserCompleted = 1,
CreateNewNetworkCompleted = 2,
ConnectToNetworkCompleted = 3,
AuthenticateLocalUserCompleted = 4,
NetworkConfigurationMadeAvailable = 5,
NetworkDescriptorChanged = 6,
LocalUserRemoved = 7,
RemoveLocalUserCompleted = 8,
CreateEndpointCompleted = 10,
DestroyEndpointCompleted = 11,
EndpointCreated = 12,
EndpointDestroyed = 13,
RemoteDeviceCreated = 14,
RemoteDeviceDestroyed = 15,
RemoteDeviceJoinedNetwork = 16,
RemoteDeviceLeftNetwork = 17,
LeaveNetworkCompleted = 19,
NetworkDestroyed = 20,
EndpointMessageReceived = 21,
DataBuffersReturned = 22,
CreateChatControlCompleted = 31,
DestroyChatControlCompleted = 32,
ChatControlCreated = 33,
ChatControlDestroyed = 34,
ChatTextReceived = 36,
VoiceChatTranscriptionReceived = 37,
SetChatAudioInputCompleted = 38,
SetChatAudioOutputCompleted = 39,
LocalChatAudioInputChanged = 40,
LocalChatAudioOutputChanged = 41,
SetTextToSpeechProfileCompleted = 42,
SynthesizeTextToSpeechCompleted = 43,
ChatControlJoinedNetwork = 46,
ChatControlLeftNetwork = 47,
ConnectChatControlCompleted = 48,
DisconnectChatControlCompleted = 49,
PopulateAvailableTextToSpeechProfilesCompleted = 50,
CreateInvitationCompleted = 51,
RevokeInvitationCompleted = 52,
InvitationCreated = 53,
InvitationDestroyed = 54,
SetTranscriptionOptionsCompleted = 56,
SetTextChatOptionsCompleted = 57,
ConfigureAudioManipulationVoiceStreamCompleted = 58,
ConfigureAudioManipulationCaptureStreamCompleted = 59,
ConfigureAudioManipulationRenderStreamCompleted = 60,
}
Constants
C O N STA N T DESC RIP T IO N
RegionsChanged The list of regions in which the title may create networks has
changed.
Requirements
Header : Party.h
See also
Party members
PartySynthesizeTextToSpeechType
5/24/2022 • 2 minutes to read • Edit Online
Syntax
enum class PartySynthesizeTextToSpeechType
{
Narration = 0,
VoiceChat = 1,
}
Constants
C O N STA N T DESC RIP T IO N
Requirements
Header : Party.h
See also
Party members
PartyLocalChatControl::SetTextToSpeechProfile
PartyLocalChatControl::GetTextToSpeechProfile
PartyLocalChatControl::SynthesizeTextToSpeech
PartyTextChatFilterLevel
5/24/2022 • 2 minutes to read • Edit Online
The level of filtering that will apply to incoming text chat when text moderation is enabled with
PartyLocalChatControl::SetTextChatOptions.
Syntax
enum class PartyTextChatFilterLevel : uint32_t
{
FamilyFriendly = 0,
Medium = 1,
Mature = 2,
}
Constants
C O N STA N T DESC RIP T IO N
Requirements
Header : Party.h
See also
Party members
PartyManager::SetOption
PartyLocalChatControl::SetTextChatOptions
PartyTextChatOptions
5/24/2022 • 2 minutes to read • Edit Online
Syntax
enum class PartyTextChatOptions
{
None = 0x0,
TranslateToLocalLanguage = 0x1,
FilterOffensiveText = 0x2,
}
Constants
C O N STA N T DESC RIP T IO N
Requirements
Header : Party.h
See also
Party members
PartyLocalChatControl::SetTextChatOptions
PartyLocalChatControl::GetLanguage
PartyChatTextReceivedStateChange
PartyThreadId
5/24/2022 • 2 minutes to read • Edit Online
Syntax
enum class PartyThreadId
{
Audio = 0,
Networking = 1,
}
Constants
C O N STA N T DESC RIP T IO N
Remarks
When used with PartyManager::GetWorkMode() and PartyManager::SetWorkMode(), allows the title to read and
write (respectively) the work mode for the associated internal processing task. Title interaction with the internal
processing task differs greatly depending on the currently-configured work mode.
When the work mode of the processing task associated with PartyThreadId::Audio is set to
PartyWorkMode::Automatic, the task is performed by the Party library using internally-managed, high priority,
frequently-running threads with real-time requirements. On Windows and Xbox consoles, these audio threads
interact directly with XAudio2 every 40 milliseconds. The Party library's instance(s) of XAudio2 will be initialized
with a processor affinity that corresponds to the processor affinity configured for the audio thread type via
PartyManager::SetThreadAffinityMask(). If no processor affinity is specified for the audio thread type, the
instance(s) of XAudio2 will be initialized with a processor affinity of XAUDIO2_DEFAULT_PROCESSOR.
Similarly, when the work mode of the processing task associated with PartyThreadId::Networking is set to
PartyWorkMode::Automatic, networking threads are created and managed internally. These threads are driven
from both network I/O and polling mechanisms, waking every 50 to 100 milliseconds or whenever network
traffic is received.
For all processing tasks, when the work mode is set to PartyWorkMode::Automatic, title
interaction/responsibility is limited to specifying the processor affinity of associated internal worker threads via
PartyManager::SetThreadAffinityMask(). Alternatively, when a processing task's work mode is set to
PartyWorkMode::Manual, internal worker threads are no longer created and managed by the Party library.
Instead, it becomes the title's responsibility to perform the required processing via periodic calls to
PartyManager::DoWork(). The periodicity of these calls should match that of the internal threads that are created
when the work mode is PartyWorkMode::Automatic.
Requirements
Header : Party.h
See also
Party members
PartyManager::GetThreadAffinityMask
PartyManager::SetThreadAffinityMask
PartyManager::SetWorkMode
PartyManager::GetWorkMode
PartyManager::DoWork
PartyTranslationReceivedOptions
5/24/2022 • 2 minutes to read • Edit Online
Syntax
enum class PartyTranslationReceivedOptions
{
None = 0x0,
Truncated = 0x1,
}
Constants
C O N STA N T DESC RIP T IO N
Requirements
Header : Party.h
See also
Party members
PartyVoiceChatTranscriptionOptions
5/24/2022 • 2 minutes to read • Edit Online
Syntax
enum class PartyVoiceChatTranscriptionOptions
{
None = 0x0,
TranscribeSelf = 0x1,
TranscribeOtherChatControlsWithMatchingLanguages = 0x2,
TranscribeOtherChatControlsWithNonMatchingLanguages = 0x4,
TranslateToLocalLanguage = 0x10,
DisableProfanityMasking = 0x20,
TranscribeSelfRegardlessOfNetworkState = 0x40,
}
Constants
C O N STA N T DESC RIP T IO N
This option will have no effect unless also combined with one
or more of TranscribeSelf,
TranscribeOtherChatControlsWithMatchingLanguages, and
TranscribeOtherChatControlsWithNonMatchingLanguages.
Requirements
Header : Party.h
See also
Party members
PartyLocalChatControl::SetTranscriptionOptions
PartyVoiceChatTranscriptionReceivedStateChange
PartyVoiceChatTranscriptionPhraseType
PartyVoiceChatTranscriptionPhraseType
5/24/2022 • 2 minutes to read • Edit Online
Syntax
enum class PartyVoiceChatTranscriptionPhraseType
{
Hypothesis = 0,
Final = 1,
}
Constants
C O N STA N T DESC RIP T IO N
Remarks
A Hypothesis phrase represents a snapshot into the transcription process and does not represent a stable
accumulation of transcription. For example, a first speech hypothesis may contain the words "fine fun" and the
second hypothesis may contain the words "find funny". Hypothesis messages are frequent and there can be
many hypothesis messages associated with a particular phrase. Once a transcription of type Final is received, no
more hypothesis messages associated with that phrase will be provided; new hypothesis phrases will represent
a new logical phrase. Because each phrase is tied to a speaker, hypothesis messages for a phrase can be
correlated by inspecting the speaker field of the PartyVoiceChatTranscriptionReceivedStateChange.
Hypothesis phrases can optionally be used to improve the user experience by improving perceived
responsiveness. An example implementation might have a special text box for hypothesis messages that is
frequently updated with the latest hypothesis transcription from each chat control. Once a non-hypothesis
transcription is received, the transcription for the chat control would be removed from the hypothesis text box
and rendered in a long-lived text box.
A Final phrase represents the end of the transcription process after the speaker has completed a sentence or
phrase. Capitalization, punctuation, inverse text normalization, and profanity masking will have been applied to
this transcription. For example, if a user speaks a phrase represented by the words "my flight to seattle leaves at
six", the transcription will read "My flight to Seattle leaves at 6." Inverse text normalization is the process that
converts the word "six" to the number "6". Profane words will be replaced by asterisks.
See also
Party members
PartyLocalChatControl::SynthesizeTextToSpeech
PartyVoiceChatTranscriptionReceivedStateChange
PartyWorkMode
5/24/2022 • 2 minutes to read • Edit Online
Configuration modes representing how the Party library will manage an internal processing task.
Syntax
enum class PartyWorkMode
{
Automatic = 0,
Manual = 1,
}
Constants
C O N STA N T DESC RIP T IO N
Manual The Party library will not create internal threads to handle
the associated processing task, instead relying on the title to
perform the task through calls to PartyManager::DoWork().
Remarks
For an overview of the processing tasks and their frequencies, see PartyThreadId.
Requirements
Header : Party.h
See also
Party members
PartyManager::SetWorkMode
PartyManager::GetWorkMode
PartyManager::DoWork
PlayFab Party Typedefs
5/24/2022 • 2 minutes to read • Edit Online
The PlayFab Party library uses several typedefs for convenient declarations of arrays of core types. It also
provides typedefs for a few basic types to add semantic meaning and aid in static analysis. Macros are provided
for dealing with PartyError return codes.
Basic types
PartyBool
The size of a C++ bool is implementation defined. PartyBool provides safe cross-platform serialization of
boolean values.
PartyError
Error codes are 32-bit unsigned integers returned as PartyError . The success code is defined, as are macros for
determining if a error code represents success or failure.
PartyString
A PartyString is a UTF-8 null-terminated const char array. The typedef exists in order to add an annotation for
static analysis.
Arrays
A number of structs and method parameters use constant arrays of core types. To simplify usage and
declaration of these arrays, the following typedefs are provided.
PartyEndpointArray PartyEndpoint
PartyLocalEndpointArray PartyLocalEndpoint
PartyDeviceArray PartyDevice
PartyInvitationArray PartyInvitation
PartyNetworkArray PartyNetwork
PartyChatControlArray PartyChatControl
PartyLocalChatControlArray PartyLocalChatControl
PartyTextToSpeechProfileArray PartyTextToSpeechProfile
PartyStateChangeArray PartyStateChange
PartyLocalUserArray PartyLocalUser
Requirements
Header : Party.h
See also
Party members
PlayFab Party Unity SDK
5/24/2022 • 2 minutes to read • Edit Online
Classes
NAME DESC RIP T IO N
PlayFabLocalPlayer
PlayFabMultiplayerManager
PlayFabPlayer
Enums
NAME DESC RIP T IO N
ChatState The visual state of the player for rendering in the game's UI.
Properties
NAME DESC RIP T IO N
IsChatControlAvailable Gets the indication whether any public API that relies on a
chat control associated with this player can be safely used.
Player's chat control becomes available after the user creates
or joins a party.
Gets the indication whether any public API that relies on a chat control associated with this player can be safely
used. Player's chat control becomes available after the user creates or joins a party.
Property Value
IsChatControlAvailable
bool
LanguageCode
5/24/2022 • 2 minutes to read • Edit Online
Property Value
LanguageCode
string
The BCP 47 language code associated with the player.
PlatformSpecificUserId
5/24/2022 • 2 minutes to read • Edit Online
Property Value
PlatformSpecificUserId
string
Class PlayFabPlayer
5/24/2022 • 2 minutes to read • Edit Online
Properties
NAME DESC RIP T IO N
ChatState Gets the visual chat state of this player for display in your
game UI.
IsLocal Returns true if this player is the local player, and false if this
player is a remote player.
VoiceLevel Gets or sets the volume of the player. The value is a float
between 0 and 1.
ChatState
5/24/2022 • 2 minutes to read • Edit Online
Gets the visual chat state of this player for display in your game's UI.
Property Value
ChatState
PlayFabPlayer.EntityKey
5/24/2022 • 2 minutes to read • Edit Online
Property Value
EntityKey
IsLocal
5/24/2022 • 2 minutes to read • Edit Online
Returns true if this player is the local player, and false if this player is a remote player.
Property Value
IsLocal
bool
IsMuted
5/24/2022 • 2 minutes to read • Edit Online
Property Value
IsMuted
bool
VoiceLevel
5/24/2022 • 2 minutes to read • Edit Online
Gets or sets the volume of the player. The value is a float between 0 and 1.
Property Value
VoiceLevel
float
A value from zero to one inclusive.
Class PlayFabMultiplayerManager
5/24/2022 • 2 minutes to read • Edit Online
Properties
NAME DESC RIP T IO N
Methods
NAME DESC RIP T IO N
CreateAndJoinNetwork Creates a network for players to join. After the player joins
the network, they can send the other players that are on the
network chat and data messages.
UpdateEntityToken Updates the Entity token for the current local user.
Events
NAME DESC RIP T IO N
OnNetworkChanged Occurs when the Network changes. When this event fires
you must move all the players to the new network, specified
in the newNetworkID so the players can continue to
communicate.
Property Value
LocalPlayer
PlayFabLocalPlayer
LogLevel
5/24/2022 • 2 minutes to read • Edit Online
Property Value
LogLevel
LogLevelType
NetworkId
5/24/2022 • 2 minutes to read • Edit Online
Returns NetworkID of the current network to which the player is connected. The other players can use this string
to join the network. The NetworkId is populated when the OnNetworkJoined event fires. The NetworkId is cleared
when the OnNetworkLeft event fires.
Property Value
NetworkId
string
Remarks
The NetworkID , is an opaque serialized network descriptor string generated by the PlayFab Party library that
enables each PlayFab Party Unity client to connect to a Party network after one has been created. This string will
never contain non-ASCII characters, control characters, or other characters that would require JSON or XML
escaping.
RemotePlayers
5/24/2022 • 2 minutes to read • Edit Online
Property Value
RemotePlayers
IList<T>
SpeechToTextMode
5/24/2022 • 2 minutes to read • Edit Online
Property Value
SpeechToTextMode
AccessibilityMode
State
5/24/2022 • 2 minutes to read • Edit Online
Property Value
State
PlayFabMultiplayerManagerState
TextToSpeechMode
5/24/2022 • 2 minutes to read • Edit Online
Property Value
TextToSpeechMode
AccessibilityMode
TranslateChat
5/24/2022 • 2 minutes to read • Edit Online
Gets or sets whether incoming chat messages should be translated to local player's language.
Setting this property will have effect only when local player created or joined a party.
Property Value
TranslateChat
bool
SendChatMessage
5/24/2022 • 2 minutes to read • Edit Online
Syntax
public void PlayFabMultiplayerManager.Get().SendChatMessage(string message, IEnumerable<PlayFabPlayer>
recipients, DeliveryOption TBD);
Parameters
message string
The contents of the chat message.
recipients IEnumerable<PlayFabPlayer>
The recipients of the chat message.
TBD DeliveryOption
Remarks
PlayFabMultiplayerManager playFabMultiplayerManager = PlayFabMultiplayerManager.Get();
PlayFabMultiplayerManager.Get().SendChatMessage("Hello", targetPlayers, DeliveryOption.Guaranteed);
Return value
None.
SendChatMessageToAllPlayers
5/24/2022 • 2 minutes to read • Edit Online
Broadcasts a text message to all players. This API sends a message such that it is guaranteed to arrive and in
sequential order.
Syntax
public void PlayFabMultiplayerManager.Get().SendChatMessageToAllPlayers(string message);
Parameters
message string
The contents of the chat message.
Remarks
PlayFabMultiplayerManager playFabMultiplayerManager = PlayFabMultiplayerManager.Get();
playFabMultiplayerManager.SendChatMessageToAllPlayers("Hello");
Return value
None.
CreateAndJoinNetwork
5/24/2022 • 2 minutes to read • Edit Online
Creates a network for players to join. After the player joins the network, they can send the other players that are
on the network chat and data messages.
Syntax
public void PlayFabMultiplayerManager.Get().CreateAndJoinNetwork();
Parameters
None.
Return value
None.
Get
5/24/2022 • 2 minutes to read • Edit Online
Syntax
public static PlayFabMultiplayerManager Get()
Parameters
None.
Return value
PlayFabMultiplayerManager
Returns the singleton instance of the PlayFabMultiplayerManager.
LeaveNetwork
5/24/2022 • 2 minutes to read • Edit Online
Syntax
public void PlayFabMultiplayerManager.Get().LeaveNetwork();
Parameters
None.
Return value
None.
SendDataMessage
5/24/2022 • 2 minutes to read • Edit Online
Syntax
public void PlayFabMultiplayerManager.Get().SendDataMessage(byte[] buffer, IEnumerable<PlayFabPlayer>
recipients, DeliveryOption deliveryOption);
Parameters
Parameters
buffer IntPtr
A pointer to the buffer containing the data to send.
recipients IEnumerable<PlayFabPlayer>
The players to send the data message to. If the collection of players is empty, the data message will be broadcast
to all players.
deliver yOption DeliveryOption
Options specifying how to deliver the message.
Return value
None.
Parameters
buffer IntPtr
A pointer to the buffer containing the data to send.
bufferSize uint
The size of the buffer.
recipients IEnumerable<PlayFabPlayer>
The players to send the data message to. If the collection of players is empty, the data message will be broadcast
to all players.
deliver yOption DeliveryOption
Options specifying how to deliver the message.
Sample
...
byte[] buffer = Encoding.ASCII.GetBytes("Hello");
IntPtr unmanagedPointer = Marshal.AllocHGlobal(buffer.Length);
Marshal.Copy(buffer, 0, unmanagedPointer, buffer.Length);
PlayFabMultiplayerManager.Get().SendDataMessage(unmanagedPointer, (uint)buffer.Length, remotePlayers,
DeliveryOption.Guaranteed);
Marshal.FreeHGlobal(unmanagedPointer);
...
Return value
None.
SendDataMessageToAllPlayers
5/24/2022 • 2 minutes to read • Edit Online
Syntax
public void PlayFabMultiplayerManager.Get().SendDataMessageToAllPlayers(buffer);
Parameters
buffer byte[]
A buffer that contains the data to send.
Return value
None.
UpdateEntityToken
5/24/2022 • 2 minutes to read • Edit Online
Syntax
public void PlayFabMultiplayerManager.Get().UpdateEntityToken(entityToken);
Parameters
entityToken string
The Entity token associated with the local user.
Return value
None.
OnChatMessageReceived
5/24/2022 • 2 minutes to read • Edit Online
Arguments
sender (object)
The class that raised the event.
from (PlayFabPlayer)
The player the message was sent from.
message (string)
The contents of the message.
type (ChatMessageType )
A parameter that specifies the type of message.
OnDataMessageReceived
5/24/2022 • 2 minutes to read • Edit Online
Arguments
sender (object)
The class that raised the event.
from (PlayFabPlayer)
The player who sent the message.
buffer (byte [])
The data contents of the message.
OnDataMessageNoCopyReceived
5/24/2022 • 2 minutes to read • Edit Online
Arguments
sender (object)
The class that raised the event.
from (PlayFabPlayer)
The player who sent the message.
buffer (IntPtr)
The data contents of the message.
OnErrorEventHandler
5/24/2022 • 2 minutes to read • Edit Online
Arguments
sender (object)
The class that raised the event.
args (PlayFabMultiplayerManagerErrorArgs)
An object that contains the details of the error.
OnNetworkChanged
5/24/2022 • 2 minutes to read • Edit Online
Occurs when the Network changes. When this event fires you must move all the players to the new network,
specified in the newNetworkID so the players can continue to communicate.
Arguments
sender (object)
The class that raised the event.
newNetworkId (string)
The identifier for the new network.
OnNetworkJoined
5/24/2022 • 2 minutes to read • Edit Online
Arguments
sender (object)
The class that raised the event.
networkId (string)
A string that identifies the network. Give this string to other players to allow them to connect to the network.
OnNetworkLeft
5/24/2022 • 2 minutes to read • Edit Online
Arguments
sender (object)
The class that raised the event.
networkId (string)
A string that identifies the network.
OnRemotePlayerJoined
5/24/2022 • 2 minutes to read • Edit Online
Arguments
sender (object)
The class that raised the event.
player (PlayFabPlayer)
The remote player who joined the network.
OnRemotePlayerLeft
5/24/2022 • 2 minutes to read • Edit Online
Arguments
sender (object)
The class that raised the event.
player (PlayFabPlayer)
The player who left the network.
AccessibilityMode
5/24/2022 • 2 minutes to read • Edit Online
Syntax
public enum AccessibilityMode
{
None,
PlatformDefault,
Enabled
}
Constants
C O N STA N T DESC RIP T IO N
Syntax
public enum ChatMessageType
{
Text,
SpeechToText,
TextToSpeech
}
Constants
C O N STA N T DESC RIP T IO N
SpeechToText A chat message that was transcribed into text, using speech-
to-text technology.
The visual state of the player for rendering in the game's UI.
Syntax
public enum ChatState
{
NoAudioInput,
Muted,
MutedByPlatform,
Silent,
Talking
}
Constants
C O N STA N T DESC RIP T IO N
NoAudioInput The player has no audio input. This could be because they
do not have an audio device plugged in or they are having
an error with audio.
Syntax
public enum DeliveryOption
{
BestEffort,
Guaranteed
}
Constants
C O N STA N T DESC RIP T IO N
Flags controlling the attempted use of direct peer-to-peer connectivity among devices on a network.
Syntax
public enum PARTY_DIRECT_PEER_CONNECTIVITY_OPTIONS : UInt32
{
PARTY_DIRECT_PEER_CONNECTIVITY_OPTIONS_NONE = 0x0000,
PARTY_DIRECT_PEER_CONNECTIVITY_OPTIONS_SAME_PLATFORM_TYPE = 0x0001,
PARTY_DIRECT_PEER_CONNECTIVITY_OPTIONS_DIFFERENT_PLATFORM_TYPE = 0x0002,
PARTY_DIRECT_PEER_CONNECTIVITY_OPTIONS_ANY_PLATFORM_TYPE = 0x0003,
PARTY_DIRECT_PEER_CONNECTIVITY_OPTIONS_SAME_ENTITY_LOGIN_PROVIDER = 0x0004,
PARTY_DIRECT_PEER_CONNECTIVITY_OPTIONS_DIFFERENT_ENTITY_LOGIN_PROVIDER = 0x0008,
PARTY_DIRECT_PEER_CONNECTIVITY_OPTIONS_ANY_ENTITY_LOGIN_PROVIDER = 0x000c,
}
Constants
C O N STA N T DESC RIP T IO N
Syntax
public enum PlayFabMultiplayerManager.LogLevelType
{
None,
Minimal,
Verbose
}
Constants
C O N STA N T DESC RIP T IO N
None
Minimal
Verbose
PlayFabMultiplayerManagerErrorType
5/24/2022 • 2 minutes to read • Edit Online
Syntax
public enum PlayFabMultiplayerManagerErrorType
{
Unknown,
Error,
NetworkCreateError,
NetworkJoinError,
NetworkLeaveError
}
Constants
C O N STA N T DESC RIP T IO N
Syntax
public enum PlayFabMultiplayerManagerState
{
NotInitialized,
Initialized,
ConnectingToNetwork,
ConnectedToNetwork
}
Constants
C O N STA N T DESC RIP T IO N
Classes
C L A SS DESC RIP T IO N
PartyXblManager The primary management class for interacting with the Party
Xbox Live Helper library.
Structures
ST RUC T URE DESC RIP T IO N
State changes
STAT E C H A N GE DESC RIP T IO N
Enumerations
EN UM ERAT IO N DESC RIP T IO N
PartyXblThreadId Threads that Party Xbox Live Helper library uses for internal
purposes.
PartyXblChatUser
5/24/2022 • 2 minutes to read • Edit Online
The management class for Xbox Live operations related to a chat user.
Syntax
class PartyXblChatUser
Public Methods
NAME DESC RIP T IO N
GetXboxUserId Gets the Xbox Live User Id associated with this user.
Requirements
Header : PartyXboxLive.h
See also
PartyXboxLive members
PartyXblLocalChatUser
PartyXblChatUser::GetLocal
5/24/2022 • 2 minutes to read • Edit Online
Syntax
PartyError GetLocal(
PartyXblLocalChatUser** localChatUser
)
Parameters
localChatUser PartyXblLocalChatUser**
library-allocated output, may return nullptr
The output local version of this chat user object, or nullptr if this is not a local chat user.
Return value
PartyError
c_partyErrorSuccess if the call succeeded or an error code otherwise. The human-readable form of the error
code can be retrieved via PartyXblManager::GetErrorMessage().
Requirements
Header : PartyXboxLive.h
See also
PartyXblChatUser
PartyXblChatUser::GetXboxUserId
5/24/2022 • 2 minutes to read • Edit Online
Syntax
PartyError GetXboxUserId(
uint64_t* xboxUserId
)
Parameters
xboxUserId uint64_t*
output
The output Xbox Live User Id.
Return value
PartyError
c_partyErrorSuccess if the call succeeded or an error code otherwise. The human-readable form of the error
code can be retrieved via PartyXblManager::GetErrorMessage().
Requirements
Header : PartyXboxLive.h
See also
PartyXblChatUser
PartyXblChatUser::GetCustomContext
5/24/2022 • 2 minutes to read • Edit Online
Retrieves the app's private, custom pointer-sized context value previously associated with this local chat user
object.
Syntax
PartyError GetCustomContext(
void** customContext
)
Parameters
customContext void**
output, may return nullptr
The output custom context.
Return value
PartyError
c_partyErrorSuccess if retrieving the custom context succeeded or an error code otherwise. The human-
readable form of the error code can be retrieved via PartyXblManager::GetErrorMessage().
Remarks
If no custom context has been set yet, the value pointed to by customContext is set to nullptr.
Requirements
Header : PartyXboxLive.h
See also
PartyXblChatUser
PartyXblChatUser::SetCustomContext
PartyXblChatUser::SetCustomContext
5/24/2022 • 2 minutes to read • Edit Online
Configures an optional, custom pointer-sized context value with this local chat user object.
Syntax
PartyError SetCustomContext(
void* customContext
)
Parameters
customContext void*
optional
An arbitrary, pointer-sized value to store with the chat user object.
Return value
PartyError
c_partyErrorSuccess if configuring the custom context succeeded or an error code otherwise. The human-
readable form of the error code can be retrieved via PartyXblManager::GetErrorMessage().
Remarks
The custom context is typically used as a "shortcut" that simplifies accessing local, title-specific memory
associated with the chat user without requiring a mapping lookup. The value is retrieved using the
GetCustomContext() method.
Any configured value is treated as opaque by the library, and is only valid on the local device; it is not
transmitted over the network.
Requirements
Header : PartyXboxLive.h
See also
PartyXblChatUser
PartyXblChatUser::GetCustomContext
PartyXblLocalChatUser
5/24/2022 • 2 minutes to read • Edit Online
The management class for Xbox Live operations related to a local chat user. Inherits from PartyXblChatUser.
Syntax
class PartyXblLocalChatUser : public PartyXblChatUser
Public Methods
NAME DESC RIP T IO N
Requirements
Header : PartyXboxLive.h
See also
PartyXboxLive members
PartyXblChatUser
PartyXblChatUser::GetLocal
PartyXblLocalChatUser::GetAccessibilitySettings
5/24/2022 • 2 minutes to read • Edit Online
Syntax
PartyError GetAccessibilitySettings(
PartyXblAccessibilitySettings* settings
)
Parameters
settings PartyXblAccessibilitySettings*
output
The output accessibility settings.
Return value
PartyError
c_partyErrorSuccess if the call succeeded or an error code otherwise. The human-readable form of the error
code can be retrieved via PartyXblManager::GetErrorMessage().
Remarks
This function will fail until a PartyXblCreateLocalChatUserCompletedStateChange is provided by
PartyXblManager::StartProcessingStateChanges().
Requirements
Header : PartyXboxLive.h
See also
PartyXblLocalChatUser
PartyXblCreateLocalChatUserCompletedStateChange
PartyXblLocalChatUser::GetRequiredChatPermissionInfo
5/24/2022 • 2 minutes to read • Edit Online
Gets the cached required chat permission information related to a target chat user.
Syntax
PartyError GetRequiredChatPermissionInfo(
const PartyXblChatUser* targetChatUser,
PartyXblChatPermissionInfo* chatPermissionInfo
)
Parameters
targetChatUser PartyXblChatUser*
The chat user for which permissions relative to the local chat user should be retrieved.
chatPermissionInfo PartyXblChatPermissionInfo*
output
The output chat permission info object. The chat permission info object contains the most permissive chat
permission possible while still respecting Xbox Live requirements.
Return value
PartyError
c_partyErrorSuccess if the call succeeded or an error code otherwise. The human-readable form of the error
code can be retrieved via PartyXblManager::GetErrorMessage().
Requirements
Header : PartyXboxLive.h
See also
PartyXblLocalChatUser
PartyXblCreateLocalChatUserCompletedStateChange
PartyXblRequiredChatPermissionInfoChangedStateChange
PartyXblLocalChatUser::GetCrossNetworkCommunicationPrivacySetting
5/24/2022 • 2 minutes to read • Edit Online
Gets the cross-network communication privacy setting for this chat user.
Syntax
PartyError GetCrossNetworkCommunicationPrivacySetting(
PartyXblCrossNetworkCommunicationPrivacySetting* setting
)
Parameters
setting PartyXblCrossNetworkCommunicationPrivacySetting*
output
The output cross-network communication privacy setting.
Return value
PartyError
c_partyErrorSuccess if the call succeeded or an error code otherwise. The human-readable form of the error
code can be retrieved via PartyXblManager::GetErrorMessage().
Remarks
A cross-network user is defined as a user of a non-Xbox Live gaming network.
Requirements
Header : PartyXboxLive.h
See also
PartyXblLocalChatUser
PartyXblManager
5/24/2022 • 2 minutes to read • Edit Online
The primary management class for interacting with the Party Xbox Live Helper library.
Syntax
class PartyXblManager
Public Methods
NAME DESC RIP T IO N
FinishProcessingStateChanges Returns an array of Party Xbox Live state changes that were
being processed.
Remarks
Only a single instance of the class is permitted.
Requirements
Header : PartyXboxLive.h
See also
PartyXboxLive members
PartyXblManager::GetSingleton
5/24/2022 • 2 minutes to read • Edit Online
Syntax
PartyXblManager& GetSingleton(
)
Parameters
Return value
PartyXblManager&
The PartyXblManager singleton instance.
Requirements
Header : PartyXboxLive.h
See also
PartyXblManager
PartyXblManager::GetErrorMessage
5/24/2022 • 2 minutes to read • Edit Online
Syntax
PartyError GetErrorMessage(
PartyError error,
PartyString* errorMessage
)
Parameters
error PartyError
An error code.
errorMessage PartyString*
library-allocated output
The output, human-readable error message. The memory for the returned string remains valid for the lifetime
of the process.
Return value
PartyError
c_partyErrorSuccess if the call succeeded or an error code otherwise.
Remarks
These error messages are not localized and are only intended for developers, i.e. these error messages are not
intended to be shown to users via UI.
Requirements
Header : PartyXboxLive.h
See also
PartyXblManager
PartyXblManager::SetMemoryCallbacks
5/24/2022 • 2 minutes to read • Edit Online
Optionally configures the memory allocation and freeing callbacks the Party Xbox Live Helper library should
use.
Syntax
PartyError SetMemoryCallbacks(
PartyAllocateMemoryCallback allocateMemoryCallback,
PartyFreeMemoryCallback freeMemoryCallback
)
Parameters
allocateMemoryCallback PartyAllocateMemoryCallback
A pointer to the custom allocation callback to use.
freeMemoryCallback PartyFreeMemoryCallback
A pointer to the custom freeing callback to use.
Return value
PartyError
c_partyErrorSuccess if the call succeeded or an error code otherwise.
Remarks
This method allows the application to install custom memory allocation routines in order to service all requests
by the Party Xbox Live Helper library for new memory buffers instead of using its default allocation routines.
To use this method, it must be called before any other Party Xbox Live Helper library method except for
GetMemoryCallbacks(). This method cannot be called again for the lifetime of this process.
Requirements
Header : PartyXboxLive.h
See also
PartyXblManager
PartyXblManager::GetMemoryCallbacks
PartyXblManager::GetMemoryCallbacks
5/24/2022 • 2 minutes to read • Edit Online
Retrieves the current memory allocation and freeing callbacks the Party Xbox Live library is using.
Syntax
PartyError GetMemoryCallbacks(
PartyAllocateMemoryCallback* allocateMemoryCallback,
PartyFreeMemoryCallback* freeMemoryCallback
)
Parameters
allocateMemoryCallback PartyAllocateMemoryCallback*
output
A place to store a pointer to the memory allocation callback currently used.
freeMemoryCallback PartyFreeMemoryCallback*
output
A place to store a pointer to the memory freeing callback currently used.
Return value
PartyError
c_partyErrorSuccess if the call succeeded or an error code otherwise. The human-readable form of the error
code can be retrieved via GetErrorMessage().
Remarks
This method does not require the Initialize() method to have been called first.
Requirements
Header : PartyXboxLive.h
See also
PartyXblManager
PartyXblManager::SetMemoryCallbacks
PartyXblManager::SetThreadAffinityMask
5/24/2022 • 2 minutes to read • Edit Online
Optionally configures the processor on which internal Party Xbox Live Helper library threads will run.
Syntax
PartyError SetThreadAffinityMask(
PartyXblThreadId threadId,
uint64_t threadAffinityMask
)
Parameters
threadId PartyXblThreadId
The type of internal library thread for which processor affinity should be retrieved.
threadAffinityMask uint64_t
The affinity mask for this type of Party thread.
Return value
PartyError
c_partyErrorSuccess if the call succeeded or an error code otherwise. The human-readable form of the error
code can be retrieved via GetErrorMessage().
Remarks
This method enables the application to configure the processor affinity for internal Party Xbox Live Helper
library thread of a given type.
This method may be called at any time before or after Initialize() and will take effect immediately. Thread
processor settings are persisted across calls to Cleanup() and Initialize(). When there are more than 64 cores
present, this method always applies to processor group 0.
In order to specify any processor, pass c_anyProcessor as the threadAffinityMask parameter. This is also the
default value the Party Xbox Live Helper library will use if this method is never called.
Requirements
Header : PartyXboxLive.h
See also
PartyXblManager
PartyXblThreadId
PartyXblManager::GetThreadAffinityMask
PartyXblManager::GetThreadAffinityMask
5/24/2022 • 2 minutes to read • Edit Online
Retrieves the current set of processors on which internal Party Xbox Live Helper library threads will run or are
running as an affinity mask.
Syntax
PartyError GetThreadAffinityMask(
PartyXblThreadId threadId,
uint64_t* threadAffinityMask
)
Parameters
threadId PartyXblThreadId
The type of internal library thread for which processor affinity should be retrieved.
threadAffinityMask uint64_t*
output
A place to store the affinity mask for this type of Party thread.
Return value
PartyError
c_partyErrorSuccess if the call succeeded or an error code otherwise. The human-readable form of the error
code can be retrieved via GetErrorMessage().
Remarks
This retrieves the current processor affinity for internal Party threads Xbox Live Helper library of a given type.
This method does not require Initialize() to have been called first.
A reported value of c_anyProcessor written to threadAffinityMask indicates that the thread is free to run on any
processor.
Requirements
Header : PartyXboxLive.h
See also
PartyXblManager
PartyXblManager::SetThreadAffinityMask
PartyXblManager::Initialize
5/24/2022 • 2 minutes to read • Edit Online
Syntax
PartyError Initialize(
PartyString titleId
)
Parameters
titleId PartyString
Remarks
This must be called before any other method under the PartyXblManager namespace, aside from the static
methods GetSingleton(), SetMemoryCallbacks(), GetMemoryCallbacks(), SetThreadAffinityMask(),
GetThreadAffinityMask(). Initialize() cannot be called again without a subsequent Cleanup() call.
It is recommended for apps using the Xbox One XDK version of the Party Xbox Live Helper library to wait until
the platform is ready for networking operations before calling this method. Please refer to the XDK
documentation about networking and secure device associations best practices for more information.
Apps using the Microsoft Game Core version of the Party Xbox Live Helper library will need to wait for the
Game Core Networking stack to be initialized prior to calling this method. Determining the status of the network
stack can be done using the Game Core XNetworkingGetConnectivityHint API.
Apps using the Microsoft Game Core version of the Party Xbox Live Helper library must listen for app state
notifications via the RegisterAppStateChangeNotification API. When the app is suspended, the title must call
Cleanup(). When the app is resumed, the title must wait for the Game Core networking stack to be ready and
then re-initialize the Party Xbox Live Helper library by calling Initialize().
Requirements
Header : PartyXboxLive.h
See also
PartyXblManager
PartyXblManager::Cleanup
PartyXblManager::GetSingleton
PartyXblManager::SetMemoryCallbacks
PartyXblManager::GetMemoryCallbacks
PartyXblManager::SetThreadAffinityMask
PartyXblManager::GetThreadAffinityMask
PartyXblManager::Cleanup
5/24/2022 • 2 minutes to read • Edit Online
Syntax
PartyError Cleanup(
)
Parameters
Return value
PartyError
c_partyErrorSuccess if the call succeeded or an error code otherwise. The human-readable form of the error
code can be retrieved via GetErrorMessage().
Remarks
Every call to Initialize() should have a corresponding Cleanup() call.
Titles using the Microsoft Game Core version of the Party Xbox Live Helper library must listen for app state
notifications via the RegisterAppStateChangeNotification API. When the app is suspended, the title must call
Cleanup(). When the app is resumed, the title must wait for the Game Core networking stack to be ready and
then re-initialize the Party Xbox Live Helper library by calling Initialize().
Requirements
Header : PartyXboxLive.h
See also
PartyXblManager
PartyXblManager::Initialize
PartyXblManager::StartProcessingStateChanges
5/24/2022 • 2 minutes to read • Edit Online
Retrieves an array of all Party Xbox Live state changes to process since the last such call.
Syntax
PartyError StartProcessingStateChanges(
uint32_t* stateChangeCount,
PartyXblStateChangeArray* stateChanges
)
Parameters
stateChangeCount uint32_t*
output
A place to write the number of PartyXblStateChange entries for the title to handle in the stateChanges array.
stateChanges PartyXblStateChangeArray*
library-allocated output array of size *stateChangeCount
A place to store a pointer to the array of all PartyXblStateChange entries for the title to handle and then pass to
FinishProcessingStateChanges().
Return value
PartyError
c_partyErrorSuccess if the call succeeded or an error code otherwise. The human-readable form of the error
code can be retrieved via GetErrorMessage().
Remarks
This method provides the Party Xbox Live Helper library an opportunity to retrieves a list of all changes
currently available for the title since the last call to this method. The title should use the provided array of 0 or
more changes to update its own state or UI, and then call FinishProcessingStateChanges() with them in a timely
manner.
State exposed by the library can change during this call, so you must be thread-safe in your use of it.
StartProcessingStateChanges() should be called frequently-- at least once every 100 milliseconds. It's designed
to execute and return quickly such that it can be called on your main UI thread with negligible impact. For best
results, you should also minimize the time you spend handling state changes before calling
FinishProcessingStateChanges().
Requirements
Header : PartyXboxLive.h
See also
PartyXblManager
PartyXblStateChange
PartyXblManager::FinishProcessingStateChanges
PartyXblManager::FinishProcessingStateChanges
5/24/2022 • 2 minutes to read • Edit Online
Returns an array of Party Xbox Live state changes that were being processed.
Syntax
PartyError FinishProcessingStateChanges(
uint32_t stateChangeCount,
PartyXblStateChangeArray stateChanges
)
Parameters
stateChangeCount uint32_t
The number of changes, provided in the list specified by stateChanges , previously returned by
StartProcessingStateChanges() that have now been handled by the title.
stateChanges PartyXblStateChangeArray
input array of size stateChangeCount
The pointer to the array of changes previously returned by StartProcessingStateChanges() that have now been
handled by the title.
Return value
PartyError
c_partyErrorSuccess if the call succeeded or an error code otherwise. The human-readable form of the error
code can be retrieved via GetErrorMessage().
Remarks
This method informs the Party Xbox Live Helper library that the state changes reported by a previous call to
StartProcessingStateChanges() have now been handled by the title, so their associated resources can be
reclaimed. You may call FinishProcessingStateChanges() with any number of state changes. Each state change
returned by StartProcessingStateChanges() must be returned to FinishProcessingStateChanges() exactly once,
but may be returned out of order and may be interleaved with state changes from other calls to
StartProcessingStateChanges(). Even if state changes are held across subsequent calls to
StartProcessingStateChanges(), the Party Xbox Live Helper library state returned by all getters will advance and
may no longer reflect the same state that the held state changes refer to.
Any resources associated with a specific state change are guaranteed to stay valid until the state change is
returned to FinishProcessingStateChanges().
For best results, you should minimize the time you spend handling state changes before calling
FinishProcessingStateChanges().
Requirements
Header : PartyXboxLive.h
See also
PartyXblManager
PartyXblStateChange
PartyXblManager::StartProcessingStateChanges
PartyXblManager::CompleteGetTokenAndSignatureRequest
5/24/2022 • 2 minutes to read • Edit Online
Syntax
PartyError CompleteGetTokenAndSignatureRequest(
uint32_t correlationId,
PartyBool succeeded,
PartyString token,
PartyString signature
)
Parameters
correlationId uint32_t
The correlation id of the web request for which the token and signature were requested.
succeeded PartyBool
The title succeeded the token and signature request.
token PartyString
optional
The token for the request, if necessary, as a null terminated string.
signature PartyString
optional
The signature for the request, if necessary, as a null terminated string.
Return value
PartyError
c_partyErrorSuccess if the call succeeded or an error code otherwise. The human-readable form of the error
code can be retrieved via GetErrorMessage().
Remarks
The title can use the Xbox Authentication Library (XAL) to fulfill these request by calling the
XalUserGetTokenAndSignatureSilentlyAsync function.
This should only be called in response to a PartyXblTokenAndSignatureRequestedStateChange.
Requirements
Header : PartyXboxLive.h
See also
PartyXblManager
PartyXblTokenAndSignatureRequestedStateChange
PartyXblManager::CreateLocalChatUser
5/24/2022 • 2 minutes to read • Edit Online
Queues an asynchronous attempt to create a local chat user. Privacy and privilege information related to this
user will be tracked by the helper library.
Syntax
PartyError CreateLocalChatUser(
uint64_t xboxUserId,
void* asyncIdentifier,
PartyXblLocalChatUser** localChatUser
)
Parameters
xboxUserId uint64_t
The Xbox Live User Id associated with the local chat user.
asyncIdentifier void*
optional
An optional, app-defined, pointer-sized context value that can be used to associate the completion state change
with this call.
localChatUser PartyXblLocalChatUser**
optional, library-allocated output
The output local chat user object.
Return value
PartyError
c_partyErrorSuccess if the call succeeded or an error code otherwise. The human-readable form of the error
code can be retrieved via GetErrorMessage().
Requirements
Header : PartyXboxLive.h
See also
PartyXblManager
PartyXblManager::CreateRemoteChatUser
5/24/2022 • 2 minutes to read • Edit Online
Creates a remote chat user. A remote chat user is an Xbox Live user currently communicating with at least one
local user. Creating a remote chat user will cause the library to start tracking privacy information related to this
user in relation to every local chat user.
Syntax
PartyError CreateRemoteChatUser(
uint64_t xboxUserId,
PartyXblChatUser** chatUser
)
Parameters
xboxUserId uint64_t
The Xbox Live user id associated with the chat user.
chatUser PartyXblChatUser**
optional, library-allocated output
The output chat user object.
Return value
PartyError
c_partyErrorSuccess if the call succeeded or an error code otherwise. The human-readable form of the error
code can be retrieved via GetErrorMessage().
Requirements
Header : PartyXboxLive.h
See also
PartyXblManager
PartyXblManager::DestroyChatUser
5/24/2022 • 2 minutes to read • Edit Online
Syntax
PartyError DestroyChatUser(
const PartyXblChatUser* chatUser
)
Parameters
chatUser PartyXblChatUser*
Requirements
Header : PartyXboxLive.h
See also
PartyXblManager
PartyXblManager::GetChatUsers
5/24/2022 • 2 minutes to read • Edit Online
Gets an array containing all chat users created by CreateLocalChatUser() and CreateRemoteChatUser().
Syntax
PartyError GetChatUsers(
uint32_t* userCount,
PartyXblChatUserArray* chatUsers
)
Parameters
userCount uint32_t*
output
An output value indicating the number of chat users provided in chatUsers .
chatUsers PartyXblChatUserArray*
library-allocated output array of size *endpointCount
A library-allocated output array containing the local and remote chat users.
Return value
PartyError
c_partyErrorSuccess if the call succeeded or an error code otherwise. The human-readable form of the error
code can be retrieved via GetErrorMessage().
Remarks
The array is backed by the library's internal memory. The array is only valid until the next call to either
CreateLocalChatUser(), CreateRemoteChatUser(), StartProcessingStateChanges() or DestroyChatUser(). A call to
DestroyChatUser() will also immediately invalidate the chat user object.
Requirements
Header : PartyXboxLive.h
See also
PartyXblManager
PartyXblManager::CreateLocalChatUser
PartyXblManager::CreateRemoteChatUser
PartyXblManager::DestroyChatUser
PartyXblManager::LoginToPlayFab
5/24/2022 • 2 minutes to read • Edit Online
Signs the user in to PlayFab using an Xbox Live token, asynchronously returning an Entity ID and Entity Token
that can subsequently be used for PlayFab API calls which require an authenticated PlayFab user or to create a
PartyLocalUser. There is no difference between calling this method or using the LoginWithXbox method
provided by the PlayFab SDK.
Syntax
PartyError LoginToPlayFab(
const PartyXblLocalChatUser* localChatUser,
void* asyncIdentifier
)
Parameters
localChatUser PartyXblLocalChatUser*
The local chat user object that will be used for the login operation.
asyncIdentifier void*
optional
An optional, app-defined, pointer-sized context value that can be used to associate the completion state change
with this call.
Return value
PartyError
c_partyErrorSuccessif the operation to login the local chat user with PlayFab started or an error code
otherwise. The human-readable form of the error code can be retrieved via GetErrorMessage().
Remarks
If this is the first time the Xbox Live identity has logged in to PlayFab, a new PlayFab account will be created and
linked to the Xbox Live identity.
When a token is nearing the expiration time or if a token has expired due to the application being in a dormant
state for an extended time, a new token should be obtained by calling this method. It is recommended to acquire
a new token when the previously supplied token is halfway through its validity period.
Requirements
Header : PartyXboxLive.h
See also
PartyXblManager
PartyXblLoginToPlayFabCompletedStateChange
PartyXblManager::GetEntityIdsFromXboxLiveUserIds
5/24/2022 • 2 minutes to read • Edit Online
Queues an asynchronous operation to retrieve a list of mappings between PlayFab Entity Ids and known Xbox
Live User Ids.
Syntax
PartyError GetEntityIdsFromXboxLiveUserIds(
uint32_t xboxLiveUserIdCount,
const uint64_t* xboxLiveUserIds,
const PartyXblLocalChatUser* localChatUser,
void* asyncIdentifier
)
Parameters
xboxLiveUserIdCount uint32_t
The number of Xbox Live User Ids in the xboxLiveUserIds array.
xboxLiveUserIds uint64_t*
input array of size xboxLiveUserIdCount
An array of size xboxLiveUserIdCount containing the Xbox Live User Ids for which the library will query the
PlayFab Entity Id.
localChatUser PartyXblLocalChatUser*
Local chat user that will be used to communicate with PlayFab. The local chat user will be logged in to PlayFab if
needed.
asyncIdentifier void*
optional
An optional, app-defined, pointer-sized context value that can be used to associate the completion state change
with this call.
Return value
PartyError
c_partyErrorSuccess if the operation started or an error code otherwise. The human-readable form of the error
code can be retrieved via GetErrorMessage().
Remarks
Each Xbox Live User Id will only map to a PlayFab Entity Id if this Xbox Live User has already been linked to a
PlayFab account. A PlayFab account is automatically created and linked when calling
PartyXblManager::LoginToPlayFab for the first time. The LoginWithXbox API provided by the PlayFab SDK can
also be used to link an account.
Requirements
Header : PartyXboxLive.h
See also
PartyXblManager
PartyXblGetEntityIdsFromXboxLiveUserIdsCompletedStateChange
PartyXblAccessibilitySettings
5/24/2022 • 2 minutes to read • Edit Online
Syntax
struct PartyXblAccessibilitySettings {
PartyBool speechToTextEnabled;
PartyBool textToSpeechEnabled;
char languageCode[c_maxLanguageCodeStringLength + 1];
PartyGender gender;
}
Members
speechToTextEnabled PartyBool
True if the user has enabled speech to text in its Xbox Live settings
textToSpeechEnabled PartyBool
True if the user has enabled text to speech in its Xbox Live settings
languageCode char[c_maxLanguageCodeStringLength + 1]
Language code associated with this user's accessibility settings. Can be used as a hint when choosing the
PartyTextToSpeechProfile for this user.
gender PartyGender
Gender associated with this user's accessibility settings. Can be used as a hint when choosing the
PartyTextToSpeechProfile for this user.
Requirements
Header : PartyXboxLive.h
See also
PartyXboxLive members
PartyXblChatPermissionInfo
5/24/2022 • 2 minutes to read • Edit Online
Syntax
struct PartyXblChatPermissionInfo {
PartyChatPermissionOptions chatPermissionMask;
PartyXblChatPermissionMaskReason reason;
}
Members
chatPermissionMask PartyChatPermissionOptions
The chat permission options mask that should be applied to the target chat user.
Use a bitwise 'AND' operation against the desired chat permissions to ensure the resulting permissions will
respect Xbox Live policies.
reason PartyXblChatPermissionMaskReason
Extra information regarding the result of a required chat permission query.
Requirements
Header : PartyXboxLive.h
See also
PartyXboxLive members
PartyXblHttpHeader
5/24/2022 • 2 minutes to read • Edit Online
Syntax
struct PartyXblHttpHeader {
PartyString name;
PartyString value;
}
Members
name PartyString
Requirements
Header : PartyXboxLive.h
See also
PartyXboxLive members
PartyXblXboxUserIdToPlayFabEntityIdMapping
5/24/2022 • 2 minutes to read • Edit Online
Syntax
struct PartyXblXboxUserIdToPlayFabEntityIdMapping {
uint64_t xboxLiveUserId;
PartyString playfabEntityId;
}
Members
xboxLiveUserId uint64_t
The Xbox Live User Id.
playfabEntityId PartyString
The PlayFab Entity Id.
This value may be an empty string in the case where the Xbox Live user does not have a linked PlayFab account.
A PlayFab account is automatically created and linked when calling PartyXblManager::LoginToPlayFab for the
first time. The LoginWithXbox API provided by the PlayFab SDK can also be used to link an account.
Requirements
Header : PartyXboxLive.h
See also
PartyXboxLive members
PartyXblCreateLocalChatUserCompletedStateChange
5/24/2022 • 2 minutes to read • Edit Online
Syntax
struct PartyXblCreateLocalChatUserCompletedStateChange : PartyXblStateChange {
PartyXblStateChangeResult result;
PartyError errorDetail;
void* asyncIdentifier;
PartyXblLocalChatUser* localChatUser;
}
Members
result PartyXblStateChangeResult
Indicates that the local chat user creation operation Succeeded or provides the reason that it failed.
errorDetail PartyError
A diagnostic value providing additional troubleshooting information regarding any potential error condition.
asyncIdentifier void*
The async identifier provided to the call associated with this state change.
localChatUser PartyXblLocalChatUser*
The local chat user that was created.
Requirements
Header : PartyXboxLive.h
See also
PartyXboxLive members
PartyXblGetEntityIdsFromXboxLiveUserIdsCompletedStateChange
5/24/2022 • 2 minutes to read • Edit Online
Syntax
struct PartyXblGetEntityIdsFromXboxLiveUserIdsCompletedStateChange : PartyXblStateChange {
PartyXblStateChangeResult result;
PartyError errorDetail;
PartyString xboxLiveSandbox;
PartyXblLocalChatUser* localChatUser;
void* asyncIdentifier;
uint32_t entityIdMappingCount;
const PartyXblXboxUserIdToPlayFabEntityIdMapping* entityIdMappings;
}
Members
result PartyXblStateChangeResult
Requirements
Header : PartyXboxLive.h
See also
PartyXboxLive members
PartyXblLocalChatUserDestroyedStateChange
5/24/2022 • 2 minutes to read • Edit Online
Syntax
struct PartyXblLocalChatUserDestroyedStateChange : PartyXblStateChange {
PartyXblLocalChatUser* localChatUser;
PartyXblLocalChatUserDestroyedReason reason;
PartyError errorDetail;
}
Members
localChatUser PartyXblLocalChatUser*
The local chat user provided to the call associated with this state change.
reason PartyXblLocalChatUserDestroyedReason
The reason the local chat user was destroyed.
errorDetail PartyError
A diagnostic value providing additional troubleshooting information regarding any potential error condition.
The human-readable form of this error detail can be retrieved via PartyXblManager::GetErrorMessage().
Requirements
Header : PartyXboxLive.h
See also
PartyXboxLive members
PartyXblLoginToPlayFabCompletedStateChange
5/24/2022 • 2 minutes to read • Edit Online
Syntax
struct PartyXblLoginToPlayFabCompletedStateChange : PartyXblStateChange {
PartyXblStateChangeResult result;
PartyError errorDetail;
PartyXblLocalChatUser* localChatUser;
void* asyncIdentifier;
PartyString entityId;
PartyString titlePlayerEntityToken;
time_t expirationTime;
}
Members
result PartyXblStateChangeResult
Indicates that the login operation succeeded or the reason that it failed.
errorDetail PartyError
A diagnostic value providing additional troubleshooting information regarding any potential error condition.
localChatUser PartyXblLocalChatUser*
The local chat user who was logged in to PlayFab.
asyncIdentifier void*
The async identifier provided to the call associated with this state change.
entityId PartyString
The PlayFab Entity Id associated with the local chat user's Xbox Live identity.
titlePlayerEntityToken PartyString
The PlayFab Entity Token associated with the local chat user's Xbox Live identity.
expirationTime time_t
The timestamp describing when this token expires.
When the token is nearing the expiration time or if the token has expired due to the application being in a
dormant state for an extended time, a new token should be obtained by calling
PartyXblManager::LoginToPlayFab().
Requirements
Header : PartyXboxLive.h
See also
PartyXboxLive members
PartyXblRequiredChatPermissionInfoChangedStateChange
5/24/2022 • 2 minutes to read • Edit Online
Syntax
struct PartyXblRequiredChatPermissionInfoChangedStateChange : PartyXblStateChange {
PartyXblLocalChatUser* localChatUser;
PartyXblChatUser* targetChatUser;
}
Members
localChatUser PartyXblLocalChatUser*
The local chat user for which the chat permission info applies to.
targetChatUser PartyXblChatUser*
The chat user the chat permission info should be applied to.
Remarks
Use PartyXblLocalChatUser::GetRequiredChatPermissionInfo() with the targetChatUser provided in this state
change to get the new chat permission information.
Requirements
Header : PartyXboxLive.h
See also
PartyXboxLive members
PartyXblStateChange
5/24/2022 • 2 minutes to read • Edit Online
Syntax
struct PartyXblStateChange {
PartyXblStateChangeType stateChangeType;
}
Members
stateChangeType PartyXblStateChangeType
The specific type of the state change represented.
Use this field to determine which corresponding derived structure is represented by this PartyXblStateChange
structure header.
Remarks
PartyXblStateChange structures are reported by PartyXblManager::StartProcessingStateChanges() for the title to
handle and then promptly pass back via the PartyXblManager::FinishProcessingStateChanges() method.
The stateChangeType field indicates which kind of state change occurred, and this base structure should then be
cast to a more specific derived structure to retrieve additional event-specific information.
Requirements
Header : PartyXboxLive.h
See also
PartyXboxLive members
PartyXblManager::StartProcessingStateChanges
PartyXblManager::FinishProcessingStateChanges
PartyXblTokenAndSignatureRequestedStateChange
5/24/2022 • 2 minutes to read • Edit Online
Syntax
struct PartyXblTokenAndSignatureRequestedStateChange : PartyXblStateChange {
uint32_t correlationId;
PartyString method;
PartyString url;
uint32_t headerCount;
PartyXblHttpHeader* headers;
uint32_t bodySize;
const void* body;
PartyBool forceRefresh;
PartyBool allUsers;
PartyXblLocalChatUser* localChatUser;
}
Members
correlationId uint32_t
Opaque identifier used to associate the token and signature request with the internal HTTP request. Use this
identifier when calling PartyXblManager::CompleteGetTokenAndSignatureRequest() to complete the operation.
method PartyString
The HTTP method for the request, such as "GET" or "POST".
url PartyString
The URL for the HTTP request that needs a token and signature (fully escaped).
headerCount uint32_t
The number of headers for the HTTP request.
headers PartyXblHttpHeader*
array of size headerCount
The headers for the HTTP request.
bodySize uint32_t
The size of the request body in bytes.
body const void*
buffer of size bodySize bytes
The request body.
forceRefresh PartyBool
If true the token must be refreshed, ignoring any cached token.
allUsers PartyBool
If true , a token should be requested for all users rather than a specific user. In the case localChatUser will be
nullptr.
localChatUser PartyXblLocalChatUser*
may be nullptr
The local chat user that should be used to retrieve the token and signature.
This field is only valid when allUsers is set to false .
Remarks
The title can use the Xbox Authentication Library (XAL) to fulfill these requests by calling the
XalUserGetTokenAndSignatureSilentlyAsync() function.
Requirements
Header : PartyXboxLive.h
See also
PartyXboxLive members
PartyXblChatPermissionMaskReason
5/24/2022 • 2 minutes to read • Edit Online
Syntax
enum class PartyXblChatPermissionMaskReason
{
NoRestriction,
Determining,
Privilege,
Privacy,
InvalidTargetUser,
XboxLiveServiceError,
UnknownError,
ResolveUserIssue,
}
Constants
C O N STA N T DESC RIP T IO N
Requirements
Header : PartyXboxLive.h
See also
PartyXboxLive members
PartyXblCrossNetworkCommunicationPrivacySetting
5/24/2022 • 2 minutes to read • Edit Online
Possible cross-network communication privacy settings for a local Xbox Live user.
Syntax
enum class PartyXblCrossNetworkCommunicationPrivacySetting
{
Allowed,
FriendsOnly,
Disallowed,
}
Constants
C O N STA N T DESC RIP T IO N
Remarks
A cross-network user is defined as a user of a non-Xbox Live gaming network.
Requirements
Header : PartyXboxLive.h
See also
PartyXboxLive members
PartyXblLocalChatUserDestroyedReason
5/24/2022 • 2 minutes to read • Edit Online
Syntax
enum class PartyXblLocalChatUserDestroyedReason
{
UnauthorizedLocalChatUser,
FailedToGetTokenAndSignatureForLocalChatUser,
XboxLiveServiceTemporarilyUnavailable,
InternetConnectivityError,
XboxLiveUserNotSignedIn,
UnknownError,
}
Constants
C O N STA N T DESC RIP T IO N
Requirements
Header : PartyXboxLive.h
See also
PartyXboxLive members
PartyXblStateChangeResult
5/24/2022 • 2 minutes to read • Edit Online
Syntax
enum class PartyXblStateChangeResult
{
Succeeded,
UnknownError,
CanceledByTitle,
UserNotAuthorized,
LoginToPlayFabThrottled,
PartyServiceError,
XboxLiveServiceTemporarilyUnavailable,
InternetConnectivityError,
PlayFabRateLimitExceeded,
}
Constants
C O N STA N T DESC RIP T IO N
UserNotAuthorized The Xbox Live user or PlayFab Entity associated with the
PartyXblLocalChatUser is not authorized to perform this
request.
LoginToPlayFabThrottled The operation failed because too many logins have been
attempted for this title.
PlayFabRateLimitExceeded The rate limit for the PlayFab Service has been reached.
Requirements
Header : PartyXboxLive.h
See also
PartyXboxLive members
PartyXblStateChangeType
5/24/2022 • 2 minutes to read • Edit Online
Syntax
enum class PartyXblStateChangeType : uint32_t
{
CreateLocalChatUserCompleted,
LocalChatUserDestroyed,
RequiredChatPermissionInfoChanged,
TokenAndSignatureRequested,
LoginToPlayFabCompleted,
GetEntityIdsFromXboxLiveUserIdsCompleted,
}
Constants
C O N STA N T DESC RIP T IO N
RequiredChatPermissionInfoChanged Chat permissions between a local chat user and a target chat
user has changed.
TokenAndSignatureRequested The Xbox Live Helper library requires an Xbox Live token and
signature to complete an HTTP request.
Requirements
Header : PartyXboxLive.h
See also
PartyXboxLive members
PartyXblThreadId
5/24/2022 • 2 minutes to read • Edit Online
Threads that Party Xbox Live Helper library uses for internal purposes.
Syntax
enum class PartyXblThreadId
{
WebRequest,
}
Constants
C O N STA N T DESC RIP T IO N
WebRequest Represents the Party Xbox Live Helper library internal web
request threads.
Requirements
Header : PartyXboxLive.h
See also
PartyXboxLive members
PartyXblManager::GetThreadAffinityMask
PartyXblManager::SetThreadAffinityMask
PlayFab Party Xbox Live Helper Libary Typedefs
5/24/2022 • 2 minutes to read • Edit Online
The Party Xbox Live Helper Library uses several typedefs for convenient declarations of arrays of core types.
Additional typedefs provided by PlayFab Party are used within the PlayFab Party Xbox Live Helper Library.
Arrays
A number of structs and method parameters use constant arrays of core types. To simplify usage and
declaration of these arrays, the following typedefs are provided.
T Y P EDEF C O RE T Y P E
PartyXblStateChangeArray PartyXblStateChange
PartyXblChatUserArray PartyLocalUser
Requirements
Header : PartyXboxLive.h
See also
Party typedefs
PFMultiplayer C/C++ API overview -
PFMultiplayer.h
5/24/2022 • 2 minutes to read • Edit Online
IMPORTANT
This feature is currently in public preview. It is provided to give you an early look at an upcoming feature, and to allow you
to provide feedback while it is still in development.
Functions
F UN C T IO N DESC RIP T IO N
PFMultiplayerSetEntityToken Sets the token that should be used for authentication when
performing library actions on behalf of an entity. If a token
has previously been set for the entity, this replaces its
previous token.
Callbacks
C ALLBAC K DESC RIP T IO N
Enumerations
EN UM ERAT IO N DESC RIP T IO N
IMPORTANT
This feature is currently in public preview. It is provided to give you an early look at an upcoming feature, and to allow you
to provide feedback while it is still in development.
Functions
F UN C T IO N DESC RIP T IO N
PFLobbyGetConnectionString Gets the default connection string associated with the lobby.
PFLobbyGetMembers Gets the list of PlayFab entities currently joined to the lobby
as members.
PFLobbySendInvite Send an invite to this lobby from the local user to the invited
entity.
PFMultiplayerCreateAndJoinLobby Create a new lobby and add the creating PlayFab entity to it.
Structures
ST RUC T URE DESC RIP T IO N
PFLobbySearchFriendsFilter The filter structure used to limit lobby search results to only
those lobbies owned by the player's friends.
State changes
STAT E C H A N GE DESC RIP T IO N
Enumerations
EN UM ERAT IO N DESC RIP T IO N
PFLobbyOwnerMigrationPolicy The available policies the lobby service can use to migrate
lobby ownership between members.
IMPORTANT
This feature is currently in public preview. It is provided to give you an early look at an upcoming feature, and to allow you
to provide feedback while it is still in development.
Functions
F UN C T IO N DESC RIP T IO N
Structures
ST RUC T URE DESC RIP T IO N
State changes
STAT E C H A N GE DESC RIP T IO N
Enumerations
EN UM ERAT IO N DESC RIP T IO N
Syntax
const char * PFMultiplayerGetErrorMessage(
HRESULT error
)
Parameters
error HRESULT
An error code.
Return value
Type: const char *
The human-readable error message. The memory for the returned string remains valid for the lifetime of the
process.
Remarks
These error messages are not localized and are only intended for developers, i.e. these error messages are not
intended to be shown to users via UI.
Requirements
Header : PFMultiplayer.h
See also
PFMultiplayer members
PFMultiplayerInitialize
5/24/2022 • 2 minutes to read • Edit Online
Syntax
HRESULT PFMultiplayerInitialize(
const char* playFabTitleId,
PFMultiplayerHandle* handle
)
Parameters
playFabTitleId char*
is null-terminated
The app's PlayFab Title ID.
handle PFMultiplayerHandle*
library-allocated output
The output handle of the newly initialized PFMultiplayer API instance.
Return value
Type: HRESULT
S_OK if the call succeeded or an error code otherwise. The human-readable form of the error code can be
retrieved via PFMultiplayerGetErrorMessage().
Remarks
This must be called before any other method, aside from PFMultiplayerSetMemoryCallbacks(), and
PFMultiplayerSetThreadAffinityMask(). PFMultiplayerInitialize() cannot be called again without a subsequent
PFMultiplayerUninitialize() call.
Apps using the Microsoft Game Core version of the Multiplayer library will need to wait for the Game Core
Networking stack to be initialized prior to calling this method. Determining the status of the network stack can
be done using the Game Core XNetworkingGetConnectivityHint API.
The provided playFabTitleId must be the same PlayFab Title ID used to acquire the PlayFab Entity Keys and
Entity Tokens that will be passed to PFMultiplayerSetEntityToken().
Requirements
Header : PFMultiplayer.h
See also
PFMultiplayer members
PFMultiplayerSetEntityToken
PFMultiplayerUninitialize
PFMultiplayerSetMemoryCallbacks
PFMultiplayerSetThreadAffinityMask
PFMultiplayerSetEntityToken
5/24/2022 • 2 minutes to read • Edit Online
Sets the token that should be used for authentication when performing library actions on behalf of an entity. If a
token has previously been set for the entity, this replaces its previous token.
Syntax
HRESULT PFMultiplayerSetEntityToken(
PFMultiplayerHandle handle,
const PFEntityKey* entity,
const char* entityToken
)
Parameters
handle PFMultiplayerHandle
Remarks
This method takes a PlayFab Entity Key as entity and a PlayFab Entity Token as token . When the library
performs operations on behalf of an entity that require authentication or authorization, such as creating or
updating a lobby, the library will look up a token associated with the entity to use for the operation. If no token
has previously been set for the entity, the operation will synchronously fail. During the asynchronous operation,
the PlayFab service will validate that the token is valid, is not expired, is associated with the Entity ID provided,
and is authorized to perform the operation. If these conditions aren't met, the operation will fail.
A PlayFab Entity Key and Entity Token can be obtained from the output of a PlayFab login operation and then
provided as input to this method.
The provided entity and token must have been acquired using the same PlayFab Title ID that was passed to
PFMultiplayerInitialize().
The Multiplayer library makes a copy of the supplied PlayFab Entity Token for use in subsequent operations that
require authentication or authorization of the local user, such as PFMultiplayerCreateAndJoinLobby . If the token
provided to this call is expired or otherwise invalid, operations that require a valid token will fail. A new, valid
token can be provided to the Multiplayer library by calling this method again using the same entity key.
The caller is responsible for monitoring the expiration of the entity token provided to this method. When the
token is nearing or past the expiration time a new token should be obtained by performing a PlayFab login
operation and provided to the Multiplayer library by calling this method again. It is recommended to acquire a
new token when the previously supplied token is halfway through its validity period. On platforms that may
enter a low power state or otherwise cause the application to pause execution for a long time, preventing the
token from being refreshed before it expires, the token should be checked for expiration once execution
resumes.
Requirements
Header : PFMultiplayer.h
See also
PFMultiplayer members
PFMultiplayerInitialize
PFMultiplayerSetMemoryCallbacks
5/24/2022 • 2 minutes to read • Edit Online
Optionally configures the memory allocation and freeing callbacks the Multiplayer library should use.
Syntax
HRESULT PFMultiplayerSetMemoryCallbacks(
PFMultiplayerAllocateMemoryCallback allocateMemoryCallback,
PFMultiplayerFreeMemoryCallback freeMemoryCallback
)
Parameters
allocateMemoryCallback PFMultiplayerAllocateMemoryCallback
A pointer to the custom allocation callback to use.
freeMemoryCallback PFMultiplayerFreeMemoryCallback
A pointer to the custom freeing callback to use.
Return value
Type: HRESULT
S_OK if the call succeeded or an error code otherwise. The human-readable form of the error code can be
retrieved via PFMultiplayerGetErrorMessage().
Remarks
This method allows the title to install custom memory allocation functions in order to service all requests by the
Multiplayer library for new memory buffers instead of using its default allocation functions.
To use this method, it must be called before any other Multiplayer method. This method cannot be called again
for the lifetime of this process.
Requirements
Header : PFMultiplayer.h
See also
PFMultiplayer members
PFMultiplayerAllocateMemoryCallback
PFMultiplayerFreeMemoryCallback
PFMultiplayerSetThreadAffinityMask
5/24/2022 • 2 minutes to read • Edit Online
Optionally configures the processor on which internal Multiplayer library threads will run.
Syntax
HRESULT PFMultiplayerSetThreadAffinityMask(
PFMultiplayerThreadId threadId,
uint64_t threadAffinityMask
)
Parameters
threadId PFMultiplayerThreadId
Remarks
This method enables the title to configure the processor affinity for internal Multiplayer library threads of a
given type.
This method may be called at any time before or after PFMultiplayerInitialize() and will take effect immediately.
Thread processor settings are persisted across calls to PFMultiplayerUninitialize() and PFMultiplayerInitialize().
When there are more than 64 cores present, this method always applies to processor group 0.
In order to specify any processor, pass PFMultiplayerAnyProcessor as the threadAffinityMask parameter. This is
also the default value the Multiplayer library will use if this method is never called.
Requirements
Header : PFMultiplayer.h
See also
PFMultiplayer members
PFMultiplayerThreadId
PFMultiplayerUninitialize
5/24/2022 • 2 minutes to read • Edit Online
Immediately reclaims all resources associated with all Multiplayer library objects.
Syntax
HRESULT PFMultiplayerUninitialize(
PFMultiplayerHandle handle
)
Parameters
handle PFMultiplayerHandle
input not valid afterwards
The handle of the PFMultiplayer API instance.
Return value
Type: HRESULT
S_OK if the call succeeded or an error code otherwise. The human-readable form of the error code can be
retrieved via PFMultiplayerGetErrorMessage().
Remarks
If local users were participating in a Lobby, they are removed (it appears to remote lobby clients as if network
connectivity to these users has been lost), so best practice is to call PFLobbyLeave on all lobbies and wait for the
corresponding PFLobbyLeaveLobbyCompletedStateChange to have the local users exit any existing lobbies.
This method is not thread-safe and may not be called concurrently with other Multiplayer library methods. After
calling this method, all Multiplayer library state is invalidated.
Requirements
Header : PFMultiplayer.h
See also
PFMultiplayer members
PFMultiplayerInitialize
PFLobbyAddMember
5/24/2022 • 2 minutes to read • Edit Online
Syntax
HRESULT PFLobbyAddMember(
PFLobbyHandle lobby,
const PFEntityKey* localUser,
uint32_t memberPropertyCount,
const char* const* memberPropertyKeys,
const char* const* memberPropertyValues,
void* asyncContext
)
Parameters
lobby PFLobbyHandle
The number of initial member properties to set for this user when they join the lobby.
memberPropertyKeys char* const*
input array of size memberPropertyCount
The keys of the initial member properties to set for this user when they join the lobby.
memberPropertyValues char* const*
input array of size memberPropertyCount
The values of the initial member properties to set for this user when they join the lobby.
asyncContext void*
optional
An optional, app-defined, pointer-sized context value that can be used to associate the completion state change
with this call.
Return value
Type: HRESULT
S_OK if the call succeeded or an error code otherwise. The human-readable form of the error code can be
retrieved via PFMultiplayerGetErrorMessage().
Remarks
This is an asynchronous operation. Upon successful completion, the title will be provided a
PFLobbyMemberAddedStateChange followed by a PFLobbyAddMemberCompletedStateChange with the
PFLobbyAddMemberCompletedStateChange::result field set to S_OK . Upon a failed completion, the title will be
provided a PFLobbyAddMemberCompletedStateChange with the
PFLobbyAddMemberCompletedStateChange::result field set to a failure hresult.
This method is used to add another local PlayFab entity to a pre-existing lobby object. Because the lobby object
must have already been created either via a call to PFMultiplayerCreateAndJoinLobby or
PFMultiplayerJoinLobby, this method is primarily useful for multiple local user scenarios.
This is an asynchronous operation. The member added via this method will not be reflected in the lists returned
by PFLobbyGetMembers until the asynchronous operation successfully completes and a
PFLobbyMemberAddedStateChange struct is provided by PFMultiplayerStartProcessingLobbyStateChanges.
Requirements
Header : PFLobby.h
See also
PFLobby members
PFLobbyForceRemoveMember
5/24/2022 • 2 minutes to read • Edit Online
Syntax
HRESULT PFLobbyForceRemoveMember(
PFLobbyHandle lobby,
const PFEntityKey* targetMember,
bool preventRejoin,
void* asyncContext
)
Parameters
lobby PFLobbyHandle
Remarks
This is an asynchronous operation. Upon successful completion, the title will be provided a
PFLobbyMemberRemovedStateChange followed by a PFLobbyForceRemoveMemberCompletedStateChange
with the PFLobbyForceRemoveMemberCompletedStateChange::result field set to S_OK . Upon a failed
completion, the title will be provided a PFLobbyForceRemoveMemberCompletedStateChange with the
PFLobbyForceRemoveMemberCompletedStateChange::result field set to a failure hresult.
One of the local PlayFab entities present in this lobby must be the owner for this operation to succeed. If the
local owning entity who initiated this operation loses their ownership status while the operation is in progress,
the operation will fail asynchronously.
This is an asynchronous operation. The member removed via this method will not be removed from the lists
returned by PFLobbyGetMembers until the asynchronous operation successfully completes and a
PFLobbyMemberRemovedStateChange struct is provided by PFMultiplayerStartProcessingLobbyStateChanges.
Requirements
Header : PFLobby.h
See also
PFLobby members
PFLobbyGetAccessPolicy
5/24/2022 • 2 minutes to read • Edit Online
Syntax
HRESULT PFLobbyGetAccessPolicy(
PFLobbyHandle lobby,
PFLobbyAccessPolicy* accessPolicy
)
Parameters
lobby PFLobbyHandle
Remarks
If this lobby object was created by calling PFMultiplayerJoinLobby(), this method will return an error until
PFMultiplayerStartProcessingLobbyStateChanges() provides a PFLobbyUpdatedStateChange with
PFLobbyUpdatedStateChange::accessPolicyUpdated set to true. If joining the lobby succeeds, this field is
guaranteed to be populated by the time PFMultiplayerStartProcessingLobbyStateChanges() provides a
PFLobbyJoinLobbyCompletedStateChange.
Requirements
Header : PFLobby.h
See also
PFLobby members
PFLobbyGetConnectionString
5/24/2022 • 2 minutes to read • Edit Online
Syntax
HRESULT PFLobbyGetConnectionString(
PFLobbyHandle lobby,
const char** connectionString
)
Parameters
lobby PFLobbyHandle
Remarks
If this lobby object was created by calling PFMultiplayerCreateAndJoinLobby(), this method will return an error
until PFMultiplayerStartProcessingLobbyStateChanges() provides a successful
PFLobbyCreateAndJoinLobbyCompletedStateChange. If this lobby object was created by calling
PFMultiplayerJoinLobby(), this method will return an error until
PFMultiplayerStartProcessingLobbyStateChanges() provides a successful
PFLobbyJoinLobbyCompletedStateChange.
Requirements
Header : PFLobby.h
See also
PFLobby members
PFLobbyGetCustomContext
5/24/2022 • 2 minutes to read • Edit Online
Retrieves the app's private, custom pointer-sized context value previously associated with this lobby object.
Syntax
HRESULT PFLobbyGetCustomContext(
PFLobbyHandle lobby,
void** customContext
)
Parameters
lobby PFLobbyHandle
Remarks
If no custom context has been set yet, the value pointed to by customContext is set to nullptr.
Requirements
Header : PFLobby.h
See also
PFLobby members
PFLobbySetCustomContext
PFLobbyGetLobbyId
5/24/2022 • 2 minutes to read • Edit Online
Syntax
HRESULT PFLobbyGetLobbyId(
PFLobbyHandle lobby,
const char** id
)
Parameters
lobby PFLobbyHandle
Remarks
If this lobby object was created by calling PFMultiplayerCreateAndJoinLobby() or PFMultiplayerJoinLobby(), this
method will return an error until PFMultiplayerStartProcessingLobbyStateChanges() provides a successful
PFLobbyCreateAndJoinLobbyCompletedStateChange or PFLobbyJoinLobbyCompletedStateChange respectively.
Requirements
Header : PFLobby.h
See also
PFLobby members
PFLobbyGetLobbyProperty
5/24/2022 • 2 minutes to read • Edit Online
Syntax
HRESULT PFLobbyGetLobbyProperty(
PFLobbyHandle lobby,
const char* key,
const char** value
)
Parameters
lobby PFLobbyHandle
Remarks
Lobby properties are only visible to members of the lobby.
If this lobby object is still in the process of asynchronously being created or joined via a call to
PFMultiplayerCreateAndJoinLobby() or PFMultiplayerJoinLobby(), this method will return no properties.
Requirements
Header : PFLobby.h
See also
PFLobby members
PFLobbyGetLobbyPropertyKeys
5/24/2022 • 2 minutes to read • Edit Online
Syntax
HRESULT PFLobbyGetLobbyPropertyKeys(
PFLobbyHandle lobby,
uint32_t* propertyCount,
const char* const** keys
)
Parameters
lobby PFLobbyHandle
Remarks
Lobby properties are only visible to members of the lobby.
If this lobby object is still in the process of asynchronously being created or joined via a call to
PFMultiplayerCreateAndJoinLobby() or PFMultiplayerJoinLobby(), this method will return no keys.
Requirements
Header : PFLobby.h
See also
PFLobby members
PFLobbyGetMaxMemberCount
5/24/2022 • 2 minutes to read • Edit Online
Syntax
HRESULT PFLobbyGetMaxMemberCount(
PFLobbyHandle lobby,
uint32_t* maxMemberCount
)
Parameters
lobby PFLobbyHandle
Remarks
If this lobby object was created by calling PFMultiplayerJoinLobby(), this method will return an error until
PFMultiplayerStartProcessingLobbyStateChanges() provides a PFLobbyUpdatedStateChange with
PFLobbyUpdatedStateChange::maxMembersUpdated set to true. If joining the lobby succeeds, this field is
guaranteed to be populated by the time PFMultiplayerStartProcessingLobbyStateChanges() provides a
PFLobbyJoinLobbyCompletedStateChange.
Requirements
Header : PFLobby.h
See also
PFLobby members
PFLobbyGetMemberProperty
5/24/2022 • 2 minutes to read • Edit Online
Syntax
HRESULT PFLobbyGetMemberProperty(
PFLobbyHandle lobby,
const PFEntityKey* member,
const char* key,
const char** value
)
Parameters
lobby PFLobbyHandle
Remarks
Per-member properties are only visible to members of the lobby.
If the member is still in the process of asynchronously joining this lobby either via
PFMultiplayerCreateAndJoinLobby(), PFMultiplayerJoinLobby(), or PFLobbyAddMember(), this method will
return no properties.
Requirements
Header : PFLobby.h
See also
PFLobby members
PFLobbyGetMemberPropertyKeys
5/24/2022 • 2 minutes to read • Edit Online
Syntax
HRESULT PFLobbyGetMemberPropertyKeys(
PFLobbyHandle lobby,
const PFEntityKey* member,
uint32_t* propertyCount,
const char* const** keys
)
Parameters
lobby PFLobbyHandle
Remarks
Per-member properties are only visible to members of the lobby.
If the member is still in the process of asynchronously joining this lobby either via
PFMultiplayerCreateAndJoinLobby(), PFMultiplayerJoinLobby(), or PFLobbyAddMember, this method will return
no keys.
Requirements
Header : PFLobby.h
See also
PFLobby members
PFLobbyGetMembers
5/24/2022 • 2 minutes to read • Edit Online
Gets the list of PlayFab entities currently joined to the lobby as members.
Syntax
HRESULT PFLobbyGetMembers(
PFLobbyHandle lobby,
uint32_t* memberCount,
const PFEntityKey** members
)
Parameters
lobby PFLobbyHandle
Remarks
If this lobby object is still in the process of asynchronously being created or joined, via a call to either
PFMultiplayerCreateAndJoinLobby() or PFMultiplayerJoinLobby() respectively, this method will return no
members.
Requirements
Header : PFLobby.h
See also
PFLobby members
PFLobbyGetMembershipLock
5/24/2022 • 2 minutes to read • Edit Online
Syntax
HRESULT PFLobbyGetMembershipLock(
PFLobbyHandle lobby,
PFLobbyMembershipLock* lockState
)
Parameters
lobby PFLobbyHandle
Remarks
If this lobby object was created by calling PFMultiplayerJoinLobby(), this method will return an error until
PFMultiplayerStartProcessingLobbyStateChanges() provides a PFLobbyUpdatedStateChange with
PFLobbyUpdatedStateChange::membershipLockUpdated set to true. If joining the lobby succeeds, this field is
guaranteed to be populated by the time PFMultiplayerStartProcessingLobbyStateChanges() provides a
PFLobbyJoinLobbyCompletedStateChange.
Requirements
Header : PFLobby.h
See also
PFLobby members
PFLobbyGetOwner
5/24/2022 • 2 minutes to read • Edit Online
Syntax
HRESULT PFLobbyGetOwner(
PFLobbyHandle lobby,
const PFEntityKey** owner
)
Parameters
lobby PFLobbyHandle
Remarks
If this lobby object was created by calling PFMultiplayerJoinLobby(), this method will return an error until
PFMultiplayerStartProcessingLobbyStateChanges() provides a PFLobbyUpdatedStateChange with
PFLobbyUpdatedStateChange::ownerUpdated set to true. If joining the lobby succeeds, this field is guaranteed to
be populated by the time PFMultiplayerStartProcessingLobbyStateChanges() provides a
PFLobbyJoinLobbyCompletedStateChange.
Requirements
Header : PFLobby.h
See also
PFLobby members
PFLobbyGetOwnerMigrationPolicy
5/24/2022 • 2 minutes to read • Edit Online
Syntax
HRESULT PFLobbyGetOwnerMigrationPolicy(
PFLobbyHandle lobby,
PFLobbyOwnerMigrationPolicy* ownerMigrationPolicy
)
Parameters
lobby PFLobbyHandle
Remarks
The owner migration policy cannot change for the lifetime of the lobby.
If this lobby object was created by calling PFMultiplayerJoinLobby(), this method will return an error until
PFMultiplayerStartProcessingLobbyStateChanges() provides a PFLobbyUpdatedStateChange with
PFLobbyUpdatedStateChange::ownerMigrationPolicy set to true. If joining the lobby succeeds, this field is
guaranteed to be populated by the time PFMultiplayerStartProcessingLobbyStateChanges() provides a
PFLobbyJoinLobbyCompletedStateChange.
Requirements
Header : PFLobby.h
See also
PFLobby members
PFLobbyGetSearchProperty
5/24/2022 • 2 minutes to read • Edit Online
Syntax
HRESULT PFLobbyGetSearchProperty(
PFLobbyHandle lobby,
const char* key,
const char** value
)
Parameters
lobby PFLobbyHandle
Remarks
Search properties are visible to non-members of the lobby as metadata which can be used to filter and sort
lobby search results.
If this lobby object is still in the process of asynchronously being created or joined via a call to
PFMultiplayerCreateAndJoinLobby() or PFMultiplayerJoinLobby(), this method will return no properties.
Requirements
Header : PFLobby.h
See also
PFLobby members
PFLobbyGetSearchPropertyKeys
5/24/2022 • 2 minutes to read • Edit Online
Syntax
HRESULT PFLobbyGetSearchPropertyKeys(
PFLobbyHandle lobby,
uint32_t* propertyCount,
const char* const** keys
)
Parameters
lobby PFLobbyHandle
Remarks
Search properties are visible to non-members of the lobby as metadata which can be used to filter and sort
lobby search results.
If this lobby object is still in the process of asynchronously being created or joined via a call to
PFMultiplayerCreateAndJoinLobby() or PFMultiplayerJoinLobby(), this method will return no keys.
Requirements
Header : PFLobby.h
See also
PFLobby members
PFLobbyLeave
5/24/2022 • 2 minutes to read • Edit Online
Syntax
HRESULT PFLobbyLeave(
PFLobbyHandle lobby,
const PFEntityKey* localUser,
void* asyncContext
)
Parameters
lobby PFLobbyHandle
Remarks
This method queues an asynchronous operation to remove one or all local users from the lobby. On completion,
a PFLobbyLeaveLobbyCompletedStateChange will be provided indicating that the operation has completed.
This method does not guarantee the leave will succeed. The operation may fail due to networking or service
errors. If the leave attempt fails but is retriable, the library will continue to retry the leave operation. Otherwise,
the local client will disconnect the requested local members from the lobby, but leave them as members. They
will remain as disconnected members until they rejoin.
Requirements
Header : PFLobby.h
See also
PFLobby members
PFLobbyPostUpdate
5/24/2022 • 2 minutes to read • Edit Online
Syntax
HRESULT PFLobbyPostUpdate(
PFLobbyHandle lobby,
const PFEntityKey* localUser,
const PFLobbyDataUpdate* lobbyUpdate,
const PFLobbyMemberDataUpdate* memberUpdate,
void* asyncContext
)
Parameters
lobby PFLobbyHandle
memberUpdate PFLobbyMemberDataUpdate*
optional
An optional update to apply to the portion of the lobby owned by localUser . If this is not provided,
lobbyUpdate must be provided.
asyncContext void*
optional
An optional, app-defined, pointer-sized context value that can be used to associate the completion state change
with this call.
Return value
Type: HRESULT
S_OK if the call succeeded or an error code otherwise. The human-readable form of the error code can be
retrieved via PFMultiplayerGetErrorMessage().
Remarks
This is an asynchronous operation. Upon successful completion, the title will be provided a
PFLobbyPostUpdateCompletedStateChange with the PFLobbyPostUpdateCompletedStateChange::result field set
to S_OK . Upon a failed completion, the title will be provided a PFLobbyPostUpdateCompletedStateChange with
the PFLobbyPostUpdateCompletedStateChange::result field set to a failure. If applying the update would change
the state of the lobby, the title will be provided a PFLobbyUpdatedStateChange sometime afterwards.
This operation completing successfully only indicates that the Lobby service has accepted the update. The title's
local view of the Lobby state will not reflect this update until a PFLobbyUpdatedStateChange is provided to the
title with the updated state.
The lobbyUpdate contains fields that can only be modified by the owner of the lobby. This method will return an
error if one of those fields is specified and localUser is not the owner of the lobby.
If both a lobbyUpdate and memberUpdate are supplied to this method on behalf of a single entity, both updates
will happen atomically.
Requirements
Header : PFLobby.h
See also
PFLobby members
PFLobbySendInvite
5/24/2022 • 2 minutes to read • Edit Online
Send an invite to this lobby from the local user to the invited entity.
Syntax
HRESULT PFLobbySendInvite(
PFLobbyHandle lobby,
const PFEntityKey* sender,
const PFEntityKey* invitee,
void* asyncContext
)
Parameters
lobby PFLobbyHandle
Remarks
This is an asynchronous operation. Upon successful completion, the title will be provided a
PFLobbySendInviteCompletedStateChange with the PFLobbySendInviteCompletedStateChange::result field set
to S_OK . Upon a failed completion, the title will be provided a PFLobbySendInviteCompletedStateChange with
the PFLobbySendInviteCompletedStateChange::result field set to a failure.
The sender must be a local user of this lobby which joined from this client.
Requirements
Header : PFLobby.h
See also
PFLobby members
PFLobbySetCustomContext
5/24/2022 • 2 minutes to read • Edit Online
Configures an optional, custom pointer-sized context value with this lobby object.
Syntax
HRESULT PFLobbySetCustomContext(
PFLobbyHandle lobby,
void* customContext
)
Parameters
lobby PFLobbyHandle
Remarks
The custom context is typically used as a "shortcut" that simplifies accessing local, title-specific memory
associated with the lobby without requiring a mapping lookup. The value is retrieved using the
PFLobbyGetCustomContext() method.
Any configured value is treated as opaque by the library, and is only valid on the local device; it is not
transmitted over the network.
Requirements
Header : PFLobby.h
See also
PFLobby members
PFLobbyGetCustomContext
PFMultiplayerCreateAndJoinLobby
5/24/2022 • 2 minutes to read • Edit Online
Create a new lobby and add the creating PlayFab entity to it.
Syntax
HRESULT PFMultiplayerCreateAndJoinLobby(
PFMultiplayerHandle handle,
const PFEntityKey* creator,
const PFLobbyCreateConfiguration* createConfiguration,
const PFLobbyJoinConfiguration* joinConfiguration,
void* asyncContext,
PFLobbyHandle* lobby
)
Parameters
handle PFMultiplayerHandle
Remarks
This is an asynchronous operation. Upon successful completion, the title will be provided a
PFLobbyMemberAddedStateChange followed by a PFLobbyCreateAndJoinLobbyCompletedStateChange with
the PFLobbyCreateAndJoinLobbyCompletedStateChange::result field set to S_OK . Upon a failed completion, the
title will be provided a PFLobbyCreateAndJoinLobbyCompletedStateChange with the
PFLobbyCreateAndJoinLobbyCompletedStateChange::result field set to a failure.
Requirements
Header : PFLobby.h
See also
PFLobby members
PFMultiplayerFindLobbies
5/24/2022 • 2 minutes to read • Edit Online
Syntax
HRESULT PFMultiplayerFindLobbies(
PFMultiplayerHandle handle,
const PFEntityKey* searchingEntity,
const PFLobbySearchConfiguration* searchConfiguration,
void* asyncContext
)
Parameters
handle PFMultiplayerHandle
Remarks
This is an asynchronous operation. Upon successful completion, the title will be provided a
PFLobbyFindLobbiesCompletedStateChange with the PFLobbyFindLobbiesCompletedStateChange::result field
set to S_OK . Upon a failed completion, the title will be provided a PFLobbyFindLobbiesCompletedStateChange
with the PFLobbyFindLobbiesCompletedStateChange::result field set to a failure.
Requirements
Header : PFLobby.h
See also
PFLobby members
PFMultiplayerFinishProcessingLobbyStateChanges
5/24/2022 • 2 minutes to read • Edit Online
Syntax
HRESULT PFMultiplayerFinishProcessingLobbyStateChanges(
PFMultiplayerHandle handle,
uint32_t stateChangeCount,
const PFLobbyStateChange* const* stateChanges
)
Parameters
handle PFMultiplayerHandle
Remarks
This method informs the Lobby library that the state changes reported by a previous call to
PFMultiplayerStartProcessingLobbyStateChanges() have now been handled by the title, so their associated
resources can be reclaimed. You may call PFMultiplayerFinishProcessingLobbyStateChanges() with any number
of state changes. Each state change returned by PFMultiplayerStartProcessingLobbyStateChanges() must be
returned to PFMultiplayerFinishProcessingLobbyStateChanges() exactly once, but may be returned out of order
and may be interleaved with state changes from other calls to
PFMultiplayerStartProcessingLobbyStateChanges().
Any resources associated with a specific state change are guaranteed to stay valid until the state change is
returned to PFMultiplayerFinishProcessingLobbyStateChanges().
For best results, you should minimize the time you spend handling state changes before calling
PFMultiplayerFinishProcessingLobbyStateChanges().
Requirements
Header : PFLobby.h
See also
PFLobby members
PFLobbyStateChange
PFMultiplayerStartProcessingLobbyStateChanges
PFMultiplayerGetLobbyInviteListenerStatus
5/24/2022 • 2 minutes to read • Edit Online
Syntax
HRESULT PFMultiplayerGetLobbyInviteListenerStatus(
PFMultiplayerHandle handle,
const PFEntityKey* listeningEntity,
PFLobbyInviteListenerStatus* status
)
Parameters
handle PFMultiplayerHandle
Remarks
This value is used to understand the state of an entity's invite listener. If the invite listener encounters a fatal
error, non-fatal error, or diagnostic change, the listener's status value will reflect it.
Requirements
Header : PFLobby.h
See also
PFLobby members
PFMultiplayerJoinArrangedLobby
5/24/2022 • 2 minutes to read • Edit Online
Joins a lobby using an arrangement string provided by another service, such as matchmaking. If no one has
joined the lobby yet, the lobby is initialized using the configuration parameters.
Syntax
HRESULT PFMultiplayerJoinArrangedLobby(
PFMultiplayerHandle handle,
const PFEntityKey* newMember,
const char* arrangementString,
const PFLobbyArrangedJoinConfiguration* configuration,
void* asyncContext,
PFLobbyHandle* lobby
)
Parameters
handle PFMultiplayerHandle
Remarks
This is an asynchronous operation. Upon successful completion, the title will be provided a
PFLobbyMemberAddedStateChange followed by a PFLobbyJoinArrangedLobbyCompletedStateChange with the
PFLobbyJoinArrangedLobbyCompletedStateChange::result field set to S_OK . Upon a failed completion, the title
will be provided a PFLobbyJoinArrangedLobbyCompletedStateChange with the
PFLobbyJoinArrangedLobbyCompletedStateChange::result field set to a failure.
Requirements
Header : PFLobby.h
See also
PFLobby members
PFMultiplayerJoinLobby
5/24/2022 • 2 minutes to read • Edit Online
Syntax
HRESULT PFMultiplayerJoinLobby(
PFMultiplayerHandle handle,
const PFEntityKey* newMember,
const char* connectionString,
const PFLobbyJoinConfiguration* configuration,
void* asyncContext,
PFLobbyHandle* lobby
)
Parameters
handle PFMultiplayerHandle
Remarks
This is an asynchronous operation. Upon successful completion, the title will be provided a
PFLobbyMemberAddedStateChange followed by a PFLobbyUpdatedStateChange and
PFLobbyJoinLobbyCompletedStateChange with the PFLobbyJoinLobbyCompletedStateChange::result field set to
S_OK . Upon a failed completion, the title will be provided a PFLobbyJoinLobbyCompletedStateChange with the
PFLobbyJoinLobbyCompletedStateChange::result field set to a failure.
Requirements
Header : PFLobby.h
See also
PFLobby members
PFMultiplayerStartListeningForLobbyInvites
5/24/2022 • 2 minutes to read • Edit Online
Syntax
HRESULT PFMultiplayerStartListeningForLobbyInvites(
PFMultiplayerHandle handle,
const PFEntityKey* listeningEntity
)
Parameters
handle PFMultiplayerHandle
Remarks
This operation will synchronously start listening for invites on behalf of the provided entity. When invites are
received, they will be provided via PFLobbyInviteReceivedStateChange structs. When the status of the invite
listener changes, notifications will be provided via PFLobbyInviteListenerStatusChangedStateChange structs.
Only invites sent after the listener has been started will be received on this client. Invites sent while this listener
is not active will not be queued.
Invite listening is, by default, disabled for all entities. This method should be called for each local entity that the
title wants to receive Lobby invites.
Lobby invites and this invite listener are unrelated to and unaffected by platform invite mechanisms.
This method may only be called if the Lobby invite listener is not already enabled for the given entity.
Requirements
Header : PFLobby.h
See also
PFLobby members
PFMultiplayerStartProcessingLobbyStateChanges
5/24/2022 • 2 minutes to read • Edit Online
Retrieves an array of all PFLobbyStateChanges to process since the last such call.
Syntax
HRESULT PFMultiplayerStartProcessingLobbyStateChanges(
PFMultiplayerHandle handle,
uint32_t* stateChangeCount,
const PFLobbyStateChange* const** stateChanges
)
Parameters
handle PFMultiplayerHandle
Remarks
This method provides the Lobby library an opportunity to synchronize state with remote devices or services,
and retrieves a list of all changes currently available for the title since the last call to this method. The title should
use the provided array of 0 or more changes to update its own state or UI, and then call
PFMultiplayerFinishProcessingLobbyStateChanges() with them in a timely manner.
Lobby library state exposed by the library can change during this call, so you must be thread-safe in your use of
it. For example, invoking PFMultiplayerStartProcessingLobbyStateChanges() on your UI thread at the same time
a separate worker thread is looping through the list of lobby members returned by PFLobbyGetMembers() may
result in crashes because PFMultiplayerStartProcessingLobbyStateChanges() can alter the memory associated
with the member list. PFMultiplayerStartProcessingLobbyStateChanges() should be called frequently-- at least
once per graphics frame. It's designed to execute and return quickly such that it can be called on your main UI
thread with negligible impact. For best results, you should also minimize the time you spend handling state
changes before calling PFMultiplayerFinishProcessingLobbyStateChanges().
Each state change returned by PFMultiplayerStartProcessingLobbyStateChanges() must be returned to
PFMultiplayerFinishProcessingLobbyStateChanges() exactly once, but may be returned out of order and may be
interleaved with state changes from other calls to PFMultiplayerStartProcessingLobbyStateChanges(). Any
resources associated with a specific state change are guaranteed to stay valid until the state change is returned
to PFMultiplayerFinishProcessingLobbyStateChanges().
Requirements
Header : PFLobby.h
See also
PFLobby members
PFLobbyStateChange
PFMultiplayerFinishProcessingLobbyStateChanges
PFMultiplayerStopListeningForLobbyInvites
5/24/2022 • 2 minutes to read • Edit Online
Syntax
HRESULT PFMultiplayerStopListeningForLobbyInvites(
PFMultiplayerHandle handle,
const PFEntityKey* listeningEntity
)
Parameters
handle PFMultiplayerHandle
Remarks
This operation will synchronously stop listening for invites on behalf of the provided entity.
Invite notifications which have already been queued internally will still be provided via the next call to
PFMultiplayerStartProcessingLobbyStateChanges().
Lobby invites and this invite listener are unrelated to and unaffected by platform invite mechanisms.
This method may only be called if the Lobby invite listener is already enabled for the given entity.
Requirements
Header : PFLobby.h
See also
PFLobby members
PFMatchmakingTicketCancel
5/24/2022 • 2 minutes to read • Edit Online
Syntax
HRESULT PFMatchmakingTicketCancel(
PFMatchmakingTicketHandle ticket
)
Parameters
ticket PFMatchmakingTicketHandle
Remarks
This method queues an asynchronous operation to cancel this matchmaking ticket. On success, a
PFMatchmakingTicketCompletedStateChange will be provided indicating that the ticket has been canceled.
This method does not guarantee the ticket will be canceled. The ticket may complete before the cancelation can
be processed, or the cancelation request may fail due to networking or service errors. If the cancelation attempt
fails but is retriable, the library will continue to retry the cancelation. Otherwise, a
PFMatchmakingTicketCompletedStateChange will be provided that indicates the ticket failed.
Requirements
Header : PFMatchmaking.h
See also
PFMatchmaking members
PFMatchmakingTicketGetMatch
5/24/2022 • 2 minutes to read • Edit Online
Syntax
HRESULT PFMatchmakingTicketGetMatch(
PFMatchmakingTicketHandle ticket,
const PFMatchmakingMatchDetails** match
)
Parameters
ticket PFMatchmakingTicketHandle
Remarks
This method will fail if the ticket isn't in the PFMatchmakingTicketStatus::Matched state. The ticket state can be
retrieved via PFMatchmakingTicketGetStatus.
Requirements
Header : PFMatchmaking.h
See also
PFMatchmaking members
PFMatchmakingTicketGetStatus
5/24/2022 • 2 minutes to read • Edit Online
Syntax
HRESULT PFMatchmakingTicketGetStatus(
PFMatchmakingTicketHandle ticket,
PFMatchmakingTicketStatus* status
)
Parameters
ticket PFMatchmakingTicketHandle
TBD
status PFMatchmakingTicketStatus*
output
The matchmaking ticket status.
Return value
Type: HRESULT
S_OK if the call succeeded or an error code otherwise. The human-readable form of the error code can be
retrieved via PFMultiplayerGetErrorMessage().
Requirements
Header : PFMatchmaking.h
See also
PFMatchmaking members
PFMatchmakingTicketGetTicketId
5/24/2022 • 2 minutes to read • Edit Online
Syntax
HRESULT PFMatchmakingTicketGetTicketId(
PFMatchmakingTicketHandle ticket,
const char** id
)
Parameters
ticket PFMatchmakingTicketHandle
Remarks
The ticket ID will be an empty string if the ticket is in the PFMatchmakingTicketStatus::Creating state or if the
ticket is in the PFMatchmakingTicketStatus::Failed state due to failure to submit a ticket to the matchmaking
service. The ticket state can be retrieved via PFMatchmakingTicketGetStatus.
Requirements
Header : PFMatchmaking.h
See also
PFMatchmaking members
PFMultiplayerCreateMatchmakingTicket
5/24/2022 • 2 minutes to read • Edit Online
Syntax
HRESULT PFMultiplayerCreateMatchmakingTicket(
PFMultiplayerHandle handle,
uint32_t localUserCount,
const PFEntityKey* localUsers,
const char* const* localUserAttributes,
const PFMatchmakingTicketConfiguration* configuration,
void* asyncContext,
PFMatchmakingTicketHandle* ticket
)
Parameters
handle PFMultiplayerHandle
The array of local user attribute strings. There should be one attribute string for each local user. Each attribute
string should either be an empty string or a serialized JSON object. For example,
{"player_color":"blue","player_role":"tank"} .
configuration PFMatchmakingTicketConfiguration*
The ticket configuration.
asyncContext void*
optional
An optional, app-defined, pointer-sized context value that can be used to associate the completion state change
with this call.
ticket PFMatchmakingTicketHandle*
library-allocated output
The resulting ticket object.
Return value
Type: HRESULT
S_OK if the call succeeded or an error code otherwise. The human-readable form of the error code can be
retrieved via PFMultiplayerGetErrorMessage().
Remarks
The library automatically, and asynchronously, will submit all local users on a ticket to the matchmaking service.
Each time the ticket status changes, a PFMatchmakingTicketStatusChangedStateChange will be provided. The
ticket status can be quered at any time via PFMatchmakingTicketGetStatus(). The ticket immediately starts in the
PFMatchmakingTicketStatus::Creating state.
All existing tickets in which a local user is a member will be canceled as part of this operation.
A match can't be found until all remote users specified in the membersToMatchWith field of the configuration
parameter have joined the ticket via PFMultiplayerJoinMatchmakingTicketFromId().
Requirements
Header : PFMatchmaking.h
See also
PFMatchmaking members
PFMultiplayerDestroyMatchmakingTicket
5/24/2022 • 2 minutes to read • Edit Online
Syntax
HRESULT PFMultiplayerDestroyMatchmakingTicket(
PFMultiplayerHandle handle,
PFMatchmakingTicketHandle ticket
)
Parameters
handle PFMultiplayerHandle
Remarks
This method destroys the matchmaking ticket and reclaims local resources associated with it. If the ticket has not
yet completed, a background operation will perform a single best-effort attempt to cancel the ticket with the
matchmaking service.
Requirements
Header : PFMatchmaking.h
See also
PFMatchmaking members
PFMultiplayerFinishProcessingMatchmakingStateChanges
5/24/2022 • 2 minutes to read • Edit Online
Syntax
HRESULT PFMultiplayerFinishProcessingMatchmakingStateChanges(
PFMultiplayerHandle handle,
uint32_t stateChangeCount,
const PFMatchmakingStateChange* const* stateChanges
)
Parameters
handle PFMultiplayerHandle
Remarks
This method informs the Matchmaking library that the state changes reported by a previous call to
PFMultiplayerStartProcessingMatchmakingStateChanges() have now been handled by the title, so their
associated resources can be reclaimed. You may call PFMultiplayerFinishProcessingMatchmakingStateChanges()
with any number of state changes. Each state change returned by
PFMultiplayerStartProcessingMatchmakingStateChanges() must be returned to
PFMultiplayerFinishProcessingMatchmakingStateChanges() exactly once, but may be returned out of order and
may be interleaved with state changes from other calls to
PFMultiplayerStartProcessingMatchmakingStateChanges().
Any resources associated with a specific state change are guaranteed to stay valid until the state change is
returned to PFMultiplayerFinishProcessingMatchmakingStateChanges().
For best results, you should minimize the time you spend handling state changes before calling
PFMultiplayerFinishProcessingMatchmakingStateChanges().
Requirements
Header : PFMatchmaking.h
See also
PFMatchmaking members
PFMatchmakingStateChange
PFMultiplayerStartProcessingMatchmakingStateChanges
PFMultiplayerJoinMatchmakingTicketFromId
5/24/2022 • 2 minutes to read • Edit Online
Joins one or more multiple local users to a matchmaking ticket using a ticket ID and queue name.
Syntax
HRESULT PFMultiplayerJoinMatchmakingTicketFromId(
PFMultiplayerHandle handle,
uint32_t localUserCount,
const PFEntityKey* localUsers,
const char* localUserAttributes,
const char* ticketId,
const char* queueName,
void* asyncContext,
PFMatchmakingTicketHandle* ticket
)
Parameters
handle PFMultiplayerHandle
The array of local user attribute strings. There should be one attribute string for each local user. Each attribute
string should either be an empty string or a serialized JSON object. For example,
{"player_color":"blue","player_role":"tank"} .
ticketId char*
is null-terminated
The ID of the ticket to join.
queueName char*
is null-terminated
The queue to which the ticket belongs.
asyncContext void*
optional
An optional, app-defined, pointer-sized context value that can be used to associate the completion state change
with this call.
ticket PFMatchmakingTicketHandle*
library-allocated output
The resulting ticket object.
Return value
Type: HRESULT
S_OK if the call succeeded or an error code otherwise. The human-readable form of the error code can be
retrieved via PFMultiplayerGetErrorMessage().
Remarks
The library automatically, and asynchronously, will submit all local users to join the ticket on the matchmaking
service. Each time the ticket status changes, a PFMatchmakingTicketStatusChangedStateChange will be
provided. The ticket status can be quered at any time via PFMatchmakingTicketGetStatus(). The ticket
immediately starts in the PFMatchmakingTicketStatus::Joining state.
All existing tickets in which a local user is a member will be canceled as part of this operation.
Requirements
Header : PFMatchmaking.h
See also
PFMatchmaking members
PFMultiplayerStartProcessingMatchmakingStateChanges
5/24/2022 • 2 minutes to read • Edit Online
Retrieves an array of all matchmaking state changes to process since the last such call.
Syntax
HRESULT PFMultiplayerStartProcessingMatchmakingStateChanges(
PFMultiplayerHandle handle,
uint32_t* stateChangeCount,
const PFMatchmakingStateChange* const** stateChanges
)
Parameters
handle PFMultiplayerHandle
Remarks
This method provides the Matchmaking library an opportunity to synchronize state with remote devices or
services, and retrieves a list of all changes currently available for the title since the last call to this method. The
title should use the provided array of 0 or more changes to update its own state or UI, and then call
PFMultiplayerFinishProcessingMatchmakingStateChanges() with them in a timely manner.
Matchmaking library state exposed by the library can change during this call, so you must be thread-safe in
your use of it. PFMultiplayerStartProcessingMatchmakingStateChanges() should be called frequently-- at least
once per graphics frame. It's designed to execute and return quickly such that it can be called on your main UI
thread with negligible impact. For best results, you should also minimize the time you spend handling state
changes before calling PFMultiplayerFinishProcessingMatchmakingStateChanges().
Requirements
Header : PFMatchmaking.h
See also
PFMatchmaking members
PFMatchmakingStateChange
PFMultiplayerFinishProcessingMatchmakingStateChanges
PFMultiplayerThreadId
5/24/2022 • 2 minutes to read • Edit Online
Syntax
enum class PFMultiplayerThreadId : uint32_t
{
Networking = 0,
}
Constants
C O N STA N T DESC RIP T IO N
Requirements
Header : PFMultiplayer.h
See also
PFMultiplayer members
PFMultiplayerSetThreadAffinityMask
PFLobbyAccessPolicy
5/24/2022 • 2 minutes to read • Edit Online
Syntax
enum class PFLobbyAccessPolicy : uint32_t
{
Public = 0,
Friends = 1,
Private = 2,
}
Constants
C O N STA N T DESC RIP T IO N
Public The lobby is both visible in queries and any player may join,
including invited players.
Friends The lobby and its connection string are queryable by friends
of members in this lobby.
Private The lobby is not visible in queries, and a player must receive
an invite to join.
Remarks
The access policy controls whether this lobby's connection string is accessible in search queries.
Requirements
Header : PFLobby.h
See also
PFLobby members
PFLobbyDisconnectingReason
5/24/2022 • 2 minutes to read • Edit Online
Syntax
enum class PFLobbyDisconnectingReason : uint32_t
{
NoLocalMembers = 0,
LobbyDeleted = 1,
ConnectionInterruption = 2,
}
Constants
C O N STA N T DESC RIP T IO N
LobbyDeleted The client is being disconnected from the lobby because the
lobby's server owner has deleted the lobby.
ConnectionInterruption The client is being disconnected from the lobby because the
client has lost connection.
Requirements
Header : PFLobby.h
See also
PFLobby members
PFLobbyInviteListenerStatus
5/24/2022 • 2 minutes to read • Edit Online
Syntax
enum class PFLobbyInviteListenerStatus : uint32_t
{
NotListening = 0,
Listening = 1,
NotAuthorized = 2,
}
Constants
C O N STA N T DESC RIP T IO N
NotListening The invite listener has not been started or has been stopped
and is not listening for invites.
Listening The invite listener has been established and is listening for
invites.
This status is fatal. The title should clear the invite listener
with PFMultiplayerStopListeningForLobbyInvites. No invites
will be received on the corresponding listener after this
status update.
Requirements
Header : PFLobby.h
See also
PFLobby members
PFLobbyMemberRemovedReason
5/24/2022 • 2 minutes to read • Edit Online
Syntax
enum class PFLobbyMemberRemovedReason : uint32_t
{
LocalUserLeftLobby = 0,
LocalUserForciblyRemoved = 1,
RemoteUserLeftLobby = 2,
}
Constants
C O N STA N T DESC RIP T IO N
LocalUserLeftLobby The local user is being removed because the title called
PFLobbyLeave().
LocalUserForciblyRemoved The local user entity was forcibly removed by the owner.
RemoteUserLeftLobby The remote user has been removed from the lobby. It is
unspecified whether they left voluntarily or if they were
forcibly removed by the owner.
Requirements
Header : PFLobby.h
See also
PFLobby members
PFLobbyMembershipLock
5/24/2022 • 2 minutes to read • Edit Online
Syntax
enum class PFLobbyMembershipLock : uint32_t
{
Unlocked = 0,
Locked = 1,
}
Constants
C O N STA N T DESC RIP T IO N
Requirements
Header : PFLobby.h
See also
PFLobby members
PFLobbyOwnerMigrationPolicy
5/24/2022 • 2 minutes to read • Edit Online
The available policies the lobby service can use to migrate lobby ownership between members.
Syntax
enum class PFLobbyOwnerMigrationPolicy : uint32_t
{
Automatic = 0,
Manual = 1,
None = 2,
Server = 3,
}
Constants
C O N STA N T DESC RIP T IO N
None At any point, any member may elect themselves the owner
of the lobby, regardless of the state of the current owner.
Server The server is the owner and owner migration is not possible.
Requirements
Header : PFLobby.h
See also
PFLobby members
PFLobbyStateChangeType
5/24/2022 • 2 minutes to read • Edit Online
Syntax
enum class PFLobbyStateChangeType : uint32_t
{
CreateAndJoinLobbyCompleted = 0,
JoinLobbyCompleted = 1,
MemberAdded = 2,
AddMemberCompleted = 3,
MemberRemoved = 4,
ForceRemoveMemberCompleted = 5,
LeaveLobbyCompleted = 6,
Updated = 7,
PostUpdateCompleted = 8,
Disconnecting = 9,
Disconnected = 10,
JoinArrangedLobbyCompleted = 11,
FindLobbiesCompleted = 12,
InviteReceived = 13,
InviteListenerStatusChanged = 14,
SendInviteCompleted = 15,
}
Constants
C O N STA N T DESC RIP T IO N
Requirements
Header : PFLobby.h
See also
PFLobby members
PFMatchmakingStateChangeType
5/24/2022 • 2 minutes to read • Edit Online
Syntax
enum class PFMatchmakingStateChangeType : uint32_t
{
TicketStatusChanged = 0,
TicketCompleted = 1,
}
Constants
C O N STA N T DESC RIP T IO N
Requirements
Header : PFMatchmaking.h
See also
PFMatchmaking members
PFMatchmakingTicketStatus
5/24/2022 • 2 minutes to read • Edit Online
Syntax
enum class PFMatchmakingTicketStatus : uint32_t
{
Creating = 0,
Joining = 1,
WaitingForPlayers = 2,
WaitingForMatch = 3,
Matched = 4,
Canceled = 5,
Failed = 6,
}
Constants
C O N STA N T DESC RIP T IO N
Requirements
Header : PFMatchmaking.h
See also
PFMatchmaking members
PFLobbyArrangedJoinConfiguration
5/24/2022 • 2 minutes to read • Edit Online
Syntax
struct PFLobbyArrangedJoinConfiguration {
uint32_t maxMemberCount;
PFLobbyOwnerMigrationPolicy ownerMigrationPolicy;
PFLobbyAccessPolicy accessPolicy;
uint32_t memberPropertyCount;
const char* const* memberPropertyKeys;
const char* const* memberPropertyValues;
}
Members
maxMemberCount uint32_t
The maximum number of members allowed in the lobby, if joiner is the first member in the lobby.
This value must be at least PFLobbyMaxMemberCountLowerLimit and no more than
PFLobbyMaxMemberCountUpperLimit .
If a client would violate this limit by calling PFMultiplayerJoinLobby() or PFLobbyAddMember, the operation will
fail asynchronously.
ownerMigrationPolicy PFLobbyOwnerMigrationPolicy
The owner migration policy for the lobby, if the joiner is the first member in the lobby.
This value cannot be set to PFLobbyOwnerMigrationPolicy::Server .
accessPolicy PFLobbyAccessPolicy
The access policy for the lobby, if the joiner is the first member in the lobby.
memberPropertyCount uint32_t
The number of initial member properties for the joiner of the lobby.
memberPropertyKeys const char* const*
array of size memberPropertyCount
The keys of the initial member properties for the joiner of the lobby.
Per-member properties are only visible to members of the lobby.
memberPropertyValues const char* const*
array of size memberPropertyCount
The values of the initial member properties for the joiner of the lobby.
Per-member properties are only visible to members of the lobby.
Requirements
Header : PFLobby.h
See also
PFLobby members
PFLobbyCreateConfiguration
5/24/2022 • 2 minutes to read • Edit Online
Syntax
struct PFLobbyCreateConfiguration {
uint32_t maxMemberCount;
PFLobbyOwnerMigrationPolicy ownerMigrationPolicy;
PFLobbyAccessPolicy accessPolicy;
uint32_t searchPropertyCount;
const char* const* searchPropertyKeys;
const char* const* searchPropertyValues;
uint32_t lobbyPropertyCount;
const char* const* lobbyPropertyKeys;
const char* const* lobbyPropertyValues;
}
Members
maxMemberCount uint32_t
The maximum number of members allowed in the new lobby.
This value must be at least PFLobbyMaxMemberCountLowerLimit and no more than
PFLobbyMaxMemberCountUpperLimit .
If a client would violate this limit by calling PFMultiplayerJoinLobby() or PFLobbyAddMember, the operation will
fail asynchronously.
ownerMigrationPolicy PFLobbyOwnerMigrationPolicy
The owner migration policy for the new lobby.
This value cannot be set to PFLobbyOwnerMigrationPolicy::Server .
accessPolicy PFLobbyAccessPolicy
The access policy for the new lobby.
searchPropertyCount uint32_t
The number of initial search properties for the new lobby.
searchPropertyKeys const char* const*
array of size searchPropertyCount
The keys of the initial search properties for the new lobby.
Search properties are visible to non-members of the lobby as metadata which can be used to filter and sort
lobby search results.
Search properties must be of the form string_keyN or number_keyN where "N" is a number between 1 and
PFLobbyMaxSearchPropertyCount . e.g. string_key1, number_key14, etc.
searchPropertyValues const char* const*
array of size searchPropertyCount
The values of the initial search properties for the new lobby.
Search properties are visible to non-members of the lobby as metadata which can be used to filter and sort
lobby search results.
lobbyPropertyCount uint32_t
The number of initial lobby properties for the new lobby.
lobbyPropertyKeys const char* const*
array of size lobbyPropertyCount
The keys of the initial lobby properties for the new lobby.
Lobby properties are only visible to members of the lobby.
lobbyPropertyValues const char* const*
array of size lobbyPropertyCount
The values of the initial lobby properties for the new lobby.
Lobby properties are only visible to members of the lobby.
Requirements
Header : PFLobby.h
See also
PFLobby members
PFLobbyDataUpdate
5/24/2022 • 3 minutes to read • Edit Online
A request to make an update to the shared portion of the lobby on behalf of a member.
Syntax
struct PFLobbyDataUpdate {
const PFEntityKey* newOwner;
const uint32_t* maxMemberCount;
const PFLobbyAccessPolicy* accessPolicy;
const PFLobbyMembershipLock* membershipLock;
uint32_t searchPropertyCount;
const char* const* searchPropertyKeys;
const char* const* searchPropertyValues;
uint32_t lobbyPropertyCount;
const char* const* lobbyPropertyKeys;
const char* const* lobbyPropertyValues;
}
Members
newOwner const PFEntityKey*
may be nullptr
An optional, new owner of the lobby.
This value can only be updated under one of the following conditions:
The member updating this field is the lobby's current owner
The owner migration policy is PFLobbyOwnerMigrationPolicy::Manual and there is currently no owner
The owner migration policy is PFLobbyOwnerMigrationPolicy::None
maxMemberCount const uint32_t*
may be nullptr
An optional, updated capacity for the number of members in this lobby.
This new value must be greater than than the number of members currently in the lobby and less than
PFLobbyMaxMemberCountUpperLimit .
There may only be PFLobbyMaxSearchPropertyCount concurrent search properties at any given time. Therefore, at
most, twice that many unique properties can be specified in this update if half of those properties are being
deleted.
If the property limits are violated, the entire update operation will fail.
searchPropertyKeys const char* const*
array of size searchPropertyCount
Search properties are visible to non-members of the lobby as metadata which can be used to filter and sort
lobby search results.
Only the properties specified in this list of keys will be updated. If the key doesn't exist yet, the property will be
created. If the new property value is nullptr, the property will be deleted. Any existing properties omitted from
this list will be left unmodified.
Search properties must be of the form string_keyN or number_keyN where "N" is a number between 1 and
PFLobbyMaxSearchPropertyCount . e.g. string_key1, number_key14, etc.
Search properties are visible to non-members of the lobby as metadata which can be used to filter and sort
lobby search results.
There may only be PFLobbyMaxLobbyPropertyCount concurrent lobby properties at any given time. Therefore, at
most, twice that many unique properties can be specified in this update if half of those properties are being
deleted.
If the property limits are violated, the entire update operation will fail.
lobbyPropertyKeys const char* const*
array of size lobbyPropertyCount
The keys of the lobby properties to update.
Only the current lobby owner can update the lobby properties.
Only the properties specified in this list of keys will be updated. If the key doesn't exist yet, the property will be
created. If the new property value is nullptr, the property will be deleted. Any existing properties omitted from
this list will be left unmodified.
lobbyPropertyValues const char* const*
array of size lobbyPropertyCount
Requirements
Header : PFLobby.h
See also
PFLobby members
PFLobbyJoinConfiguration
5/24/2022 • 2 minutes to read • Edit Online
Syntax
struct PFLobbyJoinConfiguration {
uint32_t memberPropertyCount;
const char* const* memberPropertyKeys;
const char* const* memberPropertyValues;
}
Members
memberPropertyCount uint32_t
The number of initial member properties for the joiner of the lobby.
memberPropertyKeys const char* const*
array of size memberPropertyCount
The keys of the initial member properties for the joiner of the lobby.
Per-member properties are only visible to members of the lobby.
memberPropertyValues const char* const*
array of size memberPropertyCount
The values of the initial member properties for the joiner of the lobby.
Per-member properties are only visible to members of the lobby.
Requirements
Header : PFLobby.h
See also
PFLobby members
PFLobbyMemberDataUpdate
5/24/2022 • 2 minutes to read • Edit Online
Syntax
struct PFLobbyMemberDataUpdate {
uint32_t memberPropertyCount;
const char* const* memberPropertyKeys;
const char* const* memberPropertyValues;
}
Members
memberPropertyCount uint32_t
The number of member properties to update for the updating member.
There may only be PFLobbyMaxMemberPropertyCount concurrent properties at any given time per-member.
Therefore, at most, twice that many unique properties can be specified in this update if half of those properties
are being deleted.
If the property limits are violated, the entire update operation will fail.
memberPropertyKeys const char* const*
array of size memberPropertyCount
The keys of the member properties to update for the updating member.
Per-member properties are only visible to members of the lobby.
Only the properties specified in this list of keys will be updated. If the key doesn't exist yet, the property will be
created. If the new property value is nullptr, the property will be deleted. Any existing properties omitted from
this list will be left unmodified.
memberPropertyValues const char* const*
array of size memberPropertyCount
The values of the member properties to update for the updating member.
Per-member properties are only visible to members of the lobby.
Requirements
Header : PFLobby.h
See also
PFLobby members
PFLobbyMemberUpdateSummary
5/24/2022 • 2 minutes to read • Edit Online
A collection of hints about an update which has been successfully applied to the lobby on behalf of a member.
Syntax
struct PFLobbyMemberUpdateSummary {
PFEntityKey member;
bool connectionStatusUpdated;
uint32_t updatedMemberPropertyCount;
const char* const* updatedMemberPropertyKeys;
}
Members
member PFEntityKey
The keys of the member properties which have been updated for member .
Requirements
Header : PFLobby.h
See also
PFLobby members
PFLobbySearchConfiguration
5/24/2022 • 2 minutes to read • Edit Online
The configuration structure used to specify how a PFMultiplayerFindLobbies operation should be performed.
Syntax
struct PFLobbySearchConfiguration {
const PFLobbySearchFriendsFilter* friendsFilter;
const char* filterString;
const char* sortString;
const uint32_t* clientSearchResultCount;
}
Members
friendsFilter const PFLobbySearchFriendsFilter*
may be nullptr
A filter that, when provided, will constrain the lobby search operation to only those owned by the members of
that player's various friend lists.
If omitted, the search operation will search all available lobbies.
filterString const char*
is null-terminated
The query string used to filter which lobbies are returned in the search results.
This string is formatted in an OData-like filtering syntax.
Only the following operators are supported: "and" (logical and), "eq" (equal), "ne" (not equals), "ge" (greater than
or equal), "gt" (greater than), "le" (less than or equal), and "lt" (less than).
The left-hand side of each OData logical expression should be either a search property key (e.g. string_key1,
number_key3, etc) or one of the pre-defined search keys ( PFLobbyMemberCountSearchKey or
PFLobbyAmMemberSearchKey ).
The left-hand side of each OData logical expression should be a search property key.
To specify ascending order, use the "asc" operator after the associated search property key. To specify
descending order, use the "desc" operator after the associated search property key.
Additionally, a special sorting moniker, distance, is supported to enable sorting by closest distance from some
numeric value. For example, "distance{number_key10=5} asc" will sort the results so that lobbies who have their
"number_key10" search property closer to the value "5" will return earlier in the search results.
When not specified, the limit on the number of search results is service-defined but will be no greater than
PFLobbyClientRequestedSearchResultCountUpperLimit .
Requirements
Header : PFLobby.h
See also
PFLobby members
PFLobbySearchFriendsFilter
5/24/2022 • 2 minutes to read • Edit Online
The filter structure used to limit lobby search results to only those lobbies owned by the player's friends.
Syntax
struct PFLobbySearchFriendsFilter {
bool includeSteamFriends;
bool includeFacebookFriends;
const char* includeXboxFriendsToken;
}
Members
includeSteamFriends bool
A flag which includes the player's Steam friends list if their PlayFab account is linked to their Steam account.
includeFacebookFriends bool
A flag which includes the player's Facebook friends list if their PlayFab account is linked to their Facebook
account.
includeXboxFriendsToken const char*
is null-terminated
An Xbox Live token that, when provided, includes the player's Xbox Live friends list if their PlayFab account is
linked to their Xbox Live account.
To retrieve this token, make a POST request to "https://playfabapi.com" with an empty request body using one
of the GetTokenAndSignature APIs provided by Xbox Live.
GetTokenAndSignature APIs are provided natively as part of the Microsoft Game Core Development Kit (GDK).
On all other platforms, these APIs are provided via the Xbox Authentication Library API (XAL).
Remarks
Regardless of which external friend lists are included when constructing this filter, friends from the PlayFab
friends list will always be included.
Requirements
Header : PFLobby.h
See also
PFLobby members
PFLobbySearchResult
5/24/2022 • 2 minutes to read • Edit Online
An entry in the collection of lobby search results received upon successful completion of a
PFMultiplayerFindLobbies operation.
Syntax
struct PFLobbySearchResult {
const char* lobbyId;
const char* connectionString;
const PFEntityKey* ownerEntity;
uint32_t maxMemberCount;
uint32_t currentMemberCount;
uint32_t searchPropertyCount;
const char* const* searchPropertyKeys;
const char* const* searchPropertyValues;
uint32_t friendCount;
const PFEntityKey* friends;
}
Members
lobbyId const char*
is null-terminated
The ID of the found lobby.
connectionString const char*
is null-terminated
The connection string of the found lobby.
connectionString can be null. In this case, an invite is required to join.
ownerEntity const PFEntityKey*
may be nullptr
The current owner of the lobby.
ownerEntity may be null if the lobby doesn't currently have an owner.
maxMemberCount uint32_t
The maximum number of members that can be present in this lobby.
currentMemberCount uint32_t
The current number of members that are present in this lobby.
searchPropertyCount uint32_t
The number of search properties associated with this lobby.
searchPropertyKeys const char* const*
array of size searchPropertyCount
The keys of the search properties associated with this lobby.
searchPropertyValues const char* const*
array of size searchPropertyCount
In some multiplayer social networks, friendship is a unidirectional relationship. One user may "follow" another
or be their friend, but the same is not necessarily true in the reverse direction. Friends will only be returned in
this search result when a bidirectional friendship exists. That is, the user querying for the lobby and the user in
the lobby must both be friends with each other.
friends const PFEntityKey*
array of size friendCount
The list of friends in the found lobby, if the lobby search was performed with a PFLobbySearchFriendsFilter .
If the lobby search which generated this search result was not performed with a PFLobbySearchFriendsFilter ,
this list will always be empty.
In some multiplayer social networks, friendship is a unidirectional relationship. One user may "follow" another
or be their friend, but the same is not necessarily true in the reverse direction. Friends will only be returned in
this search result when a bidirectional friendship exists. That is, the user querying for the lobby and the user in
the lobby must both be friends with each other.
Requirements
Header : PFLobby.h
See also
PFLobby members
PFMatchmakingMatchDetails
5/24/2022 • 2 minutes to read • Edit Online
Syntax
struct PFMatchmakingMatchDetails {
const char* matchId;
const PFMatchmakingMatchMember* members;
uint32_t memberCount;
const char* const* regionPreferences;
uint32_t regionPreferenceCount;
const char* lobbyArrangementString;
}
Members
matchId const char*
is null-terminated
The ID of the match.
members const PFMatchmakingMatchMember*
The users that have been matched together.
memberCount uint32_t
The count of members that have been matched together.
regionPreferences const char* const*
Preferred regions for the match, sorted from most to least preferred.
regionPreferenceCount uint32_t
The count of preferred regions for the match.
lobbyArrangementString const char*
is null-terminated
The lobby arrangement string associated with the match.
This connection string can optionally be used with PFMultiplayerJoinArrangedLobby() to join a lobby associated
with this match result. The lobby is not created until a user attempts to join it.
Requirements
Header : PFMatchmaking.h
See also
PFMatchmaking members
PFMatchmakingMatchMember
5/24/2022 • 2 minutes to read • Edit Online
Syntax
struct PFMatchmakingMatchMember {
PFEntityKey entityKey;
const char* teamId;
const char* attributes;
}
Members
entityKey PFEntityKey
The Entity Key for this match member.
teamId const char*
is null-terminated
The team ID assigned to this match member.
May be empty if the matchmaking queue doesn't use team rules.
attributes const char*
is null-terminated
The attributes for this user in serialized JSON format.
Requirements
Header : PFMatchmaking.h
See also
PFMatchmaking members
PFMatchmakingTicketConfiguration
5/24/2022 • 2 minutes to read • Edit Online
Syntax
struct PFMatchmakingTicketConfiguration {
uint32_t timeoutInSeconds;
const char* queueName;
uint32_t membersToMatchWithCount;
const PFEntityKey* membersToMatchWith;
}
Members
timeoutInSeconds uint32_t
How long to attempt matchmaking the ticket, in seconds.
queueName const char*
is null-terminated
The ID of a match queue.
membersToMatchWithCount uint32_t
The number of other specific users expected to join the ticket.
membersToMatchWith const PFEntityKey*
array of size membersToMatchWithCount
The PlayFab Entity Keys of other specific users expected to join the ticket.
This field specifies the number of other specific users expected to join the ticket. Typically this list represents a
group of friends or fireteam that are looking for a match together. A match can't be found until all specified
users join the ticket via PFMultiplayerJoinMatchmakingTicketFromId.
Requirements
Header : PFMatchmaking.h
See also
PFMatchmaking members
PFLobbyAddMemberCompletedStateChange
5/24/2022 • 2 minutes to read • Edit Online
Syntax
struct PFLobbyAddMemberCompletedStateChange : PFLobbyStateChange {
HRESULT result;
PFLobbyHandle lobby;
PFEntityKey localUser;
void* asyncContext;
}
Members
result HRESULT
Requirements
Header : PFLobby.h
See also
PFLobby members
PFLobbyCreateAndJoinLobbyCompletedStateChange
5/24/2022 • 2 minutes to read • Edit Online
Syntax
struct PFLobbyCreateAndJoinLobbyCompletedStateChange : PFLobbyStateChange {
HRESULT result;
void* asyncContext;
PFLobbyHandle lobby;
}
Members
result HRESULT
Requirements
Header : PFLobby.h
See also
PFLobby members
PFLobbyDisconnectedStateChange
5/24/2022 • 2 minutes to read • Edit Online
Syntax
struct PFLobbyDisconnectedStateChange : PFLobbyStateChange {
PFLobbyHandle lobby;
}
Members
lobby PFLobbyHandle
must not be null
The lobby that has disconnected.
Remarks
This state change signals that the lobby has completed disconnecting. This is the last state change that will be
provided for this lobby object. Once this state change is returned to
PFMultiplayerFinishProcessingLobbyStateChanges(), the Lobby object memory will become invalid.
Requirements
Header : PFLobby.h
See also
PFLobby members
PFLobbyDisconnectingStateChange
5/24/2022 • 2 minutes to read • Edit Online
Syntax
struct PFLobbyDisconnectingStateChange : PFLobbyStateChange {
PFLobbyHandle lobby;
PFLobbyDisconnectingReason reason;
}
Members
lobby PFLobbyHandle
must not be null
The lobby that has started disconnecting.
reason PFLobbyDisconnectingReason
The reason the lobby started disconnecting.
Remarks
This state change signals that the lobby is in the process of disconnecting because there are no local members
actively connected or attempting to reconnect to the lobby. At the point when this state change is provided by
PFMultiplayerStartProcessingLobbyStateChanges(), some operations which require a connected lobby object
will begin to fail such as PFLobbyAddMember.
Requirements
Header : PFLobby.h
See also
PFLobby members
PFLobbyFindLobbiesCompletedStateChange
5/24/2022 • 2 minutes to read • Edit Online
Syntax
struct PFLobbyFindLobbiesCompletedStateChange : PFLobbyStateChange {
HRESULT result;
PFEntityKey searchingEntity;
void* asyncContext;
uint32_t searchResultCount;
const PFLobbySearchResult* searchResults;
}
Members
result HRESULT
Requirements
Header : PFLobby.h
See also
PFLobby members
PFLobbyForceRemoveMemberCompletedStateChange
5/24/2022 • 2 minutes to read • Edit Online
Syntax
struct PFLobbyForceRemoveMemberCompletedStateChange : PFLobbyStateChange {
HRESULT result;
PFLobbyHandle lobby;
PFEntityKey targetMember;
void* asyncContext;
}
Members
result HRESULT
Requirements
Header : PFLobby.h
See also
PFLobby members
PFLobbyInviteListenerStatusChangedStateChange
5/24/2022 • 2 minutes to read • Edit Online
Syntax
struct PFLobbyInviteListenerStatusChangedStateChange : PFLobbyStateChange {
PFEntityKey listeningEntity;
}
Members
listeningEntity PFEntityKey
The entity associated with the invite listener.
Requirements
Header : PFLobby.h
See also
PFLobby members
PFLobbyInviteReceivedStateChange
5/24/2022 • 2 minutes to read • Edit Online
Syntax
struct PFLobbyInviteReceivedStateChange : PFLobbyStateChange {
PFEntityKey listeningEntity;
PFEntityKey invitingEntity;
const char* connectionString;
}
Members
listeningEntity PFEntityKey
The entity which is listening for invites and which has been invited.
invitingEntity PFEntityKey
The entity which has invited the listeningEntity to a lobby.
connectionString const char*
is null-terminated
The connection string of the lobby to which the listeningEntity has been invited.
Requirements
Header : PFLobby.h
See also
PFLobby members
PFLobbyJoinArrangedLobbyCompletedStateChange
5/24/2022 • 2 minutes to read • Edit Online
Syntax
struct PFLobbyJoinArrangedLobbyCompletedStateChange : PFLobbyStateChange {
HRESULT result;
PFEntityKey newMember;
void* asyncContext;
PFLobbyHandle lobby;
}
Members
result HRESULT
Requirements
Header : PFLobby.h
See also
PFLobby members
PFLobbyJoinLobbyCompletedStateChange
5/24/2022 • 2 minutes to read • Edit Online
Syntax
struct PFLobbyJoinLobbyCompletedStateChange : PFLobbyStateChange {
HRESULT result;
PFEntityKey newMember;
void* asyncContext;
PFLobbyHandle lobby;
}
Members
result HRESULT
Requirements
Header : PFLobby.h
See also
PFLobby members
PFLobbyLeaveLobbyCompletedStateChange
5/24/2022 • 2 minutes to read • Edit Online
Syntax
struct PFLobbyLeaveLobbyCompletedStateChange : PFLobbyStateChange {
PFLobbyHandle lobby;
const PFEntityKey* localUser;
void* asyncContext;
}
Members
lobby PFLobbyHandle
must not be null
The lobby provided to the call associated with this state change.
localUser const PFEntityKey*
may be nullptr
The local user provided to the call associated with this state change. May be null.
If this value is null it signifies that the title requested all local members leave the specified lobby.
asyncContext void*
The async context provided to the call associated with this state change.
Requirements
Header : PFLobby.h
See also
PFLobby members
PFLobbyMemberAddedStateChange
5/24/2022 • 2 minutes to read • Edit Online
Syntax
struct PFLobbyMemberAddedStateChange : PFLobbyStateChange {
PFLobbyHandle lobby;
PFEntityKey member;
}
Members
lobby PFLobbyHandle
must not be null
The lobby the new member was added to.
member PFEntityKey
The PlayFab entity which is now a member of the lobby.
Remarks
This state change will be generated by all operations which add members to lobbies such as
PFMultiplayerCreateAndJoinLobby, PFMultiplayerJoinLobby, and PFLobbyAddMember.
When this state change is provided by PFMultiplayerStartProcessingLobbyStateChanges the lobby will update to
reflect the new member in the member list and the member's initial properties will become queryable.
Requirements
Header : PFLobby.h
See also
PFLobby members
PFLobbyMemberRemovedStateChange
5/24/2022 • 2 minutes to read • Edit Online
Syntax
struct PFLobbyMemberRemovedStateChange : PFLobbyStateChange {
PFLobbyHandle lobby;
PFEntityKey member;
PFLobbyMemberRemovedReason reason;
}
Members
lobby PFLobbyHandle
must not be null
The lobby the new member was removed from.
member PFEntityKey
The member entity which has been removed from the lobby.
reason PFLobbyMemberRemovedReason
The reason member was removed from the lobby.
Remarks
This state change will be generated by all operations which remove members from lobbies such as
PFLobbyLeave() and PFLobbyForceRemoveMember().
When this state change is provided by PFMultiplayerStartProcessingLobbyStateChanges the lobby will update to
remove this member from the member list and the member's properties will be emptied.
Requirements
Header : PFLobby.h
See also
PFLobby members
PFLobbyPostUpdateCompletedStateChange
5/24/2022 • 2 minutes to read • Edit Online
Syntax
struct PFLobbyPostUpdateCompletedStateChange : PFLobbyStateChange {
HRESULT result;
PFLobbyHandle lobby;
PFEntityKey localUser;
void* asyncContext;
}
Members
result HRESULT
Requirements
Header : PFLobby.h
See also
PFLobby members
PFLobbySendInviteCompletedStateChange
5/24/2022 • 2 minutes to read • Edit Online
Syntax
struct PFLobbySendInviteCompletedStateChange : PFLobbyStateChange {
HRESULT result;
PFLobbyHandle lobby;
PFEntityKey sender;
PFEntityKey invitee;
void* asyncContext;
}
Members
result HRESULT
Requirements
Header : PFLobby.h
See also
PFLobby members
PFLobbyStateChange
5/24/2022 • 2 minutes to read • Edit Online
Syntax
struct PFLobbyStateChange {
PFLobbyStateChangeType stateChangeType;
}
Members
stateChangeType PFLobbyStateChangeType
The specific type of the state change represented.
Use this field to determine which corresponding derived structure is represented by this PFLobbyStateChange
structure header.
Remarks
PFLobbyStateChange structures are reported by PFMultiplayerStartProcessingLobbyStateChanges() for the title
to handle and then promptly pass back via the PFMultiplayerFinishProcessingLobbyStateChanges() method.
The stateChangeType field indicates which kind of state change occurred, and this base structure should then be
cast to a more specific derived structure to retrieve additional event-specific information.
Requirements
Header : PFLobby.h
See also
PFLobby members
PFMultiplayerStartProcessingLobbyStateChanges
PFMultiplayerFinishProcessingLobbyStateChanges
PFLobbyUpdatedStateChange
5/24/2022 • 2 minutes to read • Edit Online
Syntax
struct PFLobbyUpdatedStateChange : PFLobbyStateChange {
PFLobbyHandle lobby;
bool ownerUpdated;
bool maxMembersUpdated;
bool accessPolicyUpdated;
bool membershipLockUpdated;
uint32_t updatedSearchPropertyCount;
const char* const* updatedSearchPropertyKeys;
uint32_t updatedLobbyPropertyCount;
const char* const* updatedLobbyPropertyKeys;
uint32_t memberUpdateCount;
const PFLobbyMemberUpdateSummary* memberUpdates;
}
Members
lobby PFLobbyHandle
must not be null
The lobby which was updated.
ownerUpdated bool
A flag indicating if the lobby's owner was updated.
maxMembersUpdated bool
A flag indicating if the maxmimum number of members allowed in the lobby has been updated.
accessPolicyUpdated bool
A flag indicating if the lobby's access policy was updated.
membershipLockUpdated bool
A flag indicating if the lobby's membership lock has updated.
updatedSearchPropertyCount uint32_t
The number of search properties which have been updated.
updatedSearchPropertyKeys const char* const*
array of size updatedSearchPropertyCount
Remarks
This state change signifies that the lobby has updated and provides hints as to which values have changed.
Multiple updates may be provided by a single call to PFMultiplayerStartProcessingLobbyStateChanges(). All
state reflected by these updates will become available simultaneously when
PFMultiplayerStartProcessingLobbyStateChanges() is called, so the updates can be reconciled either individually
or as a batch.
Requirements
Header : PFLobby.h
See also
PFLobby members
PFMatchmakingStateChange
5/24/2022 • 2 minutes to read • Edit Online
Syntax
struct PFMatchmakingStateChange {
PFMatchmakingStateChangeType stateChangeType;
}
Members
stateChangeType PFMatchmakingStateChangeType
The specific type of the state change represented.
Use this field to determine which corresponding derived structure is represented by this
PFMatchmakingStateChange structure header.
Remarks
PFMatchmakingStateChange structures are reported by
PFMultiplayerStartProcessingMatchmakingStateChanges() for the title to handle and then promptly pass back
via the PFMultiplayerFinishProcessingMatchmakingStateChanges() method.
The stateChangeType field indicates which kind of state change occurred, and this base structure should then be
cast to a more specific derived structure to retrieve additional event-specific information.
Requirements
Header : PFMatchmaking.h
See also
PFMatchmaking members
PFMultiplayerStartProcessingMatchmakingStateChanges
PFMultiplayerFinishProcessingMatchmakingStateChanges
PFMatchmakingTicketCompletedStateChange
5/24/2022 • 2 minutes to read • Edit Online
Syntax
struct PFMatchmakingTicketCompletedStateChange : PFMatchmakingStateChange {
HRESULT result;
PFMatchmakingTicketHandle ticket;
void* asyncContext;
}
Members
result HRESULT
An error code indicating whether the ticket succeeded or, if it failed, why it failed.
ticket PFMatchmakingTicketHandle
must not be null
The matchmaking ticket that completed.
asyncContext void*
The async context provided to the call associated with this state change.
Requirements
Header : PFMatchmaking.h
See also
PFMatchmaking members
PFMatchmakingTicketStatusChangedStateChange
5/24/2022 • 2 minutes to read • Edit Online
Syntax
struct PFMatchmakingTicketStatusChangedStateChange : PFMatchmakingStateChange {
PFMatchmakingTicketHandle ticket;
}
Members
ticket PFMatchmakingTicketHandle
must not be null
The matchmaking ticket whose status changed.
The new ticket status can be retrieved via PFMatchmakingTicketGetStatus.
Requirements
Header : PFMatchmaking.h
See also
PFMatchmaking members
PFMultiplayerAllocateMemoryCallback
5/24/2022 • 2 minutes to read • Edit Online
A callback invoked every time a new memory buffer must be dynamically allocated by the PlayFab Multiplayer
library.
Syntax
typedef
void* (*PFMultiplayerAllocateMemoryCallback)(
size_t size,
uint32_t memoryTypeId
)
Parameters
size size_t
The size of the allocation to be made. This value will never be zero.
memoryTypeId uint32_t
An opaque identifier representing the PlayFab Multiplayer library internal category of memory being allocated.
This value should be ignored.
Return value
Type: void*
A pointer to an allocated block of memory of the specified size, or nullptr if the allocation failed.
Remarks
This callback is optionally installed using the PFMultiplayerSetMemoryCallbacks() method.
The callback must allocate and return a pointer to a contiguous block of memory of the specified size that will
remain valid until the title's corresponding PFMultiplayerFreeMemoryCallback is invoked to release it. If this is
not possible, the callback must return nullptr to fail the allocation. Memory allocation failures are sometimes
considered benign but will usually cause current PlayFab Multiplayer library operation(s) to fail.
Every non-nullptr returned by this method will be subsequently passed to the corresponding
PFMultiplayerFreeMemoryCallback once the memory is no longer needed.
Requirements
Header : PFMultiplayer.h
See also
PFMultiplayer members
PFMultiplayerFreeMemoryCallback
PFMultiplayerSetMemoryCallbacks
PFMultiplayerFreeMemoryCallback
5/24/2022 • 2 minutes to read • Edit Online
A callback invoked every time a previously allocated memory buffer is no longer needed by the PlayFab
Multiplayer library and can be freed.
Syntax
typedef
void (*PFMultiplayerFreeMemoryCallback)(
void* pointer,
uint32_t memoryTypeId
)
Parameters
pointer void*
Post_invalid
A pointer to a memory buffer previously allocated. This value will never be nullptr.
memoryTypeId uint32_t
An opaque identifier representing the PlayFab Multiplayer library internal category of memory being freed. This
value should be ignored.
Return value
Type: void
The callback does not return a value.
Remarks
This callback is optionally installed using the PFMultiplayerSetMemoryCallbacks() method.
The callback is invoked whenever the PlayFab Multiplayer library has finished using a memory buffer previously
returned by the title's corresponding PFMultiplayerAllocateMemoryCallback, so that the title can free the
memory buffer.
Requirements
Header : PFMultiplayer.h
See also
PFMultiplayer members
PFMultiplayerAllocateMemoryCallback
PFMultiplayerSetMemoryCallbacks
PFEntityKey
5/24/2022 • 2 minutes to read • Edit Online
PFEntityKey data model. Combined entity type and ID structure which uniquely identifies a single entity.
Syntax
typedef struct PFEntityKey {
const char* id;
const char* type;
} PFEntityKey;
Members
id const char*
Null_terminated
Unique ID of the entity.
type const char*
Null_terminated
Entity type. See https://docs.microsoft.com/gaming/playfab/features/data/entities/available-built-in-entity-
types.
Player entities are typically the title_player_account type. For more information, see See
https://docs.microsoft.com/gaming/playfab/features/data/entities/available-built-in-entity-types.
Remarks
For more information about entities, see https://docs.microsoft.com/gaming/playfab/features/data/entities/.
Requirements
Header : PFEntityKey.h
PlayFab Multiplayer Unity SDK
5/24/2022 • 2 minutes to read • Edit Online
IMPORTANT
This feature is currently in public preview. It is provided to give you an early look at an upcoming feature, and to allow you
to provide feedback while it is still in development.
Classes
NAME DESC RIP T IO N
Lobby
LobbyError
LobbyJoinConfiguration The initial configuration data for the member creating and
joining the lobby.
LobbySearchFriendsFilter The filter structure used to limit lobby search results to only
those lobbies owned by the player's friends.
MatchmakingMatchDetails
MatchmakingTicket
MatchmakingTicketMatchMember
PlayFabMultiplayer
NAME DESC RIP T IO N
PlayfabMultiplayerEventProcessor
Structs
NAME DESC RIP T IO N
MatchUser
Enums
NAME DESC RIP T IO N
LobbyMembershipLock
LobbyOwnerMigrationPolicy The available policies the lobby service can use to migrate
lobby ownership between members.
Properties
NAME DESC RIP T IO N
AccessPolicy
ConnectionString
Id
MaxMemberCount
MembershipLock
OwnerMigrationPolicy
Methods
NAME DESC RIP T IO N
GetLobbyProperties
GetMemberProperties
GetMembers
GetSearchProperties
Leave (2 methods)
LeaveAllLocalUsers
PostUpdate (6 methods)
SendInvite Send an invite to this lobby from the local user to the invited
entity. (2 methods)
TryGetOwner
See Also
namespace PlayFab.Multiplayer
Lobby.AccessPolicy property
5/24/2022 • 2 minutes to read • Edit Online
See Also
enum LobbyAccessPolicy
class Lobby
namespace PlayFab.Multiplayer
Lobby.ConnectionString property
5/24/2022 • 2 minutes to read • Edit Online
See Also
class Lobby
namespace PlayFab.Multiplayer
Lobby.Id property
5/24/2022 • 2 minutes to read • Edit Online
See Also
class Lobby
namespace PlayFab.Multiplayer
Lobby.MaxMemberCount property
5/24/2022 • 2 minutes to read • Edit Online
See Also
class Lobby
namespace PlayFab.Multiplayer
Lobby.MembershipLock property
5/24/2022 • 2 minutes to read • Edit Online
See Also
enum LobbyMembershipLock
class Lobby
namespace PlayFab.Multiplayer
Lobby.OwnerMigrationPolicy property
5/24/2022 • 2 minutes to read • Edit Online
See Also
enum LobbyOwnerMigrationPolicy
class Lobby
namespace PlayFab.Multiplayer
Lobby.AddMember method
5/24/2022 • 2 minutes to read • Edit Online
PA RA M ET ER DESC RIP T IO N
localUser The PlayFab Entity Key of the local user to add to the lobby
as a member.
memberProperties The initial member properties to set for this user when they
join the lobby.
Remarks
This is an asynchronous operation. Upon successful completion, the title will be provided a OnLobbyMemberAdded
event followed by a OnAddMemberCompleted event with the result field set to Succeeded (0). Upon a failed
completion, the result field will be set to Failed (negative value).
This method is used to add an additional local PlayFab entity to a pre-existing lobby object. Because the lobby
object, must have already been created either via a call to CreateAndJoinLobby or JoinLobby , this method is
primarily useful for multiple local user scenarios.
This is an asynchronous operation. The member added via this method will not be reflected in the lists returned
by GetMembers until the asynchronous operation successfully completes.
See Also
class PFEntityKey
class Lobby
namespace PlayFab.Multiplayer
Lobby.ForceRemoveMember method
5/24/2022 • 2 minutes to read • Edit Online
PA RA M ET ER DESC RIP T IO N
Remarks
This is an asynchronous operation. Upon successful completion, the title will be provided a
OnLobbyMemberRemoved event followed by a OnForceRemoveMemberCompleted event with the result field set to
LobbyStateChangeResult.Succeeded . Upon a failed completion, the title will be provided a
OnForceRemoveMemberCompleted event with the result field set to a failure
One of the local PlayFab entities present in this lobby must be the owner for this operation to succeed. If the
local owning entity who initiated this operation loses their ownership status while the operation is in progress,
the operation will fail asynchronously and the provided OnForceRemoveMemberCompleted event result which will be
set to !:LobbyStateChangeResult.UserNotAuthorized
This is an asynchronous operation. The member removed via this method will not be removed from the lists
returned by GetMembers until the asynchronous operation successfully completes and a OnLobbyMemberRemoved
event
See Also
class PFEntityKey
class Lobby
namespace PlayFab.Multiplayer
Lobby.GetLobbyProperties method
5/24/2022 • 2 minutes to read • Edit Online
See Also
class Lobby
namespace PlayFab.Multiplayer
Lobby.GetMemberProperties method
5/24/2022 • 2 minutes to read • Edit Online
See Also
class PFEntityKey
class Lobby
namespace PlayFab.Multiplayer
Lobby.GetMembers method
5/24/2022 • 2 minutes to read • Edit Online
See Also
class PFEntityKey
class Lobby
namespace PlayFab.Multiplayer
Lobby.GetSearchProperties method
5/24/2022 • 2 minutes to read • Edit Online
See Also
class Lobby
namespace PlayFab.Multiplayer
Lobby.Leave method
5/24/2022 • 2 minutes to read • Edit Online
Lobby.Leave (1 of 2)
public void Leave(PFEntityKey localUser)
See Also 1
class PFEntityKey
class Lobby
namespace PlayFab.Multiplayer
Lobby.Leave (2 of 2)
public void Leave(PlayFabAuthenticationContext localUser)
See Also 2
class Lobby
namespace PlayFab.Multiplayer
Lobby.LeaveAllLocalUsers method
5/24/2022 • 2 minutes to read • Edit Online
See Also
class Lobby
namespace PlayFab.Multiplayer
Lobby.PostUpdate method
5/24/2022 • 2 minutes to read • Edit Online
Lobby.PostUpdate (1 of 6)
public void PostUpdate(PFEntityKey localUser, IDictionary<string, string> memberProperties)
See Also 1
class PFEntityKey
class Lobby
namespace PlayFab.Multiplayer
Lobby.PostUpdate (2 of 6)
public void PostUpdate(PFEntityKey localUser, LobbyDataUpdate lobbyUpdate)
See Also 2
class PFEntityKey
class LobbyDataUpdate
class Lobby
namespace PlayFab.Multiplayer
Lobby.PostUpdate (3 of 6)
public void PostUpdate(PlayFabAuthenticationContext localUser,
IDictionary<string, string> memberProperties)
See Also 3
class Lobby
namespace PlayFab.Multiplayer
Lobby.PostUpdate (4 of 6)
public void PostUpdate(PlayFabAuthenticationContext localUser, LobbyDataUpdate lobbyUpdate)
See Also 4
class LobbyDataUpdate
class Lobby
namespace PlayFab.Multiplayer
Lobby.PostUpdate (5 of 6)
public void PostUpdate(PFEntityKey localUser, LobbyDataUpdate lobbyUpdate,
IDictionary<string, string> memberProperties)
See Also 5
class PFEntityKey
class LobbyDataUpdate
class Lobby
namespace PlayFab.Multiplayer
Lobby.PostUpdate (6 of 6)
public void PostUpdate(PlayFabAuthenticationContext localUser, LobbyDataUpdate lobbyUpdate,
IDictionary<string, string> memberProperties)
See Also 6
class LobbyDataUpdate
class Lobby
namespace PlayFab.Multiplayer
Lobby.SendInvite method
5/24/2022 • 2 minutes to read • Edit Online
Lobby.SendInvite (1 of 2)
Send an invite to this lobby from the local user to the invited entity.
PA RA M ET ER DESC RIP T IO N
Remarks 1
This is an asynchronous operation. Upon successful completion, the title will be provided a
OnLobbySendInviteCompleted with the !:PlayFabMultiplayer.OnLobbySendInviteCompleted.result field set to
LobbyStateChangeResult.Succeeded . Upon a failed completion, the title will be provided a
OnLobbySendInviteCompleted with the !:PlayFabMultiplayer.OnLobbySendInviteCompleted.result field set to a
failure !:LobbyStateChangeResult.
The sender must be a local user of this lobby which joined from this client.
See Also 1
class PFEntityKey
class Lobby
namespace PlayFab.Multiplayer
Lobby.SendInvite (2 of 2)
Send an invite to this lobby from the local user to the invited entity.
PA RA M ET ER DESC RIP T IO N
Remarks 2
This is an asynchronous operation. Upon successful completion, the title will be provided a
OnLobbySendInviteCompleted with the !:PlayFabMultiplayer.OnLobbySendInviteCompleted.result field set to
LobbyStateChangeResult.Succeeded . Upon a failed completion, the title will be provided a
OnLobbySendInviteCompleted with the !:PlayFabMultiplayer.OnLobbySendInviteCompleted.result field set to a
failure !:LobbyStateChangeResult.
The sender must be a local user of this lobby which joined from this client.
See Also 2
class PFEntityKey
class Lobby
namespace PlayFab.Multiplayer
Lobby.TryGetOwner method
5/24/2022 • 2 minutes to read • Edit Online
See Also
class PFEntityKey
class Lobby
namespace PlayFab.Multiplayer
Class LobbyArrangedJoinConfiguration
5/24/2022 • 2 minutes to read • Edit Online
Constructors
NAME DESC RIP T IO N
Properties
NAME DESC RIP T IO N
AccessPolicy The access policy for the lobby, if the joiner is the first
member in the lobby.
MemberProperties The initial member properties for the joiner of the lobby.
OwnerMigrationPolicy The owner migration policy for the lobby, if the joiner is the
first member in the lobby.
See Also
namespace PlayFab.Multiplayer
LobbyArrangedJoinConfiguration constructor
5/24/2022 • 2 minutes to read • Edit Online
public LobbyArrangedJoinConfiguration()
See Also
class LobbyArrangedJoinConfiguration
namespace PlayFab.Multiplayer
LobbyArrangedJoinConfiguration.AccessPolicy
property
5/24/2022 • 2 minutes to read • Edit Online
The access policy for the lobby, if the joiner is the first member in the lobby.
See Also
enum LobbyAccessPolicy
class LobbyArrangedJoinConfiguration
namespace PlayFab.Multiplayer
LobbyArrangedJoinConfiguration.MaxMemberCount
property
5/24/2022 • 2 minutes to read • Edit Online
The maximum number of members allowed in the lobby, if joiner is the first member in the lobby.
Remarks
This value must be at least PlayFabMultiplayer.LobbyMaxMemberCountLowerLimit and no more than
PlayFabMultiplayer.LobbyMaxMemberCountUpperLimit .
If a client would violate this limit by calling !:JoinLobby() or !:Lobby.AddMember, the operation will fail
asynchronously and !:LobbyJoinCompletedStateChange.result or
!:LobbyAddMemberCompletedStateChange.result, respectively, will be set to
!:LobbyStateChangeResult.LobbyNotJoinable.
See Also
class LobbyArrangedJoinConfiguration
namespace PlayFab.Multiplayer
LobbyArrangedJoinConfiguration.MemberProperties
property
5/24/2022 • 2 minutes to read • Edit Online
See Also
class LobbyArrangedJoinConfiguration
namespace PlayFab.Multiplayer
LobbyArrangedJoinConfiguration.OwnerMigrationPolicy
property
5/24/2022 • 2 minutes to read • Edit Online
The owner migration policy for the lobby, if the joiner is the first member in the lobby.
Remarks
This value cannot be set to LobbyOwnerMigrationPolicy.Server .
See Also
enum LobbyOwnerMigrationPolicy
class LobbyArrangedJoinConfiguration
namespace PlayFab.Multiplayer
Class LobbyCreateConfiguration
5/24/2022 • 2 minutes to read • Edit Online
Constructors
NAME DESC RIP T IO N
Properties
NAME DESC RIP T IO N
See Also
namespace PlayFab.Multiplayer
LobbyCreateConfiguration constructor
5/24/2022 • 2 minutes to read • Edit Online
public LobbyCreateConfiguration()
See Also
class LobbyCreateConfiguration
namespace PlayFab.Multiplayer
LobbyCreateConfiguration.AccessPolicy property
5/24/2022 • 2 minutes to read • Edit Online
See Also
enum LobbyAccessPolicy
class LobbyCreateConfiguration
namespace PlayFab.Multiplayer
LobbyCreateConfiguration.LobbyProperties
property
5/24/2022 • 2 minutes to read • Edit Online
See Also
class LobbyCreateConfiguration
namespace PlayFab.Multiplayer
LobbyCreateConfiguration.MaxMemberCount
property
5/24/2022 • 2 minutes to read • Edit Online
Remarks
This value must be at least PlayFabMultiplayer.LobbyMaxMemberCountLowerLimit and no more than
PlayFabMultiplayer.LobbyMaxMemberCountUpperLimit .
If a client would violate this limit by calling !:JoinLobby() or !:Lobby.AddMember, the operation will fail
asynchronously and !:OnLobbyJoinCompleted.result or !:OnLobbyAddMemberCompleted.result, respectively,
will be set to !:LobbyStateChangeResult.LobbyNotJoinable.
See Also
class LobbyCreateConfiguration
namespace PlayFab.Multiplayer
LobbyCreateConfiguration.OwnerMigrationPolicy
property
5/24/2022 • 2 minutes to read • Edit Online
Remarks
This value cannot be set to LobbyOwnerMigrationPolicy.Server .
See Also
enum LobbyOwnerMigrationPolicy
class LobbyCreateConfiguration
namespace PlayFab.Multiplayer
LobbyCreateConfiguration.SearchProperties
property
5/24/2022 • 2 minutes to read • Edit Online
See Also
class LobbyCreateConfiguration
namespace PlayFab.Multiplayer
Class LobbyDataUpdate
5/24/2022 • 2 minutes to read • Edit Online
A request to make an update to the shared portion of the lobby on behalf of a member.
Constructors
NAME DESC RIP T IO N
Properties
NAME DESC RIP T IO N
See Also
namespace PlayFab.Multiplayer
LobbyDataUpdate constructor
5/24/2022 • 2 minutes to read • Edit Online
public LobbyDataUpdate()
See Also
class LobbyDataUpdate
namespace PlayFab.Multiplayer
LobbyDataUpdate.AccessPolicy property
5/24/2022 • 2 minutes to read • Edit Online
Remarks
This value can only be updated by the current lobby owner.
See Also
enum LobbyAccessPolicy
class LobbyDataUpdate
namespace PlayFab.Multiplayer
LobbyDataUpdate.LobbyProperties property
5/24/2022 • 2 minutes to read • Edit Online
Remarks
Only the current lobby owner can update the lobby properties.
There may only be PlayFabMultiplayer.LobbyMaxLobbyPropertyCount concurrent lobby properties at any given
time. Therefore, at most, twice that many unique properties can be specified in this update if half of those
properties are being deleted.
If the property limits are violated, the entire update operation will fail.
See Also
class LobbyDataUpdate
namespace PlayFab.Multiplayer
LobbyDataUpdate.MaxMemberCount property
5/24/2022 • 2 minutes to read • Edit Online
Remarks
This new value must be greater than than the number of members currently in the lobby and less than
LobbyMaxMemberCountUpperLimit .
See Also
class LobbyDataUpdate
namespace PlayFab.Multiplayer
LobbyDataUpdate.MembershipLock property
5/24/2022 • 2 minutes to read • Edit Online
Remarks
This value can only be updated by the current lobby owner.
See Also
enum LobbyMembershipLock
class LobbyDataUpdate
namespace PlayFab.Multiplayer
LobbyDataUpdate.NewOwner property
5/24/2022 • 2 minutes to read • Edit Online
Remarks
This value can only be updated under one of the following conditions:
* The member updating this field is the lobby's current owner * The owner migration policy is
LobbyOwnerMigrationPolicy.Manual and there is currently no owner * The owner migration policy is
LobbyOwnerMigrationPolicy.None`
See Also
class PFEntityKey
class LobbyDataUpdate
namespace PlayFab.Multiplayer
LobbyDataUpdate.SearchProperties property
5/24/2022 • 2 minutes to read • Edit Online
Remarks
Only the current lobby owner can update the search properties.
There may only be PlayFabMultiplayer.LobbyMaxSearchPropertyCount concurrent search properties at any given
time. Therefore, at most, twice that many unique properties can be specified in this update if half of those
properties are being deleted.
If the property limits are violated, the entire update operation will fail.
See Also
class LobbyDataUpdate
namespace PlayFab.Multiplayer
Class LobbyError
5/24/2022 • 2 minutes to read • Edit Online
Constructors
NAME DESC RIP T IO N
Constants
NAME DESC RIP T IO N
const InvalidArg
const Success
Methods
NAME DESC RIP T IO N
static FAILED
static SUCCEEDED
See Also
namespace PlayFab.Multiplayer
LobbyError constructor
5/24/2022 • 2 minutes to read • Edit Online
public LobbyError()
See Also
class LobbyError
namespace PlayFab.Multiplayer
LobbyError.InvalidArg field
5/24/2022 • 2 minutes to read • Edit Online
See Also
class LobbyError
namespace PlayFab.Multiplayer
LobbyError.Success field
5/24/2022 • 2 minutes to read • Edit Online
See Also
class LobbyError
namespace PlayFab.Multiplayer
LobbyError.FAILED method
5/24/2022 • 2 minutes to read • Edit Online
See Also
class LobbyError
namespace PlayFab.Multiplayer
LobbyError.SUCCEEDED method
5/24/2022 • 2 minutes to read • Edit Online
See Also
class LobbyError
namespace PlayFab.Multiplayer
Class LobbyJoinConfiguration
5/24/2022 • 2 minutes to read • Edit Online
The initial configuration data for the member creating and joining the lobby.
Constructors
NAME DESC RIP T IO N
Properties
NAME DESC RIP T IO N
See Also
namespace PlayFab.Multiplayer
LobbyJoinConfiguration constructor
5/24/2022 • 2 minutes to read • Edit Online
public LobbyJoinConfiguration()
See Also
class LobbyJoinConfiguration
namespace PlayFab.Multiplayer
LobbyJoinConfiguration.MemberProperties
property
5/24/2022 • 2 minutes to read • Edit Online
See Also
class LobbyJoinConfiguration
namespace PlayFab.Multiplayer
Class LobbyMemberUpdateSummary
5/24/2022 • 2 minutes to read • Edit Online
A collection of hints about an update which has been successfully applied to the lobby on behalf of a member.
Properties
NAME DESC RIP T IO N
See Also
namespace PlayFab.Multiplayer
LobbyMemberUpdateSummary.ConnectionStatusUpdated
property
5/24/2022 • 2 minutes to read • Edit Online
See Also
class LobbyMemberUpdateSummary
namespace PlayFab.Multiplayer
LobbyMemberUpdateSummary.Member property
5/24/2022 • 2 minutes to read • Edit Online
See Also
class PFEntityKey
class LobbyMemberUpdateSummary
namespace PlayFab.Multiplayer
LobbyMemberUpdateSummary.UpdatedMemberPropertyKeys
property
5/24/2022 • 2 minutes to read • Edit Online
See Also
class LobbyMemberUpdateSummary
namespace PlayFab.Multiplayer
Class LobbySearchConfiguration
5/24/2022 • 2 minutes to read • Edit Online
The configuration structure used to specify how a !:FindLobbies operation should be performed.
Constructors
NAME DESC RIP T IO N
Properties
NAME DESC RIP T IO N
FilterString The query string used to filter which lobbies are returned in
the search results.
FriendsFilter A filter that, when provided, will constrain the lobby search
operation to only those owned by the members of that
player's various friend lists.
SortString The query string used to sort the lobbies returned in the
search results.
See Also
namespace PlayFab.Multiplayer
LobbySearchConfiguration constructor
5/24/2022 • 2 minutes to read • Edit Online
public LobbySearchConfiguration()
See Also
class LobbySearchConfiguration
namespace PlayFab.Multiplayer
LobbySearchConfiguration.ClientSearchResultCount
property
5/24/2022 • 2 minutes to read • Edit Online
An optional value which, when specified, will limit the number of results provided in the completion response.
Remarks
This value may only be specified when !:FindLobbies is called with a client-entity.
This value can be no higher than PlayFabMultiplayer.LobbyClientRequestedSearchResultCountUpperLimit .
When not specified, the limit on the number of search results is service-defined but will be no greater than
PlayFabMultiplayer.LobbyClientRequestedSearchResultCountUpperLimit .
See Also
class LobbySearchConfiguration
namespace PlayFab.Multiplayer
LobbySearchConfiguration.FilterString property
5/24/2022 • 2 minutes to read • Edit Online
The query string used to filter which lobbies are returned in the search results.
Remarks
This string is formatted in an OData-like filtering syntax.
Only the following operators are supported: "and" (logical and), "eq" (equal), "ne" (not equals), "ge" (greater than
or equal), "gt" (greater than), "le" (less than or equal), and "lt" (less than).
The left-hand side of each OData logical expression should be either a search property key (e.g. string_key1,
number_key3, etc) or one of the pre-defined search keys (!:LobbyMemberCountSearchKey or
!:LobbyMemberSearchKey).
The left-hand side of each OData logical expression should be a search property key.
This string cannot exceed 500 characters.
Example: "string_key1 eq 'CaptureTheFlag' and number_key10 gt 50 and memberCount lt 5"
See Also
class LobbySearchConfiguration
namespace PlayFab.Multiplayer
LobbySearchConfiguration.FriendsFilter property
5/24/2022 • 2 minutes to read • Edit Online
A filter that, when provided, will constrain the lobby search operation to only those owned by the members of
that player's various friend lists.
Remarks
If omitted, the search operation will search all available lobbies.
See Also
class LobbySearchFriendsFilter
class LobbySearchConfiguration
LobbySearchConfiguration.SortString property
5/24/2022 • 2 minutes to read • Edit Online
The query string used to sort the lobbies returned in the search results.
Remarks
This string is formatted in an OData-like order-by syntax: a comma-separated list of search property keys with
an optional specifier to sort in either ascending or descending order.
To specify ascending order, use the "asc" operator after the associated search property key. To specify
descending order, use the "desc" operator after the associated search property key.
Additionally, a special sorting moniker, distance, is supported to enable sorting by closest distance from some
numeric value. For example, "distance{number_key10=5} asc" will sort the results so that lobbies who have their
"number_key10" search property closer to the value "5" will return earlier in the search results.
This string cannot exceed 100 characters.
Example: "string_key1 asc,memberCount desc"
See Also
class LobbySearchConfiguration
namespace PlayFab.Multiplayer
Class LobbySearchFriendsFilter
5/24/2022 • 2 minutes to read • Edit Online
The filter structure used to limit lobby search results to only those lobbies owned by the player's friends.
Properties
NAME DESC RIP T IO N
IncludeFacebookFriends A flag which includes the player's Facebook friends list if their
PlayFab account is linked to their Facebook account.
IncludeSteamFriends A flag which includes the player's Steam friends list if their
PlayFab account is linked to their Steam account.
Remarks
Regardless of which external friend lists are included when constructing this filter, friends from the PlayFab
friends list will always be included.
See Also
namespace PlayFab.Multiplayer
LobbySearchFriendsFilter.IncludeFacebookFriends
property
5/24/2022 • 2 minutes to read • Edit Online
A flag which includes the player's Facebook friends list if their PlayFab account is linked to their Facebook
account.
See Also
class LobbySearchFriendsFilter
namespace PlayFab.Multiplayer
LobbySearchFriendsFilter.IncludeSteamFriends
property
5/24/2022 • 2 minutes to read • Edit Online
A flag which includes the player's Steam friends list if their PlayFab account is linked to their Steam account.
See Also
class LobbySearchFriendsFilter
namespace PlayFab.Multiplayer
LobbySearchFriendsFilter.IncludeXboxFriendsToken
property
5/24/2022 • 2 minutes to read • Edit Online
An Xbox Live token that, when provided, includes the player's Xbox Live friends list if their PlayFab account is
linked to their Xbox Live account.
Remarks
To retrieve this token, make a POST request to "https://playfabapi.com" with an empty request body using one
of the GetTokenAndSignature APIs provided by Xbox Live.
GetTokenAndSignature APIs are provided natively as part of the Microsoft Game Core Development Kit (GDK).
On all other platforms, these APIs are provided via the Xbox Authentication Library API (XAL).
See Also
class LobbySearchFriendsFilter
namespace PlayFab.Multiplayer
Class LobbySearchResult
5/24/2022 • 2 minutes to read • Edit Online
An entry in the collection of lobby search results received upon successful completion of a FindLobbies
operation.
Properties
NAME DESC RIP T IO N
Friends The friends in the found lobby, if the lobby search was
performed with a LobbySearchFriendsFilter .
See Also
namespace PlayFab.Multiplayer
LobbySearchResult.ConnectionString property
5/24/2022 • 2 minutes to read • Edit Online
Remarks
LobbySearchResult.ConnectionString can be null. In this case, an invite is required to join.
See Also
class LobbySearchResult
namespace PlayFab.Multiplayer
LobbySearchResult.CurrentMemberCount property
5/24/2022 • 2 minutes to read • Edit Online
See Also
class LobbySearchResult
namespace PlayFab.Multiplayer
LobbySearchResult.Friends property
5/24/2022 • 2 minutes to read • Edit Online
The friends in the found lobby, if the lobby search was performed with a LobbySearchFriendsFilter .
Remarks
If the lobby search which generated this search result was not performed with a LobbySearchFriendsFilter , this
value will always be 0.
In some multiplayer social networks, friendship is a unidirectional relationship. One user may "follow" another
or be their friend, but the same is not necessarily true in the reverse direction. Friends will only be returned in
this search result when a bidirectional friendship exists. That is, the user querying for the lobby and the user in
the lobby must both be friends with each other.
See Also
class PFEntityKey
class LobbySearchResult
namespace PlayFab.Multiplayer
LobbySearchResult.LobbyId property
5/24/2022 • 2 minutes to read • Edit Online
See Also
class LobbySearchResult
namespace PlayFab.Multiplayer
LobbySearchResult.MaxMemberCount property
5/24/2022 • 2 minutes to read • Edit Online
See Also
class LobbySearchResult
namespace PlayFab.Multiplayer
LobbySearchResult.OwnerEntity property
5/24/2022 • 2 minutes to read • Edit Online
Remarks
LobbySearchResult.OwnerEntity may be null if the lobby doesn't currently have an owner.
See Also
class PFEntityKey
class LobbySearchResult
namespace PlayFab.Multiplayer
LobbySearchResult.SearchProperties property
5/24/2022 • 2 minutes to read • Edit Online
See Also
class LobbySearchResult
namespace PlayFab.Multiplayer
Class MatchmakingMatchDetails
5/24/2022 • 2 minutes to read • Edit Online
Properties
NAME DESC RIP T IO N
RegionPreferences Preferred regions for the match, sorted from most to least
preferred.
See Also
namespace PlayFab.Multiplayer
MatchmakingMatchDetails.LobbyArrangementString
property
5/24/2022 • 2 minutes to read • Edit Online
Remarks
This connection string can optionally be used with JoinArrangedLobby to join a lobby associated with this match
result. The lobby is not created until a user attempts to join it.
See Also
class MatchmakingMatchDetails
namespace PlayFab.Multiplayer
MatchmakingMatchDetails.MatchId property
5/24/2022 • 2 minutes to read • Edit Online
See Also
class MatchmakingMatchDetails
namespace PlayFab.Multiplayer
MatchmakingMatchDetails.Members property
5/24/2022 • 2 minutes to read • Edit Online
See Also
class MatchmakingTicketMatchMember
class MatchmakingMatchDetails
namespace PlayFab.Multiplayer
MatchmakingMatchDetails.RegionPreferences
property
5/24/2022 • 2 minutes to read • Edit Online
Preferred regions for the match, sorted from most to least preferred.
See Also
class MatchmakingMatchDetails
namespace PlayFab.Multiplayer
Class MatchmakingTicket
5/24/2022 • 2 minutes to read • Edit Online
Properties
NAME DESC RIP T IO N
Methods
NAME DESC RIP T IO N
See Also
namespace PlayFab.Multiplayer
MatchmakingTicket.Status property
5/24/2022 • 2 minutes to read • Edit Online
See Also
enum MatchmakingTicketStatus
class MatchmakingTicket
namespace PlayFab.Multiplayer
MatchmakingTicket.TicketId property
5/24/2022 • 2 minutes to read • Edit Online
See Also
class MatchmakingTicket
namespace PlayFab.Multiplayer
MatchmakingTicket.Cancel method
5/24/2022 • 2 minutes to read • Edit Online
Remarks
This method queues an asynchronous operation to cancel this matchmaking ticket. On success, a
OnMatchmakingTicketCompleted will be provided indicating that the ticket has been canceled.
This method does not guarantee the ticket will be canceled. The ticket may complete before the cancellation can
be processed, or the cancellation request may fail due to networking or service errors. If the cancellation attempt
fails but is retrievable, the library will continue to retry the cancellation. Otherwise, a
OnMatchmakingTicketCompleted will be provided that indicates the ticket failed.
See Also
class MatchmakingTicket
namespace PlayFab.Multiplayer
MatchmakingTicket.GetMatchDetails method
5/24/2022 • 2 minutes to read • Edit Online
See Also
class MatchmakingMatchDetails
class MatchmakingTicket
namespace PlayFab.Multiplayer
Class MatchmakingTicketMatchMember
5/24/2022 • 2 minutes to read • Edit Online
Properties
NAME DESC RIP T IO N
See Also
namespace PlayFab.Multiplayer
MatchmakingTicketMatchMember.AttributesJSON
property
5/24/2022 • 2 minutes to read • Edit Online
See Also
class MatchmakingTicketMatchMember
namespace PlayFab.Multiplayer
MatchmakingTicketMatchMember.EntityKey
property
5/24/2022 • 2 minutes to read • Edit Online
See Also
class PFEntityKey
class MatchmakingTicketMatchMember
namespace PlayFab.Multiplayer
MatchmakingTicketMatchMember.TeamId property
5/24/2022 • 2 minutes to read • Edit Online
Remarks
May be empty if the matchmaking queue doesn't use team rules.
See Also
class MatchmakingTicketMatchMember
namespace PlayFab.Multiplayer
Class PFEntityKey
5/24/2022 • 2 minutes to read • Edit Online
PFEntityKey data model. Combined entity type and ID structure which uniquely identifies a single entity.
Constructors
NAME DESC RIP T IO N
Properties
NAME DESC RIP T IO N
Remarks
For more information about entities, see https://docs.microsoft.com/gaming/playfab/features/data/entities/.
See Also
namespace PlayFab.Multiplayer
PFEntityKey constructor
5/24/2022 • 2 minutes to read • Edit Online
PFEntityKey (1 of 2)
Initializes a new instance of the PFEntityKey class. Pass in a PlayFabAuthenticationContext authContext returned
by a PlayFab login method.
See Also 1
class PFEntityKey
namespace PlayFab.Multiplayer
PFEntityKey (2 of 2)
Initializes a new instance of the PFEntityKey class.
See Also 2
class PFEntityKey
namespace PlayFab.Multiplayer
PFEntityKey.Id property
5/24/2022 • 2 minutes to read • Edit Online
See Also
class PFEntityKey
namespace PlayFab.Multiplayer
PFEntityKey.Type property
5/24/2022 • 2 minutes to read • Edit Online
Remarks
Player entities are typically the title_player_account type. For more information, see See
https://docs.microsoft.com/gaming/playfab/features/data/entities/available-built-in-entity-types.
See Also
class PFEntityKey
namespace PlayFab.Multiplayer
Class PlayFabMultiplayer
5/24/2022 • 3 minutes to read • Edit Online
Constructors
NAME DESC RIP T IO N
Properties
NAME DESC RIP T IO N
Constants
NAME DESC RIP T IO N
Events
NAME DESC RIP T IO N
static event OnError Event triggered when an there is an error calling another API
to be used for debugging purposes.
static event OnForceRemoveMemberCompleted Event triggered when a force remove member is completed.
static event OnLobbyDisconnected Event triggered when a client has disconnected from a lobby.
static event OnLobbyFindLobbiesCompleted Event triggered when the operation started by a previous
call to !:PlayFabMultiplayer.FindLobbies() completed.
static event OnLobbyInviteListenerStatusChanged Event triggered when an invite listener's status has changed.
static event OnLobbyInviteReceived Event triggered when an entity on this client has received an
invite to a lobby.
static event OnLobbyJoinArrangedLobbyCompleted Event triggered when the operation started by a previous
call to !:PlayFabMultiplayer.JoinArrangedLobby() completed.
static event OnLobbyJoinCompleted Event triggered when the operation started by a previous
call to !:PlayFabMultiplayer.JoinLobby() completed.
static event OnLobbyLeaveCompleted Event triggered when the operation started by a previous
call to !:Lobby.Leave() completed.
static event OnLobbyMemberAdded Event triggered when a PlayFab entity was added to a lobby
as a member.
static event OnLobbyMemberRemoved Event triggered when a PlayFab entity was removed from a
lobby as a member.
static event OnLobbyPostUpdateCompleted Event triggered when the operation started by a previous
call to !:Lobby.PostUpdate() completed.
static event OnLobbySendInviteCompleted Event triggered when the operation started by a previous
call to !:PlayFabMultiplayer.SendInvite() completed.
static event OnLobbyUpdated Event triggered when the lobby was updated.
static event OnMatchmakingTicketCompleted Event triggered when a matchmaking ticket status has
completed
static event OnMatchmakingTicketStatusChanged Event triggered when a matchmaking ticket status has
changed.
Delegates
NAME DESC RIP T IO N
delegate OnAddMemberCompletedHandler Handler for when the operation started by a previous call to
!:Lobby.AddMember completed
delegate OnErrorEventHandler Handler for when there is an error calling another API to be
used for debugging purposes.
delegate OnForceRemoveMemberCompletedHandler Handler for when the operation started by a previous call to
!:PlayFabLobby.ForceRemoveMember() completed.
delegate OnLobbyCreateAndJoinCompletedHandler Handler for when the operation started by a previous call to
!:PlayFabMultiplayer.CreateAndJoinLobby() completed.
delegate OnLobbyDisconnectedHandler Handler for when the client has disconnected from a lobby.
delegate OnLobbyFindLobbiesCompletedHandler Handler for when the operation started by a previous call to
!:PlayFabMultiplayer.FindLobbies() completed.
delegate OnLobbyInviteListenerStatusChangedHandler Handler for when an invite listener's status has changed.
delegate OnLobbyInviteReceivedHandler Handler for when an entity on this client has received an
invite to a lobby.
delegate OnLobbyJoinArrangedLobbyCompletedHandler Handler for when the operation started by a previous call to
!:PlayFabMultiplayer.JoinArrangedLobby() completed.
delegate OnLobbyJoinCompletedHandler Handler for when the operation started by a previous call to
!:PlayFabMultiplayer.JoinLobby() completed.
delegate OnLobbyLeaveCompletedHandler Handler for when the operation started by a previous call to
!:Lobby.Leave() completed.
delegate OnLobbyMemberAddedHandler Handler for when a local PlayFab entity was added to lobby
as a member.
delegate OnLobbyMemberRemovedHandler Handler for when a PlayFab entity was removed from a
lobby as a member.
delegate OnLobbyPostUpdateCompletedHandler Handler for when the operation started by a previous call to
!:Lobby.PostUpdate() completed.
delegate OnLobbySendInviteCompletedHandler Handler for when the operation started by a previous call to
!:PlayFabMultiplayer.SendInvite() completed.
delegate OnMatchmakingTicketCompletedHandler Handler for when a matchmaking ticket status has changed.
delegate OnMatchmakingTicketStatusChangedHandler Handler for when a matchmaking ticket status has changed.
Methods
NAME DESC RIP T IO N
static CreateMatchmakingTicket Creates a matchmaking ticket for one or more local users. (3
methods)
static GetLobbyInviteListenerStatus Retrieve the status of the entity's invite listener. (2 methods)
static ProcessLobbyStateChanges
static ProcessMatchmakingStateChanges
static SetEntityToken Sets the token that should be used for authentication when
performing library actions on behalf of an entity. If a token
has previously been set for the entity, this replaces its
previous token. (2 methods)
static StartListeningForLobbyInvites Enables the Lobby invite listener for a given entity. (2
methods)
static StopListeningForLobbyInvites Disables the Lobby invite listener for a given entity. (2
methods)
See Also
namespace PlayFab.Multiplayer
PlayFabMultiplayer constructor
5/24/2022 • 2 minutes to read • Edit Online
public PlayFabMultiplayer()
See Also
class PlayFabMultiplayer
namespace PlayFab.Multiplayer
PlayFabMultiplayer.IsInitialized property
5/24/2022 • 2 minutes to read • Edit Online
See Also
class PlayFabMultiplayer
namespace PlayFab.Multiplayer
PlayFabMultiplayer.LogLevel property
5/24/2022 • 2 minutes to read • Edit Online
See Also
enum LogLevelType
class PlayFabMultiplayer
namespace PlayFab.Multiplayer
PlayFabMultiplayer.LobbyClientRequestedSearchResultCountUpperLimit
field
5/24/2022 • 2 minutes to read • Edit Online
The maximum number of search results that client-entity callers may request when performing a FindLobbies
operation.
See Also
class PlayFabMultiplayer
namespace PlayFab.Multiplayer
PlayFabMultiplayer.LobbyMaxLobbyPropertyCount
field
5/24/2022 • 2 minutes to read • Edit Online
The maximum number of concurrent properties which can be stored for the lobby and which aren't owned by
any specific member.
See Also
class PlayFabMultiplayer
namespace PlayFab.Multiplayer
PlayFabMultiplayer.LobbyMaxMemberCountLowerLimit
field
5/24/2022 • 2 minutes to read • Edit Online
See Also
class PlayFabMultiplayer
namespace PlayFab.Multiplayer
PlayFabMultiplayer.LobbyMaxMemberCountUpperLimit
field
5/24/2022 • 2 minutes to read • Edit Online
See Also
class PlayFabMultiplayer
PlayFabMultiplayer.LobbyMaxMemberPropertyCount
field
5/24/2022 • 2 minutes to read • Edit Online
The maximum number of concurrent properties allowed for each member in the lobby.
See Also
class PlayFabMultiplayer
namespace PlayFab.Multiplayer
PlayFabMultiplayer.LobbyMaxSearchPropertyCount
field
5/24/2022 • 2 minutes to read • Edit Online
The maximum number of concurrent search properties which can be stored for the lobby.
See Also
class PlayFabMultiplayer
namespace PlayFab.Multiplayer
PlayFabMultiplayer.OnAddMemberCompleted
event
5/24/2022 • 2 minutes to read • Edit Online
See Also
delegate OnAddMemberCompletedHandler
class PlayFabMultiplayer
namespace PlayFab.Multiplayer
PlayFabMultiplayer.OnError event
5/24/2022 • 2 minutes to read • Edit Online
Event triggered when an there is an error calling another API to be used for debugging purposes.
See Also
delegate OnErrorEventHandler
class PlayFabMultiplayer
namespace PlayFab.Multiplayer
PlayFabMultiplayer.OnForceRemoveMemberCompleted
event
5/24/2022 • 2 minutes to read • Edit Online
See Also
delegate OnForceRemoveMemberCompletedHandler
class PlayFabMultiplayer
namespace PlayFab.Multiplayer
PlayFabMultiplayer.OnLobbyCreateAndJoinCompleted
event
5/24/2022 • 2 minutes to read • Edit Online
See Also
delegate OnLobbyCreateAndJoinCompletedHandler
class PlayFabMultiplayer
namespace PlayFab.Multiplayer
PlayFabMultiplayer.OnLobbyDisconnected event
5/24/2022 • 2 minutes to read • Edit Online
See Also
delegate OnLobbyDisconnectedHandler
class PlayFabMultiplayer
namespace PlayFab.Multiplayer
PlayFabMultiplayer.OnLobbyFindLobbiesCompleted
event
5/24/2022 • 2 minutes to read • Edit Online
Event triggered when the operation started by a previous call to !:PlayFabMultiplayer.FindLobbies() completed.
See Also
delegate OnLobbyFindLobbiesCompletedHandler
class PlayFabMultiplayer
PlayFabMultiplayer.OnLobbyInviteListenerStatusChanged
event
5/24/2022 • 2 minutes to read • Edit Online
See Also
delegate OnLobbyInviteListenerStatusChangedHandler
class PlayFabMultiplayer
namespace PlayFab.Multiplayer
PlayFabMultiplayer.OnLobbyInviteReceived event
5/24/2022 • 2 minutes to read • Edit Online
Event triggered when an entity on this client has received an invite to a lobby.
See Also
delegate OnLobbyInviteReceivedHandler
class PlayFabMultiplayer
namespace PlayFab.Multiplayer
PlayFabMultiplayer.OnLobbyJoinArrangedLobbyCompleted
event
5/24/2022 • 2 minutes to read • Edit Online
See Also
delegate OnLobbyJoinArrangedLobbyCompletedHandler
class PlayFabMultiplayer
PlayFabMultiplayer.OnLobbyJoinCompleted event
5/24/2022 • 2 minutes to read • Edit Online
Event triggered when the operation started by a previous call to !:PlayFabMultiplayer.JoinLobby() completed.
See Also
delegate OnLobbyJoinCompletedHandler
class PlayFabMultiplayer
namespace PlayFab.Multiplayer
PlayFabMultiplayer.OnLobbyLeaveCompleted event
5/24/2022 • 2 minutes to read • Edit Online
Event triggered when the operation started by a previous call to !:Lobby.Leave() completed.
See Also
delegate OnLobbyLeaveCompletedHandler
class PlayFabMultiplayer
namespace PlayFab.Multiplayer
PlayFabMultiplayer.OnLobbyMemberAdded event
5/24/2022 • 2 minutes to read • Edit Online
See Also
delegate OnLobbyMemberAddedHandler
class PlayFabMultiplayer
namespace PlayFab.Multiplayer
PlayFabMultiplayer.OnLobbyMemberRemoved
event
5/24/2022 • 2 minutes to read • Edit Online
Event triggered when a PlayFab entity was removed from a lobby as a member.
See Also
delegate OnLobbyMemberRemovedHandler
class PlayFabMultiplayer
namespace PlayFab.Multiplayer
PlayFabMultiplayer.OnLobbyPostUpdateCompleted
event
5/24/2022 • 2 minutes to read • Edit Online
Event triggered when the operation started by a previous call to !:Lobby.PostUpdate() completed.
See Also
delegate OnLobbyPostUpdateCompletedHandler
class PlayFabMultiplayer
namespace PlayFab.Multiplayer
PlayFabMultiplayer.OnLobbySendInviteCompleted
event
5/24/2022 • 2 minutes to read • Edit Online
Event triggered when the operation started by a previous call to !:PlayFabMultiplayer.SendInvite() completed.
See Also
delegate OnLobbySendInviteCompletedHandler
class PlayFabMultiplayer
namespace PlayFab.Multiplayer
PlayFabMultiplayer.OnLobbyUpdated event
5/24/2022 • 2 minutes to read • Edit Online
See Also
delegate OnLobbyUpdatedHandler
class PlayFabMultiplayer
namespace PlayFab.Multiplayer
PlayFabMultiplayer.OnMatchmakingTicketCompleted
event
5/24/2022 • 2 minutes to read • Edit Online
See Also
delegate OnMatchmakingTicketCompletedHandler
class PlayFabMultiplayer
namespace PlayFab.Multiplayer
PlayFabMultiplayer.OnMatchmakingTicketStatusChanged
event
5/24/2022 • 2 minutes to read • Edit Online
See Also
delegate OnMatchmakingTicketStatusChangedHandler
class PlayFabMultiplayer
namespace PlayFab.Multiplayer
PlayFabMultiplayer.OnAddMemberCompletedHandler
delegate
5/24/2022 • 2 minutes to read • Edit Online
Handler for when the operation started by a previous call to !:Lobby.AddMember completed
PA RA M ET ER DESC RIP T IO N
Remarks
OnLobbyMemberAdded event fires anytime any member is added to the lobby (remote or local).
OnAddMemberCompleted event only fires when you invoke !:PlayFabMultiplayer.AddMember which allows you to
add additional members to the lobby. The first local member was the one who created the lobby, it will fire the
OnLobbyCreateAndJoinCompleted event. If the local member is using JoinLobby , it will fire the
OnLobbyJoinCompleted event. If the local member is using JoinArrangedLobby , it will fire the
OnLobbyJoinArrangedLobbyCompleted event.
See Also
class Lobby
class PFEntityKey
class PlayFabMultiplayer
namespace PlayFab.Multiplayer
PlayFabMultiplayer.OnErrorEventHandler delegate
5/24/2022 • 2 minutes to read • Edit Online
Handler for when there is an error calling another API to be used for debugging purposes.
PA RA M ET ER DESC RIP T IO N
args The error args containing the error message and error code
See Also
class PlayFabMultiplayerErrorArgs
class PlayFabMultiplayer
namespace PlayFab.Multiplayer
PlayFabMultiplayer.OnForceRemoveMemberCompletedHandler
delegate
5/24/2022 • 2 minutes to read • Edit Online
Handler for when the operation started by a previous call to !:PlayFabLobby.ForceRemoveMember() completed.
PA RA M ET ER DESC RIP T IO N
targetMember The member entity which is the target to the force remove.
See Also
class Lobby
class PFEntityKey
class PlayFabMultiplayer
namespace PlayFab.Multiplayer
PlayFabMultiplayer.OnLobbyCreateAndJoinCompletedHandler
delegate
5/24/2022 • 2 minutes to read • Edit Online
PA RA M ET ER DESC RIP T IO N
See Also
class Lobby
class PlayFabMultiplayer
namespace PlayFab.Multiplayer
PlayFabMultiplayer.OnLobbyDisconnectedHandler
delegate
5/24/2022 • 2 minutes to read • Edit Online
PA RA M ET ER DESC RIP T IO N
See Also
class Lobby
class PlayFabMultiplayer
namespace PlayFab.Multiplayer
PlayFabMultiplayer.OnLobbyFindLobbiesCompletedHandler
delegate
5/24/2022 • 2 minutes to read • Edit Online
Handler for when the operation started by a previous call to !:PlayFabMultiplayer.FindLobbies() completed.
PA RA M ET ER DESC RIP T IO N
searchingEntity The entity provided to the call associated with this state
change.
See Also
class LobbySearchResult
class PFEntityKey
class PlayFabMultiplayer
namespace PlayFab.Multiplayer
PlayFabMultiplayer.OnLobbyInviteListenerStatusChangedHandler
delegate
5/24/2022 • 2 minutes to read • Edit Online
PA RA M ET ER DESC RIP T IO N
See Also
class PFEntityKey
enum LobbyInviteListenerStatus
class PlayFabMultiplayer
namespace PlayFab.Multiplayer
PlayFabMultiplayer.OnLobbyInviteReceivedHandler
delegate
5/24/2022 • 2 minutes to read • Edit Online
Handler for when an entity on this client has received an invite to a lobby.
PA RA M ET ER DESC RIP T IO N
listeningEntity The entity which is listening for invites and which has been
invited.
See Also
class PFEntityKey
class PlayFabMultiplayer
namespace PlayFab.Multiplayer
PlayFabMultiplayer.OnLobbyJoinArrangedLobbyCompletedHandler
delegate
5/24/2022 • 2 minutes to read • Edit Online
PA RA M ET ER DESC RIP T IO N
newMember The local member entity provided to the call associated with
this state change which is joining this lobby.
Remarks
OnLobbyMemberAdded event fires anytime any member is added to the lobby (remote or local).
OnAddMemberCompleted event only fires when you invoke !:PlayFabMultiplayer.AddMember which allows you to
add additional members to the lobby. The first local member was the one who created the lobby, it will fire the
OnLobbyCreateAndJoinCompleted event. If the local member is using JoinLobby , it will fire the
OnLobbyJoinCompleted event. If the local member is using JoinArrangedLobby , it will fire the
OnLobbyJoinArrangedLobbyCompleted event.
See Also
class Lobby
class PFEntityKey
class PlayFabMultiplayer
namespace PlayFab.Multiplayer
PlayFabMultiplayer.OnLobbyJoinCompletedHandler
delegate
5/24/2022 • 2 minutes to read • Edit Online
Handler for when the operation started by a previous call to !:PlayFabMultiplayer.JoinLobby() completed.
PA RA M ET ER DESC RIP T IO N
newMember The local member entity provided to the call associated with
this state change which is joining this lobby.
Remarks
OnLobbyMemberAdded event fires anytime any member is added to the lobby (remote or local).
OnAddMemberCompleted event only fires when you invoke !:PlayFabMultiplayer.AddMember which allows you to
add additional members to the lobby. The first local member was the one who created the lobby, it will fire the
OnLobbyCreateAndJoinCompleted event. If the local member is using JoinLobby , it will fire the
OnLobbyJoinCompleted event. If the local member is using JoinArrangedLobby , it will fire the
OnLobbyJoinArrangedLobbyCompleted event.
See Also
class Lobby
class PFEntityKey
class PlayFabMultiplayer
namespace PlayFab.Multiplayer
PlayFabMultiplayer.OnLobbyLeaveCompletedHandler
delegate
5/24/2022 • 2 minutes to read • Edit Online
Handler for when the operation started by a previous call to !:Lobby.Leave() completed.
PA RA M ET ER DESC RIP T IO N
localUser The local user provided to the call associated with this state
change. May be null. If this value is null it signifies that the
title requested all local members leave the specified lobby.
See Also
class Lobby
class PFEntityKey
class PlayFabMultiplayer
namespace PlayFab.Multiplayer
PlayFabMultiplayer.OnLobbyMemberAddedHandler
delegate
5/24/2022 • 2 minutes to read • Edit Online
Handler for when a local PlayFab entity was added to lobby as a member.
PA RA M ET ER DESC RIP T IO N
Remarks
OnLobbyMemberAdded event fires anytime any member is added to the lobby (remote or local).
OnAddMemberCompleted event only fires when you invoke !:PlayFabMultiplayer.AddMember which allows you to
add additional members to the lobby. The first local member was the one who created the lobby, it will fire the
OnLobbyCreateAndJoinCompleted event. If the local member is using JoinLobby , it will fire the
OnLobbyJoinCompleted event. If the local member is using JoinArrangedLobby , it will fire the
OnLobbyJoinArrangedLobbyCompleted event.
See Also
class Lobby
class PFEntityKey
class PlayFabMultiplayer
namespace PlayFab.Multiplayer
PlayFabMultiplayer.OnLobbyMemberRemovedHandler
delegate
5/24/2022 • 2 minutes to read • Edit Online
Handler for when a PlayFab entity was removed from a lobby as a member.
PA RA M ET ER DESC RIP T IO N
member The member entity which has been removed from the lobby.
See Also
class Lobby
class PFEntityKey
enum LobbyMemberRemovedReason
class PlayFabMultiplayer
namespace PlayFab.Multiplayer
PlayFabMultiplayer.OnLobbyPostUpdateCompletedHandler
delegate
5/24/2022 • 2 minutes to read • Edit Online
Handler for when the operation started by a previous call to !:Lobby.PostUpdate() completed.
PA RA M ET ER DESC RIP T IO N
localUser The local user provided to the call associated with this state
change.
See Also
class Lobby
class PFEntityKey
class PlayFabMultiplayer
namespace PlayFab.Multiplayer
PlayFabMultiplayer.OnLobbySendInviteCompletedHandler
delegate
5/24/2022 • 2 minutes to read • Edit Online
Handler for when the operation started by a previous call to !:PlayFabMultiplayer.SendInvite() completed.
PA RA M ET ER DESC RIP T IO N
See Also
class Lobby
class PFEntityKey
class PlayFabMultiplayer
namespace PlayFab.Multiplayer
PlayFabMultiplayer.OnLobbyUpdatedHandler
delegate
5/24/2022 • 2 minutes to read • Edit Online
PA RA M ET ER DESC RIP T IO N
updatedSearchPropertyKeys The keys of the search properties which have been updated.
updatedLobbyPropertyKeys The keys of the lobby properties which have been updated.
See Also
class Lobby
class LobbyMemberUpdateSummary
class PlayFabMultiplayer
namespace PlayFab.Multiplayer
PlayFabMultiplayer.OnMatchmakingTicketCompletedHandler
delegate
5/24/2022 • 2 minutes to read • Edit Online
PA RA M ET ER DESC RIP T IO N
See Also
class MatchmakingTicket
class PlayFabMultiplayer
namespace PlayFab.Multiplayer
PlayFabMultiplayer.OnMatchmakingTicketStatusChangedHandler
delegate
5/24/2022 • 2 minutes to read • Edit Online
PA RA M ET ER DESC RIP T IO N
See Also
class MatchmakingTicket
class PlayFabMultiplayer
namespace PlayFab.Multiplayer
PlayFabMultiplayer.CreateAndJoinLobby method
5/24/2022 • 2 minutes to read • Edit Online
PlayFabMultiplayer.CreateAndJoinLobby (1 of 2)
public static Lobby CreateAndJoinLobby(PFEntityKey creator,
LobbyCreateConfiguration createConfiguration, LobbyJoinConfiguration joinConfiguration)
See Also 1
class Lobby
class PFEntityKey
class LobbyCreateConfiguration
class LobbyJoinConfiguration
class PlayFabMultiplayer
namespace PlayFab.Multiplayer
PlayFabMultiplayer.CreateAndJoinLobby (2 of 2)
public static Lobby CreateAndJoinLobby(PlayFabAuthenticationContext creator,
LobbyCreateConfiguration createConfiguration, LobbyJoinConfiguration joinConfiguration)
See Also 2
class Lobby
class LobbyCreateConfiguration
class LobbyJoinConfiguration
class PlayFabMultiplayer
namespace PlayFab.Multiplayer
PlayFabMultiplayer.CreateMatchmakingTicket
method
5/24/2022 • 3 minutes to read • Edit Online
PlayFabMultiplayer.CreateMatchmakingTicket (1 of 3)
Creates a matchmaking ticket for one or more local users.
PA RA M ET ER DESC RIP T IO N
localUsers The array of local users along with local user attributes to
include in the ticket.
Return Value 1
The resulting ticket object.
Remarks 1
The library automatically, and asynchronously, will submit all local users on a ticket to the matchmaking service.
Each time the ticket status changes, a OnMatchmakingTicketStatusChanged will be provided. The ticket status can
be queried at any time via Status . The ticket immediately starts in the MatchmakingTicketStatus.Creating state.
When the ticket has completed, a OnMatchmakingTicketStatusChanged will be provided. At that point, a match will
have been found or the ticket stopped due to failure. On success, the match that was found can be queried via
GetMatchDetails .
All existing tickets in which a local user is a member will be canceled as part of this operation.
A match can't be found until all remote users specified in the membersToMatchWith field of the configuration
parameter have joined the ticket via !:PlayFabMultiplayer.JoinMatchmakingTicketFromId().
See Also 1
class MatchmakingTicket
struct MatchUser
class PlayFabMultiplayer
namespace PlayFab.Multiplayer
PlayFabMultiplayer.CreateMatchmakingTicket (2 of 3)
Creates a matchmaking ticket for one or more local users.
PA RA M ET ER DESC RIP T IO N
localUser The local user along with local user attributes to include in
the ticket.
Return Value 2
The resulting ticket object.
Remarks 2
The library automatically, and asynchronously, will submit all local users on a ticket to the matchmaking service.
Each time the ticket status changes, a OnMatchmakingTicketStatusChanged will be provided. The ticket status can
be queried at any time via Status . The ticket immediately starts in the MatchmakingTicketStatus.Creating state.
When the ticket has completed, a OnMatchmakingTicketStatusChanged will be provided. At that point, a match will
have been found or the ticket stopped due to failure. On success, the match that was found can be queried via
GetMatchDetails .
All existing tickets in which a local user is a member will be canceled as part of this operation.
A match can't be found until all remote users specified in the membersToMatchWith field of the configuration
parameter have joined the ticket via !:PlayFabMultiplayer.JoinMatchmakingTicketFromId().
See Also 2
class MatchmakingTicket
struct MatchUser
class PlayFabMultiplayer
namespace PlayFab.Multiplayer
PlayFabMultiplayer.CreateMatchmakingTicket (3 of 3)
Creates a matchmaking ticket for one or more local users.
PA RA M ET ER DESC RIP T IO N
localUsers The array of local users along with local user attributes to
include in the ticket.
PA RA M ET ER DESC RIP T IO N
Return Value 3
The resulting ticket object.
Remarks 3
The library automatically, and asynchronously, will submit all local users on a ticket to the matchmaking service.
Each time the ticket status changes, a OnMatchmakingTicketStatusChanged will be provided. The ticket status can
be queried at any time via Status . The ticket immediately starts in the MatchmakingTicketStatus.Creating state.
When the ticket has completed, a OnMatchmakingTicketStatusChanged will be provided. At that point, a match will
have been found or the ticket stopped due to failure. On success, the match that was found can be queried via
GetMatchDetails .
All existing tickets in which a local user is a member will be canceled as part of this operation.
A match can't be found until all remote users specified in the membersToMatchWith field of the configuration
parameter have joined the ticket via !:PlayFabMultiplayer.JoinMatchmakingTicketFromId().
See Also 3
class MatchmakingTicket
struct MatchUser
class PFEntityKey
class PlayFabMultiplayer
namespace PlayFab.Multiplayer
PlayFabMultiplayer.FindLobbies method
5/24/2022 • 2 minutes to read • Edit Online
PlayFabMultiplayer.FindLobbies (1 of 2)
public static void FindLobbies(PFEntityKey searchingEntity,
LobbySearchConfiguration searchConfiguration)
See Also 1
class PFEntityKey
class LobbySearchConfiguration
class PlayFabMultiplayer
namespace PlayFab.Multiplayer
PlayFabMultiplayer.FindLobbies (2 of 2)
public static void FindLobbies(PlayFabAuthenticationContext searchingEntity,
LobbySearchConfiguration searchConfiguration)
See Also 2
class LobbySearchConfiguration
class PlayFabMultiplayer
namespace PlayFab.Multiplayer
PlayFabMultiplayer.GetLobbyInviteListenerStatus
method
5/24/2022 • 2 minutes to read • Edit Online
PlayFabMultiplayer.GetLobbyInviteListenerStatus (1 of 2)
Retrieve the status of the entity's invite listener.
PA RA M ET ER DESC RIP T IO N
Return Value 1
The output status value.
Remarks 1
This value is used to understand the state of an entity's invite listener. If the invite listener encounters a fatal
error, non-fatal error, or diagnostic change, the listener's status value will reflect it.
When the invite listener's status changes, a OnLobbyInviteListenerStatusChanged struct will be provided by
!:PlayFabMultiplayer.OnMultiplayerStartProcessingLobby. This method can then be called to retrieve the latest
status and act accordingly.
See Also 1
enum LobbyInviteListenerStatus
class PFEntityKey
class PlayFabMultiplayer
namespace PlayFab.Multiplayer
PlayFabMultiplayer.GetLobbyInviteListenerStatus (2 of 2)
Retrieve the status of the entity's invite listener.
PA RA M ET ER DESC RIP T IO N
Remarks 2
This value is used to understand the state of an entity's invite listener. If the invite listener encounters a fatal
error, non-fatal error, or diagnostic change, the listener's status value will reflect it.
When the invite listener's status changes, a OnLobbyInviteListenerStatusChanged struct will be provided by
!:PlayFabMultiplayer.OnMultiplayerStartProcessingLobby. This method can then be called to retrieve the latest
status and act accordingly.
See Also 2
enum LobbyInviteListenerStatus
class PlayFabMultiplayer
namespace PlayFab.Multiplayer
PlayFabMultiplayer.Initialize method
5/24/2022 • 2 minutes to read • Edit Online
Remarks
Initialize() cannot be called again without a subsequent Uninitialize call.
Every call to Initialize() should have a corresponding Uninitialize() call.
The playFabTitleId is read from PlayFab's static PlayFabSettings asset. It can be changed Using Unity menu,
PlayFab | MakePlayFabSharedSettings menu. It must be the same PlayFab Title ID used to acquire the PlayFab
Entity Keys and Entity Tokens that will be passed to !:PlayFabMultiplayer.SetEntityToken().
See Also
method Uninitialize
class PlayFabMultiplayer
namespace PlayFab.Multiplayer
PlayFabMultiplayer.JoinArrangedLobby method
5/24/2022 • 2 minutes to read • Edit Online
PlayFabMultiplayer.JoinArrangedLobby (1 of 2)
public static Lobby JoinArrangedLobby(PFEntityKey newMember, string arrangementString,
LobbyArrangedJoinConfiguration config)
See Also 1
class Lobby
class PFEntityKey
class LobbyArrangedJoinConfiguration
class PlayFabMultiplayer
namespace PlayFab.Multiplayer
PlayFabMultiplayer.JoinArrangedLobby (2 of 2)
public static Lobby JoinArrangedLobby(PlayFabAuthenticationContext newMember,
string arrangementString, LobbyArrangedJoinConfiguration config)
See Also 2
class Lobby
class LobbyArrangedJoinConfiguration
class PlayFabMultiplayer
namespace PlayFab.Multiplayer
PlayFabMultiplayer.JoinLobby method
5/24/2022 • 2 minutes to read • Edit Online
PlayFabMultiplayer.JoinLobby (1 of 2)
public static Lobby JoinLobby(PFEntityKey newMember, string connectionString,
IDictionary<string, string> memberKeyValuePairs)
See Also 1
class Lobby
class PFEntityKey
class PlayFabMultiplayer
namespace PlayFab.Multiplayer
PlayFabMultiplayer.JoinLobby (2 of 2)
public static Lobby JoinLobby(PlayFabAuthenticationContext newMember, string connectionString,
IDictionary<string, string> memberKeyValuePairs)
See Also 2
class Lobby
class PlayFabMultiplayer
namespace PlayFab.Multiplayer
PlayFabMultiplayer.JoinMatchmakingTicketFromId
method
5/24/2022 • 2 minutes to read • Edit Online
PlayFabMultiplayer.JoinMatchmakingTicketFromId (1 of 2)
Joins one or more multiple local users to a matchmaking ticket using a ticket ID and queue name.
PA RA M ET ER DESC RIP T IO N
localUsers The array of local users along with local user attributes to
include in the ticket.
Return Value 1
The resulting ticket object.
Remarks 1
The library automatically, and asynchronously, will submit all local users to join the ticket on the matchmaking
service. Each time the ticket status changes, a OnMatchmakingTicketStatusChanged will be provided. The ticket
status can be quered at any time via Status . The ticket immediately starts in the
MatchmakingTicketStatus.Joining state.
When the ticket has completed, a OnMatchmakingTicketStatusChanged will be provided. At that point, a match will
have been found or the ticket stopped due to failure. On success, the match that was found can be queried via
GetMatchDetails .
All existing tickets in which a local user is a member will be canceled as part of this operation.
See Also 1
class MatchmakingTicket
struct MatchUser
class PFEntityKey
class PlayFabMultiplayer
namespace PlayFab.Multiplayer
PlayFabMultiplayer.JoinMatchmakingTicketFromId (2 of 2)
Joins one or more multiple local users to a matchmaking ticket using a ticket ID and queue name.
PA RA M ET ER DESC RIP T IO N
localUser The local user along with local user attributes to include in
the ticket.
Return Value 2
The resulting ticket object.
Remarks 2
The library automatically, and asynchronously, will submit all local users to join the ticket on the matchmaking
service. Each time the ticket status changes, a OnMatchmakingTicketStatusChanged will be provided. The ticket
status can be quered at any time via Status . The ticket immediately starts in the
MatchmakingTicketStatus.Joining state.
When the ticket has completed, a OnMatchmakingTicketStatusChanged will be provided. At that point, a match will
have been found or the ticket stopped due to failure. On success, the match that was found can be queried via
GetMatchDetails .
All existing tickets in which a local user is a member will be canceled as part of this operation.
See Also 2
class MatchmakingTicket
struct MatchUser
class PFEntityKey
class PlayFabMultiplayer
PlayFabMultiplayer.ProcessLobbyStateChanges
method
5/24/2022 • 2 minutes to read • Edit Online
See Also
class PlayFabMultiplayer
namespace PlayFab.Multiplayer
PlayFabMultiplayer.ProcessMatchmakingStateChanges
method
5/24/2022 • 2 minutes to read • Edit Online
See Also
class PlayFabMultiplayer
namespace PlayFab.Multiplayer
PlayFabMultiplayer.SetEntityToken method
5/24/2022 • 4 minutes to read • Edit Online
PlayFabMultiplayer.SetEntityToken (1 of 2)
Sets the token that should be used for authentication when performing library actions on behalf of an entity. If a
token has previously been set for the entity, this replaces its previous token.
PA RA M ET ER DESC RIP T IO N
Remarks 1
This method takes a PlayFabAuthenticationContext authContext returned by a PlayFab login method. When the
library performs operations on behalf of an entity that require authentication or authorization, such as creating
or updating a lobby, the library will look up a token associated with the entity to use for the operation. If no
token has previously been set for the entity, the operation will synchronously fail. During the asynchronous
operation, the PlayFab service will validate that the token is valid, is not expired, is associated with the Entity ID
provided, and is authorized to perform the operation. If these conditions aren't met, the operation will fail.
A PlayFab Entity Key and Entity Token can be obtained from the output of a PlayFab login operation and then
provided as input to this method.
The provided authContext must have been acquired using the same PlayFab Title ID that was passed to
Initialize .
The Multiplayer library makes a copy of the supplied PlayFab Entity Token for use in subsequent operations that
require authentication or authorization of the local user, such as !:PlayFabMultiplayer.CreateAndJoinLobby(). If
the token provided to this call is expired or otherwise invalid, operations that require a valid token will fail. A
new, valid token can be provided to the Multiplayer library by calling this method again using the same entity
key.
The caller is responsible for monitoring the expiration of the entity token provided to this method. When the
token is nearing or past the expiration time a new token should be obtained by performing a PlayFab login
operation and provided to the Multiplayer library by calling this method again. It is recommended to acquire a
new token when the previously supplied token is halfway through its validity period. On platforms that may
enter a low power state or otherwise cause the application to pause execution for a long time, preventing the
token from being refreshed before it expires, the token should be checked for expiration once execution
resumes.
See Also 1
method Initialize
class PlayFabMultiplayer
namespace PlayFab.Multiplayer
PlayFabMultiplayer.SetEntityToken (2 of 2)
Sets the token that should be used for authentication when performing library actions on behalf of an entity. If a
token has previously been set for the entity, this replaces its previous token.
PA RA M ET ER DESC RIP T IO N
Remarks 2
This method takes a PlayFab Entity Key as localMember and a PlayFab Entity Token as entityToken. When the
library performs operations on behalf of an entity that require authentication or authorization, such as creating
or updating a lobby, the library will look up a token associated with the entity to use for the operation. If no
token has previously been set for the entity, the operation will synchronously fail. During the asynchronous
operation, the PlayFab service will validate that the token is valid, is not expired, is associated with the Entity ID
provided, and is authorized to perform the operation. If these conditions aren't met, the operation will fail.
A PlayFab Entity Key and Entity Token can be obtained from the output of a PlayFab login operation and then
provided as input to this method.
The provided localMember and entityToken must have been acquired using the same PlayFab Title ID that was
passed to Initialize .
The Multiplayer library makes a copy of the supplied PlayFab Entity Token for use in subsequent operations that
require authentication or authorization of the local user, such as !:PlayFabMultiplayer.CreateAndJoinLobby(). If
the token provided to this call is expired or otherwise invalid, operations that require a valid token will fail. A
new, valid token can be provided to the Multiplayer library by calling this method again using the same entity
key.
The caller is responsible for monitoring the expiration of the entity token provided to this method. When the
token is nearing or past the expiration time a new token should be obtained by performing a PlayFab login
operation and provided to the Multiplayer library by calling this method again. It is recommended to acquire a
new token when the previously supplied token is halfway through its validity period. On platforms that may
enter a low power state or otherwise cause the application to pause execution for a long time, preventing the
token from being refreshed before it expires, the token should be checked for expiration once execution
resumes.
See Also 2
method Initialize
class PFEntityKey
class PlayFabMultiplayer
namespace PlayFab.Multiplayer
PlayFabMultiplayer.StartListeningForLobbyInvites
method
5/24/2022 • 2 minutes to read • Edit Online
PlayFabMultiplayer.StartListeningForLobbyInvites (1 of 2)
Enables the Lobby invite listener for a given entity.
PA RA M ET ER DESC RIP T IO N
Remarks 1
This operation will synchronously start listening for invites on behalf of the provided entity. When invites are
received, they will be provided via OnLobbyInviteReceived events. When the status of the invite listener changes,
notifications will be provided via OnLobbyInviteListenerStatusChanged events.
Only invites sent after the listener has been started will be received on this client. Invites sent while this listener
is not active will not be queued.
Invite listening is, by default, disabled for all entities. This method should be called for each local entity that the
title wants to receive Lobby invites.
Lobby invites and this invite listener are unrelated to and unaffected by platform invite mechanisms.
This method may only be called if the Lobby invite listener is not already enabled for the given entity.
See Also 1
class PFEntityKey
class PlayFabMultiplayer
namespace PlayFab.Multiplayer
PlayFabMultiplayer.StartListeningForLobbyInvites (2 of 2)
Enables the Lobby invite listener for a given entity.
PA RA M ET ER DESC RIP T IO N
See Also 2
class PlayFabMultiplayer
namespace PlayFab.Multiplayer
PlayFabMultiplayer.StopListeningForLobbyInvites
method
5/24/2022 • 2 minutes to read • Edit Online
PlayFabMultiplayer.StopListeningForLobbyInvites (1 of 2)
Disables the Lobby invite listener for a given entity.
PA RA M ET ER DESC RIP T IO N
Remarks 1
This operation will synchronously stop listening for invites on behalf of the provided entity.
Invite notifications which have already been queued internally will still be provided via the next call to
!:PlayFabMultiplayer.ProcessingLobbyStateChanges().
Lobby invites and this invite listener are unrelated to and unaffected by platform invite mechanisms.
This method may only be called if the Lobby invite listener is already enabled for the given entity.
See Also 1
class PFEntityKey
class PlayFabMultiplayer
namespace PlayFab.Multiplayer
PlayFabMultiplayer.StopListeningForLobbyInvites (2 of 2)
Disables the Lobby invite listener for a given entity.
PA RA M ET ER DESC RIP T IO N
Remarks 2
This operation will synchronously stop listening for invites on behalf of the provided entity.
Invite notifications which have already been queued internally will still be provided via the next call to
!:PlayFabMultiplayer.ProcessingLobbyStateChanges().
Lobby invites and this invite listener are unrelated to and unaffected by platform invite mechanisms.
This method may only be called if the Lobby invite listener is already enabled for the given entity.
See Also 2
class PlayFabMultiplayer
namespace PlayFab.Multiplayer
PlayFabMultiplayer.Uninitialize method
5/24/2022 • 2 minutes to read • Edit Online
Immediately reclaims all resources associated with all Multiplayer library objects.
Remarks
If local users were participating in a Lobby, they are removed (it appears to remote lobby clients as if network
connectivity to these users has been lost), so best practice is to call !:Lobby.Leave() on all lobbies and wait for the
corresponding OnLobbyLeaveCompleted event to have the local users exit any existing lobbies.
This method is not thread-safe and may not be called concurrently with other Multiplayer library methods. After
calling this method, all Multiplayer library state is invalidated.
Titles using the Microsoft Game Core version of the Multiplayer library must listen for app state notifications via
the RegisterAppStateChangeNotification API. When the app is suspended, the title must call Uninitialize(). When
the app is resumed, the title must wait for the Game Core networking stack to be ready and then re-initialize the
Multiplayer library by calling Initialize().
Every call to Initialize should have a corresponding Uninitialize() call.
See Also
method Initialize
class PlayFabMultiplayer
namespace PlayFab.Multiplayer
Class PlayFabMultiplayerErrorArgs
5/24/2022 • 2 minutes to read • Edit Online
Properties
NAME DESC RIP T IO N
Code Gets the error code indicating the result of the operation.
See Also
namespace PlayFab.Multiplayer
PlayFabMultiplayerErrorArgs.Code property
5/24/2022 • 2 minutes to read • Edit Online
See Also
class PlayFabMultiplayerErrorArgs
namespace PlayFab.Multiplayer
PlayFabMultiplayerErrorArgs.Message property
5/24/2022 • 2 minutes to read • Edit Online
Gets a call-specific error message with debug information. This message is not localized as it is meant to be
used for debugging only.
See Also
class PlayFabMultiplayerErrorArgs
namespace PlayFab.Multiplayer
Class PlayfabMultiplayerEventProcessor
5/24/2022 • 2 minutes to read • Edit Online
Constructors
NAME DESC RIP T IO N
See Also
namespace PlayFab.Multiplayer
PlayfabMultiplayerEventProcessor constructor
5/24/2022 • 2 minutes to read • Edit Online
public PlayfabMultiplayerEventProcessor()
See Also
class PlayfabMultiplayerEventProcessor
namespace PlayFab.Multiplayer
Struct MatchUser
5/24/2022 • 2 minutes to read • Edit Online
Constructors
NAME DESC RIP T IO N
Properties
NAME DESC RIP T IO N
LocalUserJsonAttributesJSON The local user attributes as JSON string. There should be one
attribute string for each local user. Each attribute string
should either be an empty string or a serialized JSON object.
For example,
{"player_color":"blue","player_role":"tank"} .
See Also
namespace PlayFab.Multiplayer
MatchUser constructor
5/24/2022 • 2 minutes to read • Edit Online
MatchUser (1 of 2)
Initializes a new instance of the MatchUser struct.
PA RA M ET ER DESC RIP T IO N
localUserJsonAttributesJSON The array of local user attribute strings. There should be one
attribute string for each local user. Each attribute string
should either be an empty string or a serialized JSON object.
For example,
{"player_color":"blue","player_role":"tank"} .
See Also 1
class PFEntityKey
struct MatchUser
namespace PlayFab.Multiplayer
MatchUser (2 of 2)
Initializes a new instance of the MatchUser struct.
PA RA M ET ER DESC RIP T IO N
localUserJsonAttributesJSON The array of local user attribute strings. There should be one
attribute string for each local user. Each attribute string
should either be an empty string or a serialized JSON object.
For example,
{"player_color":"blue","player_role":"tank"} .
See Also 2
struct MatchUser
namespace PlayFab.Multiplayer
MatchUser.LocalUser property
5/24/2022 • 2 minutes to read • Edit Online
See Also
class PFEntityKey
struct MatchUser
namespace PlayFab.Multiplayer
MatchUser.LocalUserJsonAttributesJSON property
5/24/2022 • 2 minutes to read • Edit Online
The local user attributes as JSON string. There should be one attribute string for each local user. Each attribute
string should either be an empty string or a serialized JSON object. For example,
{"player_color":"blue","player_role":"tank"} .
See Also
struct MatchUser
namespace PlayFab.Multiplayer
LobbyAccessPolicy
5/24/2022 • 2 minutes to read • Edit Online
Values
NAME VA L UE DESC RIP T IO N
See Also
namespace PlayFab.Multiplayer
LobbyDisconnectingReason
5/24/2022 • 2 minutes to read • Edit Online
Values
NAME VA L UE DESC RIP T IO N
See Also
namespace PlayFab.Multiplayer
LobbyInviteListenerStatus
5/24/2022 • 2 minutes to read • Edit Online
Values
NAME VA L UE DESC RIP T IO N
See Also
namespace PlayFab.Multiplayer
LobbyMemberRemovedReason
5/24/2022 • 2 minutes to read • Edit Online
Values
NAME VA L UE DESC RIP T IO N
See Also
namespace PlayFab.Multiplayer
LobbyMembershipLock
5/24/2022 • 2 minutes to read • Edit Online
Values
NAME VA L UE DESC RIP T IO N
Unlocked 0
Locked 1
See Also
namespace PlayFab.Multiplayer
LobbyOwnerMigrationPolicy
5/24/2022 • 2 minutes to read • Edit Online
The available policies the lobby service can use to migrate lobby ownership between members.
Values
NAME VA L UE DESC RIP T IO N
See Also
namespace PlayFab.Multiplayer
PlayFab.Multiplayer.LogLevelType
5/24/2022 • 2 minutes to read • Edit Online
Values
NAME VA L UE DESC RIP T IO N
None 0 No logging
See Also
namespace PlayFab.Multiplayer
MatchmakingTicketStatus
5/24/2022 • 2 minutes to read • Edit Online
Values
NAME VA L UE DESC RIP T IO N
See Also
namespace PlayFab.Multiplayer
PlayStream Event Model reference
5/24/2022 • 10 minutes to read • Edit Online
These are the built-in PlayStream events which are automatically generated by PlayFab Game Services APIs and
written to the event pipeline. In addition to these events, you can create your own custom events using the
WriteEvents API.
Each event type has a set of properties that are included as part of event's data wherever it is sent. You can view
these properties and build rules for triggering actions based on their values in the PlayStream tab of the Game
Manager.
General
entity_created
This event is triggered when an entity is created.
entity_executed_cloud_script
This event is optionally triggered when an Entity CloudScript function is executed, either by calling the
ExecuteCloudScript API with the GeneratePlayStreamEvent option or triggered by a PlayStream event
action with the 'Publish results as a PlayStream Event' box checked.
entity_files_set
This event is triggered when files are attached to an entity.
entity_language_updated
This event is triggered when the language associated with an entity is changed.
entity_logged_in
This event is triggered when an entity has logged in.
entity_objects_set
This event is triggered when objects are attached to an entity.
entity_virtual_currency_balances_changed
This event is triggered when an entity's virtual currency balance changes.
group_created This event is triggered when an entity group is created.
group_deleted
This event is triggered when an entity group is deleted.
group_members_added
This event is triggered when a member is added to an entity group.
group_members_removed
This event is triggered when a member is removed from an entity group.
group_role_created
This event is triggered when a role is created for a group.
group_role_deleted
This event is triggered when a role is deleted from a group.
group_role_members_added
This event is triggered when a list of entities are added to a role within a group.
group_role_members_removed
This event is triggered when a list of entities are removed from a role within a group.
group_role_updated
This event is triggered when a role is updated within a group.
group_updated
This event is triggered when an entity group is updated.
matchmaking_match_found
This event is triggered when a group of tickets are matched together.
matchmaking_ticket_completed
This event is triggered when a matchmaking ticket reaches a completion state.
matchmaking_user_ticket_completed
This event is sent to each of the users in the completed ticket.
matchmaking_user_ticket_invite
This event is triggered when a ticket with an invited user is created. The event will be sent to the invited
user.
multiplayer_server_build_deleted
This event is triggered when a multiplayer server build is deleted.
multiplayer_server_build_region_status_changed
This event is triggered when a multiplayer server's build region status is changed.
multiplayer_server_build_region_updated
This event is triggered when a multiplayer server build region is updated.
multiplayer_server_certificate_deleted
This event is triggered when a multiplayer server certificate is deleted.
multiplayer_server_certificate_uploaded
This event is triggered when a multiplayer server certificate is uploaded.
multiplayer_server_create_build_initiated
This event is triggered when a multiplayer server build is initiated.
multiplayer_server_game_asset_deleted
This event is triggered when a multiplayer server game asset is deleted.
multiplayer_server_requested
This event is triggered when a multiplayer server shutdown is requested.
multiplayer_server_state_changed
This event is triggered when a multiplayer server's state is changed.
multiplayer_server_vm_assigned
This event is triggered when a virtual machine is assigned to a multiplayer server build.
multiplayer_server_vm_remote_user_created
This event is triggered when a multiplayer server virtual machine remote user is created.
multiplayer_server_vm_remote_user_deleted
This event is triggered when a multiplayer server virtual machine remote user is deleted.
multiplayer_server_vm_unassignment_started
This event is triggered when a virtual machine is unassigned from a multiplayer server build.
multiplayer_server_vm_unhealthy
This event is triggered when a virtual machine is found to be unhealthy.
studio_created
This event is triggered when a studio is created.
studio_user_added
This event is triggered when a user accepts a studio invitation.
studio_user_invited
This event is triggered when a user is invited to a studio.
studio_user_removed
This event is triggered when a user is removed from a studio.
tenancy_connector_onboard
This event is triggered when a tenancy connector is onboarded.
studio_tier_updated
This event is triggered when a studio tier is updated.
Character
character_consumed_item
This event is triggered when a character consumes an item from their inventory.
character_created
This event is triggered when a character is created for the first time.
character_inventory_item_added
This event is triggered when an item is granted to a character.
character_statistic_changed
This event is triggered when a character statistic is changed.
character_statistic_deleted
This event is triggered when a character statistic is deleted.
character_vc_item_purchased
This event is triggered when the character makes a purchase using virtual currency.
character_virtual_currency_balance_changed
This event is triggered when a character's virtual currency balance changes.
Partner
display_name_filtered
This event is triggered when a display name is filtered by community sift.
player_display_name_filtered
This event is triggered when a display name is filtered by community sift only if there is an associated
player EntityId for the event.
player_photon_session_authenticated
This event is triggered when a player connects to a Photon Cloud application and authenticates with
PlayFab using Photon custom authentication.
Player
auth_token_validated
This event is triggered when an email confirmation link is clicked.
title_deleted_master_player
This event is triggered when a GDPR delete is finished.
player_action_executed
This event is triggered when an action linked to a segmentation change or event rule executes on a player.
player_ad_campaign_attribution
This event is triggered by an attribution tracking Add-on when a player is matched to a paid acquisition
campaign.
player_ad_closed
This event is triggered when a player closes an ad.
player_added_title
This event is triggered when a player creates a new account for a title. Note: this event is triggered once
per title rather than once per publisher.
player_ad_ended
This event is triggered when a player finishes an ad.
player_ad_opened
This event is triggered when a player opens an ad.
player_ad_rewarded
This event is triggered when a player recieves an ad reward.
player_ad_activity_valued
Event triggered when reported value of ad view is recorded
player_ad_started
This event is triggered when a player starts an ad.
player_banned
This event is triggered when a player is banned.
player_changed_avatar
This event is triggered when a player's avatar URL is changed.
player_completed_password_reset
This event is triggered when a player completes the password reset process by visiting the link URL that
was sent to them and choosing a new password.
player_consumed_item
This event is triggered when a player consumes an item from their inventory.
player_created
This event is triggered when a player account is created for the first time. Note: this event is only
triggered once per publisher, not once per title.
player_data_exported
This event is triggered when a player's data is exported.
player_device_info
This event is triggered once after the player logs in based on the settings for your title.
player_displayname_changed
This event is triggered when a player's display name is changed.
player_executed_cloudscript
This event is optionally triggered when a CloudScript function is executed, either by calling the
ExecuteCloudScript API with the GeneratePlayStreamEvent option or triggered by a PlayStream event
action with the 'Publish results as a PlayStream Event' box checked.
player_inventory_item_added
This event is triggered when an item is granted to a player.
player_joined_lobby
This event is triggered when a player joins a multiplayer game session.
player_left_lobby
This event is triggered when a player leaves a multiplayer game session.
player_linked_account
This event is triggered when a new authentication method is linked to a player's account.
player_logged_in
This event is triggered when a player logs in.
player_matched_with_lobby
This event is triggered when a player is assigned to a game lobby and issued a connection ticket, before
the player has connected to the game lobby.
player_password_reset_link_sent
This event is triggered when a player is sent a link to reset their password.
player_paid_for_purchase
This event is triggered when the second step of the payment process completes, paying for the purchase.
player_ranked_on_leaderboard_version
This event is triggered for the top-ranked players on a leaderboard when the leaderboard version
changes (e.g. when a leaderboard statistic version is incremented). The maximum number of leaderboard
entries for which the event is generated is controlled by the "Leaderboard version change top rank events
sent" title limit.
player_realmoney_purchase
This event is triggered when a player makes a real money purchase, and generates revenue for the game.
player_receipt_validation
This event is triggered when a player attempts to make a real money purchase and the purchase receipt
is being validated.
player_redeemed_coupon
This event is triggered when a player redeems a coupon.
player_registered_push_notifications
This event is triggered when a player registers for push notifications.
player_removed_title
This event is triggered when a player account for a title is removed. Note: this event is triggered once per
title rather than once per publisher.
player_reported_as_abusive
This event is triggered when a player is reported by another player as abusive.
player_set_profile_property
This event is triggered when PlayFab makes an internal adjustment to a player profile.
player_started_purchase
This event is triggered when a player starts a purchase.
player_statistic_changed
This event is triggered when a player statistic is changed.
player_statistic_deleted
This event is triggered when a player statistic is deleted.
player_tag_added
This event is triggered when a tag is added to a player profile.
player_tag_removed
This event is triggered when a tag is removed from a player profile.
player_triggered_action_executed_cloudscript
This event is triggered when a CloudScript function is run as the result of a PlayStream action, and the
'Publish results as a PlayStream Event' box was checked.
player_unlinked_account
This event is triggered when an authentication method is unlinked from a player's account.
player_updated_contact_email
This event is triggered when a player updates a contact email on their profile.
player_vc_item_purchased
This event is triggered when the player makes a purchase using virtual currency.
player_verified_contact_email
This event is triggered when a contact email is verified for a player.
player_virtual_currency_balance_changed
This event is triggered when a player's virtual currency balance changes.
sent_push_notification
This event is triggered when a push notification is sent or fails to be sent to a player.
sent_email
This event is triggered when an email is sent or fails to send to a player.
Session
client_focus_change
This event is triggered every time the application enters or exits focus on the player's device.
client_session_start
This event is triggered when a new client session starts.
gamelobby_ended
This event is triggered when a multiplayer game lobby ends.
gamelobby_started
This event is triggered when a multiplayer game lobby starts.
gameserverhost_started
This event is triggered when a multiplayer game lobby starts.
gameserverhost_stopped
This event is triggered when a multiplayer game lobby stops.
session_ended
This event is triggered when a session ends
session_started
This event is triggered when a session starts.
Title
title_aborted_task
This event is triggered when a task instance is aborted.
title_added_cloudscript
This event is triggered when new CloudScript is uploaded to PlayFab.
title_game_build_added
This event is triggered when a new game build is uploaded for a game title.
title_api_settings_changed
This event is triggered when an API Features setting is changed for the title.
title_catalog_updated
This event is triggered when a catalog is changed.
title_client_rate_limited_alert
This event is triggered when a single IP address generates too many API calls to PlayFab and is throttled.
title_completed_task
This event is triggered when a scheduled task has completed
title_created_task
This event is triggered when a task is created.
title_deleted
This event is triggered when a game title is deleted.
title_deleted_task
This event is triggered when a task is deleted.
title_exceeded_limit
This event is triggererd when a title exceeds a service limit and receives an error.
title_high_error_rate_alert
This event is triggered when a game title experiences a high rate of errors.
title_initiated_player_password_reset
This event is triggered when a title initiates the account recovery process for a player.
title_limit_changed
This event is triggered when a title changes a service limit.
title_game_build_modified
This event is triggered when any of the game build settings are modified.
title_news_updated
This event is triggered when a title news is created or updated.
title_permission_policy_changed
This event is triggered when an update occurs to a a title's permission policies.
title_profile_view_constraints_changed
This event is triggered when a profile view constraint is changed for the title.
title_published_cloudscript
An inactive revision of CloudScript has been made into the active 'live' version.
title_queue_config_updated
This event is triggered when a queue config is changed.
title_requested_limit_change
This event is triggered when a title requests a service limit change.
title_saved_survey
This event is triggered when a game's survey is saved.
title_scheduled_cloudscript_executed
This event is triggered when a CloudScript function is run by a scheduled task.
title_secret_key_changed
This event is triggered when a title adds or updates a Secret Key
title_started_task
This event is triggered when a task is scheduled to run.
title_statistic_version_changed
This event is triggered when the version of a statistic changes, causing its leaderboard to reset.
title_store_updated
This event is triggered when a store is changed.
title_updated_task
This event is triggered when a task is updated.
auth_token_validated
5/24/2022 • 2 minutes to read • Edit Online
Properties
NAME TYPE DESC RIP T IO N
Common Properties
All PlayStream events are formatted as JSON objects and share the following common properties:
This event is triggered when a character consumes an item from their inventory.
Properties
NAME TYPE DESC RIP T IO N
PlayerId String
TitleId String
Common Properties
All PlayStream events are formatted as JSON objects and share the following common properties:
Properties
This event is triggered when a character is created for the first time.
PlayerId String
TitleId String
Common Properties
All PlayStream events are formatted as JSON objects and share the following common properties:
Properties
NAME TYPE DESC RIP T IO N
PlayerId String
TitleId String
Common Properties
All PlayStream events are formatted as JSON objects and share the following common properties:
Properties
NAME TYPE DESC RIP T IO N
PlayerId String
TitleId String
Common Properties
All PlayStream events are formatted as JSON objects and share the following common properties:
Properties
NAME TYPE DESC RIP T IO N
PlayerId String
TitleId String
Common Properties
All PlayStream events are formatted as JSON objects and share the following common properties:
This event is triggered when the character makes a purchase using virtual currency.
Properties
NAME TYPE DESC RIP T IO N
PlayerId String
TitleId String
Common Properties
All PlayStream events are formatted as JSON objects and share the following common properties:
Properties
NAME TYPE DESC RIP T IO N
PlayerId String
TitleId String
Common Properties
All PlayStream events are formatted as JSON objects and share the following common properties:
This event is triggered every time the application enters or exits focus on the player's device.
Properties
NAME TYPE DESC RIP T IO N
Common Properties
All PlayStream events are formatted as JSON objects and share the following common properties:
Common Properties
All PlayStream events are formatted as JSON objects and share the following common properties:
Properties
NAME TYPE DESC RIP T IO N
Common Properties
All PlayStream events are formatted as JSON objects and share the following common properties:
This event is optionally triggered when a CloudScript function is executed by calling the
ExecuteEntityCloudScript API. If you want the Event logged, you can pass in GeneratePlayStreamEvent.
Properties
NAME TYPE DESC RIP T IO N
Common Properties
All PlayStream events are formatted as JSON objects and share the following common properties:
Properties
NAME TYPE DESC RIP T IO N
Common Properties
All PlayStream events are formatted as JSON objects and share the following common properties:
This event is triggered when the language associated with an entity is changed.
Properties
NAME TYPE DESC RIP T IO N
Common Properties
All PlayStream events are formatted as JSON objects and share the following common properties:
Properties
NAME TYPE DESC RIP T IO N
Common Properties
All PlayStream events are formatted as JSON objects and share the following common properties:
Properties
NAME TYPE DESC RIP T IO N
Common Properties
All PlayStream events are formatted as JSON objects and share the following common properties:
Properties
NAME TYPE DESC RIP T IO N
Common Properties
All PlayStream events are formatted as JSON objects and share the following common properties:
Properties
NAME TYPE DESC RIP T IO N
Common Properties
All PlayStream events are formatted as JSON objects and share the following common properties:
Properties
NAME TYPE DESC RIP T IO N
Common Properties
All PlayStream events are formatted as JSON objects and share the following common properties:
Properties
NAME TYPE DESC RIP T IO N
Common Properties
All PlayStream events are formatted as JSON objects and share the following common properties:
Properties
NAME TYPE DESC RIP T IO N
Common Properties
All PlayStream events are formatted as JSON objects and share the following common properties:
Properties
NAME TYPE DESC RIP T IO N
Common Properties
All PlayStream events are formatted as JSON objects and share the following common properties:
Properties
NAME TYPE DESC RIP T IO N
Common Properties
All PlayStream events are formatted as JSON objects and share the following common properties:
Properties
NAME TYPE DESC RIP T IO N
Common Properties
All PlayStream events are formatted as JSON objects and share the following common properties:
Properties
NAME TYPE DESC RIP T IO N
Common Properties
All PlayStream events are formatted as JSON objects and share the following common properties:
Properties
NAME TYPE DESC RIP T IO N
Common Properties
All PlayStream events are formatted as JSON objects and share the following common properties:
Properties
NAME TYPE DESC RIP T IO N
Common Properties
All PlayStream events are formatted as JSON objects and share the following common properties:
This event is triggered when a list of entities are added to a role within a group.
Properties
NAME TYPE DESC RIP T IO N
Common Properties
All PlayStream events are formatted as JSON objects and share the following common properties:
This event is triggered when a list of entities are removed from a role within a group.
Properties
NAME TYPE DESC RIP T IO N
Common Properties
All PlayStream events are formatted as JSON objects and share the following common properties:
Properties
NAME TYPE DESC RIP T IO N
Common Properties
All PlayStream events are formatted as JSON objects and share the following common properties:
Properties
NAME TYPE DESC RIP T IO N
Common Properties
All PlayStream events are formatted as JSON objects and share the following common properties:
Properties
NAME TYPE DESC RIP T IO N
Common Properties
All PlayStream events are formatted as JSON objects and share the following common properties:
Properties
NAME TYPE DESC RIP T IO N
Common Properties
All PlayStream events are formatted as JSON objects and share the following common properties:
This event is triggered when a matchmaking ticket reaches a completion state. This event is sent to each of the
users in the completed ticket
Properties
NAME TYPE DESC RIP T IO N
Common Properties
All PlayStream events are formatted as JSON objects and share the following common properties:
This event is triggered when a ticket with an invited user is created. The event will be sent to the invited user.
Properties
NAME TYPE DESC RIP T IO N
Common Properties
All PlayStream events are formatted as JSON objects and share the following common properties:
Properties
NAME TYPE DESC RIP T IO N
Common Properties
All PlayStream events are formatted as JSON objects and share the following common properties:
This event is triggered when a multiplayer server's build region status is changed.
Properties
NAME TYPE DESC RIP T IO N
Common Properties
All PlayStream events are formatted as JSON objects and share the following common properties:
Properties
NAME TYPE DESC RIP T IO N
Common Properties
All PlayStream events are formatted as JSON objects and share the following common properties:
Properties
NAME TYPE DESC RIP T IO N
Common Properties
All PlayStream events are formatted as JSON objects and share the following common properties:
Properties
NAME TYPE DESC RIP T IO N
Common Properties
All PlayStream events are formatted as JSON objects and share the following common properties:
Properties
NAME TYPE DESC RIP T IO N
Common Properties
All PlayStream events are formatted as JSON objects and share the following common properties:
Properties
NAME TYPE DESC RIP T IO N
Common Properties
All PlayStream events are formatted as JSON objects and share the following common properties:
Properties
NAME TYPE DESC RIP T IO N
Common Properties
All PlayStream events are formatted as JSON objects and share the following common properties:
Properties
NAME TYPE DESC RIP T IO N
Common Properties
All PlayStream events are formatted as JSON objects and share the following common properties:
This event is triggered when a virtual machine is assigned to a multiplayer server build.
Properties
NAME TYPE DESC RIP T IO N
Common Properties
All PlayStream events are formatted as JSON objects and share the following common properties:
This event is triggered when a multiplayer server virtual machine remote user is created.
Properties
NAME TYPE DESC RIP T IO N
Common Properties
All PlayStream events are formatted as JSON objects and share the following common properties:
This event is triggered when a multiplayer server virtual machine remote user is deleted.
Properties
NAME TYPE DESC RIP T IO N
Common Properties
All PlayStream events are formatted as JSON objects and share the following common properties:
This event is triggered when a virtual machine is unassigned from a multiplayer server build.
Properties
NAME TYPE DESC RIP T IO N
Common Properties
All PlayStream events are formatted as JSON objects and share the following common properties:
This event is triggered when an action linked to a segmentation change or event rule executes on a player.
Properties
Common Properties
All PlayStream events are formatted as JSON objects and share the following common properties:
Properties
NAME TYPE DESC RIP T IO N
Common Properties
All PlayStream events are formatted as JSON objects and share the following common properties:
This event is triggered by an attribution tracking Add-on when a player is matched to a paid acquisition
campaign.
Properties
NAME TYPE DESC RIP T IO N
Common Properties
All PlayStream events are formatted as JSON objects and share the following common properties:
Properties
NAME TYPE DESC RIP T IO N
Common Properties
All PlayStream events are formatted as JSON objects and share the following common properties:
Properties
NAME TYPE DESC RIP T IO N
Common Properties
All PlayStream events are formatted as JSON objects and share the following common properties:
Properties
NAME TYPE DESC RIP T IO N
Common Properties
All PlayStream events are formatted as JSON objects and share the following common properties:
Properties
NAME TYPE DESC RIP T IO N
Common Properties
All PlayStream events are formatted as JSON objects and share the following common properties:
Properties
NAME TYPE DESC RIP T IO N
Common Properties
All PlayStream events are formatted as JSON objects and share the following common properties:
Properties
NAME TYPE DESC RIP T IO N
Common Properties
All PlayStream events are formatted as JSON objects and share the following common properties:
This event is triggered when a player creates a new account for a title. Note: this event is triggered once per title
rather than once per publisher.
Properties
NAME TYPE DESC RIP T IO N
Common Properties
All PlayStream events are formatted as JSON objects and share the following common properties:
Properties
NAME TYPE DESC RIP T IO N
Common Properties
All PlayStream events are formatted as JSON objects and share the following common properties:
Properties
NAME TYPE DESC RIP T IO N
Common Properties
All PlayStream events are formatted as JSON objects and share the following common properties:
This event is triggered when a player completes the password reset process by visiting the link URL that was
sent to them and choosing a new password.
Properties
NAME TYPE DESC RIP T IO N
Common Properties
All PlayStream events are formatted as JSON objects and share the following common properties:
This event is triggered when a player consumes an item from their inventory.
Properties
NAME TYPE DESC RIP T IO N
Common Properties
All PlayStream events are formatted as JSON objects and share the following common properties:
This event is triggered when a player account is created for the first time. Note: this event is only triggered once
per publisher, not once per title.
Properties
NAME TYPE DESC RIP T IO N
Common Properties
All PlayStream events are formatted as JSON objects and share the following common properties:
Properties
NAME TYPE DESC RIP T IO N
Common Properties
All PlayStream events are formatted as JSON objects and share the following common properties:
This event is triggered once after the player logs in based on the settings for your title.
Properties
NAME TYPE DESC RIP T IO N
DeviceInfo Object
Common Properties
All PlayStream events are formatted as JSON objects and share the following common properties:
This event is triggered when a display name is filtered by community sift only if there is an associated player
EntityId for the event.
Properties
NAME TYPE DESC RIP T IO N
Common Properties
All PlayStream events are formatted as JSON objects and share the following common properties:
Properties
NAME TYPE DESC RIP T IO N
Common Properties
All PlayStream events are formatted as JSON objects and share the following common properties:
This event is optionally triggered when a CloudScript function is executed, either by calling the
ExecuteCloudScript API with the GeneratePlayStreamEvent option or triggered by a PlayStream event action
with the 'Publish results as a PlayStream Event' box checked.
Properties
NAME TYPE DESC RIP T IO N
Common Properties
All PlayStream events are formatted as JSON objects and share the following common properties:
Properties
NAME TYPE DESC RIP T IO N
Common Properties
All PlayStream events are formatted as JSON objects and share the following common properties:
Properties
NAME TYPE DESC RIP T IO N
Common Properties
All PlayStream events are formatted as JSON objects and share the following common properties:
Properties
NAME TYPE DESC RIP T IO N
Common Properties
All PlayStream events are formatted as JSON objects and share the following common properties:
This event is triggered when a new authentication method is linked to a player's account.
Properties
NAME TYPE DESC RIP T IO N
Common Properties
All PlayStream events are formatted as JSON objects and share the following common properties:
Properties
NAME TYPE DESC RIP T IO N
Common Properties
All PlayStream events are formatted as JSON objects and share the following common properties:
This event is triggered when a player is assigned to a game lobby and issued a connection ticket, before the
player has connected to the game lobby.
Properties
NAME TYPE DESC RIP T IO N
Common Properties
All PlayStream events are formatted as JSON objects and share the following common properties:
Properties
NAME TYPE DESC RIP T IO N
Properties
NAME TYPE DESC RIP T IO N
This event is triggered when the second step of the payment process completes, paying for the purchase.
Properties
NAME TYPE DESC RIP T IO N
Common Properties
All PlayStream events are formatted as JSON objects and share the following common properties:
This event is triggered when a player is sent a link to reset their password.
Properties
NAME TYPE DESC RIP T IO N
Common Properties
All PlayStream events are formatted as JSON objects and share the following common properties:
This event is triggered when a player connects to a Photon Cloud application and authenticates with PlayFab
using Photon custom authentication.
Properties
Common Properties
All PlayStream events are formatted as JSON objects and share the following common properties:
This event is triggered for the top-ranked players on a leaderboard when the leaderboard version changes (e.g.
when a leaderboard statistic version is incremented). The maximum number of leaderboard entries for which
the event is generated is controlled by the "Leaderboard version change top rank events sent" title limit.
Properties
NAME TYPE DESC RIP T IO N
Common Properties
All PlayStream events are formatted as JSON objects and share the following common properties:
This event is triggered when a player makes a real money purchase, and generates revenue for the game.
Properties
NAME TYPE DESC RIP T IO N
Common Properties
All PlayStream events are formatted as JSON objects and share the following common properties:
This event is triggered when a player attempts to make a real money purchase and the purchase receipt is being
validated.
Properties
NAME TYPE DESC RIP T IO N
Common Properties
All PlayStream events are formatted as JSON objects and share the following common properties:
Properties
NAME TYPE DESC RIP T IO N
Common Properties
All PlayStream events are formatted as JSON objects and share the following common properties:
Properties
NAME TYPE DESC RIP T IO N
Common Properties
All PlayStream events are formatted as JSON objects and share the following common properties:
This event is triggered when a player account for a title is removed. Note: this event is triggered once per title
rather than once per publisher.
Properties
NAME TYPE DESC RIP T IO N
Common Properties
All PlayStream events are formatted as JSON objects and share the following common properties:
Properties
NAME TYPE DESC RIP T IO N
Common Properties
All PlayStream events are formatted as JSON objects and share the following common properties:
This event is triggered when PlayFab makes an internal adjustment to a player profile.
Properties
NAME TYPE DESC RIP T IO N
Common Properties
All PlayStream events are formatted as JSON objects and share the following common properties:
Properties
NAME TYPE DESC RIP T IO N
Common Properties
All PlayStream events are formatted as JSON objects and share the following common properties:
Properties
NAME TYPE DESC RIP T IO N
Common Properties
All PlayStream events are formatted as JSON objects and share the following common properties:
Properties
NAME TYPE DESC RIP T IO N
Common Properties
All PlayStream events are formatted as JSON objects and share the following common properties:
Properties
NAME TYPE DESC RIP T IO N
Common Properties
All PlayStream events are formatted as JSON objects and share the following common properties:
Properties
NAME TYPE DESC RIP T IO N
Common Properties
All PlayStream events are formatted as JSON objects and share the following common properties:
This event is triggered when a CloudScript function is run as the result of a PlayStream action, and the 'Publish
results as a PlayStream Event' box was checked.
Properties
NAME TYPE DESC RIP T IO N
Common Properties
All PlayStream events are formatted as JSON objects and share the following common properties:
This event is triggered when an authentication method is unlinked from a player's account.
Properties
NAME TYPE DESC RIP T IO N
Common Properties
All PlayStream events are formatted as JSON objects and share the following common properties:
This event is triggered when a player updates a contact email on their profile.
Properties
NAME TYPE DESC RIP T IO N
Common Properties
All PlayStream events are formatted as JSON objects and share the following common properties:
This event is triggered when the player makes a purchase using virtual currency.
Properties
NAME TYPE DESC RIP T IO N
Common Properties
All PlayStream events are formatted as JSON objects and share the following common properties:
Properties
NAME TYPE DESC RIP T IO N
Common Properties
All PlayStream events are formatted as JSON objects and share the following common properties:
Properties
NAME TYPE DESC RIP T IO N
Common Properties
All PlayStream events are formatted as JSON objects and share the following common properties:
Properties
NAME TYPE DESC RIP T IO N
Common Properties
All PlayStream events are formatted as JSON objects and share the following common properties:
NAME TYPE DESC RIP T IO N
This event is triggered when a push notification is sent or fails to be sent to a player.
Properties
NAME TYPE DESC RIP T IO N
Common Properties
All PlayStream events are formatted as JSON objects and share the following common properties:
Properties
NAME TYPE DESC RIP T IO N
Common Properties
All PlayStream events are formatted as JSON objects and share the following common properties:
Properties
NAME TYPE DESC RIP T IO N
Common Properties
All PlayStream events are formatted as JSON objects and share the following common properties:
Properties
NAME TYPE DESC RIP T IO N
Common Properties
All PlayStream events are formatted as JSON objects and share the following common properties:
Properties
NAME TYPE DESC RIP T IO N
Common Properties
All PlayStream events are formatted as JSON objects and share the following common properties:
Properties
NAME TYPE DESC RIP T IO N
Common Properties
All PlayStream events are formatted as JSON objects and share the following common properties:
Properties
NAME TYPE DESC RIP T IO N
Common Properties
All PlayStream events are formatted as JSON objects and share the following common properties:
Properties
NAME TYPE DESC RIP T IO N
Common Properties
All PlayStream events are formatted as JSON objects and share the following common properties:
Properties
NAME TYPE DESC RIP T IO N
Common Properties
All PlayStream events are formatted as JSON objects and share the following common properties:
Properties
NAME TYPE DESC RIP T IO N
DeveloperId String
UserId String
Common Properties
All PlayStream events are formatted as JSON objects and share the following common properties:
Properties
NAME TYPE DESC RIP T IO N
DeveloperId String
UserId String
Common Properties
All PlayStream events are formatted as JSON objects and share the following common properties:
This event is triggered when an API Features setting is changed for the title.
Properties
NAME TYPE DESC RIP T IO N
DeveloperId String
UserId String
Common Properties
All PlayStream events are formatted as JSON objects and share the following common properties:
Properties
NAME TYPE DESC RIP T IO N
DeveloperId String
UserId String
Common Properties
All PlayStream events are formatted as JSON objects and share the following common properties:
This event is triggered when a single IP address generates too many API calls to PlayFab and is throttled.
Properties
NAME TYPE DESC RIP T IO N
Common Properties
All PlayStream events are formatted as JSON objects and share the following common properties:
Properties
NAME TYPE DESC RIP T IO N
Common Properties
All PlayStream events are formatted as JSON objects and share the following common properties:
Properties
NAME TYPE DESC RIP T IO N
DeveloperId String
Common Properties
All PlayStream events are formatted as JSON objects and share the following common properties:
Common Properties
All PlayStream events are formatted as JSON objects and share the following common properties:
Properties
NAME TYPE DESC RIP T IO N
Common Properties
All PlayStream events are formatted as JSON objects and share the following common properties:
Properties
NAME TYPE DESC RIP T IO N
DeveloperId String
UserId String
Common Properties
All PlayStream events are formatted as JSON objects and share the following common properties:
This event is triggererd when a title exceeds a service limit and receives an error.
Properties
NAME TYPE DESC RIP T IO N
Common Properties
All PlayStream events are formatted as JSON objects and share the following common properties:
This event is triggered when a new game build is uploaded for a game title.
Properties
NAME TYPE DESC RIP T IO N
DeveloperId String
UserId String
Common Properties
All PlayStream events are formatted as JSON objects and share the following common properties:
This event is triggered when any of the game build settings are modified.
Properties
NAME TYPE DESC RIP T IO N
DeveloperId String
UserId String
Common Properties
All PlayStream events are formatted as JSON objects and share the following common properties:
This event is triggered when a game title experiences a high rate of errors.
Properties
NAME TYPE DESC RIP T IO N
Common Properties
All PlayStream events are formatted as JSON objects and share the following common properties:
This event is triggered when a title initiates the account recovery process for a player.
Properties
NAME TYPE DESC RIP T IO N
DeveloperId String
UserId String
Common Properties
All PlayStream events are formatted as JSON objects and share the following common properties:
Properties
NAME TYPE DESC RIP T IO N
Common Properties
All PlayStream events are formatted as JSON objects and share the following common properties:
Properties
NAME TYPE DESC RIP T IO N
Common Properties
All PlayStream events are formatted as JSON objects and share the following common properties:
Properties
NAME TYPE DESC RIP T IO N
DeveloperId String
UserId String
Common Properties
All PlayStream events are formatted as JSON objects and share the following common properties:
This event is triggered when a profile view constraint is changed for the title.
Properties
NAME TYPE DESC RIP T IO N
DeveloperId String
UserId String
Common Properties
All PlayStream events are formatted as JSON objects and share the following common properties:
An inactive revision of CloudScript has been made into the active 'live' version.
Properties
NAME TYPE DESC RIP T IO N
DeveloperId String
UserId String
Common Properties
All PlayStream events are formatted as JSON objects and share the following common properties:
Properties
NAME TYPE DESC RIP T IO N
DeveloperId String
UserId String
Common Properties
All PlayStream events are formatted as JSON objects and share the following common properties:
Properties
NAME TYPE DESC RIP T IO N
DeveloperId String
UserId String
Common Properties
All PlayStream events are formatted as JSON objects and share the following common properties:
Properties
NAME TYPE DESC RIP T IO N
Common Properties
All PlayStream events are formatted as JSON objects and share the following common properties:
Properties
NAME TYPE DESC RIP T IO N
Common Properties
All PlayStream events are formatted as JSON objects and share the following common properties:
Properties
NAME TYPE DESC RIP T IO N
DeveloperId String
UserId String
Common Properties
All PlayStream events are formatted as JSON objects and share the following common properties:
Properties
NAME TYPE DESC RIP T IO N
DeveloperId String
UserId String
Common Properties
All PlayStream events are formatted as JSON objects and share the following common properties:
This event is triggered when the version of a statistic changes, causing its leaderboard to reset.
Properties
NAME TYPE DESC RIP T IO N
Common Properties
All PlayStream events are formatted as JSON objects and share the following common properties:
Properties
NAME TYPE DESC RIP T IO N
DeveloperId String
UserId String
Common Properties
All PlayStream events are formatted as JSON objects and share the following common properties:
Properties
NAME TYPE DESC RIP T IO N
DeveloperId String
HasRenamed Boolean
UserId String
Common Properties
All PlayStream events are formatted as JSON objects and share the following common properties:
The API Access Policy controls access to API resources. At times it is necessary for a title to allow or deny certain
APIs from the game client, for anti-cheat or other security purposes. You can control the access using Policy
Statements to specify a set of access rules that are applied in specific situations.
This topic discusses the use API permission policies to create the appropriate rules.
IMPORTANT
This guide discusses advanced techniques. If applied incorrectly, it is possible to completely disable client access to your
title using this feature.
"Statements": [
{
"Resource": "pfrn:api--*",
"Action": "*",
"Effect": "Allow",
"Principal": "*",
"Comment": "The default allow all policy"
}
]
Each set of Permission Statements consists of the following items as defined in Authentication - Update Policy:
Resource - A string that uniquely identifies one or more PlayFab resources.
To describe the API resource, use the convention shown below.
pfrn:api--/API-GROUP/API-CALL
Action - A string that describes an operation to perform on the resource. Use * to match any operation.
Effect - A string that specifies a rule definition. Use Allow or Deny to allow or deny operations over the
resource.
Principal - A string that uniquely identifies the class of the user. Use * to match any user.
Comment - A user-defined string that provides more information about the policy statement.
ApiConditions - An optional object that defines advanced rule conditions, for example - Encryption and
Signed Headers.
You can set strong security rules for your application by modifying your policy to use more detailed permission
statements that only allows access by the APIs you use in your application.
The following example shows how to restrict the DeleteCharacterFromUser call:
{
"Resource": "pfrn:api--/Server/DeleteCharacterFromUser",
"Action": "",
"Effect": "Deny",
"Principal": "",
"Comment": "Disable server character delete"
}
},error=>Debug.LogError(error.GenerateErrorReport()));
}
The image below shows an example of the output after the code is run the first time. As shown, the policy
consists of several Permission Statements.
Global API method error codes
5/24/2022 • 3 minutes to read • Edit Online
This tutorial lists the global error codes that apply to every PlayFab API method. The following information can
be used to decipher API errors.
Each API error contains the following fields:
Error - A human-readable code for the error.
ErrorCode - A numerical code for the error.
NOTE
This page lists the common error codes that you might encounter. If the error code you are looking for is not available on
this page, ask for additional information on the PlayFab forum.
InvalidParams (1000) : The API request object sent to PlayFab has invalid parameters and cannot be
executed.
InvalidRequest (1071) : The API request object sent to PlayFab is invalid and cannot be executed.
InvalidTitleId (1004) : The request provided a TitleId which does not match the title provided in the URL
of the method. In most SDKs, you should not specify a TitleId for login requests, as it is done for you. In
the admin API, explicit TitleIds are a Dev ->Test ->Live safety feature.
NotAuthenticated (1074) : The client has tried to call an API that requires SessionTicket authentication,
without logging in first.
NotAuthorized (1089) : Incorrect credentials, or otherwise bad inputs related to logging in.
NotAuthorizedByTitle (1191) : This method has been disabled by the API Policy, and cannot be called.
ProfileDoesNotExist (1298) : Attempted to access an entity (player, character, title, etc.), which does not
exist. Probably a typo, or you've got a bad input somewhere.
TitleDeleted (1347) : This title has been deleted from PlayFab, and can no longer be used.
UnknownError (1039) : This typically occurs if bad information is sent to a third-party add-on, and our
server experienced an unknown result or error while interacting with external systems. To resolve this,
experiment with your inputs, and try to determine if your inputs are invalid in some way. Otherwise,
report the error on the forums, with your titleId, the full request JSON (if possible), and the error output.
Postman is a useful tool for debugging this situation.
This article lists global HTTP response status codes and what they mean. It also includes extra description that
generally applies to all PlayFab APIs.
Use this page as a reference guide to troubleshoot issues related to HTTP web requests. For specific descriptions
that relate to a particular API, you have to go to the documentation page for that API.
If you're getting a status code that is not listed here, let us know on PlayFab forums and categorize your question
under API and SDK questions .
NOTE
Not every API can return all of the status codes listed below. There are APIs that only return some of the codes.
200 OK: Returned for all successful requests. May indicate partial
success for bulk APIs.
413 Payload Too Large: The request is larger than the server is
allowed to handle. Do not retry. If unexpected, contact
support.
H T T P STAT US C O DE GEN ERA L DESC RIP T IO N
414 URI Too Long: The URI in the request is longer than the
server is allowed to handle. Do not retry.
429 Too Many Requests: API calls are being rate limited. Pause
and then retry request, check if API returned “Retry-After”
header or retryAfter in JSON response for delay needed.
501 Not Implemented: The API called has not been implemented
yet. Do not retry.
See also
PlayFab API reference documentation
SDKs overview
5/24/2022 • 2 minutes to read • Edit Online
PlayFab SDK
PlayFab SDK enables you to use a majority of our features, including LiveOps, economy, matchmaking, and data
analytics. For more information, see PlayFab SDKs.
TIP
We strongly recommend that you use the latest versions of the SDKs. All SDK versions released in the past 6 months are
fully supported unless specified otherwise. For Unreal Engine and Unity plugins, we generally support the latest 2
versions. With each release of the SDKs, we support compatibility with newest partner platform versions. Please reach out
to developer support if you have any questions.
See also
PlayFab Party SDKs
PlayFab Party quickstart
PlayFab Multiplayer Game Server SDKs
PlayFab Multiplayer Server quickstart (API/PowerShell)
PlayFab Multiplayer Server quickstart (Game Manager)
Request access for secured SDKs and samples
5/24/2022 • 2 minutes to read • Edit Online
This topic provides information about how you can access SDKs and samples for Nintendo Switch ,
PlayStation 4 , PlayStation 5 , and Google Stadia .
Adhering to platform policies, we need to ensure that you're a registered developer before granting access, so a
few extra steps are required from you. For example, you need to be a registered Switch developer to get access
to Party SDKs and samples for Switch.
NOTE
For other platforms, operating systems, and frameworks, you don't have to request for access to start using Party SDKs
and samples.
If you're not yet a registered developer for the previously mentioned platforms and want to become one, go to
their developer page to learn more. To become a registered developer for Xbox and PC, go to ID@Xbox.
Stadia
1. Email PlayFabSdkAccess@microsoft.com with your developer information.
2. After we've verified that you're a registered developer for Stadia, we'll grant you access.
Need help?
If you have more questions, post them on PlayFab forums or directly contact developer support for Nintendo,
Sony, Google, or Xbox.
See also
Party SDKs
Party samples
Getting started with Party
Azure Playfab Lobby and Matchmaking SDKs
5/24/2022 • 2 minutes to read • Edit Online
[!IMPORTANT] This feature is currently in public preview. It is provided to give you an early look at an
upcoming feature, and to allow you to provide feedback while it is still in development.
This article describes all the Azure PlayFab Lobby and Matchmaking SDKs that are currently available.
If you don't find what you need, let us know by writing a post on our forums.
Access to SDKs for Nintendo Switch, PlayStation 4, PlayStation 5, and Xbox (GDK) requires special approval and
adherence to platform policies.
If you're looking for the core PlayFab SDK that helps you implement most of our features, including LiveOps,
economy, matchmaking, and data analytics, see PlayFab SDKs.
[!Tip] Unsure if this is the SDK you need? See SDK overview - PlayFab SDK, Party SDK, Multiplayer Server
SDK.
By content type
SDK / L IB RA RY P L AT F O RM / O P ERAT IN G SY ST EM
See also
Quickstart for Unity
Quickstart for Unreal
Lobby overview
Getting started with Lobby
PlayFab Multiplayer C++ SDK release notes
5/24/2022 • 2 minutes to read • Edit Online
1.1.1
April 13, 2022
Bug fixes
Switch: Provides a new PAL header required to build against PlayFab Multiplayer.
1.1.0
March 4, 2022
API changes
PFMultiplayerGetErrorMessage's API signature has changed. Previously this function returned an HRESULT
and used an output paramter to return the error message string. Now the function returns the string directly.
New features
GDK: Added support for automatically handling suspend and resume on Xbox.
Bug fixes
Fixed a bug where using initial member data passed to PFMultiplayerJoinLobby would be ignored if the
player was rejoining a lobby.
1.0.0
November 23, 2021
PlayFab Multiplayer is now available in private preview. For an overview of Matchmaking and Lobby features,
check out:
PlayFab Lobby Overview
PlayFab Multiplayer Lobby Quickstart
PlayFab Matchmaking Overview
PlayFab Multiplayer Matchmaking Quickstart
Overview
5/24/2022 • 2 minutes to read • Edit Online
The PlayFab Online Subsystem (PF OSS) enables you to make use of Multiplayer features like Lobby,
Matchmaking, Party and Azure Cognitive Services in your Unreal Engine 4 (UE4) game. These features include
cross-talk, cross-play, and accessibility features like real-time text chat translation and voice transcription
services. It is currently designed for use when developing PC, Xbox, Steam and Nintendo Switch games. This
subsystem layer works seamlessly on top of the existing Epic provided base Online Subsystem (OSS) GDK.
PlayFab OSS compliments the base OSS by adding support for PlayFab Lobby, Matchmaking, Party networking
and Voice over Internet Protocol (VOIP).
PlayFab OSS works alongside the PlayFab SDK marketplace plugin, which provides other PlayFab functionalities
such as economy, leaderboards, and more. For more information, see PlayFab SDK on the UE4 Marketplace
(external site).
Pricing
VOIP and Game Networking functionality is free for users signed in with an Xbox Live account,
regardless of platform.
Cognitive services and other services may have a cost associated with them. For details, see Billing for PlayFab
Party or reach out to your Microsoft Representative.
QuickStart: PlayFab Online Subsystem (OSS)
5/24/2022 • 3 minutes to read • Edit Online
This quickstart guide helps you set up and use Multiplayer features such as Lobby, Matchmaking and Party for
Xbox, PC, and Nintendo Switch games built using Unreal Engine 4. For the full list of supported platforms and
versions in UE4, see Supported platforms.
After following the relevant steps below for your target platforms, you'll be ready to start using the OSS.
Authentication, networking, VOIP, grouping into lobbies, and matchmaking will be handled on your behalf with
no other changes required.
Initial setup
Copy the OnlineSubsystemPlayFab folder and its contents from to your UE4 directory under
Engine\Plugins\Online
Apply the following changes to the Plugins section of your ".uproject" file. This will add the
OnlineSubsystemPlayFab to your plugin list.
You may remove any platforms that you're not shipping on
{
"Name": "OnlineSubsystemPlayFab",
"Enabled": true,
"WhitelistPlatforms": [
"XboxOneGDK",
"WinGDK",
"XSX",
"Win64",
"Switch"
],
"SupportedTargetPlatforms": [
"XboxOneGDK",
"WinGDK",
"XSX",
"Win64",
"Switch"
]
}
Game Configuration
No matter which platform you're targeting, your game will need to configure certain PlayFab specific values
in your intended platform target's INI file (located at [yourGameDirectory]/Platforms/[yourPlatform]/Config).
Xbox Series X GDK: XSXEngine.ini
PC GDK: WinGDKEngine.ini
Xbox One GDK: XboxOneGDKEngine.ini
PC Steam: WindowsEngine.ini
Nintendo Switch SwitchEngine.ini
Replace the INI sections in the config if they already exist (for example, Engine.GameEngine) with the ones
below.
Ensure you replace all the <REPLACE ME> fields with your data:
[OnlineSubsystemPlayFab]
bEnabled=true
PlayFabTitleID=<REPLACE ME with your PlayFab title ID>
MaxDeviceCount=<REPLACE ME with your max player count (note: split screen is still 1 device). In the example
of an 8 player game, this would be 8.>
MaxDevicesPerUserCount=<REPLACE ME with your max player count per box (note: split screen is still 1 device)
In the example of an 8 player game, this would be 1.>
MaxEndpointsPerDeviceCount=<REPLACE ME with your max player count per box (note: split screen is still 1
device) In the example of an 8 player game, this would be 1.>
MaxUserCount=<REPLACE ME with your max player count (note: split screen is still 1 device) In the example
of an 8 player game, this would be 8.>
MaxUsersPerDeviceCount=<REPLACE ME with your max player count per box (note: split screen is still 1 device)
In the example of an 8 player game, this would be 1.>
DirectPeerConnectivityOptions=<REPLACE ME with your connectivity options, in the form of an array of
strings. The default case corresponds to the following:
+DirectPeerConnectivityOptions=AnyPlatformType
+DirectPeerConnectivityOptions=AnyEntityLoginProvider>
[/Script/OnlineSubsystemPlayFab.PlayFabNetDriver]
NetConnectionClassName="OnlineSubsystemPlayFab.PlayFabNetConnection"
ReplicationDriverClassName="<REPLACE ME with your existing replication driver class name>"
ConnectionTimeout=15.0
InitialConnectTimeout=30.0
[/Script/Engine.GameEngine]
!NetDriverDefinitions=ClearArray
+NetDriverDefinitions=
(DefName="GameNetDriver",DriverClassName="OnlineSubsystemPlayFab.PlayFabNetDriver",DriverClassNameFallback="
OnlineSubsystemUtils.IpNetDriver")
[OnlineSubsystem]
DefaultPlatformService=PlayFab
NativePlatformService=GDK
[OnlineSubsystemPlayFab]
Sandbox=<Optional, REPLACE ME with the sandbox Id used for the title under development >
Steam
If you're developing games for Win64 with Steam, define your platform services:
[OnlineSubsystem]
DefaultPlatformService=PlayFab
NativePlatformService=Steam
Switch
See the ReadMe.md file that comes with the Switch PlayFab OSS for more details.
Cross-platform
Finally, if your game makes use PlayFab's cross-platform networking support, define which platforms you'll
permit to connect:
[/Script/OnlineSubsystemUtils.OnlineEngineInterfaceImpl]
!CompatibleUniqueNetIdTypes=ClearArray
+CompatibleUniqueNetIdTypes=STEAM
+CompatibleUniqueNetIdTypes=GDK
+CompatibleUniqueNetIdTypes=SWITCH
This completes the setup of OSS required to be used in your game. Good luck!
Obtaining PlayFab Party libraries
5/24/2022 • 2 minutes to read • Edit Online
You will require PlayFab Party headers, library and DLL in order to be able to utilize this subsystem. See below
for the options available to you.
The PlayFab Party Cognitive Services Interface includes functions that allow for the configuration and use of the
accessibility features provided by PlayFab Party.
These features include:
Real-time text chat translation
Real-time voice chat transcription
Real-time voice chat transcription translation
Text-to-speech synthesis
Pricing
Cognitive Services and other services beyond core VOIP and game networking functionality may have a cost
associated with them. Please visit the Billing for PlayFab Party page for more details or reach out to your
Microsoft Representative.
PublicDependencyModuleNames.Add("OnlineSubsystemPlayFab");
PrivateDependencyModuleNames.Add("HTTP");
}
Additionally, you can wrap any game code with #if WITH_OSS_PL AYFAB_COGNITIVESERVICES to prevent
compilation errors on platforms that do not use Cognitive Services.
SetTextChatTranslationOptions
SetTextChatTranslationOptions allows chat translation to be toggled on or off.
SetVoiceChatTranscriptionOptions
SetVoiceChatTranscriptionOptions is required for enabling and configuring voice transcription.
bTranscribeSelf - Transcriptions of the local chat control will be generated and provided to the same local
chat control
bTranscribeOtherChatControlsWithMatchingLanguages - Transcriptions of other chat controls with
the same language as the local chat control will be generated and provided to the local chat control
bTranscribeOtherChatControlsWithNonMatchingLanguages - Transcriptions of other chat controls
with languages that are different from the local chat control's language will be generated and provided to the
local chat control
bTranslateToLocalLanguage - Transcriptions will be translated to the local chat control's language
SetTextToSpeechOptions
SetTextToSpeechOptions is required for enabling and configuring text to speech.
ETextToSpeechType::Narration - Render audio to the local chat control's audio output
ETextToSpeechType::VoiceChat - Render audio to chat controls which the local chat control is configured
to send audio to
SendTextAsVoice
Generates text to speech audio that is sent to all other clients connected to the PlayFab Party network. Text as
Voice must be enabled via a call to SetTextToSpeechOptions before calling SendTextAsVoice
SendChatText
Sends chat text string to all other clients connected to the PlayFab Party network.
Using older versions of Unreal Engine 4
5/24/2022 • 2 minutes to read • Edit Online
While not officially supported by the PlayFab Online Subsystem (OSS), it is entirely possible to use it on older
versions of Unreal Engine 4. Core networking functionality will migrate back to earlier versions of Unreal Engine
4 with minor tweaks to interface function names & signatures, with certain instances renamed or removed to
match older versions of the Unreal Engine 4 OSS interface.
[OnlineSubsystem]
DefaultPlatformService=PlayFab
NativePlatformService=Live
[OnlineSubsystemPlayFab]
bEnabled=true
PlayFabTitleID=<REPLACE ME with your PlayFab title ID>
MaxDeviceCount=<REPLACE ME with your max player count (note: split screen is still 1 device). In the example
of an 8 player game, this would be 8.>
MaxDevicesPerUserCount=<REPLACE ME with your max player count per box (note: split screen is still 1 device)
In the example of an 8 player game, this would be 1.>
MaxEndpointsPerDeviceCount=<REPLACE ME with your max player count per box (note: split screen is still 1
device) In the example of an 8 player game, this would be 1.>
MaxUserCount=<REPLACE ME with your max player count (note: split screen is still 1 device) In the example
of an 8 player game, this would be 8.>
MaxUsersPerDeviceCount=<REPLACE ME with your max player count per box (note: split screen is still 1 device)
In the example of an 8 player game, this would be 1.>
[/Script/OnlineSubsystemPlayFab.PlayFabNetDriver]
NetConnectionClassName="OnlineSubsystemPlayFab.PlayFabNetConnection"
ReplicationDriverClassName="<REPLACE ME with your existing replication driver class name>"
ConnectionTimeout=15.0
InitialConnectTimeout=30.0
[/Script/Engine.GameEngine]
!NetDriverDefinitions=ClearArray
+NetDriverDefinitions=
(DefName="GameNetDriver",DriverClassName="OnlineSubsystemPlayFab.PlayFabNetDriver",DriverClassNameFallback="
OnlineSubsystemUtils.IpNetDriver")
Refer to QuickStart: PlayFab Online Subsystem (OSS) for download and install instructions.
2.0.0
UE4 engine OSS PlayFab is updated to use Multiplayer features offered by Azure PlayFab such as Lobby,
Matchmaking along with PlayFab Party. This replaces the Xbox provided MPSD with Azure PlayFab Lobby and
XBL Smart match with Azure Matchmaking service.
XDK is not longer supported for this version of the OSS
1.0.7
UE4 Engine version 4.26 is the recommnded version to use with this version of OnlineSubsystemPlayfab.
Notes:
Rename OnlineSubsystemPlayFabParty to OnlineSubsystemPlayfab.
Getting started for Multiplayer Unity SDK
5/24/2022 • 2 minutes to read • Edit Online
IMPORTANT
This feature is currently in public preview. It is provided to give you an early look at an upcoming feature, and to allow you
to provide feedback while it is still in development.
See also
Getting started with Lobby
Lobby Client SDK reference
Getting started with Matchmaking
Matchmaking Client SDK reference
Multiplayer SDKs
PlayFab Multiplayer Unity plugin overview
5/24/2022 • 4 minutes to read • Edit Online
IMPORTANT
This feature is currently in public preview. It is provided to give you an early look at an upcoming feature, and to allow you
to provide feedback while it is still in development.
The PlayFab Multiplayer Unity SDK plugin is a Unity C# wrapper on top of a native PlayFabMultiplayer C++
library created for the convenience of Unity game developers.
It enables you to make use of PlayFab Multiplayer services in your Unity game. Currently, this includes Lobby
and Matchmaking. It is designed for developing games on multiple platforms.
PlayFab Multiplayer Unity plugin works alongside the PlayFab "core" Unity SDK. The PlayFab "core" Unity SDK
provides other PlayFab functionalities such as economy, leaderboards, and more. For more information, see
PlayFab Unity SDK and PlayFab Unity SDK documentation.
PlayFab Multiplayer Unity plugin is available for download as a Unity Asset package.
X.X.X.Y-(distribution-point-indicator).Z
For example, 1.2.0.3-gdk.0 (a version downloaded from the GDK repo with restricted access) or 1.2.0.3-ps5.0
(a version with Multiplayer binaries only for PS5, downloaded from the PS5 repo with restricted access).
Version components:
X.X.X - the lowest version of the underlying PlayFabMultiplayer library across all supported platforms. This
is used for general reference consistency with a version of the underlying C++ library. In the example above,
the version of an included PlayFabMultiplayer library for each platform is 1.2.0 or higher.
Y - an incremental index of any modifications in the Multiplayer Unity C# layer, for any given X.X.X part of
the version.
(distribution-point-indicator) - a mnemonic code for tracking which distribution point a particular PlayFab
Multiplayer Unity plugin package was downloaded from. It differs by distribution point, for example, gdk
(Microsoft Azure DevOps repo with restricted access for GDK developers), ps5 (Microsoft Azure DevOps
repo with restricted access for PS5 developers), etc.
Z - an incremental index of any modifications unique to the distribution point (for example, Multiplayer
binaries updated/patched for a specific platform only).
A higher number in any version component means a newer version, by significance from left to right.
Compatibility between versions from different distribution points
Regardless of a distribution point a PlayFab Multiplayer Unity plugin is downloaded from, it is guaranteed to be
fully compatible with a PlayFab Multiplayer Unity plugin downloaded from any other distribution point, if the
first four numbers ( X.X.X.Y ) of their version are the same . Compatible versions from different
distribution points can be imported into user's Unity project in any order without a risk of overwriting/breaking
one another, as their shared code should be identical. Though each of them may have some additional (not
shared) files, specific to a particular platform, which shouldn't overlap.
For example, you can import all the following versions of PlayFab Multiplayer Unity plugin in your Unity project,
in any sequential order, if you are targeting GDK, PS5 and Switch:
1.2.0.3-gdk.0 (imports Multiplayer binaries for GDK, among other files)
1.2.0.3-ps5.0 (imports Multiplayer binaries for PS5, among other files)
1.2.0.3-sw.0 (imports Multiplayer binaries for Switch, among other files)
The shared (cross-platform) Unity C# code included in each of these plugins will be the same.
IMPORTANT
This feature is currently in public preview. It is provided to give you an early look at an upcoming feature, and to allow you
to provide feedback while it is still in development.
Get started with the PlayFab Multiplayer Unity plugin. Follow steps below to install the package and try out
example code for a basic task.
This quickstart helps you make your first API calls using the PlayFab Multiplayer SDK for Unity. Before
continuing, make sure you have completed Getting started for developers and Quickstart: PlayFab Client library
for C# in Unity, which ensures you have a PlayFab account and are familiar with logging into PlayFab from your
game and the PlayFab Game Manager.
NOTE
If you intend to use this plugin to develop games based on the Microsoft Game Development Kit (GDK) you need to
acquire and install the GDK separately. Please also see details about Unity add-on for Game Core on Xbox consoles.
Requirements
A PlayFab developer account.
An installed copy of the Unity Editor. To install Unity for personal use via Unity Hub, or Unity+ for
professional use, see Download Unity. Check on Unity support in documentation of your specific
platform if needed. The minimum supported Unity version is Unity 2017 LTS.
A Unity Project – this can be any of the following:
A brand new project: For more information, see Starting Unity for the first time.
A guided tutorial project. For more information, see Getting Started with Unity.
An existing project.
The PlayFab "core" Unity3D SDK (also included in Multiplayer Unity plugin). For information about
installing the Unity3D SDK, see the "Download and install PlayFab SDK" section of Quickstart: PlayFab
Client library for C# in Unity.
using PlayFab;
using PlayFab.Multiplayer;
using PlayFab.ClientModels;
10. Add the following code in the Start method to log into PlayFab.
Error CS0227 Unsafe code may only appear if compiling with /unsafe
The plugin requires unsafe code because it interops with a native DLL.
Mismatch between the processor architecture of the project being built "MSIL" and the processor
architecture of the reference "XGamingRuntime", "AMD64".
PlayFabMultiplayer.OnLobbyCreateAndJoinCompleted +=
this.PlayFabMultiplayer_OnLobbyCreateAndJoinCompleted;
PlayFabMultiplayer.OnLobbyDisconnected += this.PlayFabMultiplayer_OnLobbyDisconnected;
createConfig.LobbyProperties["Prop1"] = "Value1";
createConfig.LobbyProperties["Prop2"] = "Value2";
PlayFabMultiplayer.CreateAndJoinLobby(
new PFEntityKey(
entityId,
entityType),
createConfig,
joinConfig);
2. To define the OnLobbyCreateAndJoinCompleted event handler, add the following code to the class:
private void PlayFabMultiplayer_OnLobbyCreateAndJoinCompleted(Lobby lobby, int result)
{
if (LobbyError.SUCCEEDED(result))
{
// Lobby was successfully created
Debug.Log(lobby.ConnectionString);
}
else
{
// Error creating a lobby
Debug.Log("Error creating a lobby");
}
}
3. To define the OnLobbyDisconnected event handler, add the following code to the class:
4. Save and click Play in the Unity Editor. The lobby connection string displays in the Console window.
Join a lobby
This part of the guide shows you how to join an existing lobby that another client created.
1. Open the HelloMultiplayerLogic.cs script. In the OnLoginSuccess method, add the following code to Join a
lobby:
PlayFabMultiplayer.JoinLobby(
entityKey,
connectionString,
null);
2. To define an event that fires when your local client joins the lobby, add the following code to the
OnLoginSuccess method:
PlayFabMultiplayer.OnLobbyJoinCompleted += this.PlayFabMultiplayer_OnLobbyJoinCompleted;
3. To define the OnLobbyJoinCompleted event handler, add the following code to the class:
private void PlayFabMultiplayer_OnLobbyJoinCompleted(Lobby lobby, PFEntityKey newMember, int reason)
{
if (LobbyError.SUCCEEDED(reason))
{
// Successfully joined a lobby
Debug.Log("Joined a lobby");
}
else
{
// Error joining a lobby
Debug.Log("Error joining a lobby");
}
}
4. Save and select Play in the Unity Editor. The string "Joined a lobby" displays in the Console window.
Find lobbies
This part of the guide shows you how to find existing lobbies that other clients created.
1. Open the HelloMultiplayerLogic.cs script. In the OnLoginSuccess method, add the following code to find
lobbies:
2. To define an event that fires when your local client finds lobbies, add the following code to the
OnLoginSuccess method:
PlayFabMultiplayer.OnLobbyFindLobbiesCompleted +=
this.PlayFabMultiplayer_OnLobbyFindLobbiesCompleted;
3. To define the OnLobbyFindLobbiesCompleted event handler, add the following code to the class:
PlayFabMultiplayer.OnMatchmakingTicketCompleted += PlayFabMultiplayer_OnMatchmakingTicketCompleted;
PlayFabMultiplayer.OnMatchmakingTicketStatusChanged +=
PlayFabMultiplayer_OnMatchmakingTicketStatusChanged;
PlayFabMultiplayer.CreateMatchmakingTicket(
localUsers,
"QuickMatchQueueName",
membersToMatchWith);
2. To define the OnMatchmakingTicketStatusChanged event handler, add the following code to the class:
// Examine ticket
}
3. To define the OnMatchmakingTicketCompleted event handler, add the following code to the class:
PlayFabMultiplayer.OnMatchmakingTicketCompleted += PlayFabMultiplayer_OnMatchmakingTicketCompleted;
// Create JSON string with PlayFab user's attributes for matchmaking. This will need to be shared
with other clients taking part in matchmaking
string uniqueId = System.Guid.NewGuid().ToString();
string userAttributesJson = "{\"MatchIdentifier\": \"" + uniqueId + "\"}";
PlayFabMultiplayer.JoinMatchmakingTicketFromId(
new MatchUser(entityKey, userAttributesJson),
ticketId,
"QuickMatchQueueName",
new List<PFEntityKey>());
2. To define the OnMatchmakingTicketCompleted event handler, add the following code to the class:
3. Save and select Play in the Unity Editor. The string "Completed matchmaking ticket" displays in the
Console window upon successful matchmaking.
Azure Playfab Multiplayer Game Server SDKs
5/24/2022 • 2 minutes to read • Edit Online
This topic lists the different flavors of Azure PlayFab Multiplayer Game Server SDKs (GSDKs) we have today.
Download links
Note that these SDKs are for the servers.
Game Server SDK GitHub repo for all libraries
Unity Game Server SDK (GSDK)
C++ Game Server SDK (GSDK) for Windows servers via NuGet
C# Game Server SDK (GSDK) for Windows servers via NuGet
Java Game Server SDK (GSDK) for Windows and Linux servers via Maven
TIP
Unsure if this is the SDK you need? See SDKs overview - PlayFab SDK, Party SDK, Multiplayer Game Server SDK.
See also
SDKs overview
Azure Playfab Party SDKs
5/24/2022 • 2 minutes to read • Edit Online
This topic describes all the Azure PlayFab Party SDKs that are currently available.
If you don't find what you need, let us know by writing a post on our forums.
Access to SDKs for Nintendo Switch, PlayStation 4, PlayStation 5, Google Stadia, PC (GDK), and Xbox (GDK)
requires special approval and adherence to platform policies. For more information, see Request access for SDKs
and samples.
If you're looking for the core PlayFab SDK that helps you implement a majority of our features, including
LiveOps, economy, matchmaking, and data analytics, see PlayFab SDKs.
TIP
Unsure if this is the SDK you need? See SDK overview - PlayFab SDK, Party SDK, Multiplayer Server SDK.
By content type
SDK / L IB RA RY P L AT F O RM / O P ERAT IN G SY ST EM
C/C++ SDK Android, iOS, Windows 10, Windows 8.1, Stadia, Switch,
PlayStation®4, PlayStation®5, PC (GDK) and Xbox (GDK)
(Use the version that's included in the GDK.)
Xbox Live Helper Library Windows 10, Windows 8.1, Windows 7, PC (GDK) and Xbox
(GDK) (Use the version that's included in the GDK.)
By platform/operating system
P L AT F O RM / O P ERAT IN G SY ST EM SDK / L IB RA RY
PC (GDK) and Xbox (GDK) Unity, Unreal (under Add-ins ), C/C++ SDK, Xbox Live
Helper Library (Use the version that's included in the GDK.)
See also
Party samples
Quickstart for Android
Quickstart for iOS
Quickstart for Unity
Quickstart for Unreal
Party overview
Getting started with Party
Android getting started
5/24/2022 • 4 minutes to read • Edit Online
This document lists the basic prerequisites and requirements necessary to integrate PlayFab Party into your
Android applications. Once you've set up your system according to this document, please have a look at the
Quickstart for PlayFab Party for getting set up with the building blocks of PlayFab Party.
Prerequisites
Before you start this tutorial, please ensure that the following prerequisites have been met:
1. You created a PlayFab developer account.
2. You created a PlayFab Title and your title has been allow-listed for PlayFab Party.
3. You have Android Studio version 3.2 or higher installed.
4. Your app targets Android 4.4 (Kitkat) or higher.
5. You have the Android NDK 18.1.5063045 or higher installed.
6. You have access to the PlayFab Party platforms repository
7. You have created an android signing cert and signed your app for deployment using the cert config.
NOTE
The SSL libraries are built from Open SSL Version 1.1.1b-dev. Please use an openSSL version that is 1.1.1b-dev or higher.
Header Includes
Party Headers
NOTE
In addition to the lib files and headers above, you'll also need the libs and headers for PlayFab SDK and any other
platform-specific dependencies your app needs. Please take a look at the project file organization for the Android sample
for more info.
import android.util.Log;
private NetworkManager() {
}
The above JNI bridge is backed by a pure C++ implementation file that calls into the NetworkManager.cpp,
which in turn calls the Party APIs.
Here's an example snippet that shows the various layers:
The NetworkManager Java interface exposes a method to join a Party Network.
The implementation of the joinNetwork is in the C++ layer in PartyDemo.cpp shown below.
JNIEXPORT jboolean JNICALL
Java_com_microsoft_playfab_party_sdk_NetworkManager_joinNetwork(
JNIEnv* env,
jobject thiz,
jstring networkId
)
{
if (g_isRunning && g_initializeCompleted)
{
Managers::Get<NetworkManager>()->Initialize(g_playfabTitleId.c_str());
const char* networkNameCStr = env->GetStringUTFChars(networkId, NULL);
g_networkName = networkNameCStr;
env->ReleaseStringUTFChars(networkId, networkNameCStr);
g_isSpinDone = false;
Managers::Get<PlayFabManager>()->GetDescriptor(
g_networkName,
[](std::string networkDescriptor)
{
SendSysLogToUI("OnGetDescriptorForConnectTo : %s", networkDescriptor.c_str());
g_networkDescriptor = networkDescriptor;
ReleaseSpin();
}
);
HoldSpin();
// When network connection is not stable, waiting for ConnectToNetwork callback will cost longer
time.
// To avoid App UI busy waiting, return to UI after ConnectToNetwork returns.
Managers::Get<NetworkManager>()->ConnectToNetwork(
g_networkName.c_str(),
g_networkDescriptor.c_str(),
[]()
{
OnNetworkConnected(g_networkName);
SendSysLogToUI("OnConnectToNetwork succeeded");
},
[](PartyError error)
{
SendSysLogToUI("OnConnectToNetworkFailed %s", GetErrorMessage(error));
ResetChat(GetErrorMessage(error));
});
return true;
}
else
{
SendSysLogToUI("Please waiting for initialization done.");
return false;
}
}
In the code snippet above, the joinNetwork calls into NetworkManager::CreateAndConnectToNetwork() which in
turn calls the raw Party API exposed in Party.h
void
NetworkManager::CreateAndConnectToNetwork(
const char *networkId,
std::function<void(std::string)> callback,
std::function<void(PartyError)> errorCallback
)
{
DEBUGLOG("NetworkManager::CreateAndConnectToNetwork()\n");
// Setup the network to allow the maximum number of single-device players of any device type
// Setup the network to allow the maximum number of single-device players of any device type
cfg.maxDeviceCount = c_maxNetworkConfigurationMaxDeviceCount;
cfg.maxDevicesPerUserCount = 1;
cfg.maxEndpointsPerDeviceCount = 1;
cfg.maxUserCount = c_maxNetworkConfigurationMaxDeviceCount;
cfg.maxUsersPerDeviceCount = 1;
if (PARTY_FAILED(err))
{
DEBUGLOG("GetUserIdentifier failed: %s\n", GetErrorMessage(err));
errorCallback(err);
return;
}
// Setup the network invitation configuration to use the network id as an invitation id and allow anyone
to join.
PartyInvitationConfiguration invitationConfiguration{
networkId, // invitation identifier
PartyInvitationRevocability::Anyone, // revokability
0, // authorized user count
nullptr // authorized user list
};
// Initialize an empty network descriptor to hold the result of the following call.
PartyNetworkDescriptor networkDescriptor = {};
if (PARTY_FAILED(err))
{
DEBUGLOG("CreateNewNetwork failed: %s\n", GetErrorMessage(err));
errorCallback(err);
return;
}
In a similar way, each method in the NetworkManager JNI interface is mapped to Party API via the PartyDemo
and NetworkManager.
Next steps
In this article we saw how to get started integrating the Party library into your Android application. Please refer
to Quickstart For PlayFab Party for getting set up with the rest of the building blocks of PlayFab Party.
iOS getting started
5/24/2022 • 4 minutes to read • Edit Online
This document lists the basic prerequisites and requirements necessary to integrate PlayFab Party into your iOS
applications. Once you've set up your system according to this document, please have a look at the Quickstart
for PlayFab Party for getting set up with the building blocks of PlayFab Party.
Prerequisites
Before you start this tutorial, please ensure that the following prerequisites have been met:
1. You have created a PlayFab developer account
2. You've created a PlayFab Title and your title has been allow-listed for PlayFab Party
3. You have Xcode version 10.2.1 installed
4. You have access to the PlayFab Party platforms repository
5. You have created an apple developer account that can be used to sign your app for deployment.
NOTE: If you're planning to use the XCode simulator for testing, you'll need to target your application for 64-bit
($(ARCHS_STANDARD_64_BIT)) architecture. 32-bit simulators are currently not supported.
NOTE
The SSL libs are built from Open SSL version XXX. Please use an OpenSSL version that is XXX or higher
Header includes
Party headers
Note that in addition to the lib files and headers above, you'll also need the libs and headers for PlayFab SDK
and any other platform-specific dependencies your app needs. Please take a look at the project file organization
for the Swithc Sample for more info.
#import <Foundation/Foundation.h>
#import "ChatEventHandler.h"
-(void) initialize;
-(void) setHandler:(id<ChatEventHandler>) messageHandler;
-(void) signInLocalUser;
-(NSString*) getSelectedUserName;
-(void) tick;
+(void) globalInitialize;
+(void) globalShutdown;
@end
The above object bridge is backed by a pure C++ implementation file that calls into the NetworkManager.cpp ,
which in turn calls the Party APIs.
Here's an example snippet that shows the various layers:
The SimpleClient objective-C interface exposes a method to initialize Bumblelion.
// In SimpleClient.h
-(void) createNetwork:(NSString*) networkId;
The implementation of the SimpleClient also includes a reference to the C++ object which calls into Party APIs
via the network manager.
// In SimpleClient.mm
@interface SimpleClient ()
@end
@implementation SimpleClient
SimpleClientImpl* m_impl;
The SimpleClientImpl is a C++ class that class that does the heavy lifting of creating the Party network as shown
in the code snippet below:
void
SimpleClientImpl::CreateNetwork(
std::string &networkId
)
{
if (g_isRunning && g_initializeCompleted)
{
Managers::Get<NetworkManager>()->Initialize(c_pfTitleId);
m_messageHandler->OnStartLoading();
Managers::Get<NetworkManager>()->CreateAndConnectToNetwork(
networkId.c_str(),
[this, networkId](std::string message)
{
this->SendSysLogToUI("create network: %s", message.c_str());
Managers::Get<PlayFabManager>()->SetDescriptor(
networkId,
message,
[this, message](void)
{
m_messageHandler->OnEndLoading();
this->SendSysLogToUI("set network descriptor %s", "successed");
std::string l_message = message;
m_messageHandler->OnNetworkCreated(l_message);
});
},
[this](PartyError error)
{
m_messageHandler->OnEndLoading();
this->SendSysLogToUI("create network failed: %s", GetErrorMessage(error));
});
}
}
In the code snippet above, the SimpleClient calls into NetworkManager::CreateAndConnectToNetwork() which in
turn calls the raw Party API exposed in Party.h
void
NetworkManager::CreateAndConnectToNetwork(
const char *networkId,
std::function<void(std::string)> callback,
std::function<void(PartyError)> errorCallback
)
{
DEBUGLOG("NetworkManager::CreateAndConnectToNetwork()\n");
// Setup the network to allow the maximum number of single-device players of any device type
cfg.maxDeviceCount = c_maxNetworkConfigurationMaxDeviceCount;
cfg.maxDevicesPerUserCount = 1;
cfg.maxEndpointsPerDeviceCount = 1;
cfg.maxUserCount = c_maxNetworkConfigurationMaxDeviceCount;
cfg.maxUsersPerDeviceCount = 1;
if (PARTY_FAILED(err))
{
DEBUGLOG("GetUserIdentifier failed: %s\n", GetErrorMessage(err));
errorCallback(err);
return;
}
// Setup the network invitation configuration to use the network id as an invitation id and allow anyone
// Setup the network invitation configuration to use the network id as an invitation id and allow anyone
to join.
PartyInvitationConfiguration invitationConfiguration{
networkId, // invitation identifier
PartyInvitationRevocability::Anyone, // revokability
0, // authorized user count
nullptr // authorized user list
};
// Initialize an empty network descriptor to hold the result of the following call.
PartyNetworkDescriptor networkDescriptor = {};
if (PARTY_FAILED(err))
{
DEBUGLOG("CreateNewNetwork failed: %s\n", GetErrorMessage(err));
errorCallback(err);
return;
}
In a similar way, each method in the SimpleClient objective-C interface is mapped to Party API via the
SimpleClientImpl and NetworkManager .
Next steps
In this article we saw how to get started integrating the Party library into your iOS application. Please refer to
Quickstart for PlayFab Party for getting set up with the rest of the building blocks of PlayFab Party.
Party Unity plugin overview
5/24/2022 • 4 minutes to read • Edit Online
The PlayFab Party Unity SDK plugin is a Unity C# wrapper on top of a native Party C++ library created for the
convenience of Unity game developers.
It enables you to make use of Party and Party Cognitive Services in your Unity game. This includes multiplayer
networking, chat messages and data exchange, cross-talk, cross-play, accessibility features like real-time text
chat translation and voice transcription services. It is designed for developing games on multiple platforms.
PlayFab Party Unity plugin works alongside the PlayFab "core" Unity SDK plugin which provides other PlayFab
functionalities such as economy, leaderboards, and more. For more information, see PlayFab Unity SDK and
PlayFab Unity SDK documentation.
Party Unity plugin is available for download as a Unity Asset package. It is currently supported for developing
games on the following platforms:
Microsoft Game Core (GDK)*, Windows, iOS, Android: https://github.com/playfab/PlayFabPartyUnity (public
access)
Sony PlayStation®:
PS4: https://dev.azure.com/PlayFabPrivate/PS4/_git/PlayFabPartyUnityPS4 (restricted access by
request to Microsoft Representative)
PS5: https://dev.azure.com/PlayFabPrivate/PS5/_git/PlayFabPartyUnityPS5 (restricted access by
request to Microsoft Representative)
Nintendo Switch™: https://dev.azure.com/PlayFabPrivate/Switch/_git/PlayFabPartyUnitySwitch (restricted
access by request to Microsoft Representative)
*- The underlying Party libraries for GDK are not included in plugin (see below).
X.X.X.Y-(distribution-point-indicator).Z
For example, 1.5.0.3-main.0 (a version downloaded from the main public GitHub repo) or 1.5.0.3-ps5.0 (a
version with Party binaries only for PS5, downloaded from a repo with restricted access).
Version components:
X.X.X - the lowest version of the underlying Party library across all supported platforms. This is used for
general reference consistency with a version of the underlying C++ library. In the example above, the version
of an included Party libary for each platform is 1.5.0 or higher.
Y - an incremental index of any modifications in the Party Unity C# layer, for any given X.X.X part of the
version.
(distribution-point-indicator) - a mnemonic code for tracking which distribution point a particular Party
Unity plugin package was downloaded from. It differs by distribution point, e.g. main (main public
distribution GitHub repo), ps5 (Microsoft Azure DevOps repo with restricted access for PS5 developers), etc.
Z - an incremental index of any modifications unique to the distribution point (e.g. Party binaries
updated/patched for a specific platform only).
A higher number in any version component means a newer version, by significance from left to right.
Compatibility between versions from different distribution points
Regardless of a distribution point a Party Unity plugin is downloaded from, it is guaranteed to be fully
compatible with a Party Unity plugin downloaded from any other distribution point, if the first four numbers
( X.X.X.Y ) of their version are the same . Compatible versions from different distribution points can be
imported into user's Unity project in any order without a risk of overwriting/breaking one another, as their
shared code should be identical. Though each of them may have some additional (not shared) files, specific to a
particular platform, which shouldn't overlap.
For example, you can import all the following versions of Party Unity plugin in your Unity project, in any
sequential order, if you are targeting iOS, PS5 and Switch:
1.5.0.3-main.0 (imports Party binaries for iOS, among other files)
1.5.0.3-ps5.0 (imports Party binaries for PS5, among other files)
1.5.0.3-sw.0 (imports Party binaries for Switch, among other files)
The shared (cross-platform) Unity C# code included in each of these plugins will be the same.
Pricing
VoIP and Game Networking functionality is free for users signed in with an Xbox Live account
(currently suppor ted on GDK platform only).
Party Cognitive Services and other services may have a cost associated with them. For details, see Billing for
PlayFab Party or reach out to your Microsoft Representative.
Quickstart: PlayFab Party Unity Plugin
5/24/2022 • 7 minutes to read • Edit Online
Get started with the PlayFab Party Unity plugin. Follow steps below to install the package and try out example
code for a basic task.
This quickstart helps you make your first API calls using the Party SDK for Unity. Before continuing, make sure
you have completed Getting started for developers and Quickstart: PlayFab Client library for C# in Unity, which
ensures you have a PlayFab account and are familiar with logging into PlayFab from your game and the PlayFab
Game Manager.
NOTE
If you intend to use this plugin to develop games based on the Microsoft Game Development Kit (GDK) you need to
acquire and install the GDK separately. Please also see details about Unity add-on for Game Core on Xbox consoles.
Requirements
A PlayFab developer account.
An installed copy of the Unity Editor. To install Unity for personal use via Unity Hub, or Unity+ for
professional use, see Download Unity. Check on Unity support in documentation of your specific
platform if needed. The minimum supported Unity version is Unity 2017 LTS.
A Unity Project – this can be any of the following:
A brand new project: For more information, see Starting Unity for the first time.
A guided tutorial project. For more information, see Getting Started with Unity.
An existing project.
The PlayFab "core" Unity3D SDK. For information about installing the Unity3D SDK, see the "Download
and install PlayFab SDK" section of Quickstart: PlayFab Client library for C# in Unity.
using PlayFab;
using PlayFab.Party;
using PlayFab.ClientModels;
10. Add the following code in the Start method to log into PlayFab.
NOTE
You might receive the following errors:
Error CS0227 Unsafe code may only appear if compiling with /unsafe
The plugin requires unsafe code because it interops with a native DLL.
Mismatch between the processor architecture of the project being built "MSIL" and the processor
architecture of the reference "XGamingRuntime", "AMD64".
Connecting to a network
This part of the guide shows you how to Create and Join a network.
1. Open the HelloPartyLogic.cs script. In the OnLoginSuccess method, add the following code to create and
join a network:
PlayFabMultiplayerManager.Get().CreateAndJoinNetwork();
PlayFabMultiplayerManager.Get().OnNetworkJoined += OnNetworkJoined;
2. To define the OnNetworkJoined event handler, add the following code to the class:
3. Save and click Play in the Unity Editor. The Network ID displays in the Console window.
2. To define an event that fires when your local client joins the network, add the following code to the
OnLoginSuccess method:
PlayFabMultiplayerManager.Get().OnNetworkJoined += OnNetworkJoined;
3. To define the OnNetworkJoined event handler, add the following code to the class:.
There are many ways to get the Network ID from the host to other players who want to join. Please refer
to the sample in this Unity plugin for an example of how to do that.
4. Save and select Play in the Unity Editor. The string "Network joined!" displays in the Console window.
Accessing other players
This part of the guide shows you how to access other players on the network, including the local player.
To listen for new players joining and leaving the network, register for the OnRemotePlayerJoined and
OnRemotePlayerLeft events.
1. Open the HelloPartyLogic.cs script. In the OnLoginSuccess method, add the following code to Create and
Join a network:
PlayFabMultiplayerManager.Get().OnRemotePlayerJoined += OnRemotePlayerJoined;
PlayFabMultiplayerManager.Get().OnRemotePlayerLeft += OnRemotePlayerLeft;
3. To access the local player, add the following code to the OnRemotePlayerJoined method:
The PlayFabPlayer class contains properties for identifying the player, muting, and rendering their chat state in a
chat UI.
PlayFabMultiplayerManager.Get().OnDataMessageReceived += LocalPlayer_OnDataMessageReceived;
3. To send a data message, add the following code to the Update method:
if (Input.GetButtonDown("Fire1"))
{
byte[] requestAsBytes = Encoding.UTF8.GetBytes("Hello (data message)");
PlayFabMultiplayerManager.Get().SendDataMessageToAllPlayers(requestAsBytes);
}
Save HelloPartyLogic.cs and select Play in the Unity Editor.
1. In a second client, use the code shown above in Connect to a network to create and join a network.
2. Copy the Network ID returned to your first client and connect to the network.
3. Click on the scene to send a message. "Hello (data message)" displays in the Console window.
PlayFabMultiplayerManager.Get().OnChatMessageReceived += OnChatMessageReceived;
PARTY_DIRECT_PEER_CONNECTIVITY_OPTIONS_ANY_ENTITY_LOGIN_PROVIDER;
PlayFabMultiplayerManager.Get().CreateAndJoinNetwork(networkConfiguration);
PlayFabMultiplayerManager.Get().OnNetworkJoined += OnNetworkJoined;
PlayFab Party Unity SDK
5/24/2022 • 2 minutes to read • Edit Online
Classes
NAME DESC RIP T IO N
PlayFabLocalPlayer
PlayFabMultiplayerManager
PlayFabPlayer
Enums
NAME DESC RIP T IO N
ChatState The visual state of the player for rendering in the game's UI.
1.7.0.1
Enabled peer-to-peer connection on supported platforms, except from mobile ones, by default.
1.5.0.3
Party Unity SDK plugin becomes generally available (GA) to developers on platforms:
Windows, iOS, Android: https://github.com/playfab/PlayFabPartyUnity
Sony PlayStation®:
PS4: https://dev.azure.com/PlayFabPrivate/PS4/_git/PlayFabPartyUnityPS4 (restricted access)
PS5: https://dev.azure.com/PlayFabPrivate/PS5/_git/PlayFabPartyUnityPS5 (restricted access)
Nintendo Switch™: https://dev.azure.com/PlayFabPrivate/Switch/_git/PlayFabPartyUnitySwitch (restricted
access)
New features in GA
Ability to set a language for the local player, before creating or joining a Party
Optional translation of incoming text chat messages to local language, using Party Cognitive Services
Speech-to-text (STT): optional transcription of incoming audio chat into text chat messages in local language,
using Party Cognitive Services (incurs additional cost if exceeds free quota)
Text-to-speech (TTS): optional synthesization of speech, conversion of outgoing text chat messages into
audible form received by other players (incurs additional cost if exceeds free quota)
Bug fixes
Numerous bug fixes and stability improvements since pre-release.
Overview
5/24/2022 • 2 minutes to read • Edit Online
The PlayFab Online Subsystem (PF OSS) enables you to make use of Multiplayer features like Lobby,
Matchmaking, Party and Azure Cognitive Services in your Unreal Engine 4 (UE4) game. These features include
cross-talk, cross-play, and accessibility features like real-time text chat translation and voice transcription
services. It is currently designed for use when developing PC, Xbox, Steam and Nintendo Switch games. This
subsystem layer works seamlessly on top of the existing Epic provided base Online Subsystem (OSS) GDK.
PlayFab OSS compliments the base OSS by adding support for PlayFab Lobby, Matchmaking, Party networking
and Voice over Internet Protocol (VOIP).
PlayFab OSS works alongside the PlayFab SDK marketplace plugin, which provides other PlayFab functionalities
such as economy, leaderboards, and more. For more information, see PlayFab SDK on the UE4 Marketplace
(external site).
Pricing
VOIP and Game Networking functionality is free for users signed in with an Xbox Live account,
regardless of platform.
Cognitive services and other services may have a cost associated with them. For details, see Billing for PlayFab
Party or reach out to your Microsoft Representative.
QuickStart: PlayFab Online Subsystem (OSS)
5/24/2022 • 3 minutes to read • Edit Online
This quickstart guide helps you set up and use Multiplayer features such as Lobby, Matchmaking and Party for
Xbox, PC, and Nintendo Switch games built using Unreal Engine 4. For the full list of supported platforms and
versions in UE4, see Supported platforms.
After following the relevant steps below for your target platforms, you'll be ready to start using the OSS.
Authentication, networking, VOIP, grouping into lobbies, and matchmaking will be handled on your behalf with
no other changes required.
Initial setup
Copy the OnlineSubsystemPlayFab folder and its contents from to your UE4 directory under
Engine\Plugins\Online
Apply the following changes to the Plugins section of your ".uproject" file. This will add the
OnlineSubsystemPlayFab to your plugin list.
You may remove any platforms that you're not shipping on
{
"Name": "OnlineSubsystemPlayFab",
"Enabled": true,
"WhitelistPlatforms": [
"XboxOneGDK",
"WinGDK",
"XSX",
"Win64",
"Switch"
],
"SupportedTargetPlatforms": [
"XboxOneGDK",
"WinGDK",
"XSX",
"Win64",
"Switch"
]
}
Game Configuration
No matter which platform you're targeting, your game will need to configure certain PlayFab specific values
in your intended platform target's INI file (located at [yourGameDirectory]/Platforms/[yourPlatform]/Config).
Xbox Series X GDK: XSXEngine.ini
PC GDK: WinGDKEngine.ini
Xbox One GDK: XboxOneGDKEngine.ini
PC Steam: WindowsEngine.ini
Nintendo Switch SwitchEngine.ini
Replace the INI sections in the config if they already exist (for example, Engine.GameEngine) with the ones
below.
Ensure you replace all the <REPLACE ME> fields with your data:
[OnlineSubsystemPlayFab]
bEnabled=true
PlayFabTitleID=<REPLACE ME with your PlayFab title ID>
MaxDeviceCount=<REPLACE ME with your max player count (note: split screen is still 1 device). In the example
of an 8 player game, this would be 8.>
MaxDevicesPerUserCount=<REPLACE ME with your max player count per box (note: split screen is still 1 device)
In the example of an 8 player game, this would be 1.>
MaxEndpointsPerDeviceCount=<REPLACE ME with your max player count per box (note: split screen is still 1
device) In the example of an 8 player game, this would be 1.>
MaxUserCount=<REPLACE ME with your max player count (note: split screen is still 1 device) In the example
of an 8 player game, this would be 8.>
MaxUsersPerDeviceCount=<REPLACE ME with your max player count per box (note: split screen is still 1 device)
In the example of an 8 player game, this would be 1.>
DirectPeerConnectivityOptions=<REPLACE ME with your connectivity options, in the form of an array of
strings. The default case corresponds to the following:
+DirectPeerConnectivityOptions=AnyPlatformType
+DirectPeerConnectivityOptions=AnyEntityLoginProvider>
[/Script/OnlineSubsystemPlayFab.PlayFabNetDriver]
NetConnectionClassName="OnlineSubsystemPlayFab.PlayFabNetConnection"
ReplicationDriverClassName="<REPLACE ME with your existing replication driver class name>"
ConnectionTimeout=15.0
InitialConnectTimeout=30.0
[/Script/Engine.GameEngine]
!NetDriverDefinitions=ClearArray
+NetDriverDefinitions=
(DefName="GameNetDriver",DriverClassName="OnlineSubsystemPlayFab.PlayFabNetDriver",DriverClassNameFallback="
OnlineSubsystemUtils.IpNetDriver")
[OnlineSubsystem]
DefaultPlatformService=PlayFab
NativePlatformService=GDK
[OnlineSubsystemPlayFab]
Sandbox=<Optional, REPLACE ME with the sandbox Id used for the title under development >
Steam
If you're developing games for Win64 with Steam, define your platform services:
[OnlineSubsystem]
DefaultPlatformService=PlayFab
NativePlatformService=Steam
Switch
See the ReadMe.md file that comes with the Switch PlayFab OSS for more details.
Cross-platform
Finally, if your game makes use PlayFab's cross-platform networking support, define which platforms you'll
permit to connect:
[/Script/OnlineSubsystemUtils.OnlineEngineInterfaceImpl]
!CompatibleUniqueNetIdTypes=ClearArray
+CompatibleUniqueNetIdTypes=STEAM
+CompatibleUniqueNetIdTypes=GDK
+CompatibleUniqueNetIdTypes=SWITCH
This completes the setup of OSS required to be used in your game. Good luck!
Obtaining PlayFab Party libraries
5/24/2022 • 2 minutes to read • Edit Online
You will require PlayFab Party headers, library and DLL in order to be able to utilize this subsystem. See below
for the options available to you.
The PlayFab Party Cognitive Services Interface includes functions that allow for the configuration and use of the
accessibility features provided by PlayFab Party.
These features include:
Real-time text chat translation
Real-time voice chat transcription
Real-time voice chat transcription translation
Text-to-speech synthesis
Pricing
Cognitive Services and other services beyond core VOIP and game networking functionality may have a cost
associated with them. Please visit the Billing for PlayFab Party page for more details or reach out to your
Microsoft Representative.
PublicDependencyModuleNames.Add("OnlineSubsystemPlayFab");
PrivateDependencyModuleNames.Add("HTTP");
}
Additionally, you can wrap any game code with #if WITH_OSS_PL AYFAB_COGNITIVESERVICES to prevent
compilation errors on platforms that do not use Cognitive Services.
SetTextChatTranslationOptions
SetTextChatTranslationOptions allows chat translation to be toggled on or off.
SetVoiceChatTranscriptionOptions
SetVoiceChatTranscriptionOptions is required for enabling and configuring voice transcription.
bTranscribeSelf - Transcriptions of the local chat control will be generated and provided to the same local
chat control
bTranscribeOtherChatControlsWithMatchingLanguages - Transcriptions of other chat controls with
the same language as the local chat control will be generated and provided to the local chat control
bTranscribeOtherChatControlsWithNonMatchingLanguages - Transcriptions of other chat controls
with languages that are different from the local chat control's language will be generated and provided to the
local chat control
bTranslateToLocalLanguage - Transcriptions will be translated to the local chat control's language
SetTextToSpeechOptions
SetTextToSpeechOptions is required for enabling and configuring text to speech.
ETextToSpeechType::Narration - Render audio to the local chat control's audio output
ETextToSpeechType::VoiceChat - Render audio to chat controls which the local chat control is configured
to send audio to
SendTextAsVoice
Generates text to speech audio that is sent to all other clients connected to the PlayFab Party network. Text as
Voice must be enabled via a call to SetTextToSpeechOptions before calling SendTextAsVoice
SendChatText
Sends chat text string to all other clients connected to the PlayFab Party network.
Using older versions of Unreal Engine 4
5/24/2022 • 2 minutes to read • Edit Online
While not officially supported by the PlayFab Online Subsystem (OSS), it is entirely possible to use it on older
versions of Unreal Engine 4. Core networking functionality will migrate back to earlier versions of Unreal Engine
4 with minor tweaks to interface function names & signatures, with certain instances renamed or removed to
match older versions of the Unreal Engine 4 OSS interface.
[OnlineSubsystem]
DefaultPlatformService=PlayFab
NativePlatformService=Live
[OnlineSubsystemPlayFab]
bEnabled=true
PlayFabTitleID=<REPLACE ME with your PlayFab title ID>
MaxDeviceCount=<REPLACE ME with your max player count (note: split screen is still 1 device). In the example
of an 8 player game, this would be 8.>
MaxDevicesPerUserCount=<REPLACE ME with your max player count per box (note: split screen is still 1 device)
In the example of an 8 player game, this would be 1.>
MaxEndpointsPerDeviceCount=<REPLACE ME with your max player count per box (note: split screen is still 1
device) In the example of an 8 player game, this would be 1.>
MaxUserCount=<REPLACE ME with your max player count (note: split screen is still 1 device) In the example
of an 8 player game, this would be 8.>
MaxUsersPerDeviceCount=<REPLACE ME with your max player count per box (note: split screen is still 1 device)
In the example of an 8 player game, this would be 1.>
[/Script/OnlineSubsystemPlayFab.PlayFabNetDriver]
NetConnectionClassName="OnlineSubsystemPlayFab.PlayFabNetConnection"
ReplicationDriverClassName="<REPLACE ME with your existing replication driver class name>"
ConnectionTimeout=15.0
InitialConnectTimeout=30.0
[/Script/Engine.GameEngine]
!NetDriverDefinitions=ClearArray
+NetDriverDefinitions=
(DefName="GameNetDriver",DriverClassName="OnlineSubsystemPlayFab.PlayFabNetDriver",DriverClassNameFallback="
OnlineSubsystemUtils.IpNetDriver")
Refer to QuickStart: PlayFab Online Subsystem (OSS) for download and install instructions.
2.0.0
UE4 engine OSS PlayFab is updated to use Multiplayer features offered by Azure PlayFab such as Lobby,
Matchmaking along with PlayFab Party. This replaces the Xbox provided MPSD with Azure PlayFab Lobby and
XBL Smart match with Azure Matchmaking service.
XDK is not longer supported for this version of the OSS
1.0.7
UE4 Engine version 4.26 is the recommnded version to use with this version of OnlineSubsystemPlayfab.
Notes:
Rename OnlineSubsystemPlayFabParty to OnlineSubsystemPlayfab.
Xbox XDK Prerequisites
5/24/2022 • 2 minutes to read • Edit Online
Next steps
Quickstart for PlayFab Party
Xbox Requirements
Using MPSD
Xbox Requirements
5/24/2022 • 10 minutes to read • Edit Online
If your game is targeting Xbox consoles, it must adhere to a set of requirements to ensure consistent
functionality and behavior when interacting with Xbox Live. This set of requirements is listed in the Xbox
Requirements (XRs for short). XRs interact and overlap with the policies that are required to make use of Xbox
Live in your game on PC and other platforms. Here we describe best practices for PlayFab Party that will help
you comply with these requirements.
For quick reference, refer to the following table which matches PlayFab Party scenarios to the XRs they address:
SC EN A RIO XR
Aligning PlayFab Party with an Xbox Live user's chat settings XR-015, XR-045
and privileges
Honoring Xbox Live service retry policy and service access XR-074, XR-132
limitations
Aligning PlayFab Party with an Xbox Live user's chat settings and
privileges
PlayFab Party uses an opt-in model of chat communication and, by default, restricts all communications between
two chat controls to the set of communications which both participants have enabled. For more information, see
the documentation for chat permissions and muting.
PlayFab Party's Xbox Live Helper library indicates which set of chat permissions should be enabled to match the
preferences and privileges of the Xbox Live users currently communicating in the Party session. For more
information, see the documentation about respecting an Xbox Live user's privacy settings and permissions.
By properly making use of PlayFab Party and the Xbox Live Helper library, your game can entirely meet the
requirements specified by XR-015 and can meet the relevant communication requirements specified by XR-045.
Refer to the XR-045 technical documentation for further requirements outside the scope of PlayFab Party.
IMPORTANT
This section provides best practices when using PlayFab Party together with MPSD, but PlayFab Party itself does not
implicitly satisfy the MPSD requirements of XR-067. Refer to the XR-067 technical documentation for information on
satisfying these requirements.
PartyInvitationConfiguration newNetworkInitialInvite{};
newNetworkInitialInvite.identifier = nullptr; // let Party select the invitation identifier for simplicity
newNetworkInitialInvite.revocability = PartyInvitationRevocability::Anyone; // the initial invitation must
be revocable by anyone
// this initial invitation only allows the original xbl user creating the network
newNetworkInitialInvite.entityIdCount = 1;
newNetworkInitialInvite.entityIds = &networkCreatorEntityId;
Similar to the join-in-progress flow, when a new Xbox user wants to join the network, they will first add
themselves to the session document. When the player that wants to allow them into the network sees the
update, they will update the set of invitations to reflect the session document. This will ensure that only users in
the session document (which are guaranteed to be Xbox Live users) can join the network.
void
OnSessionDocumentUpdated(
PartyNetwork* network,
uint32_t usersInDocumentCount,
const uint64_t* usersInDocument
)
{
PartyInvitationConfiguration newInvite{};
newInvite.identifier = nullptr; // let Party select the invitation identifier for simplicity
newInvite.revocability = PartyInvitationRevocability::Creator; // must be revocable by the creator only
// the updated invite should contain all users currently in the document
std::vector<PartyString> entityIdsInDocument;
for (uint32_t i = 0; i < usersInDocumentCount; ++i)
{
uint64_t xboxUserId = usersInDocument[i];
// Call title-defined xuid->entityid mapping helper
PartyString xboxUserEntityId = GetEntityIdFromXboxUserId(xboxUserId);
if (xboxUserEntityId != nullptr)
{
entityIdsInDocument.push_back(xboxUserEntityId);
}
else
{
DEBUGLOG("User %llu did not have a matching entity ID.", xboxUserId);
}
}
newInvite.entityIdCount = entityIdsInDocument.size();
newInvite.entityIds = entityIdsInDocument.data();
// Create a new invitation which includes all of the users currently in the document
PartyInvitation* newInvitation;
PartyError error = network->CreateInvitation(
m_localUser,
&newInvite,
nullptr,
&newInvitation);
if (PARTY_FAILED(error))
{
DEBUGLOG("PartyNetwork(0x%p)::CreateInvitation failed! (error=0x%x)", network, error);
return;
}
// Post the invitation's id somewhere that it can be seen by anyone trying to join/rejoin
PostInvitationToMPSD(newInvite);
// Cleanup previous invitations. This isn't strictly necessary, but is a good practice.
uint32_t invitationCount;
PartyInvitationArray invitations;
error = network->GetInvitations(&invitationCount, &invitations);
if (PARTY_FAILED(error))
{
DEBUGLOG("PartyNetwork(0x%p)::GetInvitations failed! (error=0x%x)", network, error);
return;
}
NOTE
Because you will need to translate between Xbox Live User IDs and PlayFab Entity IDs, it is recommended to build a
mapping between the two. See Mapping between Xbox Live User IDs and PlayFab Entity IDs for examples on how to do
this.
Friends lists
Even though PlayFab Party does not interact natively with friends lists on any platform, multiplayer games may
still need to consider friends lists for different scenarios. For information on requirements and guidance when
interacting with Xbox Live and cross-network friends lists, see the following documentation:
Xbox Live friends list requirements (XR-070)
Cross-network friends list requirements (XR-007)
Xbox Social Manager
Xbox Live Services API (XSAPI)
Honoring Xbox Live service retry policy and service access limitations.
PlayFab Party does not directly interact with Xbox Live services outside of the Xbox Live Helper library. The Xbox
Live Helper library, internally, conforms to the retry policies and access limitations for its relevant Xbox Live
services as outlined in XR-074 and XR-132. As well, you can recognize API failures as a result of complying with
these service policies through the following error codes reported by the Xbox Live Helper library:
PartyXblChatPermissionMaskReason::XboxLiveServiceError and PartyXblStateChangeResult::PartyServiceError.
For more information on complying with these service policies outside of the Xbox Live Helper library, see the
XR-074 and XR-132 technical documentation.
Using PlayFab Party with MPSD
5/24/2022 • 8 minutes to read • Edit Online
Xbox multiplayer scenarios rely on the use of the Multiplayer Session Directory (MPSD) service and MPSD
documents. MPSD documents act as the roster for your current game session and drive multiplayer experiences
such as matchmaking, platform invites, recent player lists, and join-in-prgress.
In this document we will describe how you can incorporate PlayFab Party into common multiplayer flows that
require MPSD.
This document does not provide an in-depth discussion of MPSD and all of it's capabilities. For more
information, refer to the MPSD documentation.
Matchmaking
Here's a simplified flow for how to use matchmaking and MPSD together with PlayFab Party:
1. Players will create and gather into MPSD sessions that represent the groups they want playing together
across matchmaking sessions. Players will gather into these sessions by using Xbox's invite and join
features.
2. Those player groups will submit tickets to the matchmaking service which will gather compatible player
groups into a matchmaking session. This matchmaking session will, itself, be represented by a new
session document which the players will then join. Players must also listen for changes to this session
document.
3. Once the matchmaking session has been finalized and the roster is locked, the title must elect one of the
members of the matchmaking session to set up the PlayFab Party network. A simple strategy for
selecting the Party network creator is to use the first member of the matchmaking MPSD session
document.
4. The selected member will create the network with an initial PartyInvitation that restricts network access
to only the members of the matchmaking session. Once the network has successfully completed creation,
the selected member should post the resulting network descriptor and Party invitation to the session
document as a session property for other members to use.
void
OnMatchmakingSessionFinalized(
uint32_t usersInSessionCount,
const uint64_t* usersInSession
)
{
PartyInvitationConfiguration initialInvite{};
initialInvite.identifier = nullptr; // let Party select the invitation identifier for simplicity
initialInvite.revocability = PartyInvitationRevocability::Anyone; // must be revocable by anyone
// the updated invite should contain all users in the matchmaking session
std::vector<PartyString> entityIdsInSession;
for (uint32_t i = 0; i < usersInSessionCount; ++i)
{
uint64_t xboxUserId = usersInSession[i];
// Call title-defined xuid->entityid mapping helper
PartyString xboxUserEntityId = GetEntityIdFromXboxUserId(xboxUserId);
if (xboxUserEntityId != nullptr)
{
entityIdsInSession.push_back(xboxUserEntityId);
}
else
{
DEBUGLOG("User %llu did not have a matching entity ID.", xboxUserId);
}
}
initialInvite.entityIdCount = entityIdsInSession.size();
initialInvite.entityIds = entityIdsInSession.data();
void
HandleCreateNewNetworkCompleted(
const PartyCreateNewNetworkCompletedStateChange& createNewNetworkCompletedStateChange
)
{
if (createNewNetworkCompletedStateChange.result == PartyStateChangeResult::Succeeded)
{
// The network was created successfully! Post the networks descriptor and invitation
UpdateSessionProperty(
"PartyNetworkDescriptor", // arbitrary property name
serializedDescriptor);
UpdateSessionProperty(
"PartyInitialInvitation", // arbitrary property name
createNewNetworkCompletedStateChange.appliedInitialInvitationIdentifier);
}
else
{
// The network was not created successfully.
// Please refer to CreateNewNetwork reference documentation for retry guidance
}
}
5. When each member sees the session document updated, they may use the network descriptor and
invitation to connect to and join the network.
void
OnNetworkInformationPostedToSessionDocument(
PartyString serializedNetworkDescriptor,
PartyString invitationId
)
{
PartyNetworkDescriptor networkDescriptor;
PartyError error = PartyManager::DeserializeNetworkDescriptor(serializedNetworkDescriptor,
&networkDescriptor);
if (PARTY_FAILED(error))
{
DEBUGLOG("PartyManager::DeserializeNetworkDescriptor failed: 0x%08x\n", error);
return;
}
NOTE
Here we've presented one flow for incorporating matchmaking and MPSD with PlayFab Party. The core ideas of this flow
can be extended to other flows you might be interested in with MPSD, but presenting all possible flows is outside the
scope of this documentation. For more information, see the full MPSD documentation.
Platform invites
Here's a flow for how to incorporate Xbox platform invites into PlayFab Party:
1. PlayerA creates an MPSD session document, listens for session changes, and a creates a Party network.
When the Party network creation has completed, *PlayerA *posts the network descriptor and an initial
invite (if necessary) to the MPSD session document.
void
OnSessionDocumentCreated()
{
// This is an asynchronous call. It will be completed when StartProcessingStateChanges generates
a
// PartyCreateNewNetworkCompletedStateChange struct
PartyError error = PartyManager::GetSingleton().CreateNewNetwork(
m_localPartyUser,
&networkConfiguration,
0,
nullptr,
nullptr,
nullptr,
nullptr,
nullptr);
if (FAILED(error))
{
DEBUGLOG("PartyManager::CreateNetwork failed! 0x%08x\n", error);
return;
}
}
void
HandleCreateNewNetworkCompleted(
const PartyCreateNewNetworkCompletedStateChange& createNewNetworkCompletedStateChange
)
{
if (createNewNetworkCompletedStateChange.result == PartyStateChangeResult::Succeeded)
{
// The network was created successfully! Post the networks descriptor and invitation
UpdateSessionProperty(
"PartyNetworkDescriptor", // arbitrary property name
serializedDescriptor);
}
else
{
// The network was not created successfully.
// Please refer to CreateNewNetwork reference documentation for retry guidance
}
}
2. When PlayerA wants to invite PlayerB to the Party network, PlayerA initiates a platform invite to PlayerB
via in-game or console UI.
3. PlayerB receives the platform invite which includes an "invite handle" that PlayerB can use to find
PlayerA's MPSD session document.
4. PlayerB joins the session document and listens for changes.
5. PlayerA sees PlayerB join the session document. PlayerA creates a new invitation for PlayerB to use and
posts that invitation to the session document
void
OnUserJoinedSessionDocument(
PartyNetwork* network,
uint64_t newSessionMemberXboxUserId
)
{
std::string newMemberIdString = std::to_string(newSessionMemberXboxUserId);
// Specify our own invitation id so we don't have to query for it after the invitation has been
created.
// Here we will specify the invite id with the format "InviterXboxUserID_InviteeXboxUserID" so
that we can
// ensure this invitation ID doesn't clash with the invitations other members might try and
create for this user.
std::string invitationId = std::to_string(m_localXboxUserId) + "_" + newMemberIdString;
PartyInvitationConfiguration newInvite{};
newInvite.identifier = invitationId.c_str();
newInvite.revocability = PartyInvitationRevocability::Creator; // must be revocable by the
creator only
// Create a new invitation which includes all of the users currently in the document
PartyInvitation* newInvitation;
PartyError error = network->CreateInvitation(
m_localUser,
&newInvite,
nullptr,
&newInvitation);
if (PARTY_FAILED(error))
{
DEBUGLOG("PartyNetwork(0x%p)::CreateInvitation failed! (error=0x%x)", network, error);
return;
}
// Post the invitation to the local user's member property store in the session document, key'd
by the invitee's
// xbox user id. This will let the invitee recognize when an invitation is intended for them.
UpdateMemberProperty(
newMemberIdString.c_str(),
invitationId.c_str());
}
6. PlayerB sees the invitation posted to the session document and uses it to join the Party network.
void
OnRemoteMemberPropertyUpdated(
PartyString memberPropertyKey,
PartyString memberPropertyValue
)
{
// The member property update signifies a new invitation, if the remote member updated a property
that matches
// our xbox user id.
if (memberPropertyKey == std::to_string(m_localXboxUserId))
{
OnUserInvitationPostedToSessionDocument(memberPropertyValue);
}
// ...
}
void
OnUserInvitationPostedToSessionDocument(
PartyString invitationId
)
{
// The network descriptor should have already been posted to the session document before the
invitation.
// Call title-defined function to pull it from the session document.
PartyNetworkDescriptor networkDescriptor = QueryNetworkDescriptorFromSessionDocument();
IMPORTANT
Invitations created via PartyNetwork::CreateInvitation will become invalid if the PartyLocalUser which created
them leaves the network. Therefore, if a new user adds themselves to a session document but the user which
invited them leaves, it is recommended that the new user remove themselves from the session document and
wait to be re-invited by another user.
Join in-progress
Joining in-progress game sessions is very similar to the platform invite scenario. The core difference is that
instead of PlayerA sending PlayerB an "invite handle", PlayerB will get a "join handle" when they initiate a join-
in-progress from the platform UI. Using this "join handle", the PlayerB will join the session document and listen
for changes. PlayerA will respond by creating and posting a new Party invitation for them to the session
document. PlayerB will see this new invitation alongside the network descriptor and will use it to join the Party
network.
IMPORTANT
Invitations created via PartyNetwork::CreateInvitation will become invalid if the PartyLocalUser which created them leaves
the network. Therefore, if a new user receives a Party invitation from the join-in-progress flow, but cannot use it becaues
the user which created it has left, it is recommended that the new user remove themselves from the session document
and re-join later. This will enable another member of the session to restart the flow and generate a new Party invitation
for this user.
NOTE
The mechanisms and heuristics which detect disconnects for Party networks and MPSD sessions are different. Even in
scenarios where a player will be disconnected from both the Party network and MPSD session, these disconnect events
are independent, and it is not guaranteed that they occur close to each other in time. Titles should handle the scenario
where a player might only be disconnected from either the Party network or MPSD session.
If the game shuts down, the player will be disconnected from the Party network and MPSD document
automatically, and no further clean up is necessary.
Xbox Live Helper library overview
5/24/2022 • 10 minutes to read • Edit Online
The Xbox Live Helper library for PlayFab Party is designed to help games using PlayFab Party meet Xbox Live
policies related to communication (XR-015 and XR-045). The Xbox Live Helper library is available on Nuget.org.
1.0.1 ✔
1.1.0 ✔
1.2.0 ✔
1.2.5 ✔
void
OnLocalXboxUserAddedToMPSD(
uint64_t xboxUserId
)
{
PartyXblLocalChatUser* localChatUser;
PartyError err = PartyXblManager::GetSingleton().CreateLocalChatUser(xboxUserId, nullptr,
&localChatUser);
if (PARTY_FAILED(err))
{
DEBUGLOG("CreateLocalChatUser failed: %s\n", PartyXblManager::GetErrorMessage(err));
return;
}
At this point, if a PartyLocalChatControl already exists for the corresponding local xbox user, you can associate it
with this PartyXblLocalChatUser via the SetCustomContext methods.
localChatControl->SetCustomContext(localChatUser);
localChatUser->SetCustomContext(localChatControl);
Otherwise you can use this new PartyXblLocalChatUser to generate the chat control and associate them then.
See Creating PartyLocalChatControls from PartyXblLocalChatUsers for more information.
For remote users:
void
OnRemoteXboxUserAddedToMPSD(
uint64_t xboxUserId
)
{
PartyXblChatUser* remoteChatUser;
PartyError err = PartyXblManager::GetSingleton().CreateRemoteChatUser(remoteXboxUserId,
&remoteChatUser);
if (PARTY_FAILED(err))
{
DEBUGLOG("CreateRemoteChatUser failed: %s\n", PartyXblManager::GetErrorMessage(err));
return;
}
At this point, if a PartyChatControl already exists for the corresponding remote xbox user, you can associate it
with this PartyXblChatUser via the SetCustomContext methods.
remoteChatControl->SetCustomContext(remoteChatUser);
remoteChatUser->SetCustomContext(remoteChatControl);
Bear in mind, updates to the session document and updates to the list of remote chat controls may not be
strongly ordered, and you may require similar association logic when processing
PartyChatControlCreatedStateChange updates for remote chat controls.
For both, local and remote chat users, it's important to keep in mind that the core Party library identifies users
and chat controls via PlayFab Entity IDs where as the Xbox Live helper library identifies chat users with Xbox
User IDs. Therefore translating between the two is often necessary. Please refer to Mapping between Xbox Live
User IDs and PlayFab Entity IDs for more information.
PartyLocalDevice* localDevice;
err = PartyManager::GetSingleton().GetLocalDevice(&localDevice);
if (PARTY_FAILED(err))
{
DEBUGLOG("GetLocalDevice failed: %s\n", PartyManager::GetErrorMessage(err));
return;
}
PartyLocalChatControl* localChatControl;
err = localDevice->CreateChatControl(partyLocalUser, nullptr, nullptr, &localChatControl);
if (PARTY_FAILED(err))
{
DEBUGLOG("CreateChatControl failed: %s\n", PartyManager::GetErrorMessage(err));
return;
}
// We can use the custom context on the PartyXblLocalChatUser to store the PartyLocalChatControl for
easy access
// in the future.
localChatUser->SetCustomContext(localChatControl);
PartyXblAccessibilitySettings accessibilitySettings;
err = localChatUser->GetAccessibilitySettings(&accessibilitySettings);
if (PARTY_FAILED(err))
{
DEBUGLOG("GetAccessibilitySettings failed: %s\n", PartyXblManager::GetErrorMessage(err));
return;
}
if (accessibilitySettings.speechToTextEnabled)
{
PartyVoiceChatTranscriptionOptions option =
PartyVoiceChatTranscriptionOptions::TranscribeOtherChatControlsWithMatchingLanguages;
m_localChatControl->SetTranscriptionOptions(option, nullptr);
}
PartyXblChatUser* remoteChatUser;
PartyError err = PartyXblManager::GetSingleton().CreateRemoteChatUser(remoteXboxUserId,
&remoteChatUser);
if (PARTY_FAILED(err))
{
DEBUGLOG("CreateRemoteChatUser failed: %s\n", PartyXblManager::GetErrorMessage(err));
return;
}
// Once the chat control representing this remote Xbox Live user joins a network, we can use the custom
context
// on the PartyXblChatUser to store the chat control object for quick access in the future.
remoteChatUser->SetCustomContext(m_remotePartyChatControl);
The Xbox Live helper library tracks the privacy and privilege settings for each remote chat user in relation to
each local chat user by communicating with Xbox Live privacy services. Additionally, the library will listen for
changes to these settings by subscribing to (Real-Time Activity)[https://docs.microsoft.com/gaming/xbox-
live/real-time-activity-service/real-time-activity-service_nav] updates. When new remote chat users are added
or when the privacy and privilege relationship between a local chat user and an existing remote chat user
changes, a PartyXblRequiredChatPermissionInfoChangedStateChange will be generated to notify you that an
updated PartyChatPermissionOptions value is now available.
// Wait for PartyXblRequiredChatPermissionInfoChangedStateChange
if (stateChange->stateChangeType == PartyXblStateChangeType::RequiredChatPermissionInfoChanged)
{
auto chatPermissionChanged = static_cast<PartyXblRequiredChatPermissionInfoChangedStateChange*>
(stateChange);
PartyXblChatPermissionInfo chatPermissionInfo;
PartyError err = localChatUser->GetRequiredChatPermissionInfo(targetChatUser, &chatPermissionInfo);
if (PARTY_FAILED(err))
{
DEBUGLOG("GetRequiredChatPermissionInfo failed: %s\n", PartyXblManager::GetErrorMessage(err));
return;
}
PartyLocalChatControl* localChatControl;
localChatUser->GetCustomContext(reinterpret_cast<void**>(&localChatControl));
if (PARTY_FAILED(err))
{
DEBUGLOG("GetCustomContext failed: %s\n", PartyXblManager::GetErrorMessage(err));
return;
}
PartyChatControl* targetChatControl;
targetChatUser->GetCustomContext(reinterpret_cast<void**>(&targetChatControl));
if (PARTY_FAILED(err))
{
DEBUGLOG("GetCustomContext failed: %s\n", PartyXblManager::GetErrorMessage(err));
return;
}
localChatControl->SetPermission(targetChatControl, chatPermissionInfo.chatPermissionMask);
if (PARTY_FAILED(err))
{
DEBUGLOG("SetPermission failed: %s\n", PartyXblManager::GetErrorMessage(err));
return;
}
}
PartyXblCrossNetworkCommunicationPrivacySetting crossNetworkSetting;
localChatUser->GetCrossNetworkCommunicationPrivacySetting(&crossNetworkSetting);
if (crossNetworkSetting == PartyXblCrossNetworkCommunicationPrivacySetting::Disallowed)
{
m_localChatControl->SetPermissions(crossNetworkChatControl, PartyChatPermissionOptions::None);
}
More information on XR-015 and how it pertains to cross-network play and communication can be found here
Mapping between Xbox Live User IDs and PlayFab Entity IDs
Xbox Live titles using PlayFab Party will often need to translate between Xbox Live Users IDs (used throughout
the Xbox Live ecosystem) and PlayFab Entity IDs (used by PlayFab Party). Using
PartyXblManager::GetEntityIdsFromXboxLiveUserIds , titles can retrieve a list of PlayFab Entity IDs corresponding
to a given list of Xbox Live User IDs. Titles are expected to already have a list of Xbox Live User IDs through the
use of an external roster service, like the Multiplayer Session Directory. By associating the Xbox Live User IDs
from the roster with their PlayFab Entity IDs, we can construct a mapping of all PlayFab Entity IDs corresponding
to your game session's roster. This mapping can then be used to associate PartyEndpoint and PartyChatControl
objects with their corresponding Xbox Live users.
NOTE
Each Xbox Live User ID will only map to a PlayFab Entity ID if this Xbox Live user has already been linked to a PlayFab
account. A PlayFab account is automatically created and linked the first time PartyXblManager::LoginToPlayFab is
called for a given Xbox user. Alternatively, consumers of the PlayFab SDK can use the LoginWithXbox API to achieve the
same results.
The local PartyXblLocalChatUser will be used to authenticate with PlayFab. If the user was not previously logged
in to PlayFab with a call to PartyXblManager::LoginToPlayFab , the Xbox Live Helper library will need to
authenticate the user in the background.
uint32_t userCount;
PartyXblChatUserArray chatUsers;
PartyError err = PartyXblManager::GetSingleton().GetChatUsers(&userCount, &users);
if (PARTY_FAILED(err))
{
DEBUGLOG("GetChatUsers failed: %s\n", PartyXblManager::GetErrorMessage(err));
return;
}
// The list of remote Xbox Live User IDs. This can be populated with arbitrary IDs
// std::vector<uint64_t> remoteXboxLiveUserIds = {2533274792693551, 2814659110958830};
//
// but can also be pulled from the list of remote chat users
std::vector<uint64_t> remoteXboxLiveUserIds;
for (uint32_t i = 0; i < userCount; ++i)
{
PartyXblChatUser* chatUser = users[i];
PartyXblLocalChatUser* localChatUser;
err = chatUser->GetLocal(&localChatUser);
if (PARTY_FAILED(err))
{
DEBUGLOG("PartyChatUser(0x%p)::GetLocal failed: %s\n", chatUser,
PartyXblManager::GetErrorMessage(err));
return;
}
if (localChatUser != nullptr)
{
continue; // ignore local users
}
uint64_t userId;
err = chatUser->GetXboxUserId(&userId);
if (PARTY_FAILED(err))
{
DEBUGLOG("PartyChatUser(0x%p)::GetXboxUserId failed: %s\n", chatUser,
PartyXblManager::GetErrorMessage(err));
return;
}
remoteXboxLiveUserIds.push_back(userId);
}
err = PartyXblManager::GetSingleton().GetEntityIdsFromXboxLiveUserIds(
remoteXboxLiveUserIds.size(),
remoteXboxLiveUserIds.data(),
localChatUser,
nullptr);
if (PARTY_FAILED(err))
{
DEBUGLOG("GetEntityIdsFromXboxLiveUserIds failed: %s\n", PartyXblManager::GetErrorMessage(err));
return;
}
auto getEntityIdsFromXboxLiveUserIdsResult =
static_cast<PartyXblGetEntityIdsFromXboxLiveUserIdsCompletedStateChange*>(stateChange);
for (uint32_t i = 0; i < getEntityIdsFromXboxLiveUserIdsResult.entityIdMappingCount; ++i)
{
const PartyXblXboxUserIdToPlayFabEntityIdMapping& idMapping =
getEntityIdsFromXboxLiveUserIdsResult.entityIdMappings[i];
m_cachedXboxUserIdToPlayFabEntityIdMap = std::move(cachedXboxUserIdToPlayFabEntityIdMap);
With such a mapping, titles can recognize when a Party object represents an Xbox Live user.
uint64_t
GetXboxUserIdFromPlayFabEntityId(
PartyString entityId
)
{
for (const std::pair<uint64_t, std::string>& idMapping : m_cachedXboxUserIdToPlayFabEntityIdMap)
{
const std::string& entityIdForXboxUserId = idMapping.second;
if (entityIdForXboxUserId == entityId)
{
return idMapping.first;
}
}
// Failed to find a matching Xbox User ID. This Entity ID does not represent an Xbox Live user.
return 0;
}
For more guidance on how to retrieve token and signature using XAL, see the Xbox Authentication Library
documentation.
Once you have the token and signature, they can be provided to the Xbox Live Helper library by calling
PartyXblManager::CompleteGetTokenAndSignatureRequest() with the same correlationId that was provided to the
title through the state change.
Xbox Live Helper library release notes
5/24/2022 • 2 minutes to read • Edit Online
1.2.9
Bug fix for GetEntityIdsFromXboxLiveUserIds crash
Fixed a bug where the async operation started by PartyManager::GetEntityIdsFromXboxLiveUserIds() may
crash on failure.
1.2.5
This release of the Party Xbox Live Helper library includes the following changes:
A small memory leak is fixed.
A bug which prevented some heap allocations from flowing through the memory callbacks set in
PartyXblManager::SetMemoryCallbacks() is fixed.
PartyXblManager::CreateLocalChatUser() will no longer asynchronously fail if Xbox Live services cannot be
queried. In the event of service failures, PartyXblLocalChatUser::GetAccessibilitySettings() will return an
empty PartyXblAccessibilitySettings struct and
PartyXblLocalChatUser::GetCrossNetworkCommunicationPrivacySetting() will return
PartyXblCrossNetworkCommunicationPrivacySetting::Disallowed .
1.2.0
This release of the Party Xbox Live Helper library includes support for the updated chat permission options in
version 1.3.0 of PlayFab Party. For a full list of Party and Party Xbox Live Helper library version compatibility, see
the Party Xbox Live Helper Library overview.
1.1.0
GetEntityIdsFromXboxLiveUserIds API
This release of the Party Xbox Live Helper library introduces the
PartyXblManager::GetEntityIdsFromXboxLiveUserIds() API and associated completion state change,
PartyXblGetEntityIdsFromXboxLiveUserIdsCompleted . This API allows Titles to query the PlayFab Entity Ids
corresponding to a given list of Xbox Live User IDs. For more information, see overview.
1.0.1
LoginToPlayFab API
This release of the Party Xbox Live Helper library introduces the PartyXblManager::LoginToPlayFab() API and
associated completion state change, PartyXblLoginToPlayFabCompletedStateChange . This API provides equivalent
functionality to the PlayFab SDK LoginWithXbox API. For more information, see overview.
PartyXboxLive C/C++ API overview
5/24/2022 • 2 minutes to read • Edit Online
Classes
C L A SS DESC RIP T IO N
PartyXblManager The primary management class for interacting with the Party
Xbox Live Helper library.
Structures
ST RUC T URE DESC RIP T IO N
State changes
STAT E C H A N GE DESC RIP T IO N
Enumerations
EN UM ERAT IO N DESC RIP T IO N
PartyXblThreadId Threads that Party Xbox Live Helper library uses for internal
purposes.
Azure PlayFab SDK
5/24/2022 • 2 minutes to read • Edit Online
This topic lists the different flavors of Azure PlayFab SDKs we currently have today.
PlayFab SDK enables you to implement a majority of our features, including LiveOps, economy, matchmaking,
and data analytics.
Access to SDKs for Nintendo Switch, PlayStation 4, PlayStation 5, and Google Stadia requires special approval
and adherence to platform policies. For more information, see Request access for SDKs and samples.
For broad API categories in this SDK, see API REST operation groups.
TIP
Unsure if this is the SDK you need? See SDK overview - PlayFab SDK, Party SDK, Multiplayer Server SDK.
By content
SDK / L IB RA RY P L AT F O RM / EN VIRO N M EN T S
C++ Android, iOS, Linux, Windows (Win32) x64, Xbox One, Xbox
Series X|S, Switch, PlayStation 4, PlayStation 5, Cocos2D
(community supported)
JavaScript Phaser.io
By platform/operating system
P L AT F O RM / O P ERAT IN G SY ST EM SDK / L IB RA RY
Alternatively, you can also view the available SDKs based on languages, frameworks, game engines, and
scripting languages.
See also
SDKs overview
What is PlayFab?
Android Studio Project (Java)
5/24/2022 • 2 minutes to read • Edit Online
Our Android SDK provides everything you need to access the PlayFab API. This includes models, methods, an
HTTP wrapper for sending and receiving web requests, and JSON serialization.
This SDK is auto-generated using our open-sourced tool—SDKGenerator. We generally build SDKs every other
week to stay current with the latest API changes.
Download links
Android (Java) PlayFab SDK GitHub repo
Quick download link for Android (Java) PlayFab SDK
C#
5/24/2022 • 2 minutes to read • Edit Online
This C# SDK is used in the .NET environment, including Common Language Runtime (CLR). It is frequently used
in cross-platform iOS and Android app titles created using the free, open-source Xamarin platform. This SDK is
also used in games and apps coded in native C# for the Windows platform.
If you have questions about the SDK or need help in resolving issues, go to PlayFab forums > API and SDK .
Download links
C# PlayFab SDK GitHub repo
NuGet package for C# PlayFab SDK
Quick download link for C# PlayFab SDK
This SDK is auto-generated using our open-sourced tool—SDKGenerator. We generally build SDKs every other
week to stay current with the latest API changes.
Get started with the PlayFab Client library for C#. Follow steps to install the package and try out example code
for a basic task.
This quickstart helps you make your first PlayFab API call in the using the Client library for C#. Before
continuing, make sure you have completed Getting started for developers, which ensures you have a PlayFab
account and are familiar with the PlayFab Game Manager.
API reference documentation
Requirements
A PlayFab developer account.
An installation of Visual Studio.
At this point, you should be able to successfully compile the project. The output window should contain
something like the following example.
1>------ Build started: Project: CSharpGettingStarted, Configuration: Debug Any CPU ------
1> CSharpGettingStarted ->
c:\dev\CSharpGettingStarted\CSharpGettingStarted\bin\Debug\CSharpGettingStarted.exe
========== Build: 1 succeeded, 0 failed, 0 up-to-date, 0 skipped ==========
using System;
using System.Threading;
using System.Threading.Tasks;
using PlayFab;
using PlayFab.ClientModels;
while (_running)
{
if (loginTask.IsCompleted) // You would probably want a more sophisticated way of tracking
pending async API calls in a real game
{
OnLoginComplete(loginTask);
}
// Presumably this would be your main game loop, doing other things
Thread.Sleep(1);
}
if (apiError != null)
{
Console.ForegroundColor = ConsoleColor.Red; // Make the error more visible
Console.WriteLine("Something went wrong with your first API call. :(");
Console.WriteLine("Here's some debug information:");
Console.WriteLine(PlayFabUtil.GenerateErrorReport(apiError));
Console.ForegroundColor = ConsoleColor.Gray; // Reset to normal
}
else if (apiResult != null)
{
Console.WriteLine("Congratulations, you made your first successful API call!");
}
_running = false; // Because this is just an example, successful login triggers the end of the
program
}
}
Finish and execute
When you execute this program, following output displays in the consol
"Congratulations, you made your first successful API call! Done! Press any key to close."
At this point, you can start making other API calls, and building your game.
To build Admin utilities, see the alternate source files in the PlayFab CSharpSdk zip file located in
{CSharpSdk}/PlayFabClientSDK/sources .
For a list of all available client API calls, or many other topics, see PlayFab API References.
Java
5/24/2022 • 2 minutes to read • Edit Online
Our Java SDK provides everything you need to access the PlayFab API. This includes models, methods, an HTTP
wrapper for sending and receiving web requests, and JSON serialization. This is the same SDK used in the
Android Project.
This SDK is auto-generated using our open-sourced tool—SDKGenerator. We generally build SDKs every other
week to stay current with the latest API changes.
Download links
Java PlayFab SDK GitHub repo
Quick download link for Java PlayFab SDK
Licenses
Java licenses
Java quickstart for Native and Android Studio
5/24/2022 • 5 minutes to read • Edit Online
This quickstart lets you get up and running with the PlayFab JavaSDK and simple Java program.
Before you can call any PlayFab API, you must have a PlayFab developer account.
The goals for this tutorial are:
Acquire necessary JAR files.
Add JAR files to the classpath.
Create minimal Java console application that executes Custom ID Login API Call.
The next step is adding JAR files to the classpath. Navigate to File -> , as shown in the example below.
Navigate to Libraries , and add a new Java library as illustrated in the image provided below.
Select the JAR files you added to the libs folder, then select OK as shown below.
If asked for the Module , select the first one in the list. Ensure that all the JAR files were added to the libraries list.
import java.util.concurrent.*;
import java.util.*;
import com.playfab.PlayFabErrors.*;
import com.playfab.PlayFabSettings;
import com.playfab.PlayFabClientModels;
import com.playfab.PlayFabClientAPI;
public class Main
{
private static boolean _running = true;
FutureTask<PlayFabResult<com.playfab.PlayFabClientModels.LoginResult>> loginTask =
PlayFabClientAPI.LoginWithCustomIDAsync(request);
loginTask.run();
while (_running) {
if (loginTask.isDone()) { // You would probably want a more sophisticated way of tracking
pending async API calls in a real game
OnLoginComplete(loginTask);
}
// Presumably this would be your main game loop, doing other things
try {
Thread.sleep(1);
} catch(Exception e) {
System.out.println("Critical error in the example main loop: " + e);
}
}
}
_running = false; // Because this is just an example, successful login triggers the end of the
program
}
// This is a utility function we haven't put into the core SDK yet. Feel free to use it.
private static <RT> String CompileErrorsFromResult(PlayFabResult<RT> result) {
if (result == null || result.Error == null)
return null;
At this point, you can start making other API calls, and building your game.
For a list of all available client API calls, see our PlayFab API References documentation.
result = loginTask.get() ;
Fetch the async result (this won't cause a block, because we confirmed the FutureTask is already
complete.
if ( result.Result != null ), then the API call was successful.
When successful, the result.Result object of many API callbacks will contain the requested
information.
LoginResult specifically contains some basic information about the player. But for most
users, login is simply a mandatory step before calling other APIs.
If ( result.Error != null ), the API call has failed.
API calls can fail for many reasons, and you should always attempt to handle failure.
Why API calls fail (In order of likelihood)
PlayFabSettings.TitleId is not set. If you forget to set TitleId to your title, then
nothing will work.
Request parameters. If you have not provided the correct or required information for a
particular API call, then it will fail. See error.errorMessage , error.errorDetails , or
error.GenerateErrorReport() for more info.
Device connectivity issue. Cell phones lose/regain connectivity constantly, and so any API
call at any time can fail randomly, and then work immediately after. Going into a tunnel
can disconnect you completely.
PlayFab server issue. As with all software, there can be issues. See our release notes for
updates.
The internet is not 100% reliable. Sometimes the message is corrupted, or fails to reach
the PlayFab server.
If you are having difficulty debugging an issue, and the information within the error information is
not sufficient, please visit us on our forums.
Objective-C (iOS)
5/24/2022 • 2 minutes to read • Edit Online
IMPORTANT
This is a community supported SDK. Information on this page is no longer maintained and updated.
To learn how you can contribute and provide support for this SDK, refer to the ReadMe at Objective-C PlayFab
SDK repo.
The team at Microsoft would no longer be providing official support for those using this SDK. You can continue
to get community support and updates at PlayFab forums.
NOTE
This topic provides information about the original version of the SDK and does not apply to the newer community
versions.
Our Objective-C SDK provides everything you need to access the PlayFab API. This includes models, methods, an
HTTP wrapper for sending and receiving web requests, and JSON serialization. This SDK allows you to build
native iOS apps in Object-C, and have access to the PlayFab service.
Download links
Objective-C (iOS) PlayFab SDK GitHub repo
Quick download link for Objective-C (iOS) PlayFab SDK
Objective-C quickstart
5/24/2022 • 2 minutes to read • Edit Online
This quickstart assists you in making your first PlayFab API call using Objective-C, by illustrating how to get
started with our Objective-C SDK for native OSX & iOS development.
NOTE
This SDK is currently in Beta, so please let us know if you run into any issues.
Before you can call any PlayFab API, you must have a PlayFab developer account.
Happy Developing!
Getting started
There are two ways to get started:
1. Start with our example implementation project.
2. Import the Objective-C SDK into an existing XCode project.
Configuring PlayFab
Set your PlayFab TitleId in PlayFabSettings.m, on the line:
//Make each call to [PlayFabClientAPI GetInstance], the first time you do this, an instance will be created
and then used.
[[PlayFabClientAPI GetInstance] LoginWithCustomID:login_request
Troubleshooting
For a complete list of available APIs, see our PlayFab API References documentation.
Contact us
We love to hear from our developer community! Do you have ideas on how we can make our products and
services better?
Our Developer Success Team can assist with answering any questions, as well as process any feedback you have
about PlayFab services.
Forums, Support and Knowledge Base
C++
5/24/2022 • 2 minutes to read • Edit Online
The cross-platform C++ PlayFab SDK provides everything you need to access the PlayFab API. This includes
models, methods, an HTTP wrapper for sending and receiving web requests, and JSON serialization.
If you have questions about the SDK or need help in resolving issues, go to PlayFab forums > API and SDK .
Get started with the PlayFab Client library for C++. Follow steps to install the package and try out example code
for a basic task.
This quickstart helps you make your first PlayFab API call in the using the Client library for C++. Before
continuing, make sure you have completed Getting started for developers, which ensures you have a PlayFab
account and are familiar with the PlayFab Game Manager.
This quickstart was written using Ubuntu 18.04 LTS.
API reference documentation | Library source code
Requirements
A PlayFab developer account.
#include <iostream>
int main()
{
std::cout << "Hello World" << std::endl;
return 0;
}
cmake_minimum_required(VERSION 3.10)
set(CMAKE_CXX_STANDARD 14)
project(PlayFab_Test)
include_directories(XPlatCppSdk/cppsdk)
include_directories(XPlatCppSdk/cppsdk/include)
target_link_libraries(PlayFab_Test -ljsoncpp -lcurl -lpthread)
Build and run the project from inside your IDE, or open a Terminal prompt and run:
cmake .
make
./PlayFab_Test
#include "playfab/PlayFabClientDataModels.h"
#include "playfab/PlayFabClientApi.h"
#include "playfab/PlayFabSettings.h"
#include <unistd.h>
int main()
{
PlayFabSettings::staticSettings->titleId = ("144");
LoginWithCustomIDRequest request;
request.CreateAccount = true;
request.CustomId = "GettingStartedGuide";
while (PlayFabClientAPI::Update() != 0)
sleep(1);
Get started with the PlayFab Client library for C++. Follow steps to install the package and try out example code
for a basic task.
This quickstart helps you make your first PlayFab API call in the using the Client library for C++. Before
continuing, make sure you have completed Getting started for developers, which ensures you have a PlayFab
account and are familiar with the PlayFab Game Manager.
API reference documentation | Library source code
Requirements
A PlayFab developer account.
An installation of Visual Studio.
#include "playfab/PlayFabError.h"
#include "playfab/PlayFabClientDataModels.h"
#include "playfab/PlayFabClientApi.h"
#include "playfab/PlayFabSettings.h"
#include "playfab/PlayFabApiSettings.h"
#include <windows.h>
int main()
{
PlayFabSettings::staticSettings->titleId = ("144");
LoginWithCustomIDRequest request;
request.CreateAccount = true;
request.CustomId = "GettingStartedGuide";
while (PlayFabClientAPI::Update() != 0)
Sleep(1);
Get started with the PlayFab Client library for C++. Follow steps to install the package and try out example code
for a basic task.
This quickstart helps you make your first PlayFab API call in the using the Client library for C++. Before
continuing, make sure you have completed Getting started for developers, which ensures you have a PlayFab
account and are familiar with the PlayFab Game Manager.
API reference documentation | Library source code
Requirements
A PlayFab developer account.
An installation of Visual Studio 2017.
The Xbox SDK is only supported on Visual Studio 2017.
NOTE
The main difference for Xbox is that it has a separate project file for the solution.
Download the latest PlayFab cross-platform (CPP) SDK. Follow the instructions in the README to recursively
clone the dependencies. Note that this SDK is supported across Windows, Linux, and Xbox.
Build the dependencies for Xbox.
1. Open the Xbox One XDK Visual Studio 2017 Command Prompt and run the
build-dependencies-{debug/profile/release}.bat script. This script is located in the build > Xbox folder.
2. We will use debug for now, so make sure you run the debug script.
To build the respective configurations of the external dependencies, run the profile and release scripts. If the
build fails, make sure that you completed a recursive clone of the repo to also clone the external dependencies.
Setting up your Visual Studio project
To help you understand how to set up the project, we use a Direct3D sample for the guide. After you are familiar
with the proper set up procedures, you can choose to start with a different starting sample.
1. Create a new Direct3D sample project by selecting File > New > Project .
2. Under Installed , select Visual C++ > Xbox One > XDK > July 2018 QFE 2 .
NOTE
Based on the XDK you have installed, the version might be different. If you do not see Xbox One under Visual
C++ , re-install the XDK and try again.
3. Select Direct3D 11 Game . Name the project as PlayFabXboxGuide and select enter the location in which
to store the project. To create the project, select OK .
4. To explicitly call out port numbers, edit the package.appxmanifest file. When using ports internally, make
the following change to allow the application to talk to the network:
For more information about using ports internally, see the manifest template code example in the "Xbox
One exclusive resource application network manifest templates" section of Configuring a XIM project in a
manifest.
5. Modify the section for the XML header <mx:Extension Category="windows.xbox.networking"> so that it
looks like what is shown below.
...
<mx:Extension Category="windows.xbox.networking">
<mx:XboxNetworkingManifest>
<mx:SocketDescriptions>
<mx:SocketDescription Name="PlayFabQosApiClient" BoundPort="0" SecureIpProtocol="Udp">
<mx:AllowedUsages>
<mx:SecureDeviceSocketUsage Type="Initiate"/>
<mx:SecureDeviceSocketUsage Type="SendInsecure"/>
<mx:SecureDeviceSocketUsage Type="ReceiveInsecure"/>
</mx:AllowedUsages>
</mx:SocketDescription>
<mx:SocketDescription Name="PlayFabQosApiServer" BoundPort="3075" SecureIpProtocol="Udp">
<mx:AllowedUsages>
<mx:SecureDeviceSocketUsage Type="Accept" />
<mx:SecureDeviceSocketUsage Type="SendInsecure"/>
<mx:SecureDeviceSocketUsage Type="ReceiveInsecure"/>
</mx:AllowedUsages>
</mx:SocketDescription>
</mx:SocketDescriptions>
<mx:SecureDeviceAssociationTemplates>
<mx:SecureDeviceAssociationTemplate Name="PlayFabQosApiTraffic"
InitiatorSocketDescription="PlayFabQosApiClient" AcceptorSocketDescription="PlayFabQosApiServer"
MultiplayerSessionRequirement="None">
<mx:AllowedUsages>
<mx:SecureDeviceAssociationUsage Type="InitiateFromMicrosoftConsole" />
<mx:SecureDeviceAssociationUsage Type="InitiateFromWindowsDesktop" />
<mx:SecureDeviceAssociationUsage Type="AcceptOnOtherDevice" />
</mx:AllowedUsages>
</mx:SecureDeviceAssociationTemplate>
</mx:SecureDeviceAssociationTemplates>
</mx:XboxNetworkingManifest>
</mx:Extension>
5. Add a new header file called PlayFabApiCall.h , and add the code shown below to the file.
#pragma once
void MakePlayFabCall();
6. Add a new source file called PlayFabApiCall.cpp with the code shown below.
#include "pch.h"
#include "PlayFabApiCall.h"
#include <playfab/PlayFabClientDataModels.h>
#include <playfab/PlayFabClientApi.h>
#include <playfab/PlayFabSettings.h>
#include <windows.h>
void MakePlayFabCall()
{
print_log("\n\n=====================Start making your first PlayFab API
call========================\n\n");
PlayFabSettings::titleId = "144";
LoginWithCustomIDRequest request;
request.CreateAccount = true;
request.CustomId = "GettingStartedGuide";
while (PlayFabClientAPI::Update() != 0)
Sleep(1);
Now you have the code to make your first API call.
1. Call the MakePlayFabCall() function in Main.cpp , and add the following include statement:
#include "PlayFabApiCall.h"
2. In the virtualvoid Initialize(CoreApplicationView^ applicationView) function in Main.cpp , add
MakePlayFabCall(); as the last call.
3. Select F5 to deploy and run the application.
4. The result of your first PlayFab API call from the Xbox, displays in the Output log window.
Cocos2D-x (C++)
5/24/2022 • 2 minutes to read • Edit Online
IMPORTANT
This is a community supported SDK. Information on this page is no longer maintained and updated. This SDK only
supports an old version of Cocos and has not been ported to support the latest version.
To learn how you can contribute and provide support for this SDK, refer to the ReadMe at Cocos2D-x PlayFab
SDK repo.
The team at Microsoft would no longer be providing official support for those using this SDK. You can continue
to get community support and updates at PlayFab forums.
NOTE
This topic provides information about the original version of the SDK and does not apply to the newer community
versions.
Our Cocos2d-x SDK provides everything you need to access the PlayFab API. This includes models, methods, an
HTTP wrapper for sending and receiving web requests, and JSON serialization.
This SDK is auto-generated using the SDKGenerator—an open-sourced tool developed by us. We generally build
SDKs every other week in order to stay current with the latest API changes.
The Cocos SDK has not yet been fully tested across all Cocos platforms - however, this list is improving over
time.
These platforms are tested, and should function very well:
win32
ios_mac
android
These platforms are not tested/working yet:
android-studio
linux
win8.1-universal
win10
Download links
Cocos2D-x PlayFab SDK GitHub repo
Quick download link for Cocos2D-x PlayFab SDK
Licenses
Cocos2D-x licenses
Cocos2D-x quickstart
5/24/2022 • 7 minutes to read • Edit Online
This quickstart assists you in making your first PlayFab API call in the Cocos2d-x engine.
Before you can call any PlayFab API, you must have a PlayFab developer account.
3. Download PlayFab Cocos2d-xSdk: Cocos2D-x SDK (C++). Save and extract it to a temporary location
{PlayFabCocos}
Open the following folder in Windows Explorer: {PlayFabCocos}/PlayFabClientSDK
Open the following folder in a second Windows Explorer: {CocosGettingStarted}/Classes
4. Copy paste all files from {PlayFabCocos}/PlayFabClientSDK to {CocosGettingStarted}/Classes
5. In Visual Studio, Load {CocosGettingStarted}/proj.win32/CocosGettingStarted.sln .
6. We want to add the PlayFab files to the Cocos project.
7. In Visual Studio, Solution Explorer panel, expand to the folder: Solution/CocosGettingStarted/src
8. Open a Windows Explorer window at {CocosGettingStarted}/Classes
Select all files in {CocosGettingStarted}/Classes, EXCEPT AppDelegate.h, AppDelegate.cpp,
HelloWorldScene.h, HelloWorldScene.cpp
Drag and drop all of those files from Explorer, onto the Visual Studio
Solution/CocosGettingStarted/src folder we found above. If you experience problems, you can
drag and drop each file one at a time, just be careful and get all of them.
You should see these files in your VS project:
PlayFab uses several Cocos libraries that have to be manually added to the dependencies list.
Open the Proper ties window for your CocosGettingStarted project (as shown below).
NOTE
We are adding curl and zlib, which are libraries that come with Cocos, but are not enabled by default.
Your CocosGettingStarted project should now compile (and even run), but we are not yet making any PlayFab
API calls.
Installation complete!
#include "cocos2d.h"
#include "PlayFabClientDataModels.h"
#include "PlayFabError.h"
#endif // __HELLOWORLD_SCENE_H__
2. Immediately next to that, open HelloWorldScene.cpp , and replace the contents with this:
#include "HelloWorldScene.h"
#include "PlayFabClientAPI.h"
#include <PlayFabSettings.h>
USING_NS_CC;
std::string HelloWorld::statusMsg;
cocos2d::Label* HelloWorld::testReportLabel;
Scene* HelloWorld::createScene()
{
auto scene = Scene::create(); // 'scene' is an autorelease object
auto layer = HelloWorld::create(); // 'layer' is an autorelease object
scene->addChild(layer); // add layer as a child to scene
return scene; // return the scene
}
bool HelloWorld::init()
{
if (!Layer::init())
return false;
return true;
}
These files take the existing HelloWorldScene that is part of the new-Cocos-project template, and modify them
to include your first PlayFab API call.
This is only trivially modified from the default HelloWorldScene.h generated by Cocos.
Specifically, it defines some Cocos GUI we are using, and the prototype for OnLoginSuccess and
OnLoginFail .
Everything else is just standard Cocos Engine functions.
HelloWorldScene.cpp
Every PlayFab developer creates a title in Game Manager. When you publish your game,
you must code that titleId into your game. This lets the client know how to access the
correct data within PlayFab. For most users, just consider it a mandatory step that makes
PlayFab work.
PlayFab::ClientModels::LoginWithCustomIDRequest request;
Most PlayFab API methods require input parameters, and those input parameters are
packed into a request object.
Every API method requires a unique request object, with a mix of optional and
mandatory parameters.
For LoginWithCustomIDRequest , there is a mandatory parameter of CustomId ,
which uniquely identifies a player and CreateAccount , which allows the creation
of a new account with this call.
For login, most developers will want to use a more appropriate login method.
See the PlayFab Login documentation for a list of all login methods, and input
parameters. Common choices are:
LoginWithAndroidDeviceID
LoginWithIOSDeviceID
LoginWithEmailAddress
PlayFab::PlayFabClientAPI::LoginWithCustomID(request, OnLoginSuccess, OnLoginFail,
nullptr);
This begins the async request to LoginWithCustomID , and will invoke the OnLoginSuccess
or OnLoginFail function when complete.
update(float delta)
Simply setting the statusMsg variable does not update the on-screen text.
This function sets the GUI text to match the contents of statusMsg every tick (not very
efficient).
OnLoginSuccess(result, customData)
When the success callback is called, the result object of many API callbacks will contain the
requested information.
LoginResult contains some basic information about the player, but for most users, login is
simply a mandatory step before calling other APIs.
OnLoginFail(error, customData)
Our JavaScript SDK is fully compatible with Phaser.io, and provides everything you need to access the PlayFab
API.
This SDK is auto-generated using our open-sourced tool—SDKGenerator. We generally build SDKs every other
week to stay current with the latest API changes.
This SDK can alternatively be obtained via our CDN. Additional details can be found here.
Download links
Phaser (JavaScript) PlayFab SDK GitHub repo
Quick download link for Phaser (JavaScript) PlayFab SDK
Photon
5/24/2022 • 2 minutes to read • Edit Online
This section provides info about using PlayFab together with Photon multiplayer services such as Photon
RealTime and Photon Unity Networking (PUN).
Currently, we offer the following Photon integrations:
Authenticate Photon players with PlayFab.
Listen for room events using PlayFab CloudScript callbacks.
Photon quickstart
5/24/2022 • 17 minutes to read • Edit Online
This quickstart shows how to set up Photon Multiplayer to work with PlayFab. Currently, PlayFab offers the
following Photon integrations:
Authenticate Photon players with PlayFab.
Listen for room events using PlayFab CloudScript callbacks.
In this quickstart, we will illustrate how both features work using the latest Photon Unity example project.
Prerequisites
1. A Unity project with the PlayFab SDK imported, and a configured title.
2. The PlayFab title registered.
NOTE
This guide omits the Chat Application settings. For your Chat Application to be integrated, create a new Photon Chat
Application, and enter the App ID in the corresponding boxes in Unity and in the PlayFab Game Manager - Photon Add-
on page.
https://{PlayFabTitleId}.playfabapi.com/photon/authenticate
Replace the Title Id place holder with your own Title Id.
{PlayFabTitleId}
NOTE
Remember to save your Photon secret key in a safe and easily accessible place. It will come in handy when configuring
Webhooks.
https://{PlayFabTitleId}.playfablogic.com/webhook/1/prod/{PhotonSecretKey}
Make sure to replace Title Id placeholder with your own Title Id.
{PlayFabTitleId}
Make sure to replace the PhotonSecretKey token with the Secret Key you generated on the Photon Add-on
page.
{PhotonSecretKey}
Right after import process finishes, the PUN Setup window will open.
Enter your Realtime Application ID (1) found in the Photon Application Dashboard for the Photon
App you created.
Select Setup Project (2) .
Once the setup finishes, select Close (3) .
If AppId was accepted, the Photon Ser ver Settings object will be selected and viewable in the Unity
Inspector window. To manually access the Ser ver Settings object:
Navigate to the top window panel.
Select Window .
Then select Photon Unity Networking (1) .
Finally select Highlight Ser ver Settings (2) .
The Standard Unity project window will reveal the PhotonSer verSettings (3) object.
Select the object to reveal its settings in the Unity Inspector window.
NOTE
As part of PhotonSer verSettings , you have the option to assign the Chat Application ID .
using PlayFab;
using PlayFab.ClientModels;
using UnityEngine;
/*
* Step 1
* We authenticate current PlayFab user normally.
* In this case we use LoginWithCustomID API call for simplicity.
* You can absolutely use any Login method you want.
* We use PlayFabSettings.DeviceUniqueIdentifier as our custom ID.
* We pass RequestPhotonToken as a callback to be our next step, if
* authentication was successful.
*/
private void AuthenticateWithPlayFab(){
LogMessage("PlayFab authenticating using Custom ID...");
PlayFabClientAPI.LoginWithCustomID(new LoginWithCustomIDRequest()
{
CreateAccount = true,
CustomId = PlayFabSettings.DeviceUniqueIdentifier
}, RequestPhotonToken, OnPlayFabError);
}
/*
* Step 2
* We request Photon authentication token from PlayFab.
* This is a crucial step, because Photon uses different authentication tokens
* than PlayFab. Thus, you cannot directly use PlayFab SessionTicket and
* you need to explicitly request a token. This API call requires you to
* pass Photon App ID. App ID may be hard coded, but, in this example,
* We are accessing it using convenient static field on PhotonNetwork class
* We pass in AuthenticateWithPhoton as a callback to be our next step, if
* we have acquired token successfully
*/
private void RequestPhotonToken(LoginResult obj) {
LogMessage("PlayFab authenticated. Requesting photon token...");
//We can player PlayFabId. This will come in handy during next step
_playFabPlayerIdCache = obj.PlayFabId;
PlayFabClientAPI.GetPhotonAuthenticationToken(new GetPhotonAuthenticationTokenRequest()
PlayFabClientAPI.GetPhotonAuthenticationToken(new GetPhotonAuthenticationTokenRequest()
{
PhotonApplicationId = PhotonNetwork.PhotonServerSettings.AppID
}, AuthenticateWithPhoton, OnPlayFabError);
}
/*
* Step 3
* This is the final and the simplest step. We create new AuthenticationValues instance.
* This class describes how to authenticate a players inside Photon environment.
*/
private void AuthenticateWithPhoton(GetPhotonAuthenticationTokenResult obj) {
LogMessage("Photon token acquired: " + obj.PhotonCustomAuthenticationToken + " Authentication
complete.");
//We set AuthType to custom, meaning we bring our own, PlayFab authentication procedure.
var customAuth = new AuthenticationValues { AuthType = CustomAuthenticationType.Custom };
//We add "username" parameter. Do not let it confuse you: PlayFab is expecting this parameter to
contain player PlayFab ID (!) and not username.
customAuth.AddAuthParameter("username", _playFabPlayerIdCache); // expected by PlayFab custom
auth service
//We add "token" parameter. PlayFab expects it to contain Photon Authentication Token issues to your
during previous step.
customAuth.AddAuthParameter("token", obj.PhotonCustomAuthenticationToken);
//We finally tell Photon to use this authentication parameters throughout the entire application.
PhotonNetwork.AuthValues = customAuth;
}
Photon will start outputting debug messages. By simply monitoring your console, you can easily spot if you
have any authentication issues.
Ensure that no Authentication Denied errors are present in the console. At this point, you have set up minimal
PlayFab and Photon integration.
The following events will require additional control over Unity code to be intercepted (details are given later in
this document):
RoomPropertyUpdated
RoomEventRaised
NOTE
Once you introduce a handler for a room event, it becomes an essential part of the event handling flow. So errors
produced while running your CloudScript may cause problems for the entire system. For example, if the RoomCreated
handler throws an error, your clients will throw an error as well, and will not be able to connect properly.
Let's construct a PlayFab CloudScript by defining a handler for each event type individually.
Room Created handler
The RoomCreated handler is invoked every time a Photon room is created. The following CloudScript handler
will intercept such event.
NOTE
You may acquire additional data about the event using the "args" argument. The example of args payload is given below.
{
"ActorNr": 1,
"AppVersion": "1.2_1.85",
"AppId": "bfd5f98b-c6a4-4763-80d9-824d20db842b",
// Options with which the room was created.
"CreateOptions": {
"MaxPlayers": 4,
"LobbyId": null,
"LobbyType": 0,
"CustomProperties": {
},
"EmptyRoomTTL": 0,
"PlayerTTL": 0,
"CheckUserOnJoin": false,
"DeleteCacheOnLeave": true,
"SuppressRoomEvents": false,
"PublishUserId": false,
"ExpectedUsers": null
},
// Unique game identifier
"GameId": "8b8322de-096d-4481-a2b2-8db8bb45cfef",
"Region": "EU",
"Type": "Create",
// User that caused the room to be created
"UserId": "834D5AA5BAB1DFB6",
"Username": ""
}
This callback is not invoked for the very first user entering the room. Use RoomCreated to intercept the first
player that joins. You may acquire additional data about the event using the "args" argument.
The example of args payload is shown below.
{
"ActorNr": 2,
"AppVersion": "1.2_1.85",
"AppId": "bfd5f98b-c6a4-4763-80d9-824d20db842b",
// Unique Game Identifier
"GameId": "b0f55a2e-431d-402a-9809-b0240443267e",
"Region": "EU",
"Type": "Join",
// Id of the player that has joined
"UserId": "AAC7634BF46289DF",
"Username": ""
}
Room left
The RoomLeft handler is invoked every time a player leaves the room. The following CloudScript handler will
intercept such event.
// Triggered automatically when a player leaves a Photon room
handlers.RoomLeft = function (args) {
return { ResultCode : 0, Message: 'Success' };
};
You may acquire additional data about the event using "args" argument. The example of args payload is shown
below.
{
"ActorNr": 2,
"AppVersion": "1.2_1.85",
"AppId": "bfd5f98b-c6a4-4763-80d9-824d20db842b",
// Unique Game Identifier
"GameId": "b0f55a2e-431d-402a-9809-b0240443267e",
"IsInactive": false,
"Reason": "0",
"Region": "EU",
"Type": "ClientDisconnect",
// Id of the user that has left the room
"UserId": "AAC7634BF46289DF",
"Username": ""
}
You may acquire additional data about the event using "args" argument. The example of args payload is shown
below.
"ActorCount": 0,
"ActorNr": 1,
"AppVersion": "1.2_1.85",
"AppId": "bfd5f98b-c6a4-4763-80d9-824d20db842b",
// Unique game identifier
"GameId": "b0f55a2e-431d-402a-9809-b0240443267e",
"Region": "EU",
"State2": {
"ActorList": [
]
},
"Type": "Close"
}
NOTE
The currentPlayerId is undefined in this handler. If the room property was changed from the client, you may use the
"args" argument, and refer to the UserId to acquire the player in charge.
You may acquire additional data about the event using "args" argument. The example of args payload is shown
below.
{
"ActorNr": 1,
"AppVersion": "1.2_1.85",
"AppId": "bfd5f98b-c6a4-4763-80d9-824d20db842b",
// Custom Room Properties
"Properties": {
"CustomProperty": "It's Value"
},
"GameId": "8b8322de-096d-4481-a2b2-8db8bb45cfef",
"Region": "EU",
"State": {
"ActorCounter": 1,
"ActorList": [
{
"ActorNr": 1,
"UserId": "834D5AA5BAB1DFB6",
"Username": "",
"IsActive": true,
"Binary": "RGIAAAEBRAAAAAFi\/3MAAA==",
"DEBUG_BINARY": {
"1": {
"255": ""
}
}
}
],
"Binary": {
"18":
"RAAAAANi+nkAAHNzAA1QbGF5ZXJJbmRleGVzRGlpAAEAAAABAAAAAHMADkN1c3RvbVByb3BlcnR5cwAKSXQncyBWYWx1ZQ=="
},
"CheckUserOnJoin": false,
"CustomProperties": {
},
"DeleteCacheOnLeave": true,
"EmptyRoomTTL": 0,
"IsOpen": true,
"IsVisible": true,
"LobbyType": 0,
"LobbyProperties": [
],
"MaxPlayers": 4,
"PlayerTTL": 0,
"SuppressRoomEvents": false,
"Slice": 0,
"DebugInfo": {
"DEBUG_PROPERTIES_18": {
"250": [
],
"PlayerIndexes": {
"1": 0
},
"CustomProperty": "It's Value"
}
},
"ExcludedActors": [
],
"PublishUserId": false,
"ExpectedUsers": [
]
},
"Type": "Game",
"UserId": "834D5AA5BAB1DFB6",
"Username": ""
}
When changing custom Room properties using the Unity Photon client, it is important to mark the call, so that it
passes the event to Webhook (PlayFab in this case).
// Properties updates ( this hashtable contains the properties to be changed. Properties not mentioned here
will stay as is
var properties = new ExitGames.Client.Photon.Hashtable() { { "CustomProperty" , "It's Value" } };
// Control set. Empty in this case, because our property has not existed before.
// Otherwise you would include previous value of the property.
var expectedProperties = new ExitGames.Client.Photon.Hashtable();
// Set Custom Properties call. Notice the last argument set to "true"
// This tells Photon to forward event to the webhook.
PhotonNetwork.room.SetCustomProperties(properties, expectedProperties, true);
You may acquire additional data about the event using "args" argument. The example of args payload is shown
below.
{
"ActorNr": 1,
"AppVersion": "1.2_1.85",
"AppId": "bfd5f98b-c6a4-4763-80d9-824d20db842b",
// Custom event data
"Data": {
"Hello": "World"
},
"GameId": "8b8322de-096d-4481-a2b2-8db8bb45cfef",
"Region": "EU",
"State": {
"ActorCounter": 1,
"ActorList": [
"ActorList": [
{
"ActorNr": 1,
"UserId": "834D5AA5BAB1DFB6",
"Username": "",
"IsActive": true,
"Binary": "RGIAAAEBRAAAAAFi\/3MAAA==",
"DEBUG_BINARY": {
"1": {
"255": ""
}
}
}
],
"Binary": {
"18": "RAAAAAJi+nkAAHNzAA1QbGF5ZXJJbmRleGVzRGlpAAEAAAABAAAAAA=="
},
"CheckUserOnJoin": false,
"CustomProperties": {
},
"DeleteCacheOnLeave": true,
"EmptyRoomTTL": 0,
"IsOpen": true,
"IsVisible": true,
"LobbyType": 0,
"LobbyProperties": [
],
"MaxPlayers": 4,
"PlayerTTL": 0,
"SuppressRoomEvents": false,
"Slice": 0,
"DebugInfo": {
"DEBUG_PROPERTIES_18": {
"250": [
],
"PlayerIndexes": {
"1": 0
}
}
},
"ExcludedActors": [
],
"PublishUserId": false,
"ExpectedUsers": [
]
},
"Type": "Event",
// PlayFab User Id if he/she was the source of the event
"UserId": "834D5AA5BAB1DFB6",
"Username": "",
// Event code
"EvCode": 15
}
When raising custom room events using Unity Photon client, it is important to mark the call so that it passes the
event to Webhooks (PlayFab in this case).
var data = new Dictionary<string,object>() {
{ "Hello" , "World" }
};
The code does nothing more than posting a new title event whenever a Photon callback is invoked. Being of no
use in production, this example will let us clearly see how the callbacks are invoked.
Extend the PlayFabAuthenticator script by including new example code that will raise custom event, and set
custom room property. The extended version also utilizes an Awake method to not destroy object between
scene loads.
using System.Collections.Generic;
using PlayFab;
using PlayFab.ClientModels;
using UnityEngine;
/*
* Step 1
* We authenticate current PlayFab user normally.
* In this case we use LoginWithCustomID API call for simplicity.
* You can absolutely use any Login method you want.
* We use PlayFabSettings.DeviceUniqueIdentifier as our custom ID.
* We pass RequestPhotonToken as a callback to be our next step, if
* authentication was successful.
*/
private void AuthenticateWithPlayFab() {
LogMessage("PlayFab authenticating using Custom ID...");
PlayFabClientAPI.LoginWithCustomID(new LoginWithCustomIDRequest()
{
CreateAccount = true,
CustomId = PlayFabSettings.DeviceUniqueIdentifier+"EDITOR"
}, RequestPhotonToken, OnPlayFabError);
}
/*
* Step 2
* We request Photon authentication token from PlayFab.
* This is a crucial step, because Photon uses different authentication tokens
* than PlayFab. Thus, you cannot directly use PlayFab SessionTicket and
* you need to explicitly request a token. This API call requires you to
* pass Photon App ID. App ID may be hard coded, but, in this example,
* We are accessing it using convenient static field on PhotonNetwork class
* We pass in AuthenticateWithPhoton as a callback to be our next step, if
* we have acquired token successfully
*/
private void RequestPhotonToken(LoginResult obj) {
LogMessage("PlayFab authenticated. Requesting photon token...");
//We can player PlayFabId. This will come in handy during next step
_playFabPlayerIdCache = obj.PlayFabId;
PlayFabClientAPI.GetPhotonAuthenticationToken(new GetPhotonAuthenticationTokenRequest()
{
PhotonApplicationId = PhotonNetwork.PhotonServerSettings.AppID
}, AuthenticateWithPhoton, OnPlayFabError);
}
/*
* Step 3
* This is the final and the simplest step. We create new AuthenticationValues instance.
* This class describes how to authenticate a players inside Photon environment.
*/
private void AuthenticateWithPhoton(GetPhotonAuthenticationTokenResult obj) {
LogMessage("Photon token acquired: " + obj.PhotonCustomAuthenticationToken + " Authentication
LogMessage("Photon token acquired: " + obj.PhotonCustomAuthenticationToken + " Authentication
complete.");
//We set AuthType to custom, meaning we bring our own, PlayFab authentication procedure.
var customAuth = new AuthenticationValues { AuthType = CustomAuthenticationType.Custom };
//We add "username" parameter. Do not let it confuse you: PlayFab is expecting this parameter to
contain player PlayFab ID (!) and not username.
customAuth.AddAuthParameter("username", _playFabPlayerIdCache); // expected by PlayFab custom
auth service
//We add "token" parameter. PlayFab expects it to contain Photon Authentication Token issues to your
during previous step.
customAuth.AddAuthParameter("token", obj.PhotonCustomAuthenticationToken);
//We finally tell Photon to use this authentication parameters throughout the entire application.
PhotonNetwork.AuthValues = customAuth;
}
// Example code which raises custom room event, then sets custom room property
private void ExecuteExample() {
Run the hub scene and wait for PlayFab authentication to complete (1) .
Then load the Boxes Demo scene (2) .
Once the scene loads, wait for the peer to connect newly created room (1) .
Then select Execute Example in the top left corner (2) .
Observe the console output (3) .
Make sure no errors have occurred.
Don't forget to stop Unity from playing. This is done to ensure that we also receive RoomLeft and
RoomClosed events.
Navigate to the title Game Manager page, and observe the PlayStream panel. You should be able to see events
generated as a result of our CloudScript code handling Photon events.
1. Initially, our Photon instance had no opened room. When we launched the example, Photon has created the
room for the Boxes Demo.
2. The first player to join is the player who requested the room. So no RoomJoined Event was recorded. We
then executed our example code:
First, we raised a custom Room Event .
Then, we set a custom Room Proper ty .
Then we stopped the Unity play mode. This resulted in our client leaving the room.
3. Since our disconnected client was the last one, there are no more clients and Photon closes the room.
All the events should be logged into the PlayStream event flow, as shown on the following picture.
At this point, you have fully integrated Photon event support into your PlayFab title.
Unity3D (C#)
5/24/2022 • 2 minutes to read • Edit Online
Our Unity3d PlayFab SDK provides everything you need to access the PlayFab API. This includes models,
methods, an HTTP wrapper for sending and receiving web requests, and JSON serialization.
This SDK is auto-generated using our open-sourced tool—SDKGenerator. We generally build SDKs every other
week to stay current with the latest API changes.
Check out our Editor Extensions, for the easiest and fastest way to get started using PlayFab in Unity. This tool
provides a UI for managing SDK settings, as well as an automatic SDK upgrade with the ability to stay current
with the latest APIs.
PlayFab Party seamlessly integrate multiplayer networking and voice/text chat into Unity games. To get started,
see Party Unity Plugin.
Download links
Unity PlayFab SDK GitHub repo
Quick download link: Unity Editor Extensions for PlayFab SDK
Quick download link: Unity PlayFab SDK
Licenses
Unity3D licenses
Quickstart: PlayFab Client library for C# in Unity
5/24/2022 • 4 minutes to read • Edit Online
Get started with the PlayFab Client library for C# in Unity. Follow steps to install the package and try out
example code for a basic task.
This quickstart helps you make your first PlayFab API call in the Unity3d engine. Before continuing, make sure
you have completed Getting started for developers, which ensures you have a PlayFab account and are familiar
with the PlayFab Game Manager.
Requirements
A PlayFab developer account.
An installed copy of the Unity Editor. To install Unity for personal use via Unity Hub, or Unity+ for
professional use, see Download Unity.
NOTE
The PlayFab Unity3D SDK supports Unity Editor version 5.3 (released December 2015) and higher.
NOTE
If the panel did not open, or if you close the panel and want to reopen it, you can do so by selecting Window >
PlayFab > Editor Extensions
6. After logging in, the extension displays the SDK installation dialog.
7. Select Install PlayFab SDK to automatically import the SDK into your project or upgrade the version
that is currently installed.
2. Select the Studio entry to open the studio drop-down menu. Select the studio that contains the Title to
which you would like to connect.
3. Select the Title ID entry to open a drop-down menu of Titles associated with the selected studio.
The Developer Secret Key is automatically set to the default secret key for the Title. For more information
about secret keys, see Secret key management.
Making your first API call
This part of the guide provides the minimum steps to make your first PlayFab API call. This example does not
provide any GUI or on-screen feedback. Confirmation is displayed in the Console log.
1. If your Unity Project doesn't already have a Scripts folder (HDRP and LWRP/URP templates have one by
default), right-click on the Assets folder in the Project panel and select Create > Folder .
2. In the Assets window, name the folder Scripts.
3. Right-click the Scripts folder and select Create > C# Script .
4. Name the script PlayFabLogin.
5. Double-click the file to open it in a code-editor. Depending on your settings/installed-programs, this is
likely Visual Studio or MonoDevelop.
6. In your code editor, replace the contents of PlayFabLogin.cs with the code shown below and save the file.
using PlayFab;
using PlayFab.ClientModels;
using UnityEngine;
IMPORTANT
The code shown above is not for use with mobile Titles. This is only an example, and shows how to log in with a
CustomID . To implement login for a mobile Title, use either LoginWithAndroidDeviceID, LoginWithIOSDeviceID,
or some form of social login such as LoginWithFacebook.
7. In the Hierarchy panel, right-click your scene, then select Create Empty (or Game Object > Create
Empty in older versions of Unity).
8. Select the new Game Object and in the Inspector panel, select Add Component .
9. From the component drop-down menu, select Scripts > PlayFabLogin .
For more information on creating and using scripts in the Unity Editor, see Creating and Using Scripts in the
Unity documentation.
For a list of all available client API calls, see PlayFab API References.
Next steps
This quickstart shows a simplified procedure for authenticating a user. For additional information on user
authentication, see Login basics and best practices.
Learn how to bind an account to multiple devices and login mechanisms: Account linking quickstart.
Installing the PlayFab SDK for Unity
5/24/2022 • 2 minutes to read • Edit Online
You have two options when installing the PlayFab Unity 3D SDK:
Install the PlayFab Unity Editor Extensions Asset Package. Then use Editor Extension to install the PlayFab
Unity 3D SDK and configure your Unity Project.
PlayFab Editor Extensions is a stand-alone Unity plug-in that streamlines getting started with PlayFab.
When a supported SDK is installed, additional service menus are available. These menus provide access
to SDK configurations. These configuration settings are saved in a combination of places to ensure that
the data persists throughout Unity compilations and deployments. For more information about the
PlayFab Editor Extensions, see the readme in the PlayFab/UnityEditorExtensions GitHub repo.
Install the PlayFab Unity 3D SDK directly without using PlayFab Unity Editor Extensions. When you use
this installation method, you configure your Unity Project directly by setting properties property values in
your code.
This content assumes you that you have a PlayFab developer account and an existing Unity Project.
Install the PlayFab Unity Editor Extensions and the PlayFab SDK
1. Download the PlayFab Unity Editor Extensions Asset Package.
2. Open your Unity Project.
3. Navigate to where you downloaded the file and double-click on the
PlayFabEditorExtensions.UnityPackage file to open the Impor t Unity Package dialog in the Unity Editor.
4. To import the PlayFab Unity Editor Extensions into your project, select Impor t .
5. When the import has completed, the PlayFab Unity Editor Extensions panel should open automatically. If
you've already created a PlayFab developer account, select the Log In link to log in with your PlayFab
username and password.
NOTE
If the panel did not open, or if you close the panel and want to reopen it, you can do so by selecting Window >
PlayFab > Editor Extensions
6. After logging in, the extension displays the SDK installation dialog.
7. Select Install PlayFab SDK to automatically import the SDK into your project or upgrade the version
that is currently installed.
Set your title settings
Before you can make an API call, you must specify the Title to receive the call in the PlayFab Title Settings . To
set the Title:
1. Select SET MY TITLE in the Editor Extensions .
2. Select the Studio entry to open the studio drop-down menu. Select the studio that contains the Title to
which you would like to connect.
3. Select the Title ID entry to open a drop-down menu of Titles associated with the selected studio.
Download and install the SDK only
To install the SDK without using the PlayFab Unity Editor Extensions:
1. Open your Unity project.
2. Download the PlayFab Unity3D SDK Asset Package from the PlayFab GitHub repo.
3. Navigate to where you downloaded the file, and double-click on the .UnityPackage file to open the Impor t
Unity Package dialog in the Unity Editor.
4. To import the PlayFab Unity3D SDK into your project, select Impor t .
Setting the Title ID without using the editor extensions
To set the title:
1. In the Unity Editor Project panel select the Assets folder.
2. Open the Assets > PlayFabSdk > Shared > Public > Resources folder.
3. Select the PlayFabSettings Asset.
4. In the Inspector window, set the Title ID and the Developer Secret Key .
NOTE
Refer to Secret key Management to find your secret key, also called a developer key to your PlayFab Title.
Unreal Engine (C++, Blueprints)
5/24/2022 • 2 minutes to read • Edit Online
Our Unreal Marketplace plugin provides everything you need to access the PlayFab API. This includes models,
methods, an HTTP wrapper for sending and receiving web requests, and JSON serialization. There is a C++
interface and a Blueprint interface, giving you the best of both worlds.
This SDK is auto-generated using our open-sourced tool—SDKGenerator. We generally build SDKs every other
week to stay current with the latest API changes.
Download links
Unreal Engine PlayFab SDK GitHub repo
Unreal Engine PlayFab SDK on Unreal Marketplace site (external link)
Quick download link for Unreal Engine PlayFab SDK
Quickstart: PlayFab client library for Unreal Engine
5/24/2022 • 7 minutes to read • Edit Online
Get started with the PlayFab plugin for the Unreal Engine. Follow this quickstart to install the PlayFab Unreal
Engine plugin and create example apps that use the C++ client library and the Blueprint interface.
You can use the PlayFab plugin for the Unreal Engine to manage LiveOps for your Title and perform admin,
client, and server operations such as:
Player authentication.
Managing virtual items and currency.
Creating social features such as friends lists.
API reference documentation | Library source code | Unreal Marketplace
Prerequisites
A PlayFab developer account.
An installation of Visual Studio that is configured for Unreal Engine. For information about configuring Visual
Studio, see Setting Up Visual Studio for Unreal Engine.
An installation of the Unreal Engine. For information about installing the Ureal Engine, see the Unreal Engine
installation guide.
An installation of the PlayFab Unreal plugin. You can install the Unreal plugin from the Unreal Engine
marketplace.
IMPORTANT
For the purposes of this quickstart, you must name the Actor LoginActor . If you give the Actor a different name,
you must update the sample code provided in this quickstart to match the new name.
4. Drag-and-drop your new Actor LoginActor from the Content Browser into the Viewport panel. It will
appear in the World Outliner pane. If you don't see your LoginActor , select the Show or hide the
source panel icon. Then select the name of your project under the C++ classes.
Add PlayFab API calls to your C++ LoginActor
In this quickstart you use LoginWithCustomID to perform the log in. Log in using LoginWithCustomID is easy to
implement but is of limited usefulness in the scenario of a published Title. Before you launch your Title, see the
Login basics and best practices for information about implementing robust log in functionality.
The LoginWithCustomID call is made in your LoginActor . To add the PlayFab specific code to your LoginActor :
1. Replace the contents of LoginActor.h with the code shown below.
#pragma once
#include "CoreMinimal.h"
#include "GameFramework/Actor.h"
#include "PlayFab.h"
#include "Core/PlayFabError.h"
#include "Core/PlayFabClientDataModels.h"
#include "LoginActor.generated.h"
UCLASS()
class ALoginActor : public AActor
{
GENERATED_BODY()
public:
ALoginActor();
virtual void BeginPlay() override;
void OnSuccess(const PlayFab::ClientModels::FLoginResult& Result) const;
void OnError(const PlayFab::FPlayFabCppError& ErrorResult) const;
ALoginActor::ALoginActor()
{
PrimaryActorTick.bCanEverTick = true;
}
void ALoginActor::BeginPlay()
{
Super::BeginPlay();
clientAPI = IPlayFabModuleInterface::Get().GetClientAPI();
clientAPI->SetTitleId(TEXT("144"));
PlayFab::ClientModels::FLoginWithCustomIDRequest request;
request.CustomId = TEXT("GettingStartedGuide");
request.CreateAccount = true;
clientAPI->LoginWithCustomID(request,
PlayFab::UPlayFabClientAPI::FLoginWithCustomIDDelegate::CreateUObject(this,
&ALoginActor::OnSuccess),
PlayFab::FPlayFabErrorDelegate::CreateUObject(this, &ALoginActor::OnError)
);
}
TIP
Intellisense in Visual Studio will indicate that it cannot locate the include files and the PlayFab namespace. You can safely
disregard these warnings. When you run your project it will build and execute correctly.
TIP
If you start from a Blueprint project, you must convert it to a C++ project for the PlayFab Blueprint Actions to function.
The EventGraph opens and is prepopulated with two Actions. Event BeginPlay and Event Tick .
Actions used in this quickstart:
Set Play Fab Settings
Login with Custom ID
Make ClientLoginWithCustomIDRequest
AddCustomEvent x2
Break PlayFabError
Print String x2
For information on retrieving your Title id, see "Retrieving your TitleId" in Getting started for
developers.
Select the output pin on Set Play Fab Settings and drag it to an open location. In the Executable
Actions dialog, search for Login with Custom ID and select it to add it to your Blueprint.
Select the Request pin on Login with Custom ID and drag it to an empty location. From the Actions
providing a(n) Client Login With Custom IDRequest Structure select
Make ClientLoginWithCustomIDRequest .
On Make ClientLoginWithCustomIDRequest :
Select Create Account .
Set the Custom Id to GettingStartedGuide.
On Login with Custom ID select the On Success pin and drag it to an empty location. in the Actions
providing a(n) Delegate search for Add Custom Event and select it to add it to your Blueprint.
Name it OnLogin .
Select the On Failure pin and drag it to an empty location. in the Actions providing a(n) Delegate
search for Add Custom Event and select it to add it to your Blueprint.
Name it OnFailure .
Select the output pin on OnLogin and drag it to an empty location. In the Executable Actions dialog
search for Print String and select it to add it to the Blueprint.
On Print String set the In String value to "Congratulations, you made your first successful PlayFab
API call using Blueprint!".
Select the output pin of OnFailure nd drag it to an empty location. In the Executable Actions dialog
search for Print String and select it to add it to the Blueprint.
Select the Error pin on OnFailure and drag it to an empty location. In the Actions providing a(n)
string dialog search for Break PlayFabError and select it to add it to the Blueprint. In the Actions
taking a(n) Play Fab error structure dialog search for Break PlayFabError and select it to add it to
the Blueprint.
Connect the Error Message pin of Break PlayFabError to the In String pin of on failure Print String
Action.
When you are finished your Blueprint will look similar to the following:
Save the Blueprint, and close the Blueprint Editor window.
Execute a PlayFab call with Blueprint
1. On the toolbar, select the Play button.
2. When the Blueprint runs, the following output is shown in the Viewport window.
Congratulations, you made your first successful PlayFab API call using Blueprint!
Additional Resources
Unreal Engine documentation for Blueprints Visual Scripting.
Unreal Engine Programming Guide.
ActionScript
5/24/2022 • 2 minutes to read • Edit Online
IMPORTANT
The PlayFab ActionScript SDK has been deprecated. Information on this page is no longer maintained and updated.
Adobe ended support for Adobe Flash Player and has been completely removed from common browsers. For
more information, see Adobe Flash Player End of Life General Info (external site).
Our ActionScript SDK provides everything you need to access the PlayFab API. This includes models, methods,
and an HTTP wrapper for sending and receiving web requests and JSON serialization.
Download links
Final SDK release
ActionScript PlayFab SDK GitHub repo
Quick download link for ActionScript PlayFab SDK
ActionScript quickstart for Flash
5/24/2022 • 6 minutes to read • Edit Online
This quickstart helps you make your first PlayFab API call using ActionScript.
Before you can call any PlayFab API, you must have a PlayFab developer account.
Installation
These steps describe building an AS3 project using entirely free tools. As such, this might be more complicated
than something like Adobe Flash Builder. The instructions are the result of lots of experimentation and testing,
rather than expert knowledge. If you're already aware of simpler installation steps, feel free to skip to the next
section.
Downloads
For environment variable instructions below, anything in {curly braces} should be replaced with the actual
installation path (don't put actual curly braces in your environment variables).
1. Install the Adobe Air SDK: https://www.adobe.com/devnet/air/air-sdk-download.html.
Remember your installation path {AirSdkLocation} since you will use it below.
2. Install the Adobe Flex SDK: https://www.adobe.com/devnet/flex/flex-sdk-download.html
Remember your installation path {FlexSdkLocation}, and modify your system environment variables:
Add {FlexSdkLocation}/bin to your PATH environment variable. For example, if you install to
C:/dev/flex_sdk_4.6, then set FLEX_HOME=C:/dev/flex_sdk_4.6
Add a FLEX_HOME system environment variable, and set it to {FlexSdkLocation} For example, if you
install to C:/dev/flex_sdk_4.6, then add C:/dev/flex_sdk_4.6/bin to your PATH
3. Open two Explorer windows: {AirSdkLocation} and {FlexSdkLocation}
4. Select All in the {AirSdkLocation} folder.
5. Copy and Paste the contents of {AirSdkLocation} over the top of {FlexSdkLocation}. This will replace some
existing files, and that's correct.
6. Download the PlayFab ActionScriptSD ActionScript SDK zip file, and extract it to a location of your choice
{PlayFabAs3Location}.
NOTE
Updates to environment variables sometimes require a computer restart.
7. Create a new empty folder for your GettingStartedAs3 Project, with the following three empty files:
A new text file called GettingStarted
A new text file called GettingStarted.xml
A new text file called buildAndRun.bat
8. Import the PlayFab ActionScriptSDK into this project:
In Windows-Explorer, navigate to {PlayFabAs3Location}/PfApiTest
Select the "com" folder, and copy it to your project folder. This contains a subfolder called "playfab"
which is the PlayFabSDK.
9. Create the flexcfg.xml file.
Open a command window in your project folder. Hold shift and right-click in the empty-white-
space of the Explorer window.
PlayFabSettings.TitleId = "144"; // Please change this value to your own titleId from PlayFab
Game Manager
In your favorite text-editor, open flexcfg.xml and make the following changes:
flexcfg.xml is a large file, but we will only be making small changes.
The <external-library-path> and <library-path> sections need to be converted to absolute paths.
Replace these two sections, as shown below.
<external-library-path>
<path-element>libs/player/{targetPlayerMajorVersion}.{targetPlayerMinorVersion}/playerglobal.swc</path-
element>
</external-library-path>
...
<library-path>
<path-element>libs</path-element>
<path-element>locale/{locale}</path-element>
</library-path>
<external-library-path>
<path-element>C:/dev/flex_sdk_4.6/frameworks/libs/player/{targetPlayerMajorVersion}.
{targetPlayerMinorVersion}/playerglobal.swc</path-element>
</external-library-path>
...
<library-path>
<path-element>C:/dev/flex_sdk_4.6/frameworks/libs</path-element>
<path-element>C:/dev/flex_sdk_4.6/frameworks/locale/{locale}</path-element>
</library-path>
At this point, you can start making other api calls, and building your game.
For a list of all available client API calls, see our PlayFab API References documentation.
Happy coding!
adl is Air Debug Launcher, which launches a compiled swf file as a Windows app.
GettingStar ted.xml
This is a bare bones ActionScript project definition file. The first section of this Adobe guide
describes everything in detail.
flexcfg.xml
This file tells the mxmlc compiler all of the variables and settings it should use.
We only made trivial changes from the default setting.
GettingStarted.as
This file contains the only code relevant to the PlayFab SDK.
textField:
These lines are just controlling the GUI output, displaying the results of the API call.
PlayFabSettings.TitleId = "144";
Every PlayFab developer creates a title in Game Manager. When you publish your game,
you must code that titleId into your game. This lets the client know how to access the
correct data within PlayFab. For most users, just consider it a mandatory step that makes
PlayFab work.
var loginRequest:com.playfab.ClientModels.LoginWithCustomIDRequest = new
com.playfab.ClientModels.LoginWithCustomIDRequest();
Most PlayFab API methods require input parameters, and those input parameters are
packed into a request object.
Every API method requires a unique request object, with a mix of optional and
mandatory parameters.
For LoginWithCustomIDRequest , there is a mandatory parameter of CustomId ,
which uniquely identifies a player and CreateAccount , which allows the creation
of a new account with this call.
For login, most developers will want to use a more appropriate login method.
See the PlayFab Login documentation for a list of all login methods, and input
parameters. Common choices are:
LoginWithAndroidDeviceID
LoginWithIOSDeviceID
LoginWithEmailAddress
PlayFabClientAPI.LoginWithCustomID(loginRequest, OnLoginSuccess, OnLoginFail);
This begins the async request to LoginWithCustomID . When complete, it will call
OnLoginSuccess or OnLoginFail for success or failure respectively.
Inside of OnLoginSuccess :
The result object of many API success callbacks will contain the requested information.
LoginResult contains some basic information about the player, but for most users, login
is simply a mandatory step before calling other APIs.
Inside of OnLoginFailure :
API calls can fail for many reasons, and you should always attempt to handle failure.
Why API calls fail (In order of likelihood)
PlayFabSettings.TitleId is not set. If you forget to set titleId to your title, then
nothing will work.
Request parameters. If you have not provided the correct or required information
for a particular API method, then it will fail. See error.errorMessage,
error.errorDetails for more info.
Device connectivity issue. Cell-phones lose/regain connectivity constantly, and so
any API call at any time can fail randomly, and then work immediately after. Going
into a tunnel can disconnect you completely.
PlayFab server issue. As with all software, there can be issues. See our release
notes for updates.
The internet is not 100% reliable. Sometimes the message is corrupted or fails to
reach the PlayFab server.
If you are having difficulty debugging an issue, and the information within the error
callback is not sufficient, please visit us on our forums.
JavaScript
5/24/2022 • 2 minutes to read • Edit Online
Our JavaScript SDK provides everything you need to access the PlayFab API. This includes models, methods, an
HTTP wrapper for sending and receiving web requests, and JSON serialization.
This SDK is auto-generated using our open-sourced tool—SDKGenerator. We generally build SDKs every other
week to stay current with the latest API changes.
There are several methods to get this SDK. One method is to use our Content Delivery Network (CDN). For more
details, see our blogpost about JavaScript SDK via CDN.
Alternatively, you can also obtain this SDK via NPM using the command npm install playfab-web-sdk .
Download links
JavaScript PlayFab SDK GitHub repo
Quick download link for JavaScript PlayFab SDK
Install SDK via NPM: npm install playfab-web-sdk
Licenses
Javascript licenses
QuickStart: PlayFab client library for JavaScript
5/24/2022 • 5 minutes to read • Edit Online
Get started with the PlayFab client library for JavaScript to authenticate a player. Follow steps to install the
package and try out example code for basic tasks.
Prerequisites
A PlayFab developer account. For information about creating a Title and finding TitleId, see Game Manager
QuickStart.
The QuickStart guide works in any operating system capable of running a web browser.
Code examples
This guide provides the minimum steps to make your first PlayFab API call. Confirmation is visible on the
webpage. For more information about parameters and return values, we recommend using Postman template
first.
Authenticate the client
In your favorite text-editor, update the contents of PlayFabGettingStarted.html as follows:
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>PlayFab JavaScript Unit Tests</title>
<script type="text/javascript" src="https://download.playfab.com/PlayFabClientApi.js"></script>
<script type="text/javascript" src="PlayFabGettingStarted.js"></script>
</head>
<body>
PlayFab Getting Started Guide<br />
TitleID: <input type="text" id="titleId" value="144"><br />
CustomID: <input type="text" id="customId" value="GettingStartedGuide"><br />
<input type="button" value="Call LoginWithCustomID" onclick="DoExampleLoginWithCustomID()"><br />
Result:<br />
<textarea id="resultOutput" cols="60" rows="5"></textarea><br />
</body>
</html>
In your favorite text-editor, update the contents of PlayFabGettingStarted.js as follows:
function DoExampleLoginWithCustomID(){
PlayFab.settings.titleId = document.getElementById("titleId").value;
var loginRequest = {
// Currently, you need to look up the required and optional keys for this object in the API
reference for LoginWithCustomID. See the Request Headers and Request Body.
TitleId: PlayFab.settings.titleId,
CustomId: document.getElementById("customId").value,
CreateAccount: true
};
PlayFabClientSDK.LoginWithCustomID(loginRequest, LoginCallback);
}
To look up the correct format for the loginRequest object in this example, see the API reference for
LoginWithCustomID.
This line loads the Client-SDK directly from the PlayFab CDN. Our CDN always hosts the latest version of
PlayFabSDK. It may be safer for you to download the files, and use a fixed version: PlayFab JavaScript SDK
Every PlayFab developer creates a title in Game Manager. When you publish your game, you
must code that titleId into your game. This lets the client know how to access the correct data
within PlayFab. For most users, just consider it a mandatory step that makes PlayFab work.
var loginRequest = { TitleId: PlayFab.settings.titleId, CustomId: "GettingStartedGuide",
CreateAccount: true };
Most PlayFab API methods require input parameters, and those input parameters are packed
into a request object
Every API method requires a unique request object, with a mix of optional and mandatory
parameters
For LoginWithCustomID , there is a mandatory parameter of CustomId , which uniquely
identifies a player and CreateAccount , which allows the creation of a new account with
this call. TitleId is another mandatory parameter in JavaScript, and it must match
PlayFab.settings.titleId .
For information about where to find TitleId , see Game Manager QuickStart.
In this case, TitleId , customId , and CreateAccount are from the Request Body of
LoginWithCustomID . The Request Body fields are included as keys and values in the request object.
The Session Ticket in the Request Header will be saved from login, so the SessionTicket is not
included in the request object.
PlayFabClientSDK.LoginWithCustomID(loginRequest, LoginCallback);
This begins the async request to LoginWithCustomID , which will call LoginCallback when the
API call is complete.
For login, most developers will want to use a more appropriate login method.
See PlayFab Login Documentation for a list of all login methods, and input parameters.
Common choices are:
LoginWithAndroidDeviceID
LoginWithIOSDeviceID
LoginWithEmailAddress
If new to JavaScript, we recommend that developers read about callback functions.
LoginCallback contains two parameters: result, error
When successful, error will be null, and the result object will contain the requested information,
according to the API called.
This result contains some basic information about the player, but for most users, login is simply
a mandatory step before calling other APIs.
If error is not null , your API call has failed.
Troubleshooting
API calls can fail for many reasons, and you should always attempt to handle failure.
The error object includes the error name, error code, and error message. Together, this information should be
sufficient to diagnose your error.
Global API Method Error Codes can be found in PlayFab's Global API Method Error Codes.
Why API calls fail (In order of likelihood)
PlayFabSettings.TitleId is not set. If TitleId is not set, then nothing will work.
Request parameters. If you have not provided the correct or required information for a particular API
call, then it will fail. See error.errorMessage, error.errorDetails , or error.GenerateErrorReport() for
more info.
Device connectivity issue. Cell-phones lose/regain connectivity constantly, and so any API call at any
time can fail randomly, and then work immediately after. Going into a tunnel can disconnect you
completely.
PlayFab server issue. As with all software, there can be issues. See our release notes for updates.
The internet is not 100% reliable. Sometimes the message is corrupted or fails to reach the PlayFab
server.
If you are having difficulty debugging an issue, and the information within the error information is not
sufficient, please visit us on our forums.
Next Steps
This quickstart shows a simplified procedure for authenticating a user. For additional information about user
authentication, see Login basics and best practices.
Happy coding!
Lua
5/24/2022 • 2 minutes to read • Edit Online
Our SDK provides everything you need to access the PlayFab API. This includes models, methods, an HTTP
wrapper for sending and receiving web requests, and JSON serialization. With the Lua SDK, you gain support for
Defold and Corona game engines.
This SDK is auto-generated using our open-sourced tool—SDKGenerator. We generally build SDKs every other
week to stay current with the latest API changes.
Download links
Lua PlayFab SDK GitHub repo
Quick download link for Lua PlayFab SDK
Licenses
Lua licenses
Lua quickstart for Corona
5/24/2022 • 4 minutes to read • Edit Online
This quickstart assists you in making your first PlayFab API call in the Corona engine.
Before you can call any PlayFab API, you must have a PlayFab developer account.
NOTE
To look up the correct format for the loginRequest object in this example, see the API reference for LoginWithCustomID.
In your favorite text-editor, replace the contents of the main.lua file with the contents shown below.
local loginRequest = {
-- See the API reference for LoginWithCustomID.
CustomId = "GettingStartedGuide",
CreateAccount = true
}
PlayFabClientApi.LoginWithCustomID(loginRequest,
function(result) print("Congratulations, you made your first successful API call!") end,
function(error) print("Something went wrong with your first API call.\nHere's some debug information:\n"
.. error.errorMessage) end
)
This quickstart assists you in making your first PlayFab API call using Defold.
Before you can call any PlayFab API, you must have a PlayFab developer account.
4. Run Defold , and load your new project. You should see several windows that look something like the
example shown below.
5. Update the Project Settings, and include PlayFab in the dependencies:
https://github.com/PlayFab/LuaSdk/raw/master/Defold/PlayFabClientSdk.zip
6. Select: Project -> Fetch Libraries , and you should see a new built-in PlayFab folder, as shown below.
7. Create a few files:
main/PfGettingStar ted.gui
Right-click the "main" folder -> new -> Gui File -> PfGettingStar ted.gui .
main/PfGettingStar ted.gui_script
Right-click "main" folder -> new -> Gui Script File -> PfGettingStar ted.gui_script .
8. Hook up our new GUI in the main.collection.
Double-click main.collection to open it.
In the Outline panel:
Right-click Add Game Object (Optionally rename to PfGui ).
Right-Click the new object, Add Component From File...
PfGettingStarted.gui (Created above).
The Outline panel viewing main.collection should look like the example shown below.
The PlayFab installation is complete. This project isn't ready to build yet, but we'll fix that in the next step.
NOTE
To look up the correct format for the loginRequest object in this example, see the API reference for LoginWithCustomID.
local PlayFabClientApi = require("PlayFab.PlayFabClientApi")
local IPlayFabHttps = require("PlayFab.IPlayFabHttps")
local PlayFabHttps_Defold = require("PlayFab.PlayFabHttps_Defold")
IPlayFabHttps.SetHttp(PlayFabHttps_Defold) -- Assign the Defold-specific IHttps wrapper
PlayFabClientApi.settings.titleId = "144" -- Please change this value to your own titleId from PlayFab Game
Manager
function init(self)
local loginRequest = {
-- See the API reference for LoginWithCustomID
TitleId = PlayFabClientApi.settings.titleId,
CustomId = "GettingStartedGuide",
CreateAccount = true
}
PlayFabClientApi.LoginWithCustomID(loginRequest, OnLoginSuccess, OnLoginFailed)
end
function OnLoginSuccess(result)
local pfTestOutput = gui.get_node("pfOutput")
gui.set_text(pfTestOutput, "Congratulations, you made your first successful API call!")
end
function OnLoginFailed(error)
local pfTestOutput = gui.get_node("pfOutput")
local message = "Something went wrong with your first API call.\n"
local message = message .. "Here's some debug information:\n"
local message = message .. error.GenerateErrorReport()
gui.set_text(pfTestOutput, message)
end
4. In the Defold editor, right-click PfGettingStar ted.gui -> Open With -> Text Editor . Unfortunately, this
changes an internal setting in Defold, so:
Open it again: right-click PfGettingStar ted.gui -> Open With -> GUI Editor . This resets the
default back to normal.
Select the text-edit tab for PfGettingStar ted.gui .
Update the text contents of PfGettingStarted.gui as shown below.
script: "/main/PfGettingStarted.gui_script"
fonts {
name: "system_font"
font: "/builtins/fonts/system_font.font"
}
background_color {
x: 0.0
y: 0.0
z: 0.0
w: 1.0
}
nodes {
position {
x: 100.0
y: 620.0
z: 0.0
w: 1.0
}
rotation {
x: 0.0
y: 0.0
z: 0.0
w: 1.0
}
scale {
x: 1.0
y: 1.0
z: 1.0
w: 1.0
}
size {
x: 1080.0
y: 520.0
z: 0.0
w: 1.0
}
color {
x: 1.0
y: 1.0
z: 1.0
w: 1.0
}
type: TYPE_TEXT
blend_mode: BLEND_MODE_ADD
text: "Logging in..."
font: "system_font"
id: "pfOutput"
xanchor: XANCHOR_LEFT
yanchor: YANCHOR_TOP
pivot: PIVOT_NW
outline {
x: 1.0
y: 1.0
z: 1.0
w: 1.0
}
shadow {
x: 1.0
y: 1.0
z: 1.0
w: 1.0
}
adjust_mode: ADJUST_MODE_FIT
line_break: false
layer: ""
inherit_alpha: true
clipping_mode: CLIPPING_MODE_NONE
clipping_visible: true
clipping_inverted: false
alpha: 1.0
outline_alpha: 1.0
shadow_alpha: 1.0
template_node_child: false
text_leading: 1.0
text_tracking: 0.0
size_mode: SIZE_MODE_AUTO
}
material: "/builtins/materials/gui.material"
adjust_reference: ADJUST_REFERENCE_PARENT
max_nodes: 512
Our instructions for PfGettingStarted.gui are for expediency, not instruction. This file is a GUI
definition, which adds a text box to the screen, binds it to our other script:
PfGettingStarted.gui_script . You would NOT typically edit these files in text-form.
For proper instructions on how to build Defold GUI widgets, please read this guide:
GUI scenes in Defold
PfGettingStarted.gui_script
Every project using PlayFab should create a unique title in the PlayFab website, which we call
Game Manager. Find your titleId in Game Manager, and replace 144 with your titleId .
function init(self)
Most PlayFab API methods require input parameters, and those input parameters are packed
into a request object
Every API method requires a unique request object, with a mix of optional and mandatory
parameters
For LoginWithCustomIDRequest , there is a mandatory parameter of CustomId , which
uniquely identifies a player and CreateAccount , which allows the creation of a new
account with this call.
For login, most developers will want to use a more appropriate login method
See the PlayFab Login documentation for a list of all login methods, and input
parameters. Common choices are:
LoginWithAndroidDeviceID
LoginWithIOSDeviceID
LoginWithEmailAddress
PlayFabClientApi.LoginWithCustomID(loginRequest, OnLoginSuccess, OnLoginFailed)
This performs the API call using the request, and provides callback functions for success and fail
conditions.
function OnLoginSuccess(result)
The result object of many API success callbacks will contain the requested information.
LoginResult contains some basic information about the player, but for most users, login is
simply a mandatory step before calling other APIs.
function OnLoginFailed(error)
API calls can fail for many reasons, and you should always attempt to handle failure.
Why API calls fail (In order of likelihood)
PlayFabSettings.TitleId is not set. If you forget to set titleId to your title, then nothing
will work.
Request parameters. If you have not provided the correct or required information for
a particular API call, then it will fail. See error.errorMessage , error.errorDetails , or
error.GenerateErrorReport() for more info.
This is another Defold GUI function. It fetches the pfOutput GUI object defined in our
PfGettingStarted.gui file, and assigns it text to display to the user.
NodeJS
5/24/2022 • 2 minutes to read • Edit Online
Our Node.js SDK provides everything you need to access the PlayFab API. This includes models, methods, an
HTTP wrapper for sending and receiving web requests, and JSON serialization.
This SDK is auto-generated using our open-sourced tool—SDKGenerator. We generally build SDKs every other
week to stay current with the latest API changes.
This SDK can also be obtained via the npm install playfab-sdk command.
Download links
NodeJS PlayFab SDK GitHub repo
Quick download link for NodeJS PlayFab SDK
Install via NPM: npm install playfab-sdk
Licenses
Node Unit license
Quickstart: PlayFab client library for NodeJS
5/24/2022 • 5 minutes to read • Edit Online
Get started with the PlayFab client library for NodeJS to make your first PlayFab API call and authenticate a
player. Follow steps to install the package and try out example code for basic tasks.
Prerequisites
A PlayFab developer account. For information about creating a Title and finding TitleId, see Game Manager
QuickStart.
Node.js
Node must be in your PATH environment variable. If you used the installer, it's probably set for you to the
default location: C:/Program Files (x86)/nodejs/
Setting up
The following commands work on Windows, MacOS, and Linux.
1. Create a new folder for your project {NodeProjLocation}:
GettingStarted.js
Code examples
Authenticate the client
This guide provides the minimum steps for you to make your first PlayFab API call, without any GUI or on-
screen feedback. Confirmation is done with the Console log. For more information about parameters and return
values, we recommend using Postman template first.
In your favorite text editor, update the contents of GettingStarted.js as follows:
NOTE
To look up the correct format for the loginRequest object in this example, see the API reference for
LoginWithCustomID.
var PlayFab = require("./node_modules/playfab-sdk/Scripts/PlayFab/PlayFab");
var PlayFabClient = require("./node_modules/playfab-sdk/Scripts/PlayFab/PlayFabClient");
function DoExampleLoginWithCustomID() {
PlayFab.settings.titleId = "144";
var loginRequest = {
// Currently, you need to look up the correct format for this object in the API reference for
LoginWithCustomID. The Request Headers and Request Body are included as keys and values in the request
object.
TitleId: PlayFab.settings.titleId,
CustomId: "GettingStartedGuide",
CreateAccount: true
};
// For functions in the Node SDK, the first parameter will be the request object and the second
parameter will be the callback function. The callback function executes after the request returns.
PlayFabClient.LoginWithCustomID(loginRequest, LoginCallback);
}
// This is a utility function we haven't put into the core SDK yet. Feel free to use it.
function CompileErrorReport(error) {
if (error == null)
return "";
var fullErrors = error.errorMessage;
for (var paramName in error.errorDetails)
for (var msgIdx in error.errorDetails[paramName])
fullErrors += "\n" + paramName + ": " + error.errorDetails[paramName][msgIdx];
return fullErrors;
}
Every PlayFab developer creates a title in Game Manager. When you publish your game, you
must code that TitleId into your game. This lets the client know how to access the correct data
within PlayFab. For most users, just consider it a mandatory step that makes PlayFab work.
var loginRequest = { TitleId: PlayFab.settings.titleId, CustomId: "GettingStartedGuide",
CreateAccount: true };
Most PlayFab API methods require input parameters, and those input parameters are packed
into a request object.
Every API method requires a unique request object, with a mix of optional and mandatory
parameters.
For LoginWithCustomIDRequest , there is a mandatory parameter of CustomId , which
uniquely identifies a player and CreateAccount , which allows the creation of a new
account with this call. TitleId is another mandatory parameter in JavaScript, and it
must match PlayFab.settings.titleId .
For information about where to find TitleId , see Game Manager QuickStart.
In this case, TitleId , customId , and CreateAccount are from the Request Body of LoginWithCustomID .
PlayFabClientSDK.LoginWithCustomID(loginRequest, LoginCallback);
This begins the async request to LoginWithCustomID , which will call LoginCallback when the API
call is complete.
For login, most developers will want to use a more appropriate login method.
See PlayFab Login documentation for a list of all login methods, and input parameters.
Common choices are:
LoginWithAndroidDeviceID
LoginWithIOSDeviceID
LoginWithEmailAddress
LoginCallback contains two parameters: error and result .
When successful, error will be null , and the result object will contain the requested information,
according to the API called.
This result contains some basic information about the player, but for most users, login is
simply a mandatory step before calling other APIs.
If error is not null , your API has failed.
Troubleshooting
API calls can fail for many reasons, and you should always attempt to handle failure.
The error object includes the error name, error code, and error message. Together, this information should be
sufficient to diagnose your error.
Why API calls fail (In order of likelihood):
PlayFabSettings.TitleId is not set. If you forget to set TitleId to your title, then nothing will work.
Request parameters. If you have not provided the correct or required information for a particular API
call, then it will fail. See error.errorMessage , error.errorDetails , or error.GenerateErrorReport() for
more info.
Device connectivity issue. Cell-phones lose/regain connectivity constantly, and so any API call at any
time can fail randomly, and then work immediately after. Going into a tunnel can disconnect you
completely.
PlayFab server issue. As with all software, there can be issues. See our release notes for updates.
The internet is not 100% reliable. Sometimes the message is corrupted or fails to reach the PlayFab server.
Global API Method Error Codes can be found in Global API Method Error Codes.
If you are having difficulty debugging an issue, and the information within the error information is not
sufficient, please visit us on our forums.
Next Steps
This quickstart shows a simplified procedure for authenticating a user. For additional information about user
authentication, see Login basics and best practices.
Happy coding!
Python
5/24/2022 • 2 minutes to read • Edit Online
IMPORTANT
This is a community supported SDK. Information on this page is no longer maintained and updated.
To learn how you can contribute and provide support for this SDK, refer to the ReadMe at Python PlayFab SDK
repo.
The team at Microsoft would no longer be providing official support for those using this SDK. You can continue
to get community support and updates at PlayFab forums.
NOTE
This topic provides information about the original version of the SDK and does not apply to the newer community
versions.
Python is a general purpose scripting language that is great for automation and server-side coding. Our Python
SDK is compatible with Python 3, and provides everything you need to access the PlayFab API.
You will need Python 3 installed on your machine to use this SDK.
Download links
Python PlayFab SDK GitHub repo
Python PlayFab SDK on Package Index (PyPI) repo (external link)
Python quickstart
5/24/2022 • 3 minutes to read • Edit Online
This quickstart is designed to help you make your first API call in Python 3.
A native Python project can be used a few ways:
As a stand-alone console Admin tool for maintaining your game.
Integration into an existing Python-based game engine.
For a list of Python game engines, see PythonGameLibraries on the python.org website.
Prerequisites
A PlayFab developer account.
Python 3 installed on your system.
You must also have the requests module installed.
NOTE
This beta release of the Python SDK only supports synchronous API calls, and your game loop may become blocked
performing PlayFab API calls. You may need to create your own async/threading model to avoid this problem.
If you are having difficulty debugging an issue, and the information provided the error information is not
sufficient, please visit us on our PlayFab forums.
PlayFabSettings.TitleId = "144"
request = {
"CustomId": "GettingStartedGuide",
"CreateAccount": True
}
python playfab_test.py
When it finishes, you should see the following text: "Congratulations, you made your first successful API call!"
At this point, you can start making other API calls and building your game. For a list of all available client API
calls, see our PlayFab API References documentation.
Happy coding!
Every PlayFab developer creates a title in Game Manager. When you publish your game, you must
code that titleId into your game. This lets the client know how to access the correct data within
PlayFab. For most users, just consider it a mandatory step that makes PlayFab work.
request
Most PlayFab API methods require input parameters, and those input parameters are packed into a
dictionary object.
LoginWithCustomIDRequest takes a mandatory parameter of CustomId , which uniquely identifies
a player and returns the associated entity token, and CreateAccount , which allows the creation
of a new account with this call.
For login, most developers will want to use a more appropriate login method.
See the PlayFab Login documentation for a list of all login methods, and input
parameters. Common choices are:
LoginWithAndroidDeviceID
LoginWithIOSDeviceID
LoginWithEmailAddress
Callback
Success
If the API call was successful, success will contain the requested information and failure will be
None .
For login requests, success will contain basic information about the player, but for most users,
login is simply a mandatory step before calling other APIs.
Failure
If the API call wasn't successful, failure will contain some error information and success will be
None .
API calls can fail for many reasons, and you should always attempt to handle the failure.
Why API calls fail (In order of likelihood)
PlayFabSettings.TitleId is not set. If you forget to set titleId to your title, then
nothing will work.
Request parameters. If you have not provided the correct or required information for a
particular API call, then it will fail.
Device connectivity issue. Cell-phones lose/regain connectivity constantly, and so any
API call at any time can fail randomly, and then work immediately after. Going into a
tunnel can disconnect you completely.
PlayFab server issue. As with all software, there can be issues. See our release notes for
updates.
The internet is not 100% reliable. Sometimes the message is corrupted or fails to reach
the PlayFab server.
PlayFabClientAPI.LoginWithCustomID
Triggers the API call synchronously. When complete, the callback will be invoked.
General PlayFab samples
5/24/2022 • 2 minutes to read • Edit Online
DEM O N ST RAT ED
SA M P L E N A M E P L AT F O RM S EN GIN E DESC RIP T IO N C A PA B IL IT IES
See also
Multiplayer Servers samples
Party samples
Multiplayer Servers samples and resources
5/24/2022 • 2 minutes to read • Edit Online
This topic lists samples and resources for PlayFab Multiplayer Game Servers.
Samples
Main repo for all the samples
Wrapper (Windows and Linux)—Using the sample
MpsAllocator—Learn to call frequently used APIs
Windows Runner C#—Using the sample
OpenArena (Linux)
Matchmaking with Server (Using a C# game title)
UnityMirror—Use Unity game engine with PlayFab Multiplayer Servers
Resources
PlayFabMultiplayerAPI module
PlayFab LocalMultiplayerAgent
See also
SDKs overview
Party samples
5/24/2022 • 2 minutes to read • Edit Online
This topic lists all the Azure PlayFab Party samples that are currently available.
If there's a specific sample that you'd like to have, let us know by writing a post on our forums.
Access to samples for Nintendo Switch, PlayStation®4, PlayStation®5, Google Stadia, PC (GDK), and Xbox
(GDK) requires special approval and adherence to platform policies. For more information, see Request access
for SDKs and samples.
List of samples
SA M P L E DESC RIP T IO N P L AT F O RM / O P ERAT IN G SY ST EM
Chat app Demonstrates Party chat usage with Windows 10, Windows 8.1, Windows
full speech-to-text and text-to-speech 7, Android, iOS, Stadia, Switch,
capabilities. PlayStation 4, PlayStation 5
Bumble Rumble Demonstrates usage of Party Windows 10, Windows 8.1, Xbox (XDK)
networking, matchmaking, and
accessible voice chat—full speech-to-
text and text-to-speech capabilities. It
doesn't include Xbox Live requirements
and game invites.
See also
Party SDKs
Party overview
Getting started with Party
Recipes
5/24/2022 • 2 minutes to read • Edit Online
This collection of examples shows familiar patterns and mechanics implemented using PlayFab.
Player retention
Daily Prize Wheel - Give players a randomized gift every day, based on the values on a "Prize Wheel".
Progressive Reward System - Players that sign in consecutively over several days are granted an item,
depending on how long their login streak is.
User acquisition
Referral Code Bonus - Generate and send codes to friends that they can redeem and unlock a bonus for both
the referrer and themselves.
Cross-Promotional Rewards - Reward players participating in more than one of your games.
Monetization
Regenerating Currency Mechanic - A play-limiting mechanic (similar to Candy Crush lives), that slowly refills
to a maximum over time.
See also
General PlayFab samples
Multiplayer Servers samples
Party samples
SDK Generator
5/24/2022 • 2 minutes to read • Edit Online
Our SDK Generator provides everything you need to build your own SDK. Internally, we use this generator to
automate our many SDKs.
We have made the project open-source, to aide others who are looking for a language, platform or environment
that is not currently supported.
Download Links:
Download Source Code
Download PlayFab SDK Generator
Usage Guide
SDK Generator quickstart
5/24/2022 • 3 minutes to read • Edit Online
The SDK Generator is a node.js-based program that takes a JSON description of the PlayFab API, and uses it to
generate out all the different SDKs that must be kept up to date. The SDK Generator project also contains the
sources for all PlayFab SDKs on all platforms. If you want to make a change in an SDK, this is where the change
has to go.
Before you can call any PlayFab API, you must have a PlayFab developer account.
Prerequisites
1. Any recent MS-Windows Operating System.
2. You must have Node.js installed: https://nodejs.org/
The location of node.exe must be in your PATH environment variable. Default: C:\Program Files
(x86)\nodejs\
It is highly suggested that you install Node.js tools for Visual
Studio: https://beta.visualstudio.com/vs/node-js/.
3. SdkGenerator requires several PlayFab repositories, cloned to your local machine, as sibling folders to
SdkGenerator .
<parent-folder>/SdkGenerator = <https://github.com/PlayFab/SDKGenerator> (you're looking at it)
<parent-folder>/sdks/<targetSDK> - For every SDK you want to generate, you should git-clone the
PlayFab repository for that target into the "sdks" sub-folder first. In many cases, there are required
files in the repo which are not generated.
4. SdkGenerator can be configured to read from other PlayFab repositories, cloned to your local machine, as
sibling folders to SdkGenerator.
<parent-folder>/API_Specs = <https://github.com/PlayFab/api_specs>
Usage instructions
If you have installed Node.js tools, then you can build any existing SDK from the Visual Studio
solution: https://github.com/PlayFab/SDKGenerator/blob/master/SDKGenerator.sln
Open the solution.
Set the Project Configuration to match the SDK you wish to build.
Build -> Build Solution .
There are many prebuilt scripts which can build each SDK
automatically: https://github.com/PlayFab/SDKGenerator/tree/master/SDKBuildScripts
Find the script that matches the SDK you wish to build (EX unity_build.bat).
Double-click that file.
If you want to build a new SDK, you may need to build a new .bat file using the instructions in the next section.
Finally, you must supply a list of targets to generate, and the directory to generate them to.
To manually invoke the generator, open a command line at the root of the project and type in a target. Each
target takes the form:
<targetName>=<targetOutputLocation>
Where <targetName> is one of the supported SDK targets, and <targetOutputLocation> is a path to a directory in
which to generate the SDK.
NOTE
Make sure there are no spaces between the arguments and the equals sign.
Troubleshooting
For a complete list of available APIs, check out the API References.
Contact us
We love to hear from our developer community! Do you have ideas on how we can make our products and
services better?
Our Developer Success Team can assist with answering any questions as well as process any feedback you have
about PlayFab services.
Forums, Support and Knowledge Base
Postman (REST)
5/24/2022 • 2 minutes to read • Edit Online
Our Postman collection provides JSON mapping to our API that is directly importable into Postman. This is the
one of the fastest ways to get started testing PlayFab. When imported into Postman, you will get a full
integration that supports multiple environment configurations.
Every API call imported is set up with variables in URLs and parameters, making it easy for you to switch
between titles. To get started, check out our Quickstart.
Quickstart: PlayFab REST API collection for Postman
5/24/2022 • 3 minutes to read • Edit Online
Get started with the PlayFab REST API collection for Postman. Follow steps to install the package and try out
example code for basic tasks. PlayFab is a complete backend platform for live games. Use the PlayFab REST API
collection for Postman to:
Get an entity token
Add/modify/delete entities in a title
Configure title content
API reference documentation | PlayFab Postman Collection GitHub repository
Prerequisites
A PlayFab developer account
The Postman native app
An OS running running TLS 1.2 or higher (Windows support for TLS 1.2)
Adding PlayFab Collections
Select Impor t (top left of the window)
Copy the URL from the browser, paste the link into the URL text box and select Impor t
You should now see the PlayFab Postman SDK under the Collections tab (top left of the window)
Adding Environment Variables
Select Manage Environments (cog icon at the top right of the window)
NOTE
You can find your title id by logging into Game Manager and copying the hex value below your title name on the My
Studios and Titles main page.
EntityToken
NOTE
You can learn more about title secret keys and where to find them in the Secret Key Management documentation.
When finished, select Add (or Update) to save your new environment
Exit out of the Manage Environment window and select the environment dropdown to switch to your
new environment (top right of the window)
Getting a Title Entity Token
One way to interact with PlayFab's Entity Programming Model is to get a Title Entity Token. This can be useful if
you want to make changes to title config data, or if you want to make adjustments to a large amount of players:
Under the PlayFab Collections folder, expand the Authentication namespace and select
GetEntityToken
Select Send
Set the returned entity token to your EntityToken environment variable
In the response, highlight the EntityToken string (don't forget the '==')
Right-click and select Set: [Environment] for your new environment
Select EntityToken
NOTE
Entity tokens expire after 24 hours . Afterwards, you need to re-run GetEntityToken to get a new entity token and
update your environment variable
Troubleshooting
Title id / secret key mismatch
If you are trying to get a title entity token and receiving a 401: Unauthorized error, make sure the title
id and secret keys are correct by logging into Game Manager
Expired entity token
If you previously obtained an entity token and are unsuccessfully attempting to call other APIs, your
entity token might be expired. Get another entity token, save it into the EntityToken environment
variable, and attempt to call the previous API again
Incorrect entity token type
There are different types of entities (see Available built-in entity types). Different APIs allow different
entity types - for example, you might be attempting to call GetLanguageList with a
title_player_account entity token instead of a title entity token
Incorrect environment:
Make sure you are using the proper environment by checking the environment dropdown (top right
of the window)
Next Steps
You now have an entity token to pass into other API calls to start setting up your PlayFab title.
Getting Started: Developers >
PlayFab Quickstarts >
API References >