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

激活拉杆后Minecraft服务器卡顿优化:延迟批量删块方案

Minecraft模组批量删块卡顿优化方案

问题背景

开发模组时,激活拉杆后删除50格半径范围内的方块会导致服务器卡顿。需求是:拉杆激活后先播放声音,等待120秒再执行批量删块操作。

现有代码的核心问题

  1. 主线程阻塞:在replaceBlocksInSphere中直接调用sleep(12000)(注:代码中是12秒,和需求的120秒不符),会阻塞服务器主线程,导致整个服务器在等待期间完全无响应。
  2. 一次性批量操作:所有方块删除操作集中在单帧完成,大量同步IO和世界更新瞬间占用服务器资源,引发卡顿。
  3. 不必要的对象创建:循环中每次创建新的BlockPos,增加内存垃圾回收压力。

优化后的代码实现

@Override
public void neighborChanged(BlockState blockstate, net.minecraft.world.level.Level world, BlockPos pos, Block neighborBlock, BlockPos fromPos, boolean moving) {
    super.neighborChanged(blockstate, world, pos, neighborBlock, fromPos, moving);
    if (world instanceof ServerLevel serverLevel && serverLevel.hasNeighborSignal(pos)) {
        // 立即播放声音
        playSound(serverLevel, pos);

        strength = -1f;
        resistance = 3600000f;

        // 延迟120秒(120000毫秒)执行删块任务,避免阻塞主线程
        serverLevel.getServer().getScheduler().scheduleDelayedTask(
            () -> startBatchBlockRemoval(serverLevel, pos),
            120000L,
            TimeUnit.MILLISECONDS
        );
    }
}

// 分批次处理方块删除的入口方法
private void startBatchBlockRemoval(ServerLevel world, BlockPos centerPos) {
    int radius = RADIUS;
    int radiusSqr = radius * radius;
    // 计算需要处理的区块范围
    int chunkRadius = (int) Math.ceil((double) radius / 16);
    int centerChunkX = centerPos.getX() >> 4;
    int centerChunkZ = centerPos.getZ() >> 4;

    // 收集所有需要删除的方块位置
    List<BlockPos> blocksToRemove = new ArrayList<>();
    BlockPos.MutableBlockPos mutablePos = new BlockPos.MutableBlockPos();

    for (int chunkXOffset = -chunkRadius; chunkXOffset <= chunkRadius; chunkXOffset++) {
        for (int chunkZOffset = -chunkRadius; chunkZOffset <= chunkRadius; chunkZOffset++) {
            int chunkX = centerChunkX + chunkXOffset;
            int chunkZ = centerChunkZ + chunkZOffset;

            int startX = chunkX << 4;
            int endX = startX + 16;
            int startZ = chunkZ << 4;
            int endZ = startZ + 16;
            int startY = Math.max(world.getMinBuildHeight(), centerPos.getY() - radius);
            int endY = Math.min(world.getMaxBuildHeight(), centerPos.getY() + radius);

            for (int y = startY; y <= endY; y++) {
                for (int x = startX; x < endX; x++) {
                    for (int z = startZ; z < endZ; z++) {
                        mutablePos.set(x, y, z);
                        if (centerPos.distSqr(mutablePos) <= radiusSqr) {
                            blocksToRemove.add(mutablePos.immutable());
                        }
                    }
                }
            }
        }
    }

    // 分批次处理删除,每批次处理100个方块,间隔1 tick(约50毫秒)
    batchRemoveBlocks(world, blocksToRemove, 0, 100);
}

// 递归分批次删除方块
private void batchRemoveBlocks(ServerLevel world, List<BlockPos> blocksToRemove, int startIndex, int batchSize) {
    if (startIndex >= blocksToRemove.size()) {
        return;
    }

    int endIndex = Math.min(startIndex + batchSize, blocksToRemove.size());
    BlockPos.MutableBlockPos mutablePos = new BlockPos.MutableBlockPos();

    for (int i = startIndex; i < endIndex; i++) {
        BlockPos pos = blocksToRemove.get(i);
        mutablePos.set(pos);
        // 如果方块不是空气才进行删除,避免无效操作
        if (!world.getBlockState(mutablePos).isAir()) {
            world.setBlock(mutablePos, Blocks.AIR.defaultBlockState(), 3);
            // 3表示通知客户端更新,比setBlockAndUpdate更轻量,可根据需求调整
        }
    }

    // 调度下一批次任务,间隔1 tick分散负载
    world.getServer().getScheduler().scheduleDelayedTask(
        () -> batchRemoveBlocks(world, blocksToRemove, endIndex, batchSize),
        1L,
        TimeUnit.MILLISECONDS
    );
}

优化说明

  1. 异步延迟任务:用服务器调度器scheduleDelayedTask替代sleep,既实现120秒延迟,又不会阻塞主线程,保证服务器正常运行。
  2. 分批次处理:先收集所有待删除方块,再分批次逐步删除,每批次间隔1 tick,分散服务器负载,避免瞬间卡顿。
  3. 可变BlockPos复用:全程使用BlockPos.MutableBlockPos减少对象创建,降低内存开销和GC压力。
  4. 边界范围优化:限制Y轴操作在世界合法建造高度内,避免无效的世界访问。
  5. 无效操作过滤:删除前检查方块是否为空气,跳过不必要的更新操作。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.25 08:24:57