### Windows Startup Script Example Source: https://learn.microsoft.com/en-us/gaming/playfab/multiplayer/servers/vmstartupscript Example of a PowerShell script for Windows VMs. This script shows how to use environment variables and perform common setup tasks. Ensure the script is named PF_StartupScript.ps1 and placed at the root of the zip file. ```powershell # Example: Print environment variables Write-Host "Starting VM startup script..." Get-ChildItem Env: # Example: Install a package using Chocolatey (ensure Chocolatey is installed or bundled) # choco install -y # Example: Create a directory # New-Item -ItemType Directory -Path "C:\\CustomData" # Example: Download a file # Invoke-WebRequest -Uri -OutFile C:\\Temp\\my_asset.zip # Example: Unzip a file # Expand-Archive -Path C:\\Temp\\my_asset.zip -DestinationPath C:\\CustomData # Example: Set permissions # icacls "C:\\Path\\To\\Folder" /grant ":(OI)(CI)F" Write-Host "VM startup script finished." ``` -------------------------------- ### Start Listening for Lobby Invites (C++) Source: https://learn.microsoft.com/en-us/gaming/playfab/multiplayer/lobby/lobby-invites Call PFMultiplayerStartListeningForLobbyInvites to enable receiving in-game invites. The invitation listener's status will change to Listening upon successful setup. ```C++ HRESULT AllowInvitations( const PFEntityKey* entity) { return PFMultiplayerStartListeningForLobbyInvites(g_pfmHandle, entity); } 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: } } ``` -------------------------------- ### October 2025 GDK Layout Example Source: https://learn.microsoft.com/en-us/gaming/playfab/player-progression/game-saves/october-2025-gdk-changes Illustrates the flat, platform-centric directory structure of the October 2025 GDK, essential for build system setup. ```text \Microsoft GDK\251000\windows\include \Microsoft GDK\251000\xbox\lib\x64 \Microsoft GDK\251000\xbox\bin\x64 ``` -------------------------------- ### SetupPushNotification API Response Example Source: https://learn.microsoft.com/en-us/gaming/playfab/live-service-management/game-configuration/title-communications/push-notifications/push-notifications-for-ios This is an example of a successful response from the SetupPushNotification API call. ```JSON { “code” : 200, “status” : “OK”, “data” : { “ARN” : “arn:*******/GCM/your_game_name” } } ``` -------------------------------- ### Example Version: Main GitHub Repo Source: https://learn.microsoft.com/en-us/gaming/playfab/multiplayer/networking/party-unity-overview An example of a Party Unity plugin version downloaded from the main public GitHub repository. ```text 1.5.0.3-main.0 ``` -------------------------------- ### Run Kusto Command Example Source: https://learn.microsoft.com/en-us/gaming/playfab/data-analytics/legacy/connectivity/connecting-grafana-to-insights Example of a Kusto command to display all tables in the database. ```kusto .show tables ``` -------------------------------- ### Start HTTP server Source: https://learn.microsoft.com/en-us/gaming/playfab/identity/player-identity/platform-specific-authentication/running-an-http-server-for-testing Execute this command in the directory containing your static files to start the HTTP server. It will print IP endpoints for accessing the server. ```bash http-server ``` -------------------------------- ### HOSTS file configuration example Source: https://learn.microsoft.com/en-us/gaming/playfab/identity/player-identity/platform-specific-authentication/running-an-http-server-for-testing Example of how to configure the HOSTS file to map IP addresses to domain names. This is useful for testing with services that require a valid domain name. ```text IP_ADDRESS_1 DOMAIN_NAME_1 IP_ADDRESS_2 DOMAIN_NAME_2 IP_ADDRESS_3 DOMAIN_NAME_3 # This is comment ``` -------------------------------- ### Windows Container Asset and Start Command Configuration Source: https://learn.microsoft.com/en-us/gaming/playfab/multiplayer/servers/localmultiplayeragent/run-container-gameserver This JSON snippet configures asset details and the start command for running a game server as a Windows container. It specifies the local path to game assets and the command to start the game server within the container. ```json "AssetDetails": [ { "MountPath": "C:\\Assets", "LocalFilePath": "D:\\gameassets.zip" } ] "ContainerStartParameters": { "StartGameCommand": "C:\\Assets\\wrapper.exe -g C:\\Assets\\fakegame.exe arg1 arg2", "ImageDetails": { "Registry": "mcr.microsoft.com", "ImageName": "playfab/multiplayer", "ImageTag": "wsc-10.0.17763.973.1", "Username": "", "Password": "" } } ``` -------------------------------- ### Login with PlayFab C# Example Source: https://learn.microsoft.com/en-us/gaming/playfab/live-service-management/game-configuration/title-communications/emails/using-email-templates-to-send-an-account-recovery-email This C# code example shows how to log in a player using their username and the newly reset password with the LoginWithPlayFab API in PlayFab. ```csharp void LoginWithPlayFab(string username, string password) { var request = new LoginWithPlayFabRequest { Username = username, Password = password }; PlayFabClientAPI.LoginWithPlayFab(request, result => { Debug.Log("Successfully logged in player with ID " + result.PlayFabId); }, FailureCallback); } void FailureCallback(PlayFabError error) { Debug.LogWarning("Something went wrong with your API call. Here's some debug information:"); Debug.LogError(error.GenerateErrorReport()); } ``` -------------------------------- ### C# Project Build Output Example Source: https://learn.microsoft.com/en-us/gaming/playfab/sdks/c-sharp/quickstart This is an example of the expected output in the Visual Studio output window after a successful C# project build. ```csharp 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 ========== ``` -------------------------------- ### Install HTTP server using npm Source: https://learn.microsoft.com/en-us/gaming/playfab/identity/player-identity/platform-specific-authentication/running-an-http-server-for-testing Install the http-server package globally using npm. This command should be run in your system's command line or terminal. ```bash npm install -g http-server ``` -------------------------------- ### Get Inventory Items Request for Read-Modify-Write Source: https://learn.microsoft.com/en-us/gaming/playfab/economy-monetization/economy-v2/tutorials/etags-and-concurrency-control Example of a POST request to get inventory items, capturing the ETag for subsequent conditional writes. ```http POST /Inventory/GetInventoryItems ``` -------------------------------- ### Linux Startup Script Example Source: https://learn.microsoft.com/en-us/gaming/playfab/multiplayer/servers/vmstartupscript Example of a shell script for Linux VMs. This script demonstrates basic commands and environment variable usage. Ensure the script is named PF_StartupScript.sh and placed at the root of the zip file. ```shell #!/bin/bash # Example: Print environment variables echo "Starting VM startup script..." printenv | sort # Example: Install a package (use with caution) # apt-get update && apt-get install -y # Example: Create a directory # mkdir -p /mnt/custom_data # Example: Download a file # curl -o my_asset.zip # Example: Unzip a file # unzip my_asset.zip -d /mnt/custom_data # Example: Set permissions # chmod +x /path/to/executable echo "VM startup script finished." ``` -------------------------------- ### Get Inventory Items Request with If-Match Header Source: https://learn.microsoft.com/en-us/gaming/playfab/economy-monetization/economy-v2/tutorials/etags-and-concurrency-control Example of a POST request to get inventory items, using the X-PlayFab-Economy-If-Match header to ensure read-after-write consistency. ```json { "Entity": { "Type": "title_player_account", "Id": "{{PlayerID}}" } } ``` -------------------------------- ### Create Build with Custom Container and VmStartupScript Source: https://learn.microsoft.com/en-us/gaming/playfab/multiplayer/servers/vmstartupscript This C# snippet demonstrates how to create a new build using a custom Linux container and specifies a startup script to customize the virtual machine. Ensure the FileName matches your uploaded assets file. ```csharp var request = new CreateBuildWithCustomContainerRequest() { ContainerImageReference = new ContainerImageReference() { ImageName= "testimagename", Tag= "0.1" }, ContainerFlavor = ContainerFlavor.CustomLinux, BuildName = "testbuildwithvmstartupscript", VmSize = AzureVmSize.Standard_D2as_v4, MultiplayerServerCountPerVm = 3, Ports= new List { new Port() { Name= "port", Num= 123, Protocol = ProtocolType.TCP } }, RegionConfigurations = new List { new BuildRegionParams() { Region = "EastUs", StandbyServers = 3, MaxServers = 6 } }, VmStartupScriptConfiguration = new VmStartupScriptParams() { VmStartupScriptAssetReference = new AssetReferenceParams() { FileName = "vmstartupscriptassets.zip" } } }; var result = await PlayFabMultiplayerAPI.CreateBuildWithCustomContainerAsync(request); ``` -------------------------------- ### Start Game Server and Signal Readiness Source: https://learn.microsoft.com/en-us/gaming/playfab/multiplayer/servers/mps-unity Implement the PlayFabMultiplayerAgentAPI.Start() method and initiate a coroutine for PlayFabMultiplayerAgentAPI.ReadyForPlayers(). This is a minimum requirement for game server initialization. ```csharp //... StartCoroutine(ReadyForPlayers()); //... private IEnumerator ReadyForPlayers() { yield return new WaitForSeconds(.5f); PlayFabMultiplayerAgentAPI.ReadyForPlayers(); } ``` -------------------------------- ### Get Inventory Collection IDs Response Source: https://learn.microsoft.com/en-us/gaming/playfab/economy-monetization/economy-v2/inventory/collections Example response from the GetInventoryCollectionIds API, listing available collection IDs for a player. ```JSON { "data": { "CollectionIds": [ "default", "main_character" ] } } ``` -------------------------------- ### Login Player with XUser Source: https://learn.microsoft.com/en-us/gaming/playfab/sdks/c/entity-handles Obtain a PFEntityHandle for a player by logging in with an XUser credential. This example demonstrates the two-call pattern for getting the result. ```cpp PFAuthenticationLoginWithXUserRequest request{}; request.createAccount = true; request.user = userHandle; // XUserHandle from XUserAddAsync XAsyncBlock async{}; HRESULT hr = PFAuthenticationLoginWithXUserAsync(serviceConfigHandle, &request, &async); hr = XAsyncGetStatus(&async, true); PFEntityHandle entityHandle{ nullptr }; size_t bufferSize{}; hr = PFAuthenticationLoginWithXUserGetResultSize(&async, &bufferSize); std::vector loginResultBuffer(bufferSize); PFAuthenticationLoginResult const* loginResult{}; hr = PFAuthenticationLoginWithXUserGetResult( &async, &entityHandle, loginResultBuffer.size(), loginResultBuffer.data(), &loginResult, nullptr); ``` -------------------------------- ### Build and Run MpsAllocator Sample Source: https://learn.microsoft.com/en-us/gaming/playfab/multiplayer/servers/mps-allocator-sample Builds and runs the MpsAllocator sample application using .NET Core. Ensure .NET Core 3.1 is installed. ```bash dotnet build dotnet run ``` -------------------------------- ### v2 Initialization with Configuration Source: https://learn.microsoft.com/en-us/gaming/playfab/sdks/unified-sdk/migrating-from-v1 Demonstrates the v2 SDK initialization using a configuration struct, allowing for custom memory allocators and thread pools. ```C++ PARTY_INITIALIZATION_CONFIGURATION config{}; config.titleId = "YOUR_PLAYFAB_TITLE_ID"; config.memoryCallbacks = nullptr; // Use default or provide custom allocator config.threadPool = nullptr; // Use PlayFab Core queue or provide custom XTaskQueue PartyInitialize(&config, &g_partyHandle); ``` -------------------------------- ### Include Local PlayFab Getting Started Script Source: https://learn.microsoft.com/en-us/gaming/playfab/sdks/javascript/quickstart This line includes your custom JavaScript file that contains PlayFab API calls and binds it to the webpage. ```html ``` -------------------------------- ### Get Entity Handle with PFAuthenticationReLoginWithXUserAsync Source: https://learn.microsoft.com/en-us/gaming/playfab/sdks/c/event-pipeline/eventpipeline-tutorial Obtain a PFEntityHandle by calling PFAuthenticationReLoginWithXUserAsync. This requires a valid XUserHandle. The example shows a blocking wait for the asynchronous operation. ```cpp PFEntityHandle entityHandle; PFAuthenticationLoginWithXUserRequest request{}; request.createAccount = true; request.user = userHandle; // An XUserHandle obtained from XUserAddAsync XAsyncBlock async{}; HRESULT hr = PFAuthenticationReLoginWithXUserAsync(entityHandle, &request, &async); if (FAILED(hr)) { printf("Failed PFAuthenticationReLoginWithXUserAsync: 0x%x\r\n", hr); return; } hr = XAsyncGetStatus(&async, true); // This is doing a blocking wait for completion, but you can use the XAsyncBlock to set a callback instead for async style usage if (FAILED(hr)) { printf("Failed XAsyncGetStatus: 0x%x\r\n", hr); return; } ``` -------------------------------- ### Full PlayFab SDK Lifecycle Example Source: https://learn.microsoft.com/en-us/gaming/playfab/sdks/c/lifecycle Demonstrates the complete lifecycle from initialization through shutdown on a Windows title, including optional memory hooks, core and services initialization, player login, and shutdown sequence. ```c++ #include void RunPlayFab() { // // Optional: set custom memory hooks // PFMemoryHooks hooks{}; hooks.alloc = MyAllocFunction; hooks.free = MyFreeFunction; HRESULT hr = PFMemSetFunctions(&hooks); // // Initialize Core // hr = PFInitialize(nullptr); // // Create a service configuration // PFServiceConfigHandle serviceConfigHandle{ nullptr }; hr = PFServiceConfigCreateHandle( "https://ABCDEF.playfabapi.com", "ABCDEF", &serviceConfigHandle); // // Initialize Services // hr = PFServicesInitialize(nullptr); // // Log in a player (Windows example using XUser) // PFAuthenticationLoginWithXUserRequest request{}; request.createAccount = true; request.user = userHandle; XAsyncBlock asyncLogin{}; hr = PFAuthenticationLoginWithXUserAsync(serviceConfigHandle, &request, &asyncLogin); hr = XAsyncGetStatus(&asyncLogin, true); size_t bufferSize{}; hr = PFAuthenticationLoginWithXUserGetResultSize(&asyncLogin, &bufferSize); std::vector loginResultBuffer(bufferSize); PFAuthenticationLoginResult const* loginResult{}; PFEntityHandle entityHandle{ nullptr }; hr = PFAuthenticationLoginWithXUserGetResult( &asyncLogin, &entityHandle, loginResultBuffer.size(), loginResultBuffer.data(), &loginResult, nullptr); // // ... make service calls ... // // // Shutdown: close handles first // PFEntityCloseHandle(entityHandle); entityHandle = nullptr; PFServiceConfigCloseHandle(serviceConfigHandle); serviceConfigHandle = nullptr; // // Shutdown: uninitialize Services, then Core // XAsyncBlock asyncServices{}; hr = PFServicesUninitializeAsync(&asyncServices); hr = XAsyncGetStatus(&asyncServices, true); XAsyncBlock asyncCore{}; hr = PFUninitializeAsync(&asyncCore); hr = XAsyncGetStatus(&asyncCore, true); } ``` -------------------------------- ### Get Title Data from Game Server Source: https://learn.microsoft.com/en-us/gaming/playfab/live-service-management/game-configuration/titledata/quickstart Use GetTitleData from PlayFabServerAPI to retrieve title data key-value pairs. This example retrieves and logs the value for 'MonsterName'. ```csharp public void ServerGetTitleData() { PlayFabServerAPI.GetTitleData( new GetTitleDataRequest(), result => { if (result.Data == null || !result.Data.ContainsKey("MonsterName")) Debug.Log("No MonsterName"); else Debug.Log("MonsterName: " + result.Data["MonsterName"]); }, error => { Debug.Log("Got error getting titleData:"); Debug.Log(error.GenerateErrorReport()); }); } ``` -------------------------------- ### Requesting VM Ports with C# Source: https://learn.microsoft.com/en-us/gaming/playfab/multiplayer/servers/vmstartupscript Example of how to request two ports (TCP and UDP) for a VM startup script using C#. ```csharp VmStartupScriptConfiguration = new VmStartupScriptParams() { VmStartupScriptAssetReference = new AssetReferenceParams() { FileName = "vmstartupscriptassets.zip" }, PortRequests = new List() { new VmStartupScriptPortRequest() { Name = "port0", Protocol = ProtocolType.TCP }, new VmStartupScriptPortRequest() { Name = "port1", Protocol = ProtocolType.UDP } } } ``` -------------------------------- ### Get Title Data from Game Client Source: https://learn.microsoft.com/en-us/gaming/playfab/live-service-management/game-configuration/titledata/quickstart Use GetTitleData from PlayFabClientAPI to retrieve title data key-value pairs. This example retrieves and logs the value for 'MonsterName'. ```csharp public void ClientGetTitleData() { PlayFabClientAPI.GetTitleData(new GetTitleDataRequest(), result => { if(result.Data == null || !result.Data.ContainsKey("MonsterName")) Debug.Log("No MonsterName"); else Debug.Log("MonsterName: "+result.Data["MonsterName"]); }, error => { Debug.Log("Got error getting titleData:"); Debug.Log(error.GenerateErrorReport()); } ); } ``` -------------------------------- ### Test Game Server Connection Source: https://learn.microsoft.com/en-us/gaming/playfab/multiplayer/servers/localmultiplayeragent/run-container-gameserver Access your game server via HTTP GET request to test the connection after it's active. This example uses the Wrapper sample. ```http http://127.0.0.1:56100/Hello ``` -------------------------------- ### VM Startup Script Environment Variables (Bash) Source: https://learn.microsoft.com/en-us/gaming/playfab/multiplayer/servers/vmstartupscript Demonstrates the environment variables available to a VM startup script for accessing port information, based on the C# port request example. ```bash PF_STARTUP_SCRIPT_PORT_COUNT PF_STARTUP_SCRIPT_PORT_INTERNAL_0 PF_STARTUP_SCRIPT_PORT_EXTERNAL_0 PF_STARTUP_SCRIPT_PORT_NAME_0 PF_STARTUP_SCRIPT_PORT_PROTOCOL_0 PF_STARTUP_SCRIPT_PORT_INTERNAL_1 PF_STARTUP_SCRIPT_PORT_EXTERNAL_1 PF_STARTUP_SCRIPT_PORT_NAME_1 PF_STARTUP_SCRIPT_PORT_PROTOCOL_1 ``` -------------------------------- ### Get Player Statistics Response (Server API) Source: https://learn.microsoft.com/en-us/gaming/playfab/community/leaderboards/tournaments-leaderboards/using-resettable-statistics-and-leaderboards Example JSON response for retrieving player statistics via the server API, showing the statistic name, value, and version. ```json { "code": 200, "status": "OK", "data": { "PlayFabId": {{PlayFabId}}, "Statistics": [ { "StatisticName": "Headshots", "Value": 10, "Version": "3" }] } } ``` -------------------------------- ### Create and Join Network with Custom Configuration Source: https://learn.microsoft.com/en-us/gaming/playfab/multiplayer/networking/party-unity-plugin-quickstart Create and join a network with custom peer connectivity options. This example sets the options to allow P2P connections across any platform type and entity login provider. ```csharp PlayfabNetworkConfiguration networkConfiguration = new PlayfabNetworkConfiguration(); networkConfiguration.DirectPeerConnectivityOptions = PARTY_DIRECT_PEER_CONNECTIVITY_OPTIONS_ANY_PLATFORM_TYPE | PARTY_DIRECT_PEER_CONNECTIVITY_OPTIONS_ANY_ENTITY_LOGIN_PROVIDER; PlayFabMultiplayerManager.Get().CreateAndJoinNetwork(networkConfiguration); PlayFabMultiplayerManager.Get().OnNetworkJoined += OnNetworkJoined; ``` -------------------------------- ### StartOrRecoverSessionResponse JSON Example Source: https://learn.microsoft.com/en-us/gaming/playfab/multiplayer/real-time-messages/types/start-or-recover-session-response This JSON object represents a successful response when starting or recovering a session. It includes a new connection handle, a list of recovered topics (if any), the status, and a trace ID for debugging. ```json { "newConnectionHandle": "1.Y2VudHJhbC11c35sb2NhbGhvc3R+QkxVV1pYSEwwZkF0b1o5WUR2MV9vQQ==", "recoveredTopics": ["Opaque~Topic~String~6183258", "Another~Opaque~Topic~String~843156"], "status": "Success", "traceId": "4bf92f3577b34da6a3ce929d0e0e4736" } ``` -------------------------------- ### Complete Entity Handle Management Example Source: https://learn.microsoft.com/en-us/gaming/playfab/sdks/c/entity-handles Demonstrates the full lifecycle of an entity handle: logging in, registering token event handlers, duplicating the handle, querying entity information, and cleaning up resources. ```C++ #include #include void EntityHandleExample(PFServiceConfigHandle serviceConfigHandle, XUserHandle userHandle) { // // Log in and get an entity handle // PFAuthenticationLoginWithXUserRequest request{}; request.createAccount = true; request.user = userHandle; XAsyncBlock asyncLogin{}; HRESULT hr = PFAuthenticationLoginWithXUserAsync(serviceConfigHandle, &request, &asyncLogin); hr = XAsyncGetStatus(&asyncLogin, true); PFEntityHandle entityHandle{ nullptr }; size_t resultSize{}; hr = PFAuthenticationLoginWithXUserGetResultSize(&asyncLogin, &resultSize); std::vector loginBuffer(resultSize); PFAuthenticationLoginResult const* loginResult{}; hr = PFAuthenticationLoginWithXUserGetResult( &asyncLogin, &entityHandle, loginBuffer.size(), loginBuffer.data(), &loginResult, nullptr); // // Register token event handlers // PFRegistrationToken expiredToken{}; hr = PFEntityRegisterTokenExpiredEventHandler(nullptr, nullptr, [](void* ctx, PFEntityKey const* entityKey) { // Handle re-authentication }, &expiredToken); PFRegistrationToken refreshedToken{}; hr = PFEntityRegisterTokenRefreshedEventHandler(nullptr, nullptr, [](void* ctx, PFEntityKey const* entityKey, const PFEntityToken* newToken) { // Log token refresh }, &refreshedToken); // // Duplicate the handle for a subsystem // PFEntityHandle subsystemHandle{ nullptr }; hr = PFEntityDuplicateHandle(entityHandle, &subsystemHandle); // // Query entity info // bool isTitlePlayer{}; hr = PFEntityIsTitlePlayer(entityHandle, &isTitlePlayer); size_t keySize{}; hr = PFEntityGetEntityKeySize(entityHandle, &keySize); std::vector keyBuffer(keySize); PFEntityKey const* entityKey{}; hr = PFEntityGetEntityKey(entityHandle, keyBuffer.size(), keyBuffer.data(), &entityKey, nullptr); // // ... make service calls with entityHandle or subsystemHandle ... // // // Cleanup: unregister handlers, then close all handles // PFEntityUnregisterTokenExpiredEventHandler(expiredToken); PFEntityUnregisterTokenRefreshedEventHandler(refreshedToken); PFEntityCloseHandle(subsystemHandle); PFEntityCloseHandle(entityHandle); } ``` -------------------------------- ### StartOrRecoverSessionRequest JSON Example Source: https://learn.microsoft.com/en-us/gaming/playfab/multiplayer/real-time-messages/types/start-or-recover-session-request This JSON object represents a request to start a new session or recover an existing one. It includes an optional oldConnectionHandle for session recovery and a required traceParent for distributed tracing. ```json { "oldConnectionHandle": "1.Y2VudHJhbC11c35sb2NhbGhvc3R+QkxVV1pYSEwwZkF0b1o5WUR2MV9vQQ==", "traceParent": "00-84678fd69ae13e41fce1333289bcf482-22d157fb94ea4827-01" } ``` -------------------------------- ### Calling PFProfilesGetProfileAsync Source: https://learn.microsoft.com/en-us/gaming/playfab/sdks/c/async This example demonstrates how to call the PFProfilesGetProfileAsync function, which retrieves a player's profile. It shows the setup of XAsyncBlock, including the callback for handling results, and the initial call to the asynchronous function. ```C++ XAsyncBlock* asyncBlock = new XAsyncBlock(); asyncBlock->queue = GlobalState()->queue; asyncBlock->context = nullptr; asyncBlock->callback = [](XAsyncBlock* asyncBlock) { std::unique_ptr asyncBlockPtr{ asyncBlock }; // take ownership of XAsyncBlock size_t bufferSize; HRESULT hr = PFProfilesGetProfileGetResultSize(asyncBlock, &bufferSize); if (SUCCEEDED(hr)) { std::vector getProfileResultBuffer(bufferSize); PFProfilesGetEntityProfileResponse* getProfileResponseResult{ nullptr }; PFProfilesGetProfileGetResult(asyncBlock, getProfileResultBuffer.size(), getProfileResultBuffer.data(), &getProfileResponseResult, nullptr); } }; PFProfilesGetEntityProfileRequest profileRequest{}; HRESULT hr = PFProfilesGetProfileAsync(GlobalState()->entityHandle, &profileRequest, asyncBlock); ``` -------------------------------- ### PFMultiplayerInitialize Source: https://learn.microsoft.com/en-us/gaming/playfab/multiplayer/lobby/playfabmultiplayerreference-cpp/pfmultiplayer/pfmultiplayer_members Initializes an instance of the PlayFab Multiplayer library, preparing it for use. ```APIDOC ## PFMultiplayerInitialize ### Description Initializes an instance of the PlayFab Multiplayer library. ### Function Signature ```c++ void PFMultiplayerInitialize( const char* titleId ) ``` ### Parameters #### Path Parameters - **titleId** (const char*) - Required - The PlayFab title ID. ``` -------------------------------- ### Log Custom Data Received Source: https://learn.microsoft.com/en-us/gaming/playfab/live-service-management/game-configuration/title-communications/push-notifications/push-notifications-for-android Log a message indicating that a push notification with custom data has been received. This is a basic example of how to start processing custom data sent via PlayFab push notifications. ```csharp Debug.Log("PlayFab: Received a message with data:"); ``` -------------------------------- ### Get Inventory Collection IDs Request Source: https://learn.microsoft.com/en-us/gaming/playfab/economy-monetization/economy-v2/inventory/collections Example request to retrieve a list of collection IDs for a given player. Players can only access their own IDs, but Title Entities can specify which player's inventory to access. ```JSON { "Entity": { "Type": "title_player_account", "Id": "ABCD12345678" }, "Count": 15, "ContinuationToken": "abc=" } ``` -------------------------------- ### Starting Inventory Configuration Source: https://learn.microsoft.com/en-us/gaming/playfab/economy-monetization/economy-v2/tutorials/craftinggame/crafting-game-coding Defines the initial items and amounts for a player's inventory. Replace placeholders like {Free Item ID} and {Cream ID} with actual IDs. ```json { "ItemId": {Free Item ID}, "Amount": 0 } ] } }, { "Purchase": { "Item": { "Id": {Cream ID} }, "Amount": 1, "PriceAmounts": [ { "ItemId": {Free Item ID}, "Amount": 0 } ] } } ] } ``` -------------------------------- ### Full Entity File Management Loop Example Source: https://learn.microsoft.com/en-us/gaming/playfab/live-service-management/game-configuration/entities/quickstart Demonstrates a complete cycle of entity file operations: logging in, retrieving entity ID/Type, initiating an upload, uploading files, and finalizing the upload. Assumes familiarity with Unity. ```csharp #if !DISABLE_PLAYFABENTITY_API && !DISABLE_PLAYFABCLIENT_API using PlayFab; using PlayFab.Internal; using System; using System.Collections.Generic; using System.Text; using UnityEngine; public class EntityFileExample : MonoBehaviour { public string entityId; // Id representing the logged in player public string entityType; // entityType representing the logged in player private readonly Dictionary _entityFileJson = new Dictionary(); private readonly Dictionary _tempUpdates = new Dictionary(); public string ActiveUploadFileName; public string NewFileName; // GlobalFileLock provides is a simplistic way to avoid file collisions, specifically designed for this example. public int GlobalFileLock = 0; void OnSharedFailure(PlayFabError error) { Debug.LogError(error.GenerateErrorReport()); GlobalFileLock -= 1; } // OnGUI provides a way to build a Unity GUI entirely within script. - // Your GUI will be game-specific. void OnGUI() { if (!PlayFabClientAPI.IsClientLoggedIn() && GUI.Button(new Rect(0, 0, 100, 30), "Login")) Login(); ``` -------------------------------- ### Run LocalMultiplayerAgent for Linux Containers on Windows Source: https://learn.microsoft.com/en-us/gaming/playfab/multiplayer/servers/locally-debugging-game-servers-and-integration-with-playfab Execute this command in PowerShell to start the LocalMultiplayerAgent with support for Linux Containers on Windows (lcow). Ensure Docker Desktop is configured for Linux containers and the necessary setup scripts have been run. ```powershell LocalMultiplayerAgent.exe -lcow ``` -------------------------------- ### Full Entity-File Workflow Example Source: https://learn.microsoft.com/en-us/gaming/playfab/live-service-management/game-configuration/entities/entity-files This C# script demonstrates a complete cycle of interacting with entity files. It includes login, loading all files associated with an entity, displaying them in a UI, allowing edits, and uploading changes or new files. Ensure PlayFab SDK is integrated and necessary API calls are enabled. ```csharp #if !DISABLE_PLAYFABENTITY_API && !DISABLE_PLAYFABCLIENT_API using PlayFab; using PlayFab.Internal; using System; using System.Collections.Generic; using System.Text; using UnityEngine; public class EntityFileExample : MonoBehaviour { public string entityId; // Id representing the logged in player public string entityType; // entityType representing the logged in player private readonly Dictionary _entityFileJson = new Dictionary(); private readonly Dictionary _tempUpdates = new Dictionary(); public string ActiveUploadFileName; public string NewFileName; public int GlobalFileLock = 0; // Kind of cheap and simple way to handle this kind of lock void OnSharedFailure(PlayFabError error) { Debug.LogError(error.GenerateErrorReport()); GlobalFileLock -= 1; } 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() && GUI.Button(new Rect(100, 0, 100, 30), "(re)Load Files")) LoadAllFiles(); 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 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."); GlobalFileLock += 1; // Start GetFiles var request = new PlayFab.DataModels.GetFilesRequest { Entity = new PlayFab.DataModels.EntityKey { Id = entityId, Type = entityType } }; PlayFabDataAPI.GetFiles(request, OnGetFileMeta, OnSharedFailure); } void OnGetFileMeta(PlayFab.DataModels.GetFilesResponse result) { Debug.Log("Loading " + result.Metadata.Count + " files"); _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); } ); } void UploadFile(string fileName) { 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; GlobalFileLock += 1; // Start InitiateFileUploads var request = new PlayFab.DataModels.InitiateFileUploadsRequest { ``` -------------------------------- ### Get Player Read-Only Data (C# Unity SDK) Source: https://learn.microsoft.com/en-us/gaming/playfab/player-progression/player-data/how-to-get-read-only-player-data This C# code example demonstrates how to use the PlayFab Server API to retrieve all read-only data for a specific player. It includes error handling and checks for specific data keys. ```csharp public void GetUserReadOnlyData() { PlayFabServerAPI.GetUserReadOnlyData(new GetUserDataRequest() { PlayFabId = "user PlayFabId here - obtained from any successful LoginResult", }, result => { if(result.Data == null || !result.Data.ContainsKey("Sister")) Debug.Log("No Sister"); else Debug.Log("Sister: "+result.Data["Sister"].Value); }, error => { Debug.Log("Got error getting read-only user data:"); Debug.Log(error.GenerateErrorReport()); }); } ``` -------------------------------- ### Log in Player with Steam and Get Entity Handle Source: https://learn.microsoft.com/en-us/gaming/playfab/sdks/c/quickstart-win32 Log in a player using their Steam ticket and obtain an entity handle. This handle is used for subsequent PlayFab API calls on behalf of the player. The example shows a blocking wait for the asynchronous operation. ```C++ PFAuthenticationLoginWithSteamRequest request{}; request.createAccount = true; request.steamTicket = steamTicket; // A ticket obtained from Steam XAsyncBlock async{}; HRESULT hr = PFAuthenticationLoginWithSteamAsync(serviceConfigHandle, &request, &async); // Add your own error handling when FAILED(hr) == true hr = XAsyncGetStatus(&async, true); // This is doing a blocking wait for completion, but you can use the XAsyncBlock to set a callback instead for async style usage std::vector loginResultBuffer; PFAuthenticationLoginResult const* loginResult; size_t bufferSize; hr = PFAuthenticationLoginWithSteamGetResultSize(&async, &bufferSize); loginResultBuffer.resize(bufferSize); PFEntityHandle entityHandle{ nullptr }; hr = PFAuthenticationLoginWithSteamGetResult(&async, &entityHandle, loginResultBuffer.size(), loginResultBuffer.data(), &loginResult, nullptr); ``` -------------------------------- ### PFAccountManagementClientGetPlayFabIDsFromGameCenterIDsAsync Source: https://learn.microsoft.com/en-us/gaming/playfab/api-references/c/pfaccountmanagement/functions/pfaccountmanagementclientgetplayfabidsfromgamecenteridsasync Retrieves the unique PlayFab identifiers for the given set of Game Center identifiers (referenced in the Game Center Programming Guide as the Player Identifier). This API is available on Win32, Linux, iOS, and macOS. When the asynchronous task is complete, call PFAccountManagementClientGetPlayFabIDsFromGameCenterIDsGetResultSize and PFAccountManagementClientGetPlayFabIDsFromGameCenterIDsGetResult to get the result. ```APIDOC ## PFAccountManagementClientGetPlayFabIDsFromGameCenterIDsAsync ### Description Retrieves the unique PlayFab identifiers for the given set of Game Center identifiers. ### Method C++ ### Endpoint ```cpp HRESULT PFAccountManagementClientGetPlayFabIDsFromGameCenterIDsAsync( PFEntityHandle entityHandle, const PFAccountManagementGetPlayFabIDsFromGameCenterIDsRequest* request, XAsyncBlock* async ) ``` ### Parameters #### Path Parameters - **entityHandle** (PFEntityHandle) - Description: PFEntityHandle to use for authentication. - **request** (PFAccountManagementGetPlayFabIDsFromGameCenterIDsRequest*) - Description: Populated request object. - **async** (XAsyncBlock*) - Description: XAsyncBlock for the async operation. ### Return value Type: HRESULT Result code for this API operation. ### Remarks This API is available on Win32, Linux, iOS, and macOS. When the asynchronous task is complete, call PFAccountManagementClientGetPlayFabIDsFromGameCenterIDsGetResultSize and PFAccountManagementClientGetPlayFabIDsFromGameCenterIDsGetResult to get the result. ### Requirements **Header:** PFAccountManagement.h ``` -------------------------------- ### Set Start Command for Windows Container Mode Source: https://learn.microsoft.com/en-us/gaming/playfab/multiplayer/servers/server-sdks/unreal-gsdk/third-person-mp-example-project-cloud-deployment Define the full path to your game server executable within the container's mounted asset directory for Windows Container Mode. This ensures the server starts correctly within its isolated environment. ```bash {MountPath}\{ProjectName}Server.exe ``` ```bash {MountPath}\{ProjectName}Server.exe -log ``` ```bash {MountPath}\WindowsServer\{ProjectName}Server.exe ``` -------------------------------- ### Create a Party Network Source: https://learn.microsoft.com/en-us/gaming/playfab/multiplayer/networking/quickstart Initializes network configuration and creates a new Party Network. Ensure `maxDeviceCount` is set appropriately for your network's expected size. ```cpp // Set the maximum number of devices allowed in a network to 16 devices constexpr uint8_t c_maxSampleNetworkDeviceCount = 16; static_assert(c_maxSampleNetworkDeviceCount <= c_maxNetworkConfigurationMaxDeviceCount, "Must be less than or equal to c_maxNetworkConfigurationMaxDeviceCount."); // Initialize network configuration for Party Network. PartyNetworkConfiguration cfg = {}; cfg.maxDeviceCount = c_maxSampleNetworkDeviceCount; cfg.maxUserCount = c_maxSampleNetworkDeviceCount; ... // Initialize an empty network descriptor to hold the result of the following call. PartyNetworkDescriptor networkDescriptor = {}; // Create a new network descriptor err = PartyManager::GetSingleton().CreateNewNetwork( m_localUser, // Local User &cfg, // Network Config 0, // Region List Count nullptr, // Region List &invitationConfiguration, // Invitation configuration nullptr, // Async Identifier &networkDescriptor, // OUT network descriptor nullptr // applied initialinvitationidentifier. ); ``` -------------------------------- ### HelloWorld Azure Function Example Source: https://learn.microsoft.com/en-us/gaming/playfab/live-service-management/service-gateway/automation/cloudscript-af/quickstart This C# Azure Function demonstrates how to receive context, access player profile information, and use the PlayFab Data API to set objects. It's triggered via HTTP and expects a JSON payload containing function arguments. Ensure the PlayFab SDK is installed and CS2AFHelperClasses.cs is included. ```csharp using PlayFab; using PlayFab.Samples; using PlayFab.DataModels; using System.Collections.Generic; using System.Threading.Tasks; namespace PlayFabCS2AFSample.HelloWorld { public static class HelloWorld { [FunctionName("HelloWorld")] public static async Task Run( [HttpTrigger(AuthorizationLevel.Function, "get", "post", Route = null)] HttpRequest req, ILogger log) { FunctionExecutionContext context = JsonConvert.DeserializeObject>(await req.ReadAsStringAsync()); dynamic args = context.FunctionArgument; var message = $"Hello {context.CallerEntityProfile.Lineage.MasterPlayerAccountId}!"; log.LogInformation(message); dynamic inputValue = null; if (args != null && args["inputValue"] != null) { inputValue = args["inputValue"]; } log.LogDebug($"HelloWorld: {new { input = inputValue} }"); // The profile of the entity specified in the 'ExecuteEntityCloudScript' request. // Defaults to the authenticated entity in the X-EntityToken header. var entityProfile = context.CallerEntityProfile; var api = new PlayFabDataInstanceAPI( new PlayFabApiSettings { TitleId = context.TitleAuthenticationContext.Id }, new PlayFabAuthenticationContext { EntityToken = context.TitleAuthenticationContext.EntityToken } ); var apiResult = await api.SetObjectsAsync( new SetObjectsRequest { Entity = new EntityKey { Id = entityProfile.Entity.Id, Type = entityProfile.Entity.Type }, Objects = new List { new SetObject { ObjectName = "obj1", DataObject = new { foo = "some server computed value", prop1 = "bar" } } } }); return new { messageValue = message }; } } } ``` -------------------------------- ### Logging in a Player with Windows Hello Source: https://learn.microsoft.com/en-us/gaming/playfab/identity/player-identity/platform-specific-authentication/uwp-integration Log in a player using their existing Windows Hello credentials. This process involves obtaining a challenge, signing it with the user's key, and then submitting it to PlayFab. ```csharp var challengeResult = await PlayFabClientAPI.GetWindowsHelloChallengeAsync( new GetWindowsHelloChallengeRequest { Username = windowsUsername, PublicKeyHint = publicKeyHint } ); if (challengeResult.Error != null) { // Handle error return; } var challengeBuffer = CryptographicBuffer.DecodeFromBase64String(challengeResult.Result.Challenge); var keyCredential = await KeyCredentialManager.OpenAsync(userId); var userCredential = keyCredential.Credential; var signatureBuffer = await userCredential.RequestSignAsync(challengeBuffer); var signatureBase64 = CryptographicBuffer.EncodeToBase64String(signatureBuffer); var loginResult = await PlayFabClientAPI.LoginWithWindowsHello( new LoginWithWindowsHelloRequest { Username = windowsUsername, PublicKeyHint = publicKeyHint, Signature = signatureBase64 } ); // Handle the login result if (loginResult.Error != null) { // Handle error } else { // Player is now logged in var sessionTicket = loginResult.Result.SessionTicket; } ``` -------------------------------- ### Install PlayFab SDK using pip Source: https://learn.microsoft.com/en-us/gaming/playfab/sdks/python/quickstart Install the PlayFab Python package using pip. If pip is not in your PATH, use `python -m pip install playfab`. ```bash pip install playfab ``` ```bash python -m pip install playfab ``` -------------------------------- ### Twitch and PlayFab Authentication HTML Example Source: https://learn.microsoft.com/en-us/gaming/playfab/identity/player-identity/platform-specific-authentication/twitch-html5 This HTML file demonstrates how to initialize the Twitch SDK, handle Twitch login events, and use the obtained token to log in with PlayFab. It includes functions for logging messages and handling PlayFab API responses. ```html

Twitch Auth Example

``` -------------------------------- ### Implement Essential GSDK Functions Source: https://learn.microsoft.com/en-us/gaming/playfab/multiplayer/servers/author-a-game-server-build Implement the Start and ReadyForPlayers methods using the GSDK APIs. This is a minimum requirement for integrating your game server with PlayFab Multiplayer Servers. ```csharp using Microsoft.PlayFab.Gsdk.Samples; public class Program { public static void Main(string[] args) { // Initialize the GSDK GameServerSDK.Initialize(); // Implement essential functions GameServerSDK.Start(OnStart); GameServerSDK.ReadyForPlayers(OnReadyForPlayers); // Keep the server running System.Threading.Tasks.Task.Delay(-1).Wait(); } private static void OnStart(PlayFab.Multiplayer.IGameServerInfo gameServerInfo) { // Handle server start logic here System.Console.WriteLine("Server starting..."); } private static void OnReadyForPlayers(PlayFab.Multiplayer.IGameServerInfo gameServerInfo) { // Handle server ready for players logic here System.Console.WriteLine("Server ready for players."); } } ``` -------------------------------- ### Start Game Command for Windows Source: https://learn.microsoft.com/en-us/gaming/playfab/multiplayer/servers/basics-of-a-playfab-game-server This command is used to start the game server executable on Windows. It must initiate an application that utilizes the PlayFab Game Server SDK to signal readiness. ```batch C:\GameCoreApp\GameServer.exe -mode RETAIL ``` -------------------------------- ### Install PlayFab SDK Source: https://learn.microsoft.com/en-us/gaming/playfab/identity/player-identity/platform-specific-authentication/anonymous-login Install the PlayFab SDK using npm. This is a prerequisite for using the PlayFab JavaScript SDK. ```bash npm install playfab-sdk ``` -------------------------------- ### Run Kusto Query Example Source: https://learn.microsoft.com/en-us/gaming/playfab/data-analytics/legacy/connectivity/connecting-grafana-to-insights Example of a Kusto query to retrieve the first 100 events from the 'events.all' table. ```kusto ['events.all'] | limit 100 ``` -------------------------------- ### Batch file to launch game client Source: https://learn.microsoft.com/en-us/gaming/playfab/multiplayer/servers/server-sdks/unreal-gsdk/connect-to-mps-hosted-build Use this batch file to launch your game client and connect it to the game server. Replace `{IP-ADDRESS}:{PORT}` with the actual server IP and port. ```batch ThirdPersonMP {IP-ADDRESS}:{PORT} -log ```