Authenticating with Discord #

In this section, we’ll log into the platform with Discord. This method is appropriate for use in production. A Discord account is required to complete this section.

Complete Setting Up the Unreal SDK and Logging Into the Platform before starting this section.

Discord Developer Portal Setup #

  1. Log into the Discord Developer Portal.
  2. Click on the Applications tab, then click the New Application button.
If the application has already been created, then you can click on it under My Applications.

  1. Name your application, then click the Create button.

  1. After your application has been created, click on the Bot section in the left sidebar, then click the Add Bot button. Confirm that you wish to create a bot.

  1. Click on OAuth2 in the left sidebar, then click the Add Redirect button. Paste the following URL: http://localhost:11000/v1/account/discord-redirect. Click the Save Changes button.

  1. In the left sidebar, click URL Generator which is nested under OAuth2. Tick the identify and email boxes, then choose http://localhost:11000/v1/account/discord-redirect under the Select Redirect URL dropdown.

Configure the Pragma Platform Discord Identity Provider #

  1. Obtain your clientSecret and clientId from the OAuth2 General tab of your application in the Discord Developer Portal. If you have not yet been issued a Client Secret, click the Reset Secret button.
Be sure to securely record your Client Secret, as it will not be shown again.

  1. Navigate to the pragma-engine/platform/5-ext/config directory and open LocalConfig.yml.

  2. Insert the following code while making sure to edit in your clientSecret and clientId:

Be sure to nest AccountService.discordIdentityProvider under pluginConfigs if you already have other identity providers configured.
social:
  pluginConfigs:
    AccountService.discordIdentityProvider:
      class: "pragma.account.DiscordIdentityProviderPlugin"
      config:
        clientSecret: "*YOUR CLIENT SECRET"
        clientId: "*YOUR CLIENT ID*"
        redirectUri: "http://localhost:11000/v1/account/discord-redirect"
  1. Run make run to start Pragma Engine. Run this in a terminal with platform as the working directory.
  • Alternatively, Pragma Engine can be run from IntelliJ. From the IntelliJ toolbar in the upper right, ensure MainKt - LocalConfigured is selected, then click the play button.

  • Once the engine has successfully started it prints the message [main] INFO main - Pragma server startup complete.

Import the Discord SDK Into Unreal #

  1. Download the Discord SDK from the Discord Developer site.
  2. Follow the directions on the Discord developer site to import the Discord SDK into your Unreal project.
Note that the code provided by the Discord guide for editing your-project-name.Build.cs is missing trailing semicolons.
Do not copy the MyPawn class provided by the Discord guide. Instead, continue following the instructions here.
  1. Click on the Content Browser, then expand C++ Classes. Click on your project. Right click in an empty area in the right-hand side of the Content Browser, then click New C++ Class.

  1. In the Create Parent Class window, create a new Pawn. This guide will assume that it was created with the default name of MyPawn.

  1. OpenMyPawn.cpp with Rider and replace the contents with the following code. Be sure to replace "Discord Client Token" with your Discord application’s clientID, which can be obtained from the Discord Developer Portal. Replace all instances of [Project Name] with your project’s name.
#include "MyPawn.h"

#include <string>

#include "[Project Name]GameModeBase.h"
#include "discord-files/discord.h"

discord::Core* core{};
A[Project Name]GameModeBase* gmBase;

AMyPawn::AMyPawn()
{
    // Set this pawn to call Tick() every frame.  You can turn this off to improve performance if you don't need it.
    PrimaryActorTick.bStartWithTickEnabled = true;
    PrimaryActorTick.bCanEverTick = true;
}

// Called when the game starts or when spawned
void AMyPawn::BeginPlay()
{
    Super::BeginPlay();
    
    gmBase = Cast<A[Project Name]GameModeBase>(GetWorld()->GetAuthGameMode<A[Project Name]GameModeBase>());
    
    auto result = discord::Core::Create("Discord Client Token", DiscordCreateFlags_Default, &core);
    core->ApplicationManager().GetOAuth2Token([](discord::Result result, discord::OAuth2Token token){
        const char* charToken = token.GetAccessToken();
        //Convert Discord's UTF-8 encoded string to something Unreal can understand
        std::string test = charToken;
        FString tokenString(test .c_str());
        //Log into the Pragma Platform by passing in our string
        gmBase->LoginViaDiscord(tokenString);
    });
}

// Called every frame
void AMyPawn::Tick(float DeltaTime)
{
    Super::Tick(DeltaTime);
    ::core->RunCallbacks();
}

// Called to bind functionality to input
void AMyPawn::SetupPlayerInputComponent(UInputComponent* PlayerInputComponent)
{
    Super::SetupPlayerInputComponent(PlayerInputComponent);
}
  1. Replace the contents of [Project Name]GameModeBase.cpp with the following code. Replace all instances of [Project Name] with your project’s name.
// Copyright Epic Games, Inc. All Rights Reserved.

#include "[Project Name]GameModeBase.h"
#include "PragmaSessionLocalPlayerSubsystem.h"
#include "PragmaSession.h"
#include "GameFramework/GameMode.h"

void A[Project Name]GameModeBase::BeginPlay()
{
    Init(*GetWorld()->GetFirstLocalPlayerFromController());
}

void A[Project Name]GameModeBase::Init(ULocalPlayer& InLocalPlayer)
{
    LocalPlayer = &InLocalPlayer;
    auto* World = GetWorld();
    if (!World->IsClient())
    {
        return;
    }
    auto* SessionSubsystem = LocalPlayer->GetSubsystem<UPragmaSessionLocalPlayerSubsystem>();
    if (!ensure(SessionSubsystem))
    {
        return;
    }
    Session = &SessionSubsystem->Session();
    Session->Connection()->OnConnected.AddUObject(this, &A[Project Name]GameModeBase::HandleConnected);
    Session->Connection()->OnDisconnectedV2.AddUObject(this, &A[Project Name]GameModeBase::HandleDisconnected);
}

void A[Project Name]GameModeBase::LogIn(const FString& Username)
{
    UPragmaAccountService::FLoggedInDelegate OnLoggedIn;
    OnLoggedIn.AddUObject(this, &A[Project Name]GameModeBase::HandleLoggedIn);
    Session->Account().LogIn(EPragma_Account_IdProvider::UNSAFE, Username, OnLoggedIn);
}

void A[Project Name]GameModeBase::LoginViaDiscord(const FString& DiscoToken)
{
    UPragmaAccountService::FLoggedInDelegate OnLoggedIn;
    OnLoggedIn.AddUObject(this, &A[Project Name]GameModeBase::HandleLoggedIn);
    Session->Account().LogIn(EPragma_Account_IdProvider::DISCORD, DiscoToken, OnLoggedIn);
}

void A[Project Name]GameModeBase::HandleConnected()
{
    UE_LOG(LogTemp, Warning, TEXT("Pragma Connected") );
}

void A[Project Name]GameModeBase::HandleDisconnected(TOptional<UPragmaConnection::FConnectionError> Error)
{
    UE_LOG(LogTemp, Warning, TEXT("Pragma Disconnected") );
}

void A[Project Name]GameModeBase::HandleLoggedIn(const TPragmaResult<FString>& Result)
{
    if (Result.IsSuccessful())
    {
        UE_LOG(LogTemp, Warning, TEXT("Pragma Logged in! Player Id: %s:"), *Session->Account().GetPragmaId());
    }
    else
    {
        // Note you can access platform/sdk error enums in Result as well.
        UE_LOG(LogTemp, Warning, TEXT("Pragma Disconnected") );
    }
}
  1. Add the following code to [Project Name]GameModeBase.h nested under public::
void LoginViaDiscord(const FString& DiscoToken);
  1. Compile the project using the green hammer icon at the top of the Rider window.

  2. In Unreal Editor, drag MyPawn from the Content Browser into the game.

  1. Click the Play button to log into Discord via Unreal.

  2. Navigate to your local Pragma Platform portal and sign in via Pragma Unsafe using the test04 account.

  3. Confirm that you see both the test04 account and your Discord account’s display name in the list of logged-in players.

  4. Click on the Discord account’s display name. Under the Identity providers section, verify that the account’s identity provider is Discord.

Troubleshooting #

Plugin ‘PragmaSDK’ failed to load because module ‘PragmaSDK’ could not be loaded.

After closing Unreal Editor, rerun the update-pragma-sdk.sh script in the Plugins directory in your Unreal project folder. When the script finishes, reopen your project and let the editor rebuild the PragmaSDK.