# Unreal

You can use this plugin for desktop Unreal games - at the moment we support only Windows platform.

## Connecting plugin to your project.

1. Put **TIPlugin** in your plugins directory.&#x20;

**TIPlugin** consists of ESCS\_Subsysem subsystem classes and windows dll libraries, as well as escs plugin-specific executables.&#x20;

2. Add dependencies to your **\*Build.cs** file of your Unreal project.&#x20;

```csharp
		PublicDependencyModuleNames.AddRange(new string[] { "Core",
			"CoreUObject", 
			"Engine", 
			"InputCore", 
			"TIPlugin" // <--- add this
		});
```

3. Re-generate Visual Studio project with aforementioned changes (right-click unreal project file)

<figure><img src="https://3853901254-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2F-MAfYp0johoPRZW2PhVp%2Fuploads%2FROTscfYcyLczCk83ibl1%2Fimage.png?alt=media&#x26;token=a52f0f91-a964-4271-a8f3-910c1133e7c7" alt=""><figcaption></figcaption></figure>

4. You're ready to go! Now you have **ESCS\_SubSystem** available for you. You can either use it in code or in blueprints. Later sections mainly describe how to use it in source code, but you can easily use it in your blueprints, just search for ESCS\_Subsystem there.

## Integrating plugin into your game.

Basic integration needs just few lines of code. After this, you have all the socialization features, but not multiplayer tournaments.

In your main controller class add the following in the **BeginPlay** method:

<pre class="language-cpp"><code class="lang-cpp">void AAPC_TutorialPlayerController::BeginPlay()
{
<strong>	//...
</strong>	auto* escs = GetGameInstance()->GetSubsystem &#x3C;UESCS_SubSystem>();
	
	escs->PluginCreate();
	
	escs->PluginSetFrontendPath("");
	
	escs->PluginSetFrontendEnvVar(TEXT("ESCS_ENVIRONMENT"), "prod");
	escs->PluginSetFrontendEnvVar(TEXT("ESCS_GAME_PUBLIC_KEY"), "your-game-public-key");
	
	auto result = escs->PluginStart();
	
	UE_LOG(LogTemp, Display, TEXT("ESCS -- init result: %d"), result);
	//...
}

void AAPC_TutorialPlayerController::Destroyed()
{
	auto* escs = GetGameInstance()->GetSubsystem &#x3C;UESCS_SubSystem>();
	escs->PluginDestroy();
}
</code></pre>

Here you can see the Escs subsystem being utilized. Before you invoke any methods, you need to call **PluginCreate()**. Don't forget to **PluginDestroy()** on controller destruction.

* **PluginSetFrontendPath()** - this is path to Escs frontend executable. It is located by default at \TIPlugin\Source\ThirdParty\TIPluginLibrary\x64\escs-desktop-frontend. This path could be either relative to current executable or absolute
* **PluginSetFrontendEnvVar()** - call to set environment for plugin. Two required pieces are the environment name - in our case it's Prod, and you game public key. How to obtain public key string please refer to [this](https://docs.escs.io/integration-step-1).
* **PluginStart()** - starts plugin, at this point you are going to see the "escs ball" in your ui.

This is basic set up to have Escs UI integrated into you game. However, to support tournaments and OAuth integration, you need more steps, listed below.

## Multiplayer

### Overview

We support multiplayer games with different types of matches, matchmaking and so on. To be able to use this feature, you need to follow these steps:&#x20;

* Create multiplayer tournament in the game dashboard
* Implement several callbacks in you game, which will be called in response to player's engagement with multiplayer tournament

Currently we provide 1 such callback:

* **OnGameSetStart** callback - is called when a game set is started by escs backend. This is moment when you should start your game or create lobby and await for players to join it. What is a "set"? It's just one multiplayer game that several players are playing simultaneously. It can be real multiplayer (e.g. they, for example, race each other on track in a racing game or are participating in a deathmatch 1vs1 or 2vs2 and so on), or even "singleplayer", meaning that they all play their own singleplayer game (like solving puzzles and the one who solves it faster is the winner). In this callback you will receive information about players that are playing this set, teams that players are in (i.e. 2vs2 game), metadata that is supplied with the player (supplied by **registerInGamePlayerId**) and global metadata that is set in the game dashboard

**Currently unsupported callbacks (will be added in future releases):**

* **OnGameSetEnd** callback - is called when each player in the set has finished their game. this might be not necessary the same moment you end your multiplayer game - it is called when the escs backend processed all game end events from each participating player and saved their corresponding scores. You will receive **matchId** and **setId** as parameters
* **OnMatchStart** callback - is called when multiplayer match has started. Usually you will get this event right before getting **OnGameSetStart**. Each match consists of several game sets. You will receive **matchId** as parameter of this callback.
* **OnMatchEnd** callback - is called when multiplayer match has ended. That is when all the sets in the match has been played or timeout occurred. You will receive **matchId** as parameter of this callback

The following diagram may be helpful for understanding about aforementioned events:

![](https://3853901254-files.gitbook.io/~/files/v0/b/gitbook-legacy-files/o/assets%2F-MAfYp0johoPRZW2PhVp%2F-MMGKFBYBvgpRAu5mOpi%2F-MMHglMU0wyrPPD2Fb_z%2FUntitled%20Diagram%20\(1\).svg?alt=media\&token=269d7151-8e6a-4a42-8336-60efbb937a8c)

To utilize these events you can call methods described below.

```cpp
void AAPC_TutorialPlayerController::BeginPlay()
{	
	//...
	escs->BindPlugin_on_round_started_request(escs);

	FScriptDelegate roundDelegate;
	roundDelegate.BindUFunction(this, "RoundStarted");

	escs->OnCallBack_plugin_on_round_started_request.Add(
		roundDelegate
	);
	//...
}
		
void AAPC_TutorialPlayerController::RoundStarted(FString roundId)
{
	//here start your game session accordingly
	//...
	//get results of your game into variable metrics_value
	auto* escs = GetGameInstance()->GetSubsystem <UESCS_SubSystem>();
	auto res = escs->PluginEmitRoundStartedResponse("your metrics name", metrics_value);
}
```

Here we can see the event of set start in action. Upon game completion, you should get your game metrics (for example points, score, frags etc.) into **PluginEmitRoundStartedResponse.** You can check how to set up metrics names in escs dashboard [here](https://docs.escs.io/integration-step-1).

For your game to function properly with escs you need to tell escs what ingame player id you are using in current session. This could be done using following methods:

```cpp
escs->BindPlugin_on_get_ingame_player_id_request(escs);
FScriptDelegate playerDelegate;
playerDelegate.BindUFunction(this, "GetPlayerId");

escs->OnCallBack_plugin_on_get_ingame_player_id_request.Add(
	playerDelegate
);

void AAPC_TutorialPlayerController::GetPlayerId()
{
	//here get your player's game id to bind to current game session 
	//(this will associate current escs playuer with given ingame playerID)
	auto* escs = GetGameInstance()->GetSubsystem <UESCS_SubSystem>();
	auto res = escs->PluginEmitGetIngamePlayerIdResponse("your player id");
}
```

Given player ids of all the players that are goin to participate in match will be sent to your game backend in OnGameSetStart callback. Please refer [here ](https://docs.escs.io/plugins/android-native/basic-multiplayer-with-oauth)and [here ](https://docs.escs.io/plugins/pragma.gg)to read about backend integration.&#x20;

**NOTE:** you have to **PluginEmitGetIngamePlayerIdResponse** before game set starts. We recommend calling it right after your user logins or changes credentials in your game.

### OAuth integration

1. Create the oAuth app as described here: [using-escs-oauth-for-sign-in](https://docs.escs.io/using-escs-oauth-for-sign-in "mention")
2. Implement the callback to send the access token to escs as described below.&#x20;

#### Supporting user login using the game account (oAuth-like)

You can use our option for user game profile integration and allow your users to log in to our system without requiring them to manually create an escs account. Then the user will see an additional button **"log in using %game\_name% account"** on the main escs screen. In order to support this, first, you need to follow the required steps in the client dashboard and set up the necessary fields as described in the corresponding docs section: [using-escs-oauth-for-sign-in](https://docs.escs.io/using-escs-oauth-for-sign-in "mention"). Note that you will also need to create an additional endpoint in your game's backend for the account system for verifying tokens. If you are using pragma.gg for backend, you can read how to use escs custom services for that [here](https://docs.escs.io/plugins/pragma.gg). After this you will only need to implement one callback in your game:&#x20;

```cpp

//...
escs->BindPlugin_on_get_oauth_onetime_token_request(escs);

FScriptDelegate tokenDelegate;
tokenDelegate.BindUFunction(this, "ReturnToken");

escs->OnCallBack_plugin_on_get_oauth_onetime_token_request.Add(
	tokenDelegate
	);
//...

		
void AAPC_TutorialPlayerController::ReturnToken()
{
	//here get your one-time code from your backend
	//if you're using pragma.gg please refer to corresponding section
	auto* escs = GetGameInstance()->GetSubsystem <UESCS_SubSystem>();
	auto res = escs->PluginEmitGetOauthOnetimeTokenResponse("your one-time token");
}
```
