Plugin.Games 10.0.40

dotnet add package Plugin.Games --version 10.0.40
                    
NuGet\Install-Package Plugin.Games -Version 10.0.40
                    
This command is intended to be used within the Package Manager Console in Visual Studio, as it uses the NuGet module's version of Install-Package.
<PackageReference Include="Plugin.Games" Version="10.0.40" />
                    
For projects that support PackageReference, copy this XML node into the project file to reference the package.
<PackageVersion Include="Plugin.Games" Version="10.0.40" />
                    
Directory.Packages.props
<PackageReference Include="Plugin.Games" />
                    
Project file
For projects that support Central Package Management (CPM), copy this XML node into the solution Directory.Packages.props file to version the package.
paket add Plugin.Games --version 10.0.40
                    
#r "nuget: Plugin.Games, 10.0.40"
                    
#r directive can be used in F# Interactive and Polyglot Notebooks. Copy this into the interactive tool or source code of the script to reference the package.
#:package Plugin.Games@10.0.40
                    
#:package directive can be used in C# file-based apps starting in .NET 10 preview 4. Copy this into a .cs file before any lines of code to reference the package.
#addin nuget:?package=Plugin.Games&version=10.0.40
                    
Install as a Cake Addin
#tool nuget:?package=Plugin.Games&version=10.0.40
                    
Install as a Cake Tool

Games plugin for .NET MAUI

This project has no affiliation with Microsoft or the Maui/Xamarin teams.

dotnet add package Plugin.Games

Nuget.org

NuGet

Package Reference

<PropertyGroup>
	<PackageReference Include="Plugin.Games" Version="10.0.40" />
</PropertyGroup>

Features

Achievements Leaderboards
Android
iOS
MacCatalyst
Windows

Google Features Omitted

Events, SavedGames, Recall, PlayerStats and Friends were omitted due to limitations of supporting package or because Apple doesn't provide a feature that could be abstracted in a similar way to provide anything of use. Additionaly packages like Plugin.Firebase already achieve many of these same features with a little more setup.

Apple Features Omitted

Matchmaking, VoiceChat, GameActivities and Challenges were omitted simply because Google doesn't provide equivalent services that could be used to abstract similar features. If these features are desired, they already ship with .net Maui apps under the namespace Microsoft.Maui.Platform.GameKit.

Table of Contents

/Readme.md /docs/ Achievements.md Leaderboard.md /src/ /GamesTest/ GamesTest.csproj /Plugin.Games/ Plugin.Games.csproj

Setup

Before starting, make sure to set up a google cloud project, create an OAuth2.0 client, and register it with your published app. See below for the instructions: https://developer.android.com/games/pgs/console/setup

  1. First initialize the project by adding the package to your project.
dotnet add package Plugin.Games
  1. Override the Windows.OnCreated event in the App class for your project and call "await CrossGames.Current.SignInSilently" to sign into the Games SDK for both Android or iOS.
using Plugin.Games;

namespace GamesTest;

public partial class App : Application
{
	public App()
	{
		InitializeComponent();
	}

	protected override Window CreateWindow(IActivationState? activationState)
	{
		var window = new Window(new AppShell());
		window.Created += async (s, e) =>
		{
			//Personal sign in, no server access. See AppDelegate or MainActivity for server access sign in examples.
			try
			{
				var signedIn = await CrossGames.Current.SignInSilentlyAsync();
				System.Diagnostics.Debug.WriteLine($"User Signed In: {signedIn}");
			}
			catch (Exception ex)
			{
				System.Diagnostics.Debug.WriteLine($"Sign-in failed: {ex.Message}");
			}
		};
		return window;
	}
}

Players who are authenticated already will just sign in silently in the background with maybe a toast appearing in the user interface. For players who haven't authenticated, a sign in user interface action will prompt the user to sign in.

Android Backend Server Access and Platform Specific Properties

  1. Setup the AndroidManifest.xml to accept your Google Play Games project id.
<manifest>
  <application>
    <meta-data android:name="com.google.android.gms.games.APP_ID"
               android:value="@string/game_services_project_id"/>
  </application>
</manifest>
  • Create a strings.xml resource file in the "./Platforms/Android/Resources/values" folder with the following
<?xml version="1.0" encoding="utf-8" ?>
<resources>  
 		
	<string name="game_services_project_id" translatable="false">1024987000491</string>
</resources>
  1. (Optional) To authenticate the user with your back end server, use "await CrossGames.Current.RequestServerSideAccessAsync" in the MainActivity in the Platforms/Android folder and overriding OnCreate(Budnle savedInstanceState).
  • On Andorid, get the server OAuth2.0 identifier from your google cloud project.
string serverID = "28y9458jidfh2879";
  • Specify the scopes to which your server authentication applies
List<GamesAuthScope> scopes = new List<GamesAuthScope>
{
	GamesAuthScope.Profile,
	GamesAuthScope.Email
};
  • Request server authication by calling RequestServerSideAccessAsync and specify whether or not you want the the access token to refresh. The method can be awaited for a GamesAuthResponse which contains the access token.
try
{
	GamesAuthResponse response = await CrossGames.Current.RequestServerSideAccessAsync(serverID, false, scopes);
	if(response is null)
	{
		System.Diagnostics.Debug.WriteLine($"Server auth response is null.");
		return;
	}
	else
	{
		string token = response.Android.AuthorizationCode;
		//Pass the oauthToken to your backend server for verification and further processing.
		System.Diagnostics.Debug.WriteLine($"Server authenticated. Access Token: {token}");
	}
}
catch (Exception ex)
{
	System.Diagnostics.Debug.WriteLine($"Authentication failed: {ex.Message}");
}
  1. (Optional) On Android, there is a data caching property you can override by setting. The default of the property is false and the recommendation is to leave it false to take advantage of data caching properties.
GamesImplementation.ShouldForceReload = true;
  1. (Optional) On Android, there are request code integers that can be used to specify what integer code to use for the following:
    • FriendsResolutionRequiredException is received from a leaderboard method being called. The default code value is 1001.
    • ShowLeaderboardsCode is received from the ShowLeaderBoardsAsync methods being called. The default code value is 2002.
    • ShowAchievementsCode is received from the ShowAchievementsAsync method being called. The default code value is 3003. Simply change the codes
GamesImplementation.ShowLeaderboardsCode = 1234;
GamesImplementation.FriendRequestCode = 5678;
GamesImplementation.ShowAchievementsCode = 1337;

Then verify and handle the right intents later in the main activity by overriding OnActivityResult

protected override void OnActivityResult(int requestCode, Result resultCode, Intent? data)
{
    base.OnActivityResult(requestCode, resultCode, data);

    if (requestCode == GamesImplementation.FriendRequestCode)
    {
        if (resultCode == Result.Ok)
        {
            // User accepted → retry the friends leaderboard call
        }
        else
        {
            // User declined → fall back to public leaderboard
        }
    }
}

Apple

  1. Address access to specific content in your app based on player specific capabilities such as whether or not the player has a parental permission to access explicit content. The Apple Game Center event fires when a player should NOT have access to content.
  • First create an action event handler:
	private void OnGameCenterPrivlagesRevoked(object? sender, GamesCapability capability)
	{
		switch (capability)
		{
			case GamesCapability.Multiplayer:
				//DisableMultiplayer();
				break;

			case GamesCapability.InGameCommunication:
				//HideChat();
				break;

			case GamesCapability.ExplicitContent:
				//ShowContentWarning();
				break;
		}
	}
  • Then subscribe to the "OnCapabilityUnavailable" event in the AppDelegate for iOS and MacCatalyst by overriding FinishedLaunching(UIApplication application, NSDictionary? launchOptions).
	public override bool FinishedLaunching(UIApplication application, NSDictionary? launchOptions)
	{		
		CrossGames.Current.OnCapabilityUnavailable += OnGameCenterPrivlagesRevoked;
		return base.FinishedLaunching(application, launchOptions);
	}
  1. (Optional) To authenticate the user with your back end server, use "await CrossGames.Current.RequestServerSideAccessAsync" in the AppDelegate for iOS and MacCatalyst by overriding FinishedLaunching(UIApplication application, NSDictionary? launchOptions).
try
{
	GamesAuthResponse response = await CrossGames.Current.RequestServerSideAccessAsync();
	if(response is null)
	{
		System.Diagnostics.Debug.WriteLine($"User not signed in.");
		return;
	}
	else
	{
		var publicURI = response.Apple.PublicKeyUrl;
		var signature = Convert.ToBase64String(response.Apple.Signature);
		//Use these values to verify the identity of the player on your backend server.
		//You can also access the Salt and Timestamp from response.Apple.Salt and response.Apple.Timestamp
		//To mitigate replay attacks, make sure the timestamp parameter is recent, and to avoid high network overhead, 
		//respect the cache expiration headers.
		System.Diagnostics.Debug.WriteLine($"User signed in. Public Key URL: {publicURI}, Signature: {signature}");
	}
}
catch (Exception ex)
{
	System.Diagnostics.Debug.WriteLine($"Sign-in failed: {ex.Message}");
}

Supporting Packages

Platform Package Name Version SDK Name Version
Android Xamarin.GooglePlayServices.Games.V2 121.0.0.1 Play Games Services 21.0.0
iOS Microsoft.Maui.Platform.GameKit Game Center

Release notes

  • Version 10.0.40
    • Made calls thread safe.
    • Fixed obsolete calls.
  • Version 10.0.30
    • Release abstracting apple game center.
  • Version 10.0.20
    • Initial release abstracting Play Games Services from android.
Product Compatible and additional computed target framework versions.
.NET net10.0 is compatible.  net10.0-android was computed.  net10.0-android36.0 is compatible.  net10.0-browser was computed.  net10.0-ios was computed.  net10.0-ios26.0 is compatible.  net10.0-maccatalyst was computed.  net10.0-maccatalyst26.0 is compatible.  net10.0-macos was computed.  net10.0-tvos was computed.  net10.0-windows was computed. 
Compatible target framework(s)
Included target framework(s) (in package)
Learn more about Target Frameworks and .NET Standard.

NuGet packages

This package is not used by any NuGet packages.

GitHub repositories

This package is not used by any popular GitHub repositories.

Version Downloads Last Updated
10.0.40 71 3/4/2026
10.0.30 83 2/25/2026