> For the complete documentation index, see [llms.txt](/llms.txt)

# Implementation

Let's implement from account issuance to login




This section explains the minimum implementation for creating an account and logging in using the GS2 SDK.

For complete code for each platform, please check the [Full Sample Code]().

**About Implementation in Unity**

The Unity SDK uses Coroutines for asynchronous processing. The following code examples are intended to be executed within a Coroutine (a method that returns `IEnumerator`).

## Initialize GS2 SDK



**Unity**
```csharp

    // Setup variables

    var clientId = "YourClientId";
    var clientSecret = "YourClientSecret";
    var accountNamespaceName = "game-0001";
    var accountEncryptionKeyId = "grn:gs2:{region}:{ownerId}:key:account-encryption-key-namespace:key:account-encryption-key";

    // Setup general setting
    Gs2Domain gs2;
    {
        var future = Gs2Client.CreateFuture(
            new BasicGs2Credential(
                clientId,
                clientSecret
            ),
            Region.ApNortheast1
        );
        yield return future;
        if (future.Error != null) {
            throw future.Error;
        }
        gs2 = future.Result;
    }
```
**Unreal Engine 5**
```cpp

	// Setup variables

	const auto ClientId = "YourClientId";
	const auto ClientSecret = "YourClientSecret";
	const auto AccountNamespaceName = "game-0001";
    const auto AccountEncryptionKeyId = "grn:gs2:{region}:{ownerId}:key:account-encryption-key-namespace:key:account-encryption-key";

    // Create GS2 client

    const auto InitializeFuture = Gs2::UE5::Core::FGs2Client::Create(
        MakeShared<Gs2::Core::Model::FBasicGs2Credential>(
            ClientId,
            ClientSecret
        ),
        Gs2::Core::Model::ApNorthEast1
    );
    InitializeFuture->StartSynchronousTask();
    if (InitializeFuture->GetTask().IsError())
    {
        UE_LOG(GameLog, Error, TEXT("%s"), ToCStr(InitializeFuture->GetTask().Error()->String()));
        return InitializeFuture->GetTask().Error();
    }
    const auto Gs2 = InitializeFuture->GetTask().Result();
```
**Godot**
```gdscript

    # Setup variables

    var client_id = "YourClientId"
    var client_secret = "YourClientSecret"
    var account_namespace_name = "game-0001"
    var account_encryption_key_id = "grn:gs2:{region}:{ownerId}:key:account-encryption-key-namespace:key:account-encryption-key"

    # Initialize GS2 SDK

    var credential = Gs2BasicCredential.new(client_id, client_secret)
    var connection = Gs2Connection.new(credential, Gs2Region.AP_NORTHEAST_1)
    var ez = Gs2EzDomain.new(connection)
```


### Setup variables

First, four variables are defined.

| Variable name | Usage | Source of acquisition |
| ----- | --- | ----- |
| clientId | authentication information to access GS2 | value created in [Create credential (API key)]()
| clientSecret | authentication information for accessing GS2 | value created by [create credential (API key)]()
| accountNamespaceName | the namespace name of the GS2-Account to be used | the value created in [Prepare resources required for login process]()
| accountEncryptionKeyId | GRN of the encryption key used for account authentication | the `KeyAccountAuthenticationKeyId` output of the stack created in [Prepare resources required for login process]()

Set `accountEncryptionKeyId` to the `KeyAccountAuthenticationKeyId` stack output for your region and project. Pass this value as `AccountSetting.keyId` in Unity or the second argument of `FAccountSetting` in Unreal Engine 5; the SDK default key is different from the key created in this tutorial.

### Setup general setting

CreateFuture(Gs2Client.CreateAsync when using UniTask) to create a GS2 client.
If `clientId` or `clientSecret` is incorrect, an error is returned here.
For Godot, create a `Gs2Connection` and initialize `Gs2EzDomain` to use the game engine Ez layer. Access each service through a service property such as `ez.account` or `ez.inventory`.

### Create GS2 client

Initialize a GS2 client.
If `clientId` or `clientSecret` is incorrect, an error will be returned here.

## Create new anonymous account



**Unity**
```csharp

    // define GS2-Account namespace
    var gs2Account = gs2.Account.Namespace(
        accountNamespaceName
    );

    // Create an anonymous account
    EzAccount account;
    {
        Debug.Log("Create an anonymous account");
        var future = gs2Account.CreateFuture();
        yield return future;
        if (future.Error != null) {
            throw future.Error;
        }
        var future2 = future.Result.ModelFuture();
        yield return future2;
        if (future2.Error != null) {
            throw future2.Error;
        }
        account = future2.Result;
    }
```
**Unreal Engine 5**
```cpp

	// Create an anonymous account

    UE_LOG(GameLog, Display, TEXT("Create anonymous account"));

    const auto CreateFuture = Gs2->Account->Namespace(
        AccountNamespaceName
    )->Create();
    CreateFuture->StartSynchronousTask();
    if (CreateFuture->GetTask().IsError())
    {
        UE_LOG(GameLog, Error, TEXT("%s"), ToCStr(CreateFuture->GetTask().Error()->String()));
        return CreateFuture->GetTask().Error();
    }

	// Load created account

    const auto LoadFuture = CreateFuture->GetTask().Result()->Model();
    LoadFuture->StartSynchronousTask();
    if (LoadFuture->GetTask().IsError())
    {
        UE_LOG(GameLog, Error, TEXT("%s"), ToCStr(LoadFuture->GetTask().Error()->String()));
        return LoadFuture->GetTask().Error();
    }
    const auto Account = LoadFuture->GetTask().Result();

    // Dump anonymous account

    UE_LOG(GameLog, Display, TEXT("UserId: %s"), ToCStr(*Account->GetUserId()));
    UE_LOG(GameLog, Display, TEXT("Password: %s"), ToCStr(*Account->GetPassword()));
```
**Godot**
```gdscript

    # Define the GS2-Account namespace
    var gs2_account = ez.account.namespace_(
        account_namespace_name
    )

    # Create an anonymous account
    var create_result = await gs2_account.create()
    if create_result.error != null:
        push_error(str(create_result.error))
        return

    var model_result = await create_result.result.model()
    if model_result.error != null:
        push_error(str(model_result.error))
        return

    var account = model_result.result
    print("UserId: ", account.user_id)
    print("Password: ", account.password)
```

Here we are creating an account to identify the game player.
accountNamespaceName is the name of the namespace to which the account will be added.

In this sample, a new account is created at every startup, but normally, an account is created only at the first startup of the application.
The actual application saves this response account information in local storage, etc., and logs in as an existing game player using the created account information retrieved from local storage, etc., from the second time onward.

## Login process



**Unity**
```csharp

    // Log-in created anonymous account
    GameSession gameSession;
    {
        var future = gs2.LoginFuture(
            new Gs2AccountAuthenticator(
                accountSetting: new AccountSetting {
                    accountNamespaceName = accountNamespaceName,
                    keyId = accountEncryptionKeyId,
                }
            ),
            account.UserId,
            account.Password
        );
        yield return future;
        if (future.Error != null) {
            throw future.Error;
        }
        gameSession = future.Result;
    }
```
**Unreal Engine 5**
```cpp

    // Log-in created anonymous account

    const auto LoginFuture = Gs2->Login(
        MakeShareable<Gs2::UE5::Util::IAuthenticator>(
            new Gs2::UE5::Util::FGs2AccountAuthenticator(
                MakeShared<Gs2::UE5::Util::FAccountSetting>(
                    AccountNamespaceName,
                    AccountEncryptionKeyId
                )
            )
        ),
        *Account->GetUserId(),
        *Account->GetPassword()
    );
    LoginFuture->StartSynchronousTask();
    if (LoginFuture->GetTask().IsError())
    {
        UE_LOG(GameLog, Error, TEXT("%s"), ToCStr(LoginFuture->GetTask().Error()->String()));
        return LoginFuture->GetTask().Error();
    }
    const auto GameSession = LoginFuture->GetTask().Result();
```
**Godot**
```gdscript

    # Log in with the created anonymous account
    var authenticator = Gs2AccountAuthenticator.new(
        account_namespace_name,
        account_encryption_key_id
    )
    var game_session = Gs2GameSession.new(
        authenticator,
        connection,
        account.user_id,
        account.password
    )
    var login_result = await game_session.login()
    if login_result.error != null:
        push_error(str(login_result.error))
        return
```

Next is the GS2 login process.
Specify information on account authentication in Gs2AccountAuthenticator. Specifically, the namespace name of the GS2-Account to be used for login is specified.
For Godot, also specify the GRN of the encryption key used for account authentication.
Furthermore, userId password specifies the user ID and password of the created account.

The resulting GameSession object is returned.
From now on, when calling GS2 APIs, GameSession will be passed as an argument for APIs that can only be called if the user is logged in.

## Calling APIs that can be called after login



**Unity**
```csharp

    // Load TakeOver settings
    {
        var it = gs2Account.Me(
            gameSession
        ).TakeOvers();
        while (it.HasNext()) {
            yield return it.Next();
            if (it.Error != null)
            {
                throw it.Error;
            }
            if (it.Current != null)
            {
                Debug.Log($"Type: {it.Current.Type}");
                Debug.Log($"Identifier: {it.Current.UserIdentifier}");
            }
        }
    }
```
**Unreal Engine 5**
```cpp

	// Load TakeOver settings

	const auto It = Gs2->Account->Namespace(
		AccountNamespaceName
	)->Me(
		GameSession
	)->TakeOvers();
	for (const auto TakeOver : *It)
	{
		UE_LOG(GameLog, Display, TEXT("Type: %d"), *TakeOver->GetType());
		UE_LOG(GameLog, Display, TEXT("Identifier: %s"), ToCStr(*TakeOver->GetUserIdentifier()));
	}
```
**Godot**
```gdscript

    # Load TakeOver settings
    var load_result = await gs2_account.me(
        game_session
    ).take_overs().load()
    if load_result.error != null:
        push_error(str(load_result.error))
        return

    for take_over in load_result.result:
        print("Type: ", take_over.type)
        print("Identifier: ", take_over.user_identifier)
```


As an example of an API that can only be used while logged in, we call the API to get a list of takeover settings.
You can pass GameSession to get a list of handover settings set for the currently logged-in game player.

### GS2 SDK termination process



**Unity**
```csharp

    // Finalize GS2-SDK
    {
        var future = gs2.DisconnectFuture();
        yield return future;
        if (future.Error != null) {
            throw future.Error;
        }
    }
```
**Unreal Engine 5**
```cpp

	// Finalize GS2-SDK

    const auto FinalizeFuture = Profile->Finalize();
    FinalizeFuture->StartSynchronousTask();
    if (FinalizeFuture->GetTask().IsError())
    {
        UE_LOG(GameLog, Error, TEXT("%s"), ToCStr(FinalizeFuture->GetTask().Error()->String()));
        return FinalizeFuture->GetTask().Error();
    }
```
**Godot**
```gdscript

    # Finalize GS2 SDK
    connection.disconnect_session()
```


Terminate the connection with GS2.

## Have you completed the tutorial?

[Check out our YouTube channel for guidance on how to use GS2!] ()

[We also provide more practical examples] ()

[find out what else you can achieve with GS2]()

[learn about the development workflow using GS2]()




- [Full sample code](/get_start/tutorial/coding/all/)
  
