Linking with another data storage system

Introduction

The Asmodee.net platform provides a great number of features, but sometimes it is necessary to use another platform to get additional services. A typical example would be an app that needs a server-based virtual currency system, such as what PlayFab provides for example.

The Asmodee.net platform and the PlayFab platform both provides a linking system so that when you have an account on one side you can find its counterpart on the other side.

Problems start with late account linking: often, the game doesn’t want to bother the user with creating an Asmodee.net account right away, so a “ghost” PlayFab account would be created with some basic pre-filled virtual currency. Then at some point, at a time when the user is engaged enough to create or log in with her Asmodee.net account, the app takes her through the sign-up and login workflow and links the two accounts together. Unless it finds that the user logged to an Asmodee.net account that was already linked to another PlayFab account, with some virtual currency. What should be done without creating any security hole?

There are other corner cases, like what if the PlayFab account is not linked to the same Asmodee.net as the one the player is already connected to? This can happen when the user decides to switch from an Asmodee.net account to another.

The workflow proposed below describes how to handle all these cases. It is based on the PlayFab API calls to illustrate the matter, but it applies to any type of API that supports a linking mechanism. Follow it to resolve any cross-synchronization situation.

Formalization

Basically, the problem we are facing is to reconcile two tables that each contain records that points to the other table - possibly in an inconsistent manner if something went wrong.

We consider that we have two input parameters:

  • A PlayFab account, which already contains some data (virtual currency…).
  • An Asmodee.net account.

These two accounts are called the “current accounts”.

From each current account’s perspective, there are 3 possible situations:

It is not linked to any account on the other side.
It is linked to the other current account.
It is linked to another account,
different from the other current account.

This gives us 9 possibilities (putting the PlayFab account on the left side and the Asmodee.net account on the right side):

  Asmodee.net account
PlayFab
account


Add cross-links


Add PlayFab link


Ask user to choose


Add AN link


GOOD (nothing to do)


Ask user to choose


PlayFab wins


Fix PlayFab link


Ask user to choose

Note that cases #6 and #8 are inconsistencies that are not supposed to happen. But as we all know with software, if something is not supposed to happen, it will eventually - so better be prepared for it.

Workflow

We always have a PlayFab account (for example by using the PlayFab API LoginWithDeviceId). If we don’t have an Asmodee.net account, there are two possibilities:

  • If the current PlayFab account is already linked to an Asmodee.net account, we use that one. Note that it will require the user to login in with her password.
  • Otherwise we use the Signup and Login workflow to get an Asmodee.net account.

So at this point, we now have the two accounts.

The workflow is expected to return the PlayFab and the Asmodee.net accounts to use. The data to use will have to be fetched from the PlayFab account.

The code is very simple. For each account, we get the id (if any) of the other account it is linked to. Then it’s only a matter of testing if it’s empty, identical to the current account or different.

Case #1: none is linked: we need to marry them

BeforeAfter
- Link the PlayFab account to the Asmodee.net account using LinkCustomId
- Link the Asmodee.net account to thePlayFab account using LinkUser
BeforeAfter
- Make sure the Asmodee.net account is not used by any other PlayFab account by calling UnlinkCustomerId
- Link the PlayFab account to the Asmodee.net account by calling LinkCustomId

Case #3: The Asmodee.net account is pointing to ANOTHER PlayFab account: ask the user which PlayFab data she wants to keep

BeforeAfter
(keep "local")
After
(keep "server")
- Ask the user if she prefers to keep the current "local" data or switch to the "server" data.
- If she prefers to keep the current data
    - Call the PlayFab UnlinkCustomId API to unlink the Asmodee.net account
    - Call the Asmodee.net account UnlinkUser API to do the same thing
    - Call the PlayFab LinkCustomId API to link the Asmodee.net account to the current PlayFab account
    - Call the Asmodee.net account LinkUser API to do the same thing
- Else
    - Switch to the PlayFab account of the Asmodee.net account
    - Make sure it points back to the Asmodee.net account, just in case, by using the LinkCustomId PlayFab API
- Endif

It should be noted that the terms “local” and “servers” are technically inaccurate, since in both cases the PlayFab data are located on the PlayFab servers! But this situation is going to happen in the case of a “late linking” with an Asmodee.net account that was already used with the app. So in the player’s mind, this will be what it will look like: a choice between keeping her current (“local”) progress or switching to the previous (“server”) one.

BeforeAfter
- Call the Asmodee.net UnlinkUser API to make sure the PlayFab account is not used by any other Asmodee.net account
- Call the Asmodee.net LinkUser API to link it to the current PlayFab account

Case #5: Both accounts point to each other

BeforeAfter
Nothing to do, we're already in good shape!

Case #6: Inconsistency: the PlayFab account points to the current Asmodee.net account but the Asmodee.net account points to ANOTHER PlayFab account

Since there is an inconsistency, we need to treat it like case #3, i.e. ask the user to choose.

BeforeAfter
(keep "local")
After
(keep "server")
See case #3 about the implementation.

Note that this is a corner case that should probably never happen, unless there was a bug or a communication issue. It’s more a database fix-up case.

Case #7: orphan Asmodee.net account: the PlayFab account should win

BeforeAfter

Since the current Asmodee.net account is not linked to any PlayFab data, there is no point in using it. The PlayFab account is already linked to another Asmodee.net account, so that’s the one we should use.

However, make sure you warn the user, since you are going to switch her to another Asmodee.net account (and probably ask her to login in it).

- Tell the user that the PlayFab account is linked to another Asmodee.net account and ask her to login with it.
- Call the Asmodee.net UnlinkUser API to make sure the PlayFab account is not used by any other Asmodee.net account
- Switch to the linked Asmodee.net account
- Call the Asmodee.net LinkUser API to link it to the current PlayFab account

Case #8: Inconsistency: the Asmodee.net account points to the current PlayFab account but the PlayFab account points to ANOTHER Asmodee.net account

We fix the PlayFab account (“Asmodee.net wins”) and correct the links. Note that this does not change the user’s game data, since the PlayFab account remains the same. So it’s only a corner case to fix the links, there is no needs to warn the user. Like case #6, it’s not supposed to happen.

BeforeAfter
- Call the PlayFab UnlinkCustomId API to unlink the other Asmodee.net account from all PlayFab accounts
- Call the PlayFab LinkCustomId API to link the current PlayFab account to the current Asmodee.net account

Case #9: each is linked to another: ask the user which one to use

This would typically happen in a game where the user logs out from the current Asmodee.net account and logs in another one.

You need to ask the user to confirm that she wants to switch to the PlayFab content linked to the current Asmodee.net account. Or if she wants to keep the current PlayFab content, in which case she will have to log in with its linked Asmodee.net account. This could be presented in a simple dialog, like this:

Choose the Account to Use
You are currently connected to an Asmodee.net account ("Johnny") that has a different amount of Virtual Currency than the current amount. Please choose which account you want to play with:
Johnny
§12345
Brice
§54321
(you will need to log in)
Choose Choose
BeforeAfter
(keep connected)
After
(log in to other account)
- Ask the user if she wants to use the current Asmodee.net account or log in to the other Asmodee.net account.
- If choice is to keep the current Asmodee.net account
    - Switch to the PlayFab account linked by the current Asmodee.net account.
- Else
    - Log in to the other Asmodee.net account
- Endif

Do I really have to do all this?

Case #6 and #8 are corner cases that are not supposed to happen. But defensive coding is always a good practice. You will notice that each case is very small and simple, except case #3 in which we ask the user to choose which content to keep. You absolutely need to code this case #3, especially if your game uses “late linking”.

We went to great lengths to detail all the cases, but the resulting code is actually pretty small. We wrote a simulator, and it results in only 60 lines of codes.

You can a download and test the simulator code from GitHub.