Icterine

Icterine

进度优化(具体指InventoryChangeTrigger)

优化

摘要

  • 优化获取物品时的进度触发机制;
  • 可能与原版机制存在差异,但不会影响原版进度,也不应影响绝大多数模组/数据包;
  • 即使对某些内容产生影响,通过丢弃并重新拾取所需物品之一,进度仍然可以获得;
  • 目前,没有已知的不兼容问题或缺陷;
  • 所有对原版代码的注入均可在配置文件中禁用。
  • 所有更改均为服务端修改。

成果

在专用服务器上进行了实时测试,当时有3名活跃玩家在线,运行的是包含超过200个模组的自定义Forge整合包,并安装了 BlazeandCave 的进度包,该数据包增加了超过950个进度。使用Spark收集了一小时的统计数据。

使用Icterine后,InventoryChangeTrigger的执行速度提高了近2.5倍(截至1.1.0版本),其消耗的tick时间占比从20%降至约7.5%。

Icterine 1.0.0版本(速度提升约2倍)的统计数据对比:

统计数据

原版 InventoryChangeTrigger 的工作原理

  1. 当游戏检测到玩家物品栏中的物品堆叠发生变化时,会为其调用 InventoryChangeTrigger。这包括拾取物品、丢弃物品、丢弃整个堆叠以及移动物品栏中的物品。
    1. 此外,当你打开容器(箱子、熔炉等)时,游戏会认为你物品栏中的所有格子都发生了变化,并会为所有格子(包括空槽位)触发触发器。
  2. InventoryChangeTrigger 会统计你物品栏中空槽位、非空槽位和堆叠满的槽位数量。此信息可用于进度触发器,但原版并未使用。
  3. InventoryChangeTrigger 会遍历所有已注册的进度条件。
  4. 如果条件有槽位数量要求且与第2步统计的值不匹配,或者条件没有物品要求,则该条件会被跳过。
  5. 如果条件只有一个物品要求,则会将发生变化的物品堆叠与该项要求进行匹配。
  6. 如果条件有多个物品要求(例如,“救我于水火之中”需要拥有一整套下界合金装备),则每一组物品栏中的堆叠都会与每一项要求进行匹配(但已满足的要求会被移除,不再进行检查)。
  7. 物品匹配,尤其是针对标签的匹配,开销非常大。但游戏会首先检查玩家的物品类型是否与要求中的类型一致,然后才会检查数量、附魔和其他NBT数据等参数。

Icterine 的优化原理

  1. 在第1步中,当丢弃物品堆叠或将它们从物品栏中移出(例如放入箱子)时,不再调用 InventoryChangeTrigger。此行为由配置文件中的 ignore_triggers_for_emptied_stacks 参数控制。
  2. 同理,如果物品堆叠的变化是由于数量减少但未清空(例如玩家从一组完整的堆叠中丢弃了一个物品),也不调用 InventoryChangeTrigger。由 ignore_triggers_for_decreased_stacks 参数控制。
  3. 如果物品堆叠的数量增加,但未达到任何进度的阈值,同样不调用 InventoryChangeTrigger。例如,泥土堆叠数量从52增加到53,但你的整合包中没有“获得53个泥土”的进度。由 optimize_triggers_for_increased_stacks 参数控制。
  4. 修改游戏在玩家打开容器界面时检查物品变化的方式,使其不会在你打开任何界面的瞬间就将所有堆叠视为已变化。由 initialize_inventory_last_slots 参数控制。
  5. 在第6步中,首先检查发生变化的槽位是否匹配任何要求,然后才检查物品栏中的其他堆叠。由 optimize_multiple_predicate_trigger 参数控制。
  6. 在第7步中,首先比较堆叠数量以避免不必要的标签匹配。同时利用之前的堆叠数量来进一步避免不必要的匹配。由 check_count_before_item_predicate_match 参数控制。

进一步的优化已在计划之中。

支持的版本

Icterine v1.2.0 支持 Minecraft Fabric/Quilt 1.18.2 至 1.19.4,以及 Forge 1.18.2 至 1.19.2 (Forge 的遗憾时刻)

Icterine v1.3.0 具有与 v1.2.0 相同的功能,支持 Fabric/Quilt 1.20 - 1.20.4、Forge 1.19.3 - 1.20.4 以及 NeoForge 1.20.1 - 1.20.4。

请使用版本页面上的筛选器来选择正确的文件。

如果你需要移植到其他版本,请在 Discord 服务器上提交问题或询问。