Skip to main content

PlayFab 消费:最佳做法

借助 PlayFab 基于消费的定价模型,您只需为游戏的实际服务使用量付费。但这引出了一个显而易见的问题:如何才能在实现所需的所有功能的同时,最好地优化这些游戏以节省资金?在本文档中,我们将深入探讨这些细节,并讨论有助于您提前规划的最佳做法。 在您将游戏从开发模式迁移到正式环境之前,可以在 Game Manager 的账单摘要选项卡中查看计量表信息。 有六种消费计量表:事件、配置文件、内容和配置、CloudScript、Insights 和多人游戏服务。开始优化游戏的最佳方式是查看它使用的每种计量表,并观察它随时间的累积情况。这样,您可以快速得出一些明显的改进方向。有关计量表的更多信息,请参见 定价计量表

事件

PlayFab 中有两种类型的事件:PlayStream 和遥测。 PlayFab 处理 PlayStream 事件以检查它们是否触发您定义的 PlayStream 操作,并更新用户分群。某些 PlayStream 事件会作为对服务功能(如身份验证和统计信息更新)调用的结果自动生成。游戏可以生成自己的自定义事件以扩展此功能。 遥测事件不由 PlayStream 处理。这些事件用于分析,并直接进入数据仓库。遥测事件不会在 PlayFab 中自动生成;它们是由游戏生成的自定义事件。 对于这两种事件类型,较大的数据负载会增加计量表使用总量。您可以通过确保只发送需要的数据来减少总使用量。粗略的指南是,任何给定事件在事件正文中每 1 KB 数据会使相关计量表递增 1。 要选择最适合您使用情况的事件路径,您应该对如何使用生成的每个自定义事件有清晰的计划。仅在游戏的离线评估中需要的事件应走遥测路线。这有助于显著降低成本,因为遥测事件的超额费用不到 PlayStream 的一半。 如果您使用的是预构建的 SDK 之一,请务必记住,一些关于用户行为的分析数据会按照 PlayStream 事件模型参考 中所述自动生成。要关闭可选事件,请在 PlayFab Game Manager 的 Settings/Data Collection 选项卡中更改分析设置。同样,虽然在调试期间为 CloudScript 执行开启”生成 PlayStream 事件”选项是个好主意,但在正式上线前应确保将其禁用。对于 PlayStream 操作触发的 CloudScript,如果您需要调试正式环境中的某些行为,随时可以再次打开它们。

配置文件

配置文件实际上就是”关于玩家的一切”,包括常见元素,如库存、保存的数据和统计信息。它还包含用于通过 PlayStream 中的 LiveOps 功能驱动独特体验的元信息,例如上面提到的用户分群。此外,一些游戏级别的旧功能,例如游戏数据 (Title Data)、目录和商店,也包含在此计量表中,因为它们的数据实现实际上与用户数据相同。由于此计量表集是由所有玩家操作以及对玩家的操作驱动的,因此它绝对是最需要优化规划的。 导致定价计量表所捕获使用量的主要因素是读取、存储和写入的数据量,以及您调用生成计量数据的 API 的频率。 有关导致这些计量表”跳动”的具体 API 调用的更多信息,请参见 定价计量表 我们将从用户数据和统计信息开始,因为它们的使用模式相似,然后再讨论玩家库存管理。

数据和统计信息

在评估您对用户数据的使用时,同样的近似逻辑与事件相同——每 1 KB 使计量表计数增加 1——不过请记住,出于计算目的,调用的每个”元素”都应视为不同的。对更新用户数据的调用中的每个键值对是分开计数的。对于读取,此 1 KB 计算适用于返回的总数据,与键值对的数量无关。这意味着写入 10 个 100 字节的键为配置文件写入计量表的 10 个”跳动”(因为每次键值对写入至少为 1 KB),而读取这 10 个键则为 1 个”跳动”,因为总共为 1 KB。有关使用情况的更具体详细信息,请参见 定价计量表 统计信息稍微复杂一些,因为它们更新配置文件,也可能对排行榜产生影响。作为一般规则,您可以将每次更新的统计信息视为一次完整的配置文件更新,而读取则基于每次调用中读取的数据总大小。由于存储按每 GB 计价,而统计信息通常每个只消耗几个字节,我们将重点关注读取和写入。 由于总数据大小很重要,因此优化它是第一步。幸运的是,有各种众所周知的技术可以做到这一点——使用枚举或 ID 代替项目的完整拼写文本、将大数据打包为二进制,或者甚至使用位字段将数据打包到较小的空间中。完成此操作后,下一步是仔细评估您需要何时进行这些读取和写入调用。 如果您是从 PC 或主机开发——特别是单人游戏——转过来的,这可能是一种新的模式。但在那些环境中,您必须小心客户端设备上的资源占用和垃圾回收,因为它们可能在关键时刻导致性能下降。当您的游戏使用云端资源时,有必要扩展该逻辑,将每次资源占用视为除性能成本之外还有实际成本。 如何确定读取和写入的最佳频率?想要更频繁地更新数据和统计信息的开发者最常见的两个考虑因素是防止作弊,以及在服务器端保存及时信息,以便进行玩家对玩家交互或在游戏意外退出时防止数据丢失。

防作弊

虽然您可能觉得需要不断更新后端数据以确保基本安全,但如果您的游戏不需要完全的服务器权威式会话控制,频繁更新几乎是不必要的。首先,根本问题是您实际需要多少安全性。 对于某些游戏,特别是那些主要通过游戏内广告获利且没有排行榜的游戏,作弊并不是主要考虑的问题。在这种情况下,信任客户端上传的数据通常是可行的方法,因为该数据的安全性并不是真正的问题。为了识别作弊行为并决定如何处理它们,我们建议您实施审查玩家事件、数据和统计信息的流程。 对于其他需要维护比赛完整性或保护整体玩家体验的游戏,更强的安全性更为重要。根据您的具体要求,某些方法可以在这些情况下减少数据读取和写入的频率。 如果您的游戏不是实时的,我们建议的一种方法是聚合一段时间内(通常是游戏的一”局”,需要几分钟)关于玩家游戏的信息,然后将该数据发送到一个脚本,由其判断是否有效。要评估的关键元素可能取决于游戏,但一些要考虑的常见概念示例是:
  • 距离上次会话报告过去了多长时间,客户端说它在最新的一次中玩了多长时间?
  • 玩家注册的分数是多少,考虑到他们的等级、装备等,这些分数对该玩家来说合理吗?
对于有更多实时要求的游戏,例如需要频繁更新服务器权威式的玩家状态,比频繁更新 PlayFab 存储数据更好的解决方案是使用托管游戏服务器。在该模式下,您在会话开始时将玩家连接到服务器。服务器从服务中读取该玩家所需的所有数据,然后随着时间的推移托管该玩家的模拟状态,客户端以您需要的任何速率与服务器交换数据。然后,服务器会在会话结束时用玩家的最新数据更新 PlayFab 中的”长期存储”,或者如果会话特别长,则每隔几分钟更新一次。 这是实时多人游戏使用的模式。对于需要服务器权威式检查的单人游戏而言,它也是一种有效的技术,尽管如果频率仅为每分钟每玩家几次,Azure Functions CloudScript 可能是更好的选择。CloudScript 的总成本很容易计算。它是您消耗的总 GB·秒 (GB/s),每次执行的最小值为 128 MB 和 100 ms,加上脚本使用的任何其他服务 API 调用的常规计算。例如,如果您在脚本代码和脚本中变量使用之间的总内存占用为 250 MB,则需要该脚本运行 4 秒(很可能跨多个用户)才能达到 1 GB/s。在该脚本代码中,如果您读取或写入 Entity Objects、Title Data、User Data 等,则需要计算每个此类调用对配置文件计量表的影响。由于托管游戏服务器成本取决于您运行的服务器数量,而这反过来又取决于一次可以托管在服务器上的玩家数量,因此确定两者之间的收支平衡点并非易事。但如果您发现需要高频调用脚本,并且每次都需要从服务读取和写入数据,那么游戏服务器解决方案很可能是更好的选择。

数据的时效性

我们从配置文件写入率较高的开发者那里听到的一个共同主题是,他们担心玩家会丢失进度。如果玩家在游戏保存之前退出,且下次玩游戏时无法使用本地状态,或者该状态需要在设备之间传输,那么您希望玩家的 PlayFab 存储状态信息尽可能是最新的。 对于许多游戏,您可以通过定期、不频繁地向服务发送心跳更新(例如每 15 分钟)来解决此问题。但包含额外的逻辑来延长或缩短该频率也可能有所帮助。例如:
  • 包含一个”重要更新”覆盖,如果玩家主动执行了重要操作,就会导致立即写入并重置计时器,这样就不会丢失。
  • 如果您的游戏在没有玩家输入的情况下继续进行,请考虑在长时间没有输入的情况下延长心跳周期。这对于放置类游戏尤其重要,因为玩家经常整晚让它们运行。
  • 为玩家提供一种直接强制更新的方式,例如用户菜单中的按钮。但在这种情况下,请务必限制从客户端设备到 PlayFab 的实际调用速率,以便玩家一次又一次地按下该按钮时不会每次都生成一个调用。
如果下次玩游戏时客户端确实拥有状态信息,您可以将本地时间戳与服务中的数据时间戳进行比较,并决定使用哪个,甚至向玩家提供选择的选项。 玩家的配置文件信息可能与他们自己以外的人相关。在某些游戏中,您可能需要跨玩家查询它,无论是为了激发竞争还是通过异步好友交互、挑战等直接影响玩家体验。 对于竞争,排行榜 是通过单次调用服务共享有关其他玩家(通常是与当前玩家分数接近的玩家)的部分信息来产生这种紧张感的理想方式。由于可以使用 配置文件视图约束 返回其他配置文件元素,如统计信息和标签,因此您可以呈现关于这些其他玩家的丰富信息集。但重要的是不要遍历排行榜中所有玩家的列表,尝试从每个玩家那里读取额外信息,因为这会迅速倍增配置文件读取的总数,从而抬高您的成本。 对于在会话中直接使用跨玩家数据的游戏,最常见的优化是只读取本地玩家正在与之交互的少数特定玩家的信息。对于实时动作游戏,这通常是在托管会话的服务器上完成的。对于其他游戏——例如玩家可以攻击彼此基地的游戏——最常见的方法是将所有数据读取到本地设备,或者仅向本地玩家发送本地玩家应知道的其他玩家数据子集。前者的游戏使用服务器端逻辑来评估客户端发送的最终结果。后者的游戏在会话过程中以更多数据迭代地更新数据,当本地玩家应该能够访问它时。但即便如此,他们也会使用服务器端逻辑来评估最终结果。同样,判断这应该通过脚本还是在托管服务器上完成的转折点取决于频率。如果超过每分钟几次,那么您最好使用托管服务器来处理会话中需要该数据的部分。

经济与库存

库存和经济通常需要一种不同的方法。事实是,如果玩家放弃有实际(金钱)或感知(虚拟货币或消耗性容器)价值的东西,他们隐含地期望交易会被履行。对于任何有应用内购买的游戏,玩家使用现实货币购买时对配置文件计量表的递增是微不足道的成本。在许多类型的游戏中,库存更新的频率足够低,不会对增加您的总体使用量产生太大影响。但对于那些库存更新更频繁的游戏——即使您没有游戏内货币化——也有一些优化技巧可以帮助降低您的成本。 一种最佳做法是仅从字面意义上考虑库存,将其视为合理有限的库存。例如,在增量类(或”放置类”)游戏中,很容易将玩家获得的每种资源都视为一个物品,每次玩家购买另一个时都会增加总数。但该模型很快就会崩溃,因为您需要计算玩家采取这些操作的频率。您很快就要处理每个玩家在一次会话中触达计量表数百甚至数千次的情况。对于这样的情况,最好将这些元素视为用户数据,并根据上述配置文件部分中的建议将其更新到服务。 当涉及到库存更新率较高的游戏时,我们又回到了数据时效性的问题。例如,动作游戏可能会跟踪玩家拥有的子弹数量,但该”堆叠”子弹的后端数据不需要每次扣动扳机时都更新,特别是如果游戏状态在托管服务器中管理的话。可堆叠物品为您提供了性能和成本优势,因为您可以将一个物品的多个虚拟实例表示为具有计数的单个实际实例。您通常可以在一段时间内聚合对物品堆叠的更改,并在会话结束时或会话期间定期更新它们。更新堆叠时,最好调用 Player Item Management - Modify Item Uses 来检查您是否可以只更改堆叠的计数,而不是添加物品的 N 个实例(每个实例都必须处理才能添加到堆叠中,然后再清理)。 从本质上讲,某些游戏类型(如集换式卡牌游戏)确实需要以稍高的速率更新玩家库存。但即使在这里,仍然有机会聚合库存变化并减少配置文件计量表上的总使用量。例如,在使用 掉落表 的游戏中,设计上经常使用一个容器,该容器从几个不同的掉落表中各有一个或多个”抽取”。通常,如果这些抽取只是偶尔的操作,增量成本足够小,不会引起担忧。但如果玩家可以收集许多这样的容器,并在短时间内打开多个,您可以提供”打开 N 个”甚至”全部打开”选项。在这种情况下,您可以使用 使用 Azure Functions 的 PlayFab CloudScript 或您的自定义游戏服务器,为掉落表集查询 Player Item Management - Get Random Result Tables,或调用 Player Item Management - Evaluate Random Result Table 而不生成库存物品。然后,您可以通过仅在需要时添加实例,并为其余部分更新物品堆叠的计数,来更高效地更新玩家库存。

内容和配置

配置文件主要是关于玩家的,而内容和配置主要是关于游戏的。许多游戏级别的组件,如推送通知、电子邮件服务和游戏新闻,都包含在此计量表中。此外,此计量表还用于跟踪实体文件的使用。同样,上传和下载 CDN 文件的 URL 请求也在此计量表上跟踪,尽管重要的是要明确 CDN 成本是单独的,并根据下载的总 GB 数计费,如 内容分发网络 (CDN) 中所述。内容和配置读取及存储计量表的计算与配置文件计量表类似,因为它们基于数据大小,尽管单位显然远大于 1 KB。对于内容和配置写入计量表,它完全基于写入操作的总数,每次操作使计量表递增 1。 顺便一提,实体文件系统是用于大数据的推荐服务,无论是与游戏、组或个别玩家相关联的。对于每玩家有大数据保存的游戏,实体文件系统通常更具成本效益;不过请记住,这些更新的频率会影响所跟踪的使用量。最好优化所需文件的数量与其需要更新的频率之间的关系。 在内容和配置计量表的成本优化方面,最重要的是要跟踪您的游戏必须请求自己很少变化的配置数据的频率。这主要是游戏数据 (Title Data),通常用于管理游戏中所有用户共同的方面,如游戏平衡/调优数据、成就定义、本地化数据等。 对于使用 CloudScript 的游戏,如果您发现每次调用脚本都依赖此游戏级别数据,您可能想要考虑将该数据直接”烘焙”到脚本中。您可以通过简单地将其定义为脚本本身中的硬编码数据来做到这一点,或者通过使用静态变量作为缓存的手段,每个虚拟机 (VM) 实例只从服务中读取一次信息。这样,游戏级别数据在任何给定 VM 首次运行您的脚本时加载,并在后续执行中由该 VM 重复使用。这里需要记住三点:首先,该脚本被许多不同的用户使用,因此不应认为任何内容对个别用户在执行之间是一致的。其次,数据处理必须被视为无状态的,因为单个玩家每次调用可能会命中不同的机器。最后,您需要跟踪该数据的年龄并定期重新加载它,以确保您拥有最新版本。

CloudScript

这是 PlayFab 服务的一个主要”扩展接口”,允许您从客户端设备或服务器运行服务器权威式逻辑,甚至通过 PlayStream 规则(例如当玩家进入某个细分时)触发它。与自定义游戏服务器托管相反,您只需为脚本运行的 GB 秒 (GB/s) 付费,每次执行的最低值为 128 MB 和 100 ms。因此,如果您的脚本使用总共 250 MB 空间(在脚本代码和数据之间),它总共需要运行 4 秒——很可能跨多个执行——才能达到 1 GB/s。 由于 CloudScript 的用例通常围绕代表您的玩家采取行动,因此我们在关于配置文件和内容/配置计量表的最后两节中已经涵盖了您应该考虑的大部分优化。但是,游戏的总执行次数也作为 CloudScript 使用计量的一部分进行跟踪,因此按每玩家评估您需要多少次调用 CloudScript 是有价值的。对于某些游戏,使用托管游戏服务器为活跃玩家提供”热”数据存储,而不是尝试在对 CloudScript 的迭代调用中管理数据存储,可能显著更具成本效益。

Insights

此计量表与 PlayFab 服务的所有分析功能相关,从事件采集和导出到事件历史搜索和 Data Explorer 查询。您的使用情况受以下因素影响:您需要处理事件的速度、您希望保持多少事件数据”热”托管(用于 Game Manager 中的查询),以及您使用服务评估数据的程度,无论是通过 Data Explorer 查询还是您直接连接到数据的可视化软件。此计量表受游戏内活动(事件)和游戏外活动(分析)的影响。 最终,这意味着 Insights 上的成本由您从玩家那里获得多少事件数据以及您对该数据进行多少分析处理驱动。在最佳做法方面,上述关于事件的建议适用于前者,而对于后者,您可以通过两种方式控制成本。首先,也是最简单的,您可以在游戏 Game Manager 的 Insights Management 选项卡中设置总存储量,以控制您在 PlayFab 中保留多少事件数据。接下来,在同一选项卡中,您可以设置游戏的性能级别。这决定了分配给您游戏的 CPU 资源总量,以及在事件历史中存储多少数据”热”用于查询。您各自需要多少取决于您的数据分析团队成员的需求,因此最好与他们一起审查以了解应该设置什么。 有关 Insights 及其使用方法的信息,请参见 什么是 PlayFab Insights 有关 Insights 最佳做法的信息,请参见 最佳做法与常见问题解答

多人游戏服务

这是最简单的一项,因为定价完全没有变化。简而言之,托管的 多人游戏服务器Party 服务 一直是按使用量收费的。 具体来说,对于托管游戏服务器,您可以通过优化在任何给定时间必须运行的服务器核心数量来最大限度地降低成本,以便支持尽可能多的玩家。 如果这些服务器上的低 ping 时间很重要,您可以选择运行服务器的区域。对于大多数游戏,玩家最集中的地方局限于某些关键区域,但如果您的玩家群体分布广泛——尤其是当您处于游戏的长尾期时——您需要权衡在玩家附近每个区域运行服务器的成本与较长 ping 时间对少数区域中玩家子集的影响。有一件事可以帮助解决这个问题,就是确保您使用我们的 QOS 服务 来选择将玩家放入哪些区域,然后确定使一个区域可行所需的最少玩家数的截止值。

管理您的正式游戏

这就涵盖了计量表的基础知识,但游戏上线后您应该考虑什么?管理您的玩家社区主要涉及分析(Insights,上一节所述)和对内容与配置的更新。此外,大多数游戏需要在与游戏本身的正常交互之外与玩家互动。从重新参与活动(吸引玩家回来),到对元游戏活动的社区奖励,甚至感谢玩家在游戏外的社区工作,如今的一种常见做法是使用 LiveOps 技术来保持玩家的高度参与度。 其中的一个关键是确保您有效地将分群定位到明确定义的组,不仅是为了降低成本,还要确保您的逻辑能够快速处理。以玩家重新参与为例——让玩家在停止玩游戏一段时间后回来。一种好的方法是定义几个流失用户时间框架,也许是 3 天、7 天和 21 天没玩的玩家。对于每一种情况,您可以采取不同的重新参与方法,从简单的”我们想念你”消息开始,最终以”这里有一些免费的金币/能量等”消息结束(当然,这与自动将其添加到玩家账户结合在一起)。对于这些情况,推荐的方法是基于玩家上次登录玩游戏的时间定义一个一小时窗口。这样,您不仅针对了他们上次玩的时间,还使分群中的玩家集合最小化,以使操作尽可能高效。使用每小时对每个此类分群触发一次的计划任务,您可以发送消息并向玩家库存添加任何物品或虚拟货币 (VC)。

总结

最终,您游戏所需的功能决定了它对像 PlayFab 这样的后端服务的使用。实际上,这一切都归结为一个综合性问题:您对这些功能有什么要求?无论您优先考虑安全性、数据时效性、玩家交互/竞争的水平,还是完全其他内容,都可能有许多因素推动您与后端数据进行更高层次的交互。能够以批判的眼光看待这些要求,并辨别哪些是硬需求、哪些不是,这就好比对游戏中其他代码的优化。这需要仔细审视您的资源利用率高的地方,并决定您是否真的需要它如此高,或者是否有办法可以重新设计该逻辑以减少使用。 如果交互是实时的、玩家对玩家的,那么就要看该交互的复杂性。对于大多数此类游戏,管理模拟状态并仅在会话结束时(或者如果会话很长,则每几分钟)更新后端数据的托管服务器通常是最好的解决方案。但也有很多交互是完全可信的情况,例如合作游戏,或者只与朋友(或对抗朋友)一起玩的游戏,最大限度地减少了作弊的动机。还有一些游戏对如何检查会话数据只有最低要求,允许两个玩家在每次会话后简单地提交他们的报告,以便服务器端检查可以比较这两者。 对于任何没有实时要求的游戏,请考虑玩家是否真的需要精确到秒的准确性。在竞争激烈、社区互动强的游戏中,情况可能确实如此。但对于许多游戏来说,落后几分钟的信息不会影响玩家体验。
最后修改于 2026年8月25日