PlayFab 使用量:最佳做法

使用 PlayFab 的基于使用量的定价模型,你只需为游戏的实际服务使用量付费。 但这会引发一个明显的问题:如何最好地优化这些游戏以节省资金,同时仍实现所需的所有功能呢? 本文档中,我们将深入了解这些详细信息,并介绍有助于你提前做好规划的最佳做法。

将游戏从开发模式移动到上线之前,可以在“Game Manager”(游戏管理器)的“计费摘要”选项卡中查看计量信息。 使用单独的游戏检查实际玩家活动的计量使用情况,以定期确认计量是开始时不错的一种做法。 可以在开发模式下创建多个游戏,以便在到达要检查使用量的开发阶段时快速创建游戏,然后在完成后删除这些游戏。

有六个使用量指标:事件、配置文件、内容和配置、CloudScript、见解和多人游戏服务。 开始优化游戏的最佳方式是查看其使用的每个计量,并查看随时间的累积情况。 这让你能够快速取得一些明显的改进。 有关计量的详细信息,请参阅定价计量

事件

PlayFab 中有两种类型的事件:PlayStream 和遥测。

PlayFab 处理 PlayStream 事件,以检查它们是否触发你定义的 PlayStream 操作,以及更新用户细分。 某些 PlayStream 事件是由于调用身份验证和统计信息更新等服务功能而自动生成的。 游戏可以生成自己的自定义事件来扩展此功能。

PlayStream 不处理遥测事件。 这些事件用于分析,并直接转到数据仓库。 遥测事件不会在 PlayFab 中自动生成;它们是由游戏生成的自定义事件。

对于这两种事件类型而言,较大的数据有效负载会增加计量使用总量。 可以通过确保仅发送所需的数据来减少使用总量。 粗略指南是,任何给定事件都会将事件正文中每 1 KB 数据的相关计量递增 1。

若要选择最适合你使用情况的事件路径,应明确计划如何使用生成的每个自定义事件。 仅游戏脱机评估所需的事件应采用遥测路由。 这有助于显著降低成本,因为遥测事件的超额费用不到 PlayStream 的一半。

如果使用的是预生成的 SDK 之一,请务必记住,如 PlayStream 事件模型参考中所述,会自动生成有关用户行为的某些分析数据。 若要关闭可选事件,请在 PlayFab 游戏管理器中更改游戏的“设置/数据收集”选项卡中的分析设置。 同样,尽管最好在调试期间为 CloudScript 执行启用“生成 PlayStream 事件”选项,但应确保在上线之前禁用该选项。 对于 PlayStream 操作触发的 CloudScripts,如果需要调试某些行为,则以后可以随时启用。

配置文件

配置文件实际上是“关于玩家的所有内容”,包括物品栏、保存的数据和统计信息等常见元素。 它还包含用于通过 PlayStream 中的 LiveOps 功能(如上述的用户细分)来推动独特体验的元信息。 此外,某些游戏级旧功能(如游戏数据、目录和商店)也包含在此计量中,因为其数据实现实际上与用户数据相同。 由于这组计量由所有玩家操作以及对玩家执行的操作驱动,因此非常需要最优化的规划。

定价计量捕获的使用情况的主要因素是读取、存储和写入的数据量,以及对按流量计费生成数据的 API 的调用频率。

有关导致这些计量“增加”的特定 API 调用的详细信息,请参阅定价计量

我们将从用户数据和统计信息开始,因为它们的使用模式类似,然后我们将介绍玩家物品栏管理。

数据和统计信息

评估用户数据的使用情况时,采用与事件相同的近似逻辑,即每 1KB 将计量计数增加 1。但请记住,调用的每个“元素”都应视为不同,以用于此计算。 用于更新用户数据的调用中的每个键值对单独计数。 对于读取,无论键值对的数量是多少,此 1KB 计算适用于返回的总计数据。 这意味着,写入 10 个键(每个键 100 字节)即“记录”10 次配置文件写入计量,因为每个键值对写入至少为 1KB,而读取这 10 个键为 1“格”,因为它总共为 1KB。 有关使用情况的更多具体详细信息,请参阅定价计量

统计信息稍微复杂一些,因为它们会更新配置文件,还会对排行榜产生影响。 一般情况下,可以将每个更新的统计信息视为完整配置文件更新,而读取则基于每次调用中读取数据的总大小。 由于存储按千兆字节 (GB) 定价,而统计信息通常只消耗几个字节,因此我们将重点介绍读取和写入。

由于总数据大小非常重要,因此第一步是对其进行优化。 幸运的是,有各种各样为人熟知的技术来实现这一点:使用枚举或 ID 来代替项目的拼写文本,将大数据打包为二进制数据,甚至使用位域将数据打包到较小的空格中。 完成优化后,下一步是仔细评估何时需要调用这些读取和写入。

如果你来自电脑或主机开发团队,尤其是单机玩家游戏,这可能是一种全新模式。 但是在此类环境中,你必须注意客户端设备上的资源命中和垃圾回收,因为这些问题可能导致性能在关键时刻下降。 当游戏使用云资源时,除了性能成本外,还需要扩展该逻辑,将每个资源命中视为实际成本。

如何确定读取和写入的最佳频率? 希望更频繁地更新数据和统计信息的开发人员的两个最常见问题是防作弊,并即时将信息存储在服务器端以进行玩家到玩家的交互,或者在游戏意外退出时防止数据丢失。

防作弊

尽管你似乎需要不断更新后端数据才能确保基本的安全性,但如果游戏不需要完全由服务器授权的会话控制,则很少需要频繁更新。 首先要搞清楚的基本问题是,实际需要多高的安全性。

对于一些游戏而言,尤其是那些主要通过游戏内广告盈利且没有排行榜的游戏,作弊并不是一个问题。 在这种情况下,信任客户端发送的数据通常是一种可行的方法,因为该数据的安全性并不是真正需要考虑的问题。 为了识别作弊行为并决定如何处理此类行为,我们建议你实施流程来查看玩家的事件、数据和统计信息。

对于需要支持公平竞技或保护整体玩家体验的其他游戏而言,更高的安全性才是更重要的考虑因素。 根据具体要求,某些方法可以降低在这些情况下读取和写入数据的频率。

如果你的游戏不是实时的,我们建议的方法是在聚合一段时间内与玩家的游戏相关的信息(通常是需要几分钟时间的游戏中的一个“回合”),然后将相关数据发送到确定其是否有效的脚本。 要评估的关键元素可能因游戏而有所不同,但需要考虑的一些常见概念示例包括:

  • 自上一个会话报告以来已经过多长时间,客户端告诉你玩家在最近一个回合中玩了多长时间?

  • 玩家注册的分数是多少,根据玩家的等级、装备等数据对该玩家而言是否合理?

对于对即时性要求更高的游戏(例如需要频繁更新服务器授权玩家状态)而言,与经常更新 PlayFab 存储的数据相比,更好的解决方案是使用托管游戏服务器。 在该模式下,会话启动时会将玩家连接到服务器。 服务器从玩家的服务中读取所有所需数据,然后在此后的时间内为玩家托管模拟状态,客户端会以所需的任意频率与服务器交换数据。 然后,服务器使用玩家的最新数据更新 PlayFab 中的“长期存储”(会话结束时),或者每隔几分钟更新一次(如果会话特别长)。

即时多人游戏使用的为此模式。 对于需要服务器授权检查的单机玩家游戏,这也是一种有效的技术,但如果频率仅为每位玩家每分钟几次,则 Azure Functions CloudScript 可能是更好的选择。 CloudScript 总成本的计算公式十分简单。 你使用的总计兆字节秒即为 CloudScript 总成本,每次执行至少 128MB 和 100 毫秒,以及脚本使用的任何其他服务 API 的常规计算结果。 例如,如果脚本代码和脚本中的变量使用量之间的内存占用总量为 250MB,则需要运行该脚本 4 秒(最有可能跨多个用户)才能达到 1GB/秒。 在该脚本代码中,如果读取或写入实体对象、标题数据、用户数据等,则需要计算这些调用在配置文件计量上旋转的刻度。 由于托管的游戏服务器成本取决于你当前运行的服务器数量,而这又取决于一次可在服务器上托管的玩家数量,因此想在两者之间确定保本点并不一定很简单。 但是,如果你发现需要以高频率调用脚本,并且每次都需要从服务读取和写入数据,则游戏服务器解决方案很有可能是更好的方法。

数据即时性

我们经常听到采用高配置文件写入率的开发人员谈到一个话题是,他们担心玩家会丢失进度。 如果玩家在保存游戏之前退出游戏,并且下次玩游戏时无法使用本地状态,或者该状态需要在设备之间传输,则玩家的 PlayFab 存储状态信息最好尽可能保持最新。

对于许多游戏而言,可以通过定期、不频繁地检测服务更新(例如,每 15 分钟一次)来解决这一问题。 但是,包括用于延长或缩短该频率的其他逻辑也有助于应对此问题。 例如:

  • 包括导致立即写入的“重要更新”覆盖,并在玩家主动执行重要操作时重置计时器,以免丢失游戏进度。

  • 如果游戏在没有玩家输入的情况下继续进行,请考虑延长检测信号周期(如果长时间没有输入)。 这对挂机类游戏而言尤为重要,玩家经常让此类游戏在夜间运行。

  • 为玩家提供直接强制更新的方法,例如用户菜单中的按钮。 但在本示例中,请务必限制从客户端设备到 PlayFab 的调用频率,以便有玩家一次又一次点击该按钮时不会每次都生成调用。

如果客户端在玩家下次玩游戏时确实具有状态信息,则可以将本地时间戳与服务中数据的时间戳进行比较,并决定使用哪一个,甚至为玩家提供选择选项。

玩家的配置文件信息可能不仅与他们自己有关。 在某些游戏中,你可能需要它来进行跨玩家查询、无论是激发竞争,还是通过异步好友交互、挑战等直接影响玩家体验。

谈到竞争,排行榜制造这种紧张状态的绝佳方式,通过单次调用服务共享有关其他玩家(通常是接近当前玩家分数的玩家)的一部分信息。 由于可以使用配置文件视图约束返回其他配置文件元素(如统计信息和标记),因此可以提供有关其他玩家的丰富信息。 但是,请勿循环访问排行榜中所有玩家的列表,尝试从每个玩家中读取其他信息,因为这会快速乘以配置文件读取总数,从而增加成本。

对于直接在会话中使用跨玩家数据的游戏,最常见的优化方式是只读取有关本地玩家与之交互的少数特定玩家的信息。 对于即时动作类游戏,这一过程通常在托管会话的服务器上完成。 对于其他游戏(例如玩家可以彼此攻击对方基地的游戏),最常见的方法是将所有数据读取到本地设备,或者仅向本地玩家发送本地玩家应知道的其他玩家数据的子集。 执行上述操作的游戏使用服务器端逻辑来评估客户端发送的最终结果。 执行后一种操作的游戏会在会话过程中使用更多数据以迭代方式更新数据,此时本地玩家应有权访问这些数据。 但是即便如此,此类游戏也使用服务器端逻辑来评估最终结果。 同样,决定是应通过脚本还是在托管服务器上执行此操作的临界点可以降低调用频率。 如果超过一分钟几次,则最好是将托管服务器用于需要该数据的会话部分。

经济和物品栏

一般而言,物品栏和经济通常需要不同的方法。 无法避免的事实是:如果玩家放弃实际(货币)或感知的(虚拟货币或易耗品容器)数值,则会在心中暗自期望交易得到遵守。 对于任何具有应用内购买功能的游戏,使用实际货币购买的玩家的配置文件计量的增量是一项简单成本。 在许多类型的游戏中,物品栏的更新频率很低,因此对显著增加总体使用量几乎不会造成什么顾虑。 但是,对于物品栏更新频率更高的游戏(即使没有游戏内货币化),有一些优化技巧可帮助你降低成本。

最佳做法是仅将字面意义上的物品栏视为相当有限的物品栏。 例如,在增量(或“挂机类")游戏中,将玩家获取的每个资源视为项目可能会很诱人,每次玩家购买另一个资源时都会递增总数。 但是,当你计算玩家执行这些操作的频率时,该模式会迅速瓦解。 你必须立即处理每个玩家在一个会话中达到的数百甚至数千次计量。 在此类情况下,最好将这些元素视为“用户数据”,并使用上述“配置文件”部分中的建议将其更新到服务。

对于物品栏更新频率更高的游戏,我们将回到数据即时性的问题。 例如,某款动作游戏可能跟踪玩家的项目符号数量,但该“堆栈”项目符号的后端数据不需要使用触发器的每次拉取进行更新,尤其是当游戏状态在托管服务器中管理时。 可堆栈可提供性能和成本优势,因为可以将项的多个虚拟实例表示为具有计数的单个实际实例。 通常可以聚合一段时间内对项堆栈的更改,并在会话结束时或在整个会话中定期更新它们。 更新堆栈时,最好调用玩家项目管理 - 修改项使用来检查是否可以只更改堆栈计数,而不是添加项的 N 个实例,这些实例必须逐个处理才能添加到堆栈中,然后再清理。

从本质上讲,某些游戏类型(如收集类卡牌游戏)确实需要以更高的速率更新玩家物品栏。 但即使在此类情况下,仍有机会聚合物品栏更改并减少配置文件计量的总使用量。 例如,在使用奖品表的游戏中,设计经常使用一个容器,从多个不同的奖品表中分别具有一个或多个“拉取”。 通常,如果这些拉取只是偶尔执行的操作,则增量成本足够小,不会引起关注。 但是,如果玩家可以收集其中的许多容器,并在短时间内打开多个容器,则可以提供“打开 N 个”甚至是“全部打开”选项。 在这种情况下,可以使用使用 Azure Functions 的 PlayFab CloudScript 或自定义游戏服务器查询玩家项管理 - 获取奖品表集的随机结果表,或调用玩家项管理 - 评估随机结果表而不生成清单项。 然后,只需根据需要添加实例,然后更新其余项堆栈的计数,即可更高效地更新玩家物品栏。

内容和配置

内容和配置主要与游戏相关,其中的配置文件主要与玩家有关。 此计量中包含许多游戏级组件,如推送通知、电子邮件服务和游戏新闻。 不过,该计量用于跟踪实体文件使用情况。 同样,有关上传和下载 CDN 文件的 URL 请求也会在此计量器上进行跟踪,但请务必阐明 CDN 成本是单独的,并根据内容分发网络 (CDN) 中所述下载的总 GB 计费。 内容和配置读取和存储计量的计算类似于配置文件计量,因为它们都是基于数据大小,尽管这些单位明显大于 1KB。 对于内容和配置写入计量,它仅基于写入操作的总数,每次操作将计量递增 1。

另请注意,实体文件系统是大数据的推荐服务,无论是与游戏、组还是单个玩家相关联。 对于每个玩家节省大量数据的游戏,实体文件系统通常更具成本效益;但请记住,这些更新的频率会影响跟踪的使用情况。 最好根据需要更新文件的频率优化所需的文件数量。

在优化内容和配置计量的成本方面,要跟踪的最重要事项是游戏必须请求自己很少更改的配置数据的频率。 主要是游戏数据,它通常用于管理所有用户中相同的游戏方面,例如游戏平衡/优化数据、成就定义、本地化数据等。

对于使用 CloudScript 的游戏,如果发现每次调用脚本时都依赖于此类游戏级数据,则可能需要考虑直接将该数据“烘焙”到脚本中。 为此,可以简单方便地将其定义为脚本本身中的硬编码数据,或使用静态变量作为缓存方式,在每个虚拟机 (VM) 实例中读取一次服务中的信息。 这样,游戏级数据将在任何给定 VM 首次运行脚本时加载,并在后续执行时由该 VM 重新使用。 请注意以下三点:首先,脚本由许多不同的用户使用。因此,不应将单个用户两次执行之间的任何内容视为一致。 其次,必须将数据的处理视为无状态,因为单个玩家可能会在每次调用时点击不同的计算机。 最后,你需要跟踪该数据的期限,并定期重新加载它,以确保拥有最新版本。

CloudScript

这是 PlayFab 服务的主要“伸缩缝”之一,允许你从客户端设备或服务器运行服务器授权逻辑,甚至可以通过 PlayStream 规则触发逻辑(例如,当玩家进入细分时)。 与自定义游戏服务器托管相反,你只需为脚本运行的 GB/秒(GB/秒)付费,每个执行最小值为 128 MB 和 100 毫秒。 因此,如果脚本总共使用 250MB 的空间(在脚本代码和数据之间),则需要总共运行 4 秒(可能跨越多个执行)才能达到 1GB/秒。

由于 CloudScript 的用例通常围绕代表玩家执行操作,因此我们在最近两个部分中介绍了关于优化配置文件和内容/配置计量时应考虑的大多数情况。 但是,游戏的执行总数也作为计量 CloudScript 使用量的一部分进行跟踪,因此查看每个玩家调用 CloudScript 的频率很有价值。 对于某些游戏,使用托管的游戏服务器为活动玩家提供“热”数据存储可能会大大提高成本效益,而不是尝试在对 CloudScript 的迭代调用中管理数据存储。

Insights(见解)

此计量与 PlayFab 服务的所有分析功能相关联,从事件引入和导出到事件历史记录搜索和数据资源管理器查询。 此处的使用情况受需要处理事件的速度、希望保持托管“热度”的事件数据量(用于“游戏管理器中”中的查询),以及使用服务评估数据的量(通过数据资源管理器查询或可视化软件直接连接到数据)的影响。 此计量受游戏内活动(事件)和游戏外活动(分析)的影响。

最终,这意味着见解的成本由从玩家获取的事件数据量,以及你对该数据执行的分析处理量所推动。 至于最佳做法,针对上述事件的建议适用于前者,而对于后者,可以通过以下两种方式控制成本。 第一种,也是最简单的方式是,你可以在游戏管理器的“见解管理”选项卡中为游戏设置总存储空间,以控制在 PlayFab 中保留的事件数据总量。 接下来,在同一选项卡中,可以设置游戏的性能级别。 这决定了分配给游戏的 CPU 资源总量,以及事件历史记录中查询“热”存储的数据量。 每个游戏所需的数量取决于数据分析团队成员的需求,因此最好与他们一起查看,以了解应该做出怎样的设置。

有关见解以及如何及其用途的信息,请参阅什么是 PlayFab Insights

有关见解最佳做法的相关信息,请参阅最佳做法和常见问题解答

多人游戏服务

这是所有类型中最简单的一种,因为定价完全保持不变。 简而言之,托管的多人服务器 Party 服务始终按使用量收费。

具体而言,对于托管的游戏服务器,可以通过优化在任何给定时间运行的服务器核心数来最大程度地降低成本,以支持尽可能多的玩家。

如果低 ping 时间在这些服务器上很重要,则可以选择要运行服务器的区域。 对于大多数游戏而言,玩家最集中的情况仅限于某些关键区域,但是如果你有广泛分散的玩家群体(尤其是当游戏进入长尾阶段时),则需要权衡在靠近玩家的每个区域运行服务器的成本,而不是对玩家数量较少的区域中玩家子集的 ping 时间较长的影响。 一个行之有效的办法是,确保使用我们的 QOS 服务来选择要将玩家放入哪些区域,然后确定某一区域中玩游戏所需的最小玩家数量的截断点,以便使其切实可行。

为了帮助你完成开发,而不至耗光成本,我们在托管服务中提供了大量的免费服务器小时数,并且我们的 Party 服务对所有开发模式游戏均为免费提供。 另外值得一提的是,我们的 Party 服务也免费为 Xbox Live 已登录玩家的提供;对于标准、高级和企业级的游戏,我们免费提供大量连接、语音和认知服务(语音听录和翻译),以帮助实现《21 世纪通信和视频辅助功能法案》(CVAA) 合规性。

管理上线游戏

这涵盖了计量的基础知识,但当游戏上线后应该考虑哪些方面? 管理玩家社区主要涉及分析(上一节中的见解)以及内容和配置的更新。 此外,大多数游戏需要在玩家与游戏本身的正常交互之外与玩家开展互动。 从老用户召回营销活动(旨在吸引玩家返回),到元游戏活动的社区奖励,甚至是感谢玩家在游戏外部开展自己的社区工作,如今的常见做法是使用 LiveOps 技术来保持玩家的高度参与。

关键的一点是确保将细分有效地定向到定义完善的群组。这样做不仅可以降低成本,还能确保快速处理逻辑。 例如,玩家召回 – 让已经有一段时间没有玩游戏的玩家重新回到游戏当中。 召回老玩家的一个有效方法是定义几个退出游戏用户的时间范围,可能是 3、7 和 21 天未玩过游戏的玩家。 对于每个用户,你可以采用不同的方法来重新吸引他们的注意,从简单的“我们想念你”消息开始,逐渐升级到“这里有一些免费的黄金/能量/等等”的信息(当然,还要自动将其添加到玩家账户中)。 对于每个玩家,我们建议根据玩家上次登录玩游戏的时间定义一个一小时的窗口期。 这样一来,你不仅以上次玩游戏的时间为目标,还可以将细分中的玩家集保持最小化,以使操作尽可能高效。 使用每小时在每个细分上触发一次的计划任务,发送消息并将任何物品或虚拟货币 (VC) 添加到玩家的物品栏中。

摘要

最终,游戏需要的功能决定了后端服务的使用情况(如 PlayFab)。 实际上,这一切都归结为一个全面的问题:你对这些功能有哪些要求? 无论你的优先事项是安全性、数据时效性、玩家交互/竞赛水平,还是完全不同的其他因素,任何数量的因素都会将你的后端数据交互水平推向更高。 能够以审慎的眼光看待这些需求,并辨别哪些是硬需求,哪些不是,这和优化游戏中的任何其他代码非常类似。 你需要深入了解资源利用率高的方面,并确定是否确实需要如此高的资源利用率,或者是否有方法可以重新设计这里的逻辑来减少使用量。

如果是实时的玩家到玩家的交互,则交互的复杂程度将是决定因素。 对于大多数这一类型的游戏,管理模拟状态且仅在会话结束时更新后端数据的托管服务器(如果会话很长,则每隔几分钟更新一次)通常是最佳解决方案。 但是,在很多情况下,交互是完全受信任的,例如合作类游戏,或仅与好友一起组队(或对抗)的游戏,从而最大限度减少作弊获得的奖励。 另外,其他一些游戏对如何检查会话数据只有最低限度的要求,允许两个玩家在每次会话后只需提交他们的报告,以便服务器端检查可以比较两者。

而那些对即时性没有要求的游戏,则需要考虑玩家是否确实需要到秒一级的准确性。 而这可能正是竞技属性极强,且社区互动异常活跃的游戏的用例。 但对于非常多的游戏而言,过期几分钟的信息并不会影响玩家体验。

展望未来

作为一项服务,PlayFab 还在不断发展,我们将继续更新我们的文档,帮助你管理成本,同时使用支持所需功能的服务。 如果你对如何改进此问题有任何建议或想法,请随时通过我们主网站上的“联系我们”表单与我们的团队联系。 有关如何优化你所想的功能的反馈,或有关使用 PlayFab 的任何常规技术问题的反馈,可以通过 社区论坛 或(如果你在任何付费服务层中),通过在 PlayFab Game Manager 中提交票证(单击游戏任何页面右上角的 ?)来联系我们的支持团队。 与开发人员社区的合作,为我们提供了持续增长和未雨绸缪,提前预测到大家需求所需的反馈,因此我们随时欢迎你提供反馈!