Hi all,
I’ll start with a description/requirement and then explain my concerns:
- When a character joins the game they go to a profile selection screen (select your character).
- All profiles must have a unique character name, regardless of player.
- The profile selection screen has some preview data for each profile (XP, Level, Faction, etc.)
- Profiles can be deleted by the owner and the username freed-up for reuse by anyone.
- There must be a way to check if a username is already taken while a player is typing in the profile creation menu.
The only way I can conceive of doing this is something along these lines:
- You have 2 datastores, one for account/player data and one for profile data.
- The account datastore has a table of all the player’s profile names so we know which profiles in the profile datastore are owned by the player.
- Each profile is saved to the profile datastore with the username as the key. This way, it is possible to run a check using the profile username to see if it is already taken.
My concerns:
- With 2 datastores, it is possible for one to update while the other errors. For example: A player goes to delete a profile and RemoveAsync runs successfully on the profile datastore, but the account datastore fails to update with the new table of profile names minus the deleted name.
- Because of this error, the next time the player logs in, the account datastore tells them they still own this profile name. But in the time since they deleted it, a different player has taken the username and made a new profile. Now BOTH players believe that they own this username/profile and both are capable of playing/deleting it.
- Likewise the opposite problem is possible where the account datastore updates successfully but RemoveAsync errors on the profile datastore, and now this username exists in limbo and can never be accessed again by anyone.
- Another concern: If the player has a lot of profiles, say 20, I am now running GetAsync() 20+ times when the player joins the game, leaving a lot of room for errors and running up against rate-limits for datastores.
Other notes:
- I already have a system to retry failed datastore requests X times. But I cannot just retry infinitely when datastore service is degraded.
- I am aware the scenarios I described in my concerns would be rare, but I am not willing to accept any occurrences as described.
I am eager to hear your thoughts about how to best build this system. Thank you.