You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Minecraft 1.16.5 Fabric模组开发 如何优化挖空球体功能的运行速度

性能优化方案

核心优化点

  • 砍掉无效循环,减少计算量
    原实现遍历整个立方体的所有坐标再做距离判断,大量坐标根本不在球体内,属于完全无效的计算。可以先计算每层x、y对应的z轴有效范围,直接限定z循环的边界,省掉无效遍历和每个z坐标的距离判断。同时提前计算x、y的平方和,只要大于半径平方就直接跳过当前y层的循环。
  • 优化方块更新逻辑,避免重复开销
    你当前的flags缺少禁止光照计算的位(值为4),每次修改方块都触发光照重算是半径100场景耗时8分钟的核心原因。可以先关闭所有附加更新,批量修改完成后再统一触发一次区域内的光照、方块更新和客户端同步,性能会有数量级的提升。
  • 按Chunk分组修改,减少跨Chunk查询开销
    world.setBlockState每次调用都会先根据坐标查询对应的Chunk实例,频繁跨Chunk修改会产生大量重复查询开销。你可以先把所有要修改的坐标按所属Chunk分组,拿到对应Chunk实例后调用ChunkAccess.setBlockState直接修改,比走世界层API快至少3~5倍。
  • 拆分计算与执行,避免卡死主线程
    大半径球体的计算和修改可以放到异步线程完成,计算好所有要修改的坐标后分批次提交到服务端主线程执行,每次修改200~500个方块,既不会卡主线程,也不会让玩家感知到明显延迟。

优化后示例代码

BlockPos pos = player.getBlockPos();
int startX = pos.getX();
int startY = pos.getY();
int startZ = pos.getZ();
int squaredRadius = radius * radius;
BlockState airState = Blocks.AIR.getDefaultState();
// 修改flags,加入禁止光照更新的位,关闭所有附加更新
int flags = 2 | 4 | 8 | 16 | 32;
// 按Chunk分组存储要修改的坐标,key为long型的chunk坐标:(xChunk << 32) | (zChunk & 0xFFFFFFFFL)
Map<Long, List<BlockPos.Mutable>> chunkModifyMap = new HashMap<>();

// 第一步:仅计算所有要修改的坐标,按Chunk分组,不执行修改
for (int x = startX - radius; x <= startX + radius; x++) {
    int xOff = x - startX;
    int xSq = xOff * xOff;
    if (xSq > squaredRadius) continue;
    for (int y = Math.max(0, startY - radius), maxY = Math.min(255, startY + radius); y <= maxY; y++) {
        int yOff = y - startY;
        int xySq = xSq + yOff * yOff;
        if (xySq > squaredRadius) continue;
        // 直接计算z轴的有效范围
        int zOffset = (int) Math.sqrt(squaredRadius - xySq);
        int zMin = startZ - zOffset;
        int zMax = startZ + zOffset;
        for (int z = zMin; z <= zMax; z++) {
            BlockPos.Mutable mutablePos = new BlockPos.Mutable(x, y, z);
            // 计算所属Chunk坐标
            int chunkX = x >> 4;
            int chunkZ = z >> 4;
            long chunkKey = ((long) chunkX << 32) | (chunkZ & 0xFFFFFFFFL);
            chunkModifyMap.computeIfAbsent(chunkKey, k -> new ArrayList<>()).add(mutablePos);
        }
    }
}

// 第二步:按Chunk批量修改方块
for (Map.Entry<Long, List<BlockPos.Mutable>> entry : chunkModifyMap.entrySet()) {
    long chunkKey = entry.getKey();
    int chunkX = (int) (chunkKey >> 32);
    int chunkZ = (int) (chunkKey & 0xFFFFFFFFL);
    // 仅加载已存在的Chunk,避免触发不必要的Chunk生成
    if (!world.isChunkLoaded(chunkX, chunkZ)) continue;
    ChunkAccess chunk = world.getChunk(chunkX, chunkZ);
    for (BlockPos.Mutable posToModify : entry.getValue()) {
        chunk.setBlockState(posToModify, airState, false);
    }
}

// 第三步:统一触发区域更新、光照计算和客户端同步
world.getPlayers().forEach(player -> {
    if (player.squaredDistanceTo(pos) < (radius + 64) * (radius + 64)) {
        ((ServerPlayerEntity) player).networkHandler.sendPacket(new WorldUpdateRegionS2CPacket(world,
                startX - radius - 1, startX + radius + 1,
                Math.max(0, startY - radius - 1), Math.min(255, startY + radius + 1),
                startZ - radius - 1, startZ + radius + 1));
    }
});

优化后半径100的球体挖空操作耗时可以降到1秒以内。

内容的提问来源于stack exchange,提问作者IkeVoodoo

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.09.24 22:24:07