使用可重置统计数据和排行榜

本教程提供有关如何使用版本控制来配置和管理统计信息的完整演练,从而 重置统计信息 ,以及按扩展、排行榜。

我们将重点介绍如何使用管理 API 方法,以及有关如何使用客户端和服务器 API 方法查询数据的其他信息 - 适用于当前版本和旧版本。

我们的目标是为您提供有关 PlayFab 中可重置统计数据工作原理的技术评审,以及在游戏中使用它们的各种方式。

统计数据和排行榜

首先,请务必注意,在 PlayFab 中为游戏中的玩家定义的所有统计数据都是排行榜的一部分。 因此,定义统计数据也就定义了排行榜。

玩家不一定能看到统计数据,但它们一直都在。 您可以使用它们按照定义的分数获取玩家列表(不管是查找所有高分、低分,还是与当前玩家分值相似的玩家),或获取用户好友列表上的玩家列表。

游戏中的许多统计信息都旨在 生存期 值 - 这意味着玩家会不断更新其得分,保留旧的统计信息,直到每个玩家超过自己的个人最佳。 但是,对于某些玩家体验,能够不时“擦除”排行榜至关重要。

这可用来鼓励用户尝试成为特定时间段内排名靠前的玩家,或只是从排名中删除任何有一阵子不活跃的玩家。

正如本教程将讨论的那样,可以将 PlayFab 中的统计数据配置为按预定的时间间隔重置。

这不仅适用于上述场景,还可用于需要具有最新分值的不同排行榜的游戏(例如,让玩家向具有相似技能水平的玩家发出邀请的游戏挑战)。

设置重置周期意味着,例如,对 GetLeaderboardAroundPlayer 的调用将返回最近玩过游戏并且分值与本地玩家相似的玩家。

也可以使用手动操作重置统计数据。 这是一个便利系统,可用于清除从发布前测试或试运营期间获得的任何数据。

对于最坏的情况,它也很有用,在这种情况下,游戏代码中引入了一个 bug,导致分数超出控制范围。 在每种情况下,都需要能够擦除排行榜 干净,以便玩家感觉他们有机会获得排行榜。

注意

重置统计数据不会删除这些值,如下所示。 在重置时,将对 PlayFab 中的统计数据进行版本控制,使新版本成为权威版本,同时保留之前的版本以供日后分析(让您能够根据玩家的旧分数为其提供奖励)。

配置可重置统计数据

可以使用管理 API 集或 Game Manager 配置统计数据的重置周期。 然后,可以通过游戏管理器、服务器 API 和客户端 API 对其进行更新和查询(尽管从客户端发布统计信息确实需要在游戏管理器中游戏的“设置”->“API 功能”选项卡中设置“允许客户端发布统计信息”选项)。

我们将介绍执行此操作的 API 方法(此处定义的参数与 Game Manager 中使用的参数相同)。

要设置统计数据,可以使用 CreatePlayerStatisticDefinition 方法和 UpdatePlayerStatisticDefinition 方法稍后进行更改。

在这两种情况下,只有两个参数:

  • StatisticName - 玩家统计信息的字符串标识符。
  • VersionChangeInterval - 定义应自动重置统计信息的时间段。

VersionChangeInterval 是此功能的关键参数,可以定义为每小时、每天、每周或每月。 如果您日后决定不再定期重置统计数据,也可以将其设置为从不重置。

在下面的示例中,对 CreatePlayerStatisticDefinition 方法的调用将统计数据 Headshots 设置为每日重置,也就是说,游戏中此统计数据的排行榜将在每天的 00:00 UTC 重置。

public void CreatePlayerStatisticDefinition() {
    PlayFabAdminAPI.CreatePlayerStatisticDefinition(
        new CreatePlayerStatisticDefinitionRequest() {
            StatisticName = "Headshots",
            VersionChangeInterval = StatisticResetIntervalOption.Day
        },
        result => Debug.Log("Complete"),
        error => Debug.Log(error.GenerateErrorReport())
    );
}

下面显示了前面的 API 调用的响应。

{
    "code": 200,
    "status": "OK",
    "data":
    {
        "Statistic":
        {
            "StatisticName": "Headshots",
            "CurrentVersion": 0,
            "VersionChangeInterval": "Day"
        }
    }
}

下面显示的编码是另一个示例。

public void UpdatePlayerStatisticDefinition() {
    PlayFabAdminAPI.UpdatePlayerStatisticDefinition(
        new UpdatePlayerStatisticDefinitionRequest() {
            StatisticName = "Headshots",
            VersionChangeInterval = StatisticResetIntervalOption.Week
        },
        result => Debug.Log("Complete"),
        error => Debug.Log(error.GenerateErrorReport())
    );
}

此调用说明将统计数据的重置周期设置为每周,响应如下。

{
    "code": 200,
    "status": "OK",
    "data":
    {
        "Statistic":
        {
            "StatisticName": "Headshots",
            "CurrentVersion": 0,
            "VersionChangeInterval": "Week"
        }
    }
}

在任何一种情况下,结果为 PlayerStatisticDefinition,包含:

  • 统计数据的字符串 ID (StatisticName)。
  • 统计数据已重置的次数 (CurrentVersion)。
  • 定义的将重置统计数据的周期 (VersionChangeInterval)。

重置周期在定义后立即生效,因此在本例中,第二个调用意味着重置现在定义为周一早上 00:00 UTC(周日午夜/周一早上,使用 UTC 时区),而不管此调用之前的定义为何。

剩余的重置时间间隔也使用 UTC 定义,月份使重置发生在每月第一天的 00:00 UTC。

对于已完成的列表,重置周期为:

  • Never:停止基于时间对统计数据进行版本控制。
  • Hour:每小时 (XX:00 UTC) 对统计数据进行版本控制。
  • Day:每午夜 (00:00 UTC) 对统计数据进行版本控制。
  • Week:每月午夜 (00:00 UTC) 对统计数据进行版本控制。
  • : 每月第一天午夜 (00:00 UTC) 对统计信息进行版本控制。

以前存在的统计数据

对于游戏中定义的所有统计数据,不管是否设置为重置统计数据,都可以查询其定义。

请务必注意,因为可以使用 UpdatePlayerStatistics 调用创建统计信息。 任何未使用重置周期(VersionChangeInterval)创建的统计信息都不会启动,因此,如果将此参数设置为 Never,则将返回对统计信息配置的查询。

使用上面的示例,如果游戏还具有一个名为 FlagsCaptured 使用 UpdatePlayerStatistics 创建的统计信息(或直接在玩家的 Game Manager 中创建),并且已经过几周,则它将如下面所示的调用中所示。

public void GetPlayerStatisticDefinitions() {
    PlayFabAdminAPI.GetPlayerStatisticDefinitions(
        new GetPlayerStatisticDefinitionsRequest(),
        result => Debug.Log("Complete"),
        error => Debug.Log(error.GenerateErrorReport())
    );
}

将产生以下结果。

{
    "code": 200,
    "status": "OK",
    "data":
    {
        "Statistics": [
        {
            "StatisticName": "Headshots",
            "CurrentVersion": 2,
            "VersionChangeInterval": "Week"
        },
        {
            "StatisticName": "FlagsCaptured",
            "CurrentVersion": 0,
            "VersionChangeInterval": “Never”
        }]
    }
}

在这种情况下,名为 Headshots 的统计信息定义了重置间隔, CurrentVersion 指示统计信息已重置两次。

同时,FlagsCaptured 没有 VersionChangeInterval,这也是 CurrentVersion0 的原因(因为从未对其进行版本控制)。

通过 UpdatePlayerStatistics (或 PlayFab Game Manager)创建的统计信息仍可定义为使用 UpdatePlayerStatisticDefinition具有重置期,如上所述。

完成此操作后,其将按此时间间隔重置,就像它们是最初使用 CreatePlayerStatisticDefinition 定义的一样。

手动重置统计信息

当游戏中存在允许在统计数据方面作弊的错误时,或您需要重置以删除发布前的试玩分值时,可以在 Game Manager 中或通过调用 IncrementPlayerStatisticVersion 强制重置统计数据。

这会立即重置您指定的当前统计数据、清除游戏排行榜并为要报告的新值提供一块“白板”。

对于我们的示例,此调用可能如下所示。

public void IncrementPlayerStatisticVersion() {
    PlayFabAdminAPI.IncrementPlayerStatisticVersion(
        new IncrementPlayerStatisticVersionRequest() {
            StatisticName = "Headshots"
        },
        result => Debug.Log("Complete"),
        error => Debug.Log(error.GenerateErrorReport())
    );
}

这会再次递增 Headshots 统计信息,并返回有关刚刚激活的版本的信息。

{
    "code": 200,
    "status": "OK",
    "data":
    {
        "StatisticVersion":
        {
            "StatisticName": "Headshots",
            "Version": 3,
            "ActivationTime": "2016-02-03T08:02:29.864Z",
            "ArchivalStatus": "NotScheduled"
        }
    }
}

在本例中,返回了 PlayerStatisticVersion 信息,其中包含统计数据的 ID (StatisticName),以及其版本号、它成为权威版本的时间 (ActivationTime) 和 ArchivalStatus(对于当前版本,它将永远为 NotScheduled)。

但是,对于具有 VersionChangeInterval 的统计数据,手动重置不会 更改下一个计划的重置时间。 如果统计信息计划每天重置,并且它是在 UTC 晚上 11:30 手动重置的,它将 在 UTC 午夜重置。

发生重置时

如上所述,重置时间间隔到期时,将对统计数据进行版本控制,这将立即启用新版本,同时存档统计数据的旧版本以供日后检索。

重置时间间隔到期(或执行手动重置)时,将对统计数据进行版本控制,接受对旧版本的写入最多持续十分钟。 超出此时间后,将锁定 统计数据,阻止后续更新。

到期后,统计数据开始进入存档过程,以便日后能够通过游戏进行检索。

统计数据的存档过程包含以下阶段:

  • NotScheduled - 尚未开始存档统计数据(通常仅适用于当前处于活动状态的统计数据版本)。
  • Scheduled - 已计划存档过程,但尚未进行。
  • InProgress - 正在将统计数据备份到存档。
  • Failed - 出现意外故障(如果遇到这种情况,请联系我们的支持论坛)。
  • Complete - 已存档此统计数据版本。

可以使用 GetPlayerStatisticVersions 查询统计数据的所有以前版本和当前版本。 这将返回每个版本的信息,如上一个手动重置示例所示。

换句话说,此调用应如下所示。

public void GetPlayerStatisticVersions() {
    PlayFabAdminAPI.GetPlayerStatisticVersions(
        new GetPlayerStatisticVersionsRequest() {
            StatisticName = "Headshots"
        },
        result => Debug.Log("Complete"),
        error => Debug.Log(error.GenerateErrorReport())
    );
}

这可能导致针对我们的示例游戏返回以下信息。

{
    "code": 200,
    "status": "OK",
    "data":
    {
        "StatisticVersions": [
        {
            "StatisticName": "Headshots",
            "Version": 0,
            "ActivationTime": "2015-01-20T05:47:27.17Z",
            "DeactivationTime": "2016-01-25T00:00:00.000Z",
            "ArchivalStatus": "Complete",
            "ArchiveDownloadUrl": {{URL}}
        },
        {
            "StatisticName": "Headshots",
            "Version": 1,
            "ActivationTime": "2016-01-25T00:00:00.000Z",
            "DeactivationTime": "2016-02-01T00:00:00.000Z",
            "ArchivalStatus": "Complete",
            "ArchiveDownloadUrl": {{URL}}
        },
        {
            "StatisticName": "Headshots",
            "Version": 2,
            "ActivationTime": "2016-02-01T00:00:00.000Z",
            "DeactivationTime": "2016-02-03T08:02:29.864Z",
            "ArchivalStatus": "InProgress"
        },
        {
            "StatisticName": "Headshots",
            "Version": 3,
            "ActivationTime": "2016-02-03T08:02:29.864Z",
            "ArchivalStatus": "NotScheduled"
        }]
    }
}

除了从 IncrementPlayerStatisticVersion 返回的值以外,响应还包括当前活动版本之前的每个版本的到期时间戳 (DeactivationTime),以及存档过程完成后用于下载包含旧排行榜完整记录的 CSV 的 URL (ArchiveDownloadUrl)。

读取和写入统计数据版本

最后,从服务器和客户端 API 方面来看,这些调用与原始 PlayFab 用户和角色统计数据调用极其相似。

区别在于,现在版本是请求或响应的一部分。

检索统计数据时,将返回当前统计数据版本的值以及版本号本身。

以下示例演示如何调用 Headshots 统计信息以及返回的数据。

服务器请求

public void GetPlayerStatistics() {
    PlayFabServerAPI.GetPlayerStatistics(
        new GetPlayerStatisticsRequest() {
            PlayFabId= "_PlayFabId_",
            StatisticNames = new List<string>() { "Headshots" }
        },
        result => Debug.Log("Complete"),
        error => Debug.Log(error.GenerateErrorReport())
    );
}

服务器响应

{
    "code": 200,
    "status": "OK",
    "data":
    {
        "PlayFabId": {{PlayFabId}},
        "Statistics": [
        {
            "StatisticName": "Headshots",
            "Value": 10,
            "Version": "3"
        }]
    }
}

客户端请求

public void GetPlayerStatistics() {
    PlayFabClientAPI.GetPlayerStatistics(
        new GetPlayerStatisticsRequest() {
            StatisticNames = new List<string>() { "Headshots" }
        },
        result => Debug.Log("Complete"),
        error => Debug.Log(error.GenerateErrorReport())
    );
}

客户端响应

{
    "code": 200,
    "status": "OK",
    "data": {
        "Statistics": [
        {
            "StatisticName": "Headshots",
            "Value": 10,
            "Version": "3"
        }]
    }
}

同时, Update 调用采用可选版本,以允许游戏控制在游戏期间版本可能递增的情况下更新的版本。

注意

在此示例中,如果游戏在仍可能的情况下写入 以前的 版本,则会写入版本 2,如下所示。

服务器请求

public void UpdatePlayerStatistics() {
    PlayFabServerAPI.UpdatePlayerStatistics(
        new UpdatePlayerStatisticsRequest() {
            PlayFabId= "_PlayFabId_",
            Statistics = new List<StatisticUpdate>() {
                new StatisticUpdate() {
                    StatisticName = "Headshots",
                    Version = 2,
                    Value = 10
                }
            }
        },
        result => Debug.Log("Complete"),
        error => Debug.Log(error.GenerateErrorReport())
    );
}

服务器响应

{
    "code": 200,
    "status": "OK",
    "data": {}
}

客户端请求

public void UpdatePlayerStatistics() {
    PlayFabClientAPI.UpdatePlayerStatistics(
        new UpdatePlayerStatisticsRequest() {
            Statistics = new List<StatisticUpdate>() {
                new StatisticUpdate() {
                    StatisticName = "Headshots",
                    Version = 2,
                    Value = 10
                }
            }
        },
        result => Debug.Log("Complete"),
        error => Debug.Log(error.GenerateErrorReport())
    );
}

客户端响应

{
    "code": 200,
    "status": "OK",
    "data": {}
}

但请注意 - 可写入到期版本的时间不超过 10 分钟,超出 此时间后,任何对到期版本的写入尝试都将失败,响应如下所示。

{
    "code": 400,
    "status": "BadRequest",
    "error": "StatisticVersionClosedForWrites",
    "errorCode": 1197,
    "errorMessage": "The statistic version is not current and is no longer accepting updates"
}

资源

为了完整起见,本节提供上述所有枚举、类和 API 方法的列表,并做了简要说明。

基本枚举

  • Interval - 重置统计数据(排行榜)的周期:

    • 从不
    • 小时
  • StatisticVersionArchivalStatus - 将某个版本的玩家统计数据值保存到一个可下载存档的过程的状态:

    • NotScheduled
    • 计划
    • InProgress
    • 已失败
    • 完成

基本类及其成员

  • PlayerStatisticDefinition

    • StatisticName (string) - 统计数据的唯一名称。
    • CurrentVersion (string) - 统计数据的当前活动版本,每次重置统计数据时递增。
    • VersionChangeInterval (Interval) - 重置所有玩家统计数据值的时间间隔。
  • PlayerStatisticVersion

    • StatisticName (string) - 版本变为活动状态时统计数据的名称。
    • Version (string) - 统计数据的版本(编码为字符串的十六进制数字)。
    • ScheduledVersionChangeIntervalTime (DateTime) - 统计数据版本计划变为活动状态的时间(基于配置的 ResetInterval)。
    • CreatedTime (DateTime) - 统计数据版本变为活动状态的时间。
    • ArchivalStatus (StatisticVersionArchivalStatus) - 将此版本的玩家统计数据值保存到一个可下载存档(如果配置)的过程的状态。
    • ResetInterval (Interval) - 触发版本变为活动状态的重置时间间隔(如果配置)。
  • StatisticValue

    • StatisticName (string) - 统计数据的唯一名称。
    • Value (Int32) - 玩家的统计数据值。
    • Version (string) - 对于玩家的现有统计数据值,加载时统计数据的版本。
  • StatisticUpdate

    • StatisticName (string) - 统计数据的唯一名称。
    • Version (string) - 对于对玩家统计数据值的更新,要更新的统计数据的版本
    • Value (Int32) - 玩家的统计数据值。

管理 API 方法

  • CreatePlayerStatisticDefinition

    • CreatePlayerStatisticDefinitionRequest

      • Name (string) - 最小长度 1,最大长度 128 - 统计数据的唯一名称。
      • (VersionChangeInterval) (Interval) - 重置所有玩家统计数据值的时间间隔(从下一个时间间隔边界开始重置)。
    • CreatePlayerStatisticDefinitionResult

      • Statistic (PlayerStatisticDefinition) - 创建的统计数据的定义。
  • UpdatePlayerStatisticDefinition

    • UpdatePlayerStatisticDefinitionRequest

      • StatisticName (string) - 统计数据的唯一名称。
      • VersionChangeInterval (Interval) - 重置所有玩家统计数据值的时间间隔(从下一个时间间隔边界开始重置)。
    • UpdatePlayerStatisticDefinitionResult

      • Statistic (PlayerStatisticDefinition) - 创建的统计数据的定义。
  • GetPlayerStatisticDefinitions

    • GetPlayerStatisticDefinitionsRequest(没有参数)。
    • GetPlayerStatisticDefinitionsResult
      • Statistics (PlayerStatisticDefinition[]) - 重置的定义数组。
  • GetPlayerStatisticVersions

    • GetPlayerStatisticVersionsRequest

      • StatisticName (string) - 统计数据的唯一名称。
    • GetPlayerStatisticVersionsResult

      • StatisticVersions (PlayerStatisticVersion[]) - 统计数据的版本更改历史记录(所有版本)。
  • IncrementPlayerStatisticVersion

    • IncrementPlayerStatisticVersionRequest

      • StatisticName (string) - 统计数据的唯一名称。
    • IncrementPlayerStatisticVersionResult

      • StatisticVersion (PlayerStatisticVersion) - 由于此操作(及其存档状态)而到期的统计数据版本。

客户端 API 方法

  • GetPlayerStatistics

    • GetPlayerStatisticsRequest

      • StatisticNames (string[]) - 要返回的统计数据的数组(按其唯一名称)。
    • GetPlayerStatisticsResult

      • Statistics (StatisticValue[]) - 请求的所有统计数据的 StatisticValue 数据的数组。
  • UpdatePlayerStatistics

    • UpdatePlayerStatisticsRequest

      • Statistics (StatisticUpdate[]) - 要更新的统计数据,包括提供的值。
    • UpdatePlayerStatisticsResult(没有参数)。

服务器 API 方法

  • GetPlayerStatistics

    • GetPlayerStatisticsRequest

      • PlayFabId (string) - 要更新其统计数据的玩家的 PlayFab ID。
      • StatisticNames (string[]) - 要返回的统计数据的数组(按其唯一名称)。
    • GetPlayerStatisticsResult

      • Statistics (StatisticValue[]) - 请求的所有统计数据的 StatisticValue 数据的数组。
  • UpdatePlayerStatistics

    • UpdatePlayerStatisticsRequest

      • PlayFabId (string) - 要更新其统计数据的玩家的 PlayFab ID。
      • Statistics (StatisticUpdate[]) - 要更新的统计数据,包括提供的值。
    • UpdatePlayerStatisticsResult(没有参数)。