我正在开发一款用户可以匿名离线播放的游戏。只要他们想要,他们就可以通过Facebook进行身份验证,并且可以将他们的分数发布到排行榜并发挥挑战。看起来很简单。它不是!
现在我遇到了一个我没想到的架构问题,我问是否已经有一种标准方法可以解决它。
假设: 用户在本地存储他们的个人分数,直到他们进行身份验 连接后,在线服务会在线存储分数。 设备和服务器应该同步,以便用户通过不同的设备尽可能地维护分数,服务器可以使用他的分数来匹配制作和排行榜。
现在,如果出现以下情况:
之前通过身份验证的玩家,可以离线播放?新分数将在第一个连接客户端同步=>服务器
玩家更改Facebook个人资料。分数存储在本地,因此新用户使用旧分数进行播放,并且当用户连接到服务时,根据1,同步客户端=>服务器将玩家1的分数推送给新玩家。错误!
玩家维护相同的Facebook个人资料,但更改设备。新设备上的分数为0,因此同步应为server =>客户端代替客户端=>服务器。此外,每当他回到之前的设备时,同步应该是server =>客户端代替客户端=>服务器
出现了很多其他问题,实际上,结合了以下三个方面:更改用户,更改设备,离线播放。
考虑一个可能的解决方案我想在fb id,得分,简单的数字计数器或保存日期,本地和远程执行可能的检查,但没有完整的解决方案,并且始终存在条件玩家可能会失去他们的分数,或者新玩家可以获得更强的玩家得分。
是否有一些算法,最佳实践,架构或任何可以帮助我解决这个(奇怪)问题的东西?
答案 0 :(得分:0)
不是一个完美的解决方案,而是我在玩游戏时观察到的一种行为,它使用谷歌游戏服务来同步数据。
当我从其他设备离线播放一段时间并上线时,这些游戏会提示我对话。
此对话框告诉我服务器上有不同的配置文件,我是否要加载该配置文件(已保存状态)或继续使用当前配置文件。
此外,如果我更改了我的Google帐户,我也会丢失所有已保存的个人资料。(以前同步的个人资料仍可在之前的帐户中使用)
这不是一个完美的解决方案,但它有效并且让用户可以选择如何处理他/她的游戏数据。
另外需要注意的是,考虑到用户可以使用连接不稳定的多台设备,任何解决方案都不能完美。
答案 1 :(得分:0)
我认为我得出了一个部分结论,可能会在以后更好地完成。
与分数一起,我存储了FBid和一个序列号。为了涵盖最常见的情况我们需要。
这是我认为同步过程需要的初始方案:
public void Sync()
{
if (local.FBid == null)
// there's no FBid stored locally, so it's the first connection to
// an online profile from this device.
// The user might have used his profile before, so we cannot trust
// a simple client-> server sync that would wipe the online score.
// On the other hand, the user could have played a lot offline and
// now decided to finally go online and export his score, that would
// be lost with a server -> client sync.
// To decide which profile is better we must trust the serial, considering
// that a empty profile has serial 0.
// We must understand if there is already a online profile.
// If there is not, create it, otherwise take the one with the highest serial.
// To do that we initialize and simply fall in the successive case.
{
local.FBid = used.FBid;
}
if (local.FBid == used.FBid)
// the local user is the same as the online user, we have to check if the player has advanced
// the score playing offline. In that case the server will be updated.
// Instead if the player is on a new device or increased the score using a different device,
// the client will be updated.
// there's no way to guarantee coherence if the player uses two devices on the same time, obviously.
{
if (local.serial > server.serial) // supposing that a non-existant profile has serial == 0
SyncClientToServer(); // update or create
else
SyncServerToClient();
} else // if (local.FBid != used.FBid)
// the local stored user is not the same that has been used for the authentication.
// the player is asked two options:
// 1. wipe the local score and get the currently authenticated user from the server (that may be empty)
// 2. keep the local score as it is, but play offline (without any sync) until the correct authentication is done
{
if (AskWipeData())
SyncServerToClient();
else
logoff(); // allow user to change the profile or go on playing offline
}
}