Skip to content

Instantly share code, notes, and snippets.

@NKID00
Last active December 17, 2021 11:18
Show Gist options
  • Save NKID00/5bbabb3be5bb3e6677e1899c80c2bdbe to your computer and use it in GitHub Desktop.
Save NKID00/5bbabb3be5bb3e6677e1899c80c2bdbe to your computer and use it in GitHub Desktop.
Minecraft 1.17.1 逻辑服务器游戏流程

基于 Minecraft: Java Edition 1.17.1 和 yarn-1.17.1+build.14-v2 映射

声明:

Minecraft 源码版权属于 Mojang。本文并非 Minecraft 官方产品,与 Mojang 无任何关联。

鸣谢:

编写本文时使用了以下软件:

编写本文时参考了以下资料或网站:

Minecraft 1.17.1 逻辑服务器游戏流程

仅代表大致流程,可能没有包括各种分支细节。

  • 服务器主循环

    MinecraftServer.runServer()
    ...
    while(this.running)
    • 判断是否过载,必要时跳过滞后的刻

    • 处理刻

      this.tick( ... );
      • 在暂停时存档(仅物理客户端内置的逻辑服务器)

      • 处理每个维度的刻

        this.tickWorlds( ... );
        • 执行持有 minecraft:tick 标签的函数

          this.getCommandFunctionManager().tick();
        • 依次处理每个维度

          ServerWorld serverWorld = (ServerWorld)var2.next();
          • 每 20 刻进行服务器客户端世界时间同步

            this.playerManager.sendToDimension(new WorldTimeUpdateS2CPacket( ... ), ... );
          • 处理该维度的刻

            serverWorld.tick( ... );
            • 更新世界边界

              this.getWorldBorder().tick();
            • 处理天气(晴天、降雨或雷暴)

            • 处理玩家睡觉并跳过夜晚重置天气

            • 计算天空光照

              this.calculateAmbientDarkness();
            • 处理世界时间

              this.tickTime();
              • 更新世界时间

                this.worldProperties.setTime( ... );
              • 执行用 /schedule 计划执行的函数

                this.worldProperties.getScheduledEvents().processEvents( ... );
              • 更新一天中的时间

                this.setTimeOfDay( ... );
            • 处理方块计划刻

              this.blockTickScheduler.tick();
            • 处理流体计划刻

              this.fluidTickScheduler.tick();
            • 处理袭击

              this.raidManager.tick();
            • 处理区块

              this.getChunkManager().tick( ... );
              • 清除过期加载票

                this.ticketManager.purge();
              • 处理加载票

                this.tick();
              • 进一步处理区块

                this.tickChunks();
                • 随机排序并依次处理每个加载的区块

                  • 更新区块的“占据时间”(用于计算区域难度)

                    worldChunk.setInhabitedTime( ... );
                  • 生成一般生物

                    SpawnHelper.spawn( ... );
                  • 处理区块刻

                    this.world.tickChunk( ... );
                    • 生成闪电和骷髅陷阱

                    • 生成冰和雪

                    • 处理随机刻

                    • 处理该位置方块随机刻

                      blockState2.randomTick( ... );
                    • 处理该位置流体随机刻

                      fluidState.onRandomTick( ... );
                • 生成特殊生物(幻翼、掠夺者、猫、僵尸围城、流浪商人)

                  this.world.tickSpawners( ... );
                • 按刚才的顺序依次处理每个加载的区块

                  • 发送区块相关数据包(packets)
                    var10000.ifPresent(chunkHolder::flushUpdates);
                • 发送实体相关数据包(packets)

                  this.threadedAnvilChunkStorage.tickEntityMovement();
              • 卸载区块

                this.threadedAnvilChunkStorage.tick( ... );
              • 初始化区块缓存

                this.initChunkCaches();
            • 处理方块事件

              this.processSyncedBlockEvents();
            • 处理龙战

              this.enderDragonFight.tick();
            • 依次处理每个实体

              this.entityList.forEach( ... );
              • 清除不正常的实体

              • 处理乘骑

                • 跳过正常的乘客实体,直接处理下一实体

                • 清除不正常的乘客实体

              • 处理该实体

                this.tickEntity( ... );
            • 处理方块实体

              this.tickBlockEntities();
        • 处理网络连接

          this.getNetworkIo().tick();
          • 发送积攒的服务器数据包(packets)

            this.sendQueuedPackets();
          • 处理玩家登录

          • 处理玩家操作

          • 处理玩家断开连接

        • 每 600 刻更新玩家列表中的延迟显示

        • 刷新服务器 GUI

        • 执行积攒的控制台命令(仅物理服务器)

          this.executeQueuedCommands();
      • 每 5 秒更新在线人数并随机抽取幸运玩家示众显示在玩家列表中

        this.metadata.setPlayers( ... );
        this.metadata.getPlayers().setSample( ... );
      • 每 6000 刻进行保存

        this.playerManager.saveAllPlayerData();
        this.save( ... );
      • 每 6000 刻更新信息收集(实际无用)

      • 在暂停时递增世界总时间数据(仅物理客户端内置的逻辑服务器)

      • 不暂停时处理视野距离调整(仅物理客户端内置的逻辑服务器)

    • 处理其他需要在主线程运行的任务

      this.runTasksTillTickEnd();

Minecraft 1.17.1 逻辑服务器关键游戏流程

仅代表关键流程,没有包括各种细节。

  • 服务器主循环
    • 处理刻
      • 处理每个维度的刻
        • 执行持有 minecraft:tick 标签的函数
        • 依次处理每个维度
          • 处理该维度的刻
            • 处理世界时间
              • 更新世界时间
              • 执行用 /schedule 计划执行的函数
              • 更新一天中的时间
            • 处理方块计划刻
            • 处理流体计划刻
            • 处理区块
              • 进一步处理区块
                • 随机排序并依次处理每个加载的区块
                  • 生成一般生物
                  • 处理区块刻
                • 生成特殊生物(幻翼、掠夺者、猫、僵尸围城、流浪商人)
              • 卸载区块
            • 处理方块事件
            • 依次处理每个实体
            • 处理方块实体
        • 处理网络连接
          • 处理玩家操作
        • 执行积攒的控制台命令(仅物理服务器)
      • 每 6000 刻进行保存
    • 处理其他需要在主线程运行的任务
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment