以我所能,优化通用拼图解构的生成。本质上,此模组旨在完全不改变结构的视觉效果。它仅致力于使结构生成得更快、更高效。仅此而已。
尽可能优化通用 Jigsaw(拼图)结构的生成。本质上,此模组旨在完全不改变结构的外观。它仅致力于让结构生成得更快、更高效。仅此而已。 以下是所执行优化的更多技术细节。如果在您的整合包中运行此模组时发现了任何冲突或问题,请报告! 将未优化的 VertexShape 调用替换为 BoxOctree(盒状八叉树),使方块块仅检查附近方块块的交叉情况,而不是整个结构。 默认情况下,原版 Minecraft 使用 VoxelShape(体素形状)来存储其正在组装的结构布局的边界。当它尝试添加一个新方块块时,需要查看它是否会与其他任何方块块发生交叉而无法放入布局中。 问题在于 VoxelShape 不适合此目的,因为在检查一个 VoxelShape 是否与另一个 VoxelShape 交叉时,会比较所有顶点。在包含大量方块块的 Jigsaw 结构中,随着有效方块块添加到布局中,这种交叉检查的速度会大幅降低。在为递归 Jigsaw 结构生成大量方块块时,可能会导致卡顿。 检查 Jigsaw 方块是否完全被阻挡,以便知道何时跳过检查子刚性方块块。 在原版中,父方块块中的每一个 Jigsaw 方块都会检查子方块块中的每一个 Jigsaw 方块,以判断何时尝试连接这两个方块块。问题是,如果父方块块的 Jigsaw 方块面向结构边界边缘,或者面向另一个独立的方块块,那么该 Jigsaw 方块就没有空间生成任何刚性结构方块块。因此,我们可以告诉游戏跳过检查这个刚性子方块块,转而检查下一个方块块。这节省了进行大量昂贵的 Jigsaw 方块匹配检查的工作。特别是在拥有大量 Jigsaw 方块块的结构中,效果显著。 (26.2 及更低版本) 将 Jigsaw 目标/朝向匹配替换为稍微优化过的版本。 将获取方块属性的次数减少了一半。原版为每个 JigsawBlock 调用 getValue 两次,以从同一属性获取顶部和正面值,而实际上只需获取一次即可获得所有所需值。同时也略微提高了从 Jigsaw 方块的 NBT 中获取关节、目标和名称字符串速度的速度。 还简化了关节数据检查,无需通过 byName(非高性能)转换为 Enum,并重新排序检查以减少经常需要运行的逻辑量。 这将有助于处理包含极多 Jigsaw 方块块的结构,因为每个 Jigsaw 方块都会针对其他结构方块块中的所有 Jigsaw 方块运行此匹配代码。 使任何没有 finalizeProcessing StructureProcessor 的大型结构 NBT 加载速度大幅提高。 当 NBT 结构方块块要在区块中生成时,整个 NBT 方块块会被加载到内存中,然后多次迭代所有位置以应用 StructureProcessors,随后忽略当前生成区块之外的所有位置。这非常低效(极其浪费资源),并且会导致大型 NBT 文件的加载时间很长。 此模组的优化方法是通过提前进行边界检查,在将其传递给 StructureProcessors 之前剔除所有不需要的坐标。然而,任何覆盖 finalizeProcessing 方法的 StructureProcessor 可能需要所有 NBT 坐标才能正常工作,因此对于拥有此类 StructureProcessors 的方块块,此优化将被禁用,这类结构非常少。在原版中,只有遗迹(Trail Ruins)不会获得此优化,因为它使用的 Capped StructureProcessor 覆盖了 finalizeProcessing 方法。 (1.21.1+) 用稍微更快的版本替换了 SinglePoolElement 中的 Jigsaw 方块块列表洗牌和优先级逻辑。 主要好处是稍微加快了从 NBT 获取 selection_priority 数据的速度,通过使用一种新方法,只获取一次条目而不是两次。原版会先检查数据类型,然后再返回值,这样做两次显得有些奇怪且浪费资源。 还尝试了一种新的排序系统用于优先级处理,但这仅对实际使用 selection_priority 的少数结构(如试炼密室)有帮助。总体而言,这可能是最弱的优化,但它确实对拥有极其庞大数量的 Jigsaw 方块块的结构有很大帮助。因此保留此优化是值得的。 这可能会破坏与原版种子在 Jigsaw 方块块运行顺序方面的一致性,但我尚未找到证据证实这一点。 跳过对我们已经检查过且无法在当前地点生成的 SinglePoolElements 运行逻辑。 这一优化源于以下事实:原版 StructureTemplatePool 包含一个 SinglePoolElements 列表,其中基于权重值重复包含元素。因此,如果在 Template Pool 中指定房屋的权重为 100,该房屋将被放入此列表 100 次!在生成布局时,游戏会复制此列表,对其进行洗牌,并迭代列表以尝试生成它找到的第一个合适的方块块。这意味着即使之前发现该方块块在此地点不合适,它仍会对列表中的重复条目重新运行检查逻辑。我做的优化是跳过我们已经检查过的方块块的逻辑,并继续处理列表中的下一个方块块。这对于在其 Template Pools 中使用大量高权重值的结构提供了不错的性能提升。 此外,您可以开启 deduplicateShuffledTemplatePoolElementList 配置选项,以从 Template Pools 中的高权重元素中获得更多性能。问题是此配置会以改变结构布局为代价。布局仍然有效且良好,只是与关闭此配置选项时的布局不同。基本上,为了获得额外的性能提升,它破坏了特定于结构布局的种子一致性。 *明确说明,种子一致性是指每次使用种子 777 时,如果在某个地点有一个村庄包含两个铁匠铺房屋,那么每次使用相同的种子,该村庄都会保持在同一地点并拥有这两个铁匠铺房屋。在此优化配置开启且使用相同种子的情况下,该村庄仍将位于同一地点。但这次它可能只有一个铁匠铺房屋。并且每次在此配置开启的情况下使用相同种子,村庄将继续生成并只拥有一个铁匠铺房屋。布局是种子稳定的,但不再与关闭配置时的布局相同。 (1.21.4 配合 v1.1.0+): 将 StructureTemplate$Palette 的 StructureBlockInfo 对象列表替换为 StructureBlockInfo 对象的调色板,以减少在未生成缓存的 StructureTemplate 时的内存占用。 此优化是 contaria 的 Glacier 模组(适用于 1.16.1)的修改形式。特别感谢他们允许我以其代码为基础进行此优化! 本质上,在原版中,每次加载结构 nbt 文件时,它都会被转换为 StructureTemplate 对象并缓存。在该对象深处,有一个列表包含来自该 nbt 文件的所有位置,以及每个位置处的方块和 nbt 标签。这是 StructureTemplate 对象最大的内存消耗源。此模组将在底层将此列表替换为一个特殊的调色板数据结构对象,该对象伪装成列表形式。调色板的内存大小显著小于列表!然后在查询世界生成时,它将构建一个 WeakReference(弱引用)形式的列表,以确保世界生成保持快速且正常运行。当世界生成完成后,此列表将被垃圾回收以释放内存,从而允许每个 StructureTemplate 仅在世界生成时使用所需的完整内存量,而在长期缓存中以较小的形式存在。缺点是这个列表不能也不应该通过 add、remove、clear 调用进行修改,如果这样做将抛出异常。幸运的是,我认为没有任何模组直接修改 StructureTemplate 上的此列表,但如果有的话,请告知我。 ModernFix 确实有一个 mixin,将使 StructureTemplate 对象本身成为 SoftReference(软引用),并在游戏内存满载时将其从内存中完全移除。这是一个有效的解决方案,旨在防止在长期游戏中加载结构 nbt 到从未清理的缓存中导致的内存泄漏。这种 mixin 的缺点是,如果该方块块已从内存中清除,则必须再次直接从文件加载它。此 mixin 将与我的模组的优化完美配合。可能发生的情况是,我的模组使 StructureTemplate 在内存中更小,从而允许 ModernFix 在内存中保留更多的 StructureTemplates 而不将它们完全从内存中移除。这在理论上应该允许在长期游戏中实现更多的缓存命中。
在鱼乐云资源中心浏览该资源,登录后可一键安装到你的游戏服务器。