刻
几乎所有的游戏(包括Minecraft)都由一个大的程序循环驱动,游戏内的计算遵照循环执行,按照固定的顺序依次被调用。当程序执行了一次循环,这个程序就进行了一次滴答(Tick),而计量滴答次数的单位就是刻(Tick)。在大多数情况下,刻不仅可以代表滴答的次数,也可以代表滴答本身。
游戏刻与计算速率[编辑 | 编辑源代码]
Minecraft的绝大多数计算逻辑都在一个游戏循环内执行,执行一次这个循环就被称为执行了一次游戏刻(Game Tick),作为单位时缩写为gt。
由于游戏不能时刻都在计算而消耗资源,所以游戏刻执行一次后线程会进行休眠,等待下一次执行,从而维持一秒内游戏刻的执行次数相等且均匀。通常每秒最多运行20次游戏刻,即从这一游戏刻开始执行到下一游戏刻执行的时间间隔为0.05秒。如果这次游戏刻计算时间小于两个游戏刻的时间间隔,则会进行休眠直到下一游戏刻的执行。在Java版中,每秒最多运行游戏刻的次数可用/tick rate
修改,从而缩短或延长两个游戏刻开始执行的时间间隔。
在实际运行中,游戏刻计算的平均时间被称为每刻毫秒数(Milliseconds per Tick,MSPT),用于衡量游戏计算的负载。每秒具体执行了多少次游戏刻被称为每秒刻数(Ticks per Second,TPS),用于衡量游戏运行的真正速率。同时,每秒最多运行多少次游戏刻也被称为最大TPS。在未使用/tick rate
修改时,游戏的正常TPS为20,MSPT不超过50。
当MSPT小于或等于游戏刻时间间隔时,游戏能够以最大TPS速率运行。但当游戏刻内计算量太大时,MSPT上升导致超过游戏刻时间间隔,TPS就不能维持在最大TPS速率,而维持在1000⁄mspt,此时游戏的运行速度就会减慢,又称掉刻。在Java版中,若一个游戏刻的执行时间超过了1秒,且距离上次警告已经超过10秒加100个游戏刻,服务端就会输出日志Can't keep up! Is the server overloaded? Running <执行时间>ms or <延迟游戏刻数> ticks behind
警告计算发生了卡顿。
在Java版中的单人模式或多人游戏主机的调试屏幕内,MSPT和游戏刻时间间隔位于左上区域,打开帧生成时间图表(F3 + 2)也可以查看当前的TPS。
游戏刻在客户端和服务端上都存在。服务端的游戏刻主要负责游戏的计算逻辑,而客户端游戏刻主要和渲染有关。
游戏刻流程[编辑 | 编辑源代码]
在每个游戏刻中,各个模块的计算都按照固定的顺序依次调用。下面的游戏刻流程中,只考虑服务端的游戏刻流程。
Java版[编辑 | 编辑源代码]
Java版中,服务端分为集成服务端和独立服务端。集成服务端内置在客户端内,会受到客户端的影响,而独立服务端的运行状态基本不会受到客户端连接的影响。
集成服务端的流程如下:
- 检查游戏是否被暂停。当暂停时,游戏自动保存。
- 当游戏暂停时,且集成服务端正以局域网联机服务器运行,则对所有玩家统计世界打开时间。
- 若游戏恢复运行,对所有玩家进行强制时间同步。
- 执行服务端逻辑。
- 更新客户端控制的渲染距离和模拟距离。
集成服务端和独立服务端都拥有同样的服务端逻辑。下文中带有蓝色星号标记(*)的流程在服务端使用/tick freeze
冻结时忽略执行。
- 更新游戏刻计数器。游戏刻计数器与世界时间无关,用于记录服务器从启动到现在执行了多少游戏刻。
- 若游戏被
/tick freeze
冻结,并使用/tick step
步进时,计算剩余的步进次数。 - 关闭与客户端的网络自动发送队列的刷新。
- *若游戏被重载,执行带有
load
标签的函数。 - *执行带有
tick
标签的函数。 - 遍历所有维度,进行每个维度的计算。默认处理顺序为主世界、末地、下界:
- 每经过20个游戏刻,与这个维度中的玩家同步这个维度的时间。
- 执行维度游戏刻逻辑。
- 若维度游戏刻逻辑内产生异常,则立刻崩溃。
- 检查客户端连接,删除已经关闭的连接,刷新发送队列,解析来自玩家客户端的网络包(包括玩家的各种动作,但处理这些动作不在此阶段),计算网络使用情况。
- 绝大多数玩家的实体计算任务在此阶段完成。
- 每600游戏刻向所有玩家发送更新延迟网络包。
- 若服务器GUI存在,更新服务器GUI。
- 对所有玩家发送正在等待发送的区块网络包,并打开与玩家客户端的网络自动发送队列刷新。
- 尝试自动保存。两次自动保存的时间不小于100游戏刻。当游戏正在快进时,两次自动保存间隔为
300×TPS
,否则两次自动保存间隔为300×最大TPS
。 - 运行处理队列中的事件,包括来自玩家客户端的各种交互网络包。
每个维度执行游戏刻的流程如下:
- *世界边界范围更新。
- *计算天气循环,更新降雨和雷暴计时器。若降雨和雷暴的程度发生变化,向维度内的玩家发送世界事件网络包。
- 玩家睡眠逻辑。当维度内所有玩家入睡时,将时间调整到下一个日出,若在降雨则重置天气循环。
- 更新内部光照等级乘数,与当前时间和降雨、雷暴有关。
- *更新时间。
- *若为非调试维度,则执行计划刻逻辑。先执行方块计划刻,再执行流体计划刻,每个游戏刻最多处理65536个方块计划刻和65536个流体计划刻。
- *更新维度内的袭击事件,清除已经结束的袭击事件。
- 计算维度内的区块数据。
- *计算方块事件,并将方块事件数据发送到玩家客户端。
- 若维度内有玩家或强制加载区块,则重置闲置超时。
- 若闲置超时小于300游戏刻,则执行实体和方块计算逻辑:
- *计算末影龙战斗数据。
- 遍历维度内的所有实体,进行实体计算。对于玩家骑乘的实体,
/tick freeze
对它们没有作用:- 遍历顺序由一个游戏内不可见的实体ID决定,实体按照ID从小到大进行遍历。从服务器启动开始,ID被初始化为0,每加载一个实体此ID自增1,即此ID代表了实体的加载顺序。对于同一个实体,若它未被卸载,那么实体ID不变,直到被卸载为止。
- 删除已被标记清除的实体。
- 若server.properties内的
spawn-npcs
为false,删除所有村民和流浪商人。如果spawn-animals
为false,删除所有动物和水生动物。 - *检查清除条件,清除满足条件的实体。
- *对于强加载区块内的实体,检查骑乘情况并使失去坐骑的实体停止骑乘,并进行它们自身的实体计算。
- 玩家的部分实体计算也会在此阶段被计算,如监守者生成数据。
- *计算维度内的方块实体逻辑。
- 加载区块内未加载的实体,卸载不需要的实体,更新各个玩家追踪的实体,并以网络包发送到玩家客户端。
基岩版[编辑 | 编辑源代码]
你可以帮助我们加入信息。
区块刻[编辑 | 编辑源代码]
此章节仍需完善,你可以帮助我们扩充更多信息。
说明:基岩版相关内容并不全
在游戏刻计算流程中,游戏会以一个区块为单位进行一次游戏刻计算,而这次计算被称为区块刻。在Java版中,加载等级为实体计算等级的区块才可以执行区块刻,在游戏冻结时区块刻全部停止计算;在基岩版中,每个游戏刻内,所有加载的区块都得到区块刻处理。
在Java版中,区块刻的执行顺序如下:
- 以随机顺序,遍历所有满足区块刻条件、加载等级为实体计算等级、且区块中心距离玩家128格(水平距离)以内的区块。
- 遍历所有满足区块刻条件的区块。
随机刻[编辑 | 编辑源代码]

在区块刻的执行过程中,区块会在其中选取几个方块进行计算,这种计算被称为随机刻(Random Tick)。随机刻由随机刻速率,即游戏规则randomTickSpeed
控制。
在Java版中,随机刻在每个子区块内进行,每个子区块随机选取随机刻速率个方块执行随机刻。默认情况下,随机刻速率为3,即每个子区块在其中选取3个方块执行随机刻。由于随机刻为随机选取,每个方块被选中执行随机刻的时间间隔随机。两次随机刻时间间隔的中位数为47.30秒(946.03游戏刻),平均数为68.27秒(1365.33游戏刻)。也就是说时间间隔有50%的概率短于47.30秒,有50%的概率长于47.30秒。不过,有时候这个时间间隔会长得多或短得多:比如,时间间隔有1.38%的概率会比一秒还短,且有1.23%的概率比五分钟还长。
在基岩版中,随机刻在每个区块内进行,每个区块随机选取2.5×子区块数量×随机刻速率
个方块执行随机刻。默认情况下,随机刻速率为1。
一次随机刻中方块可被选取多次,从而在方块上同时产生多次随机刻。
绝大多数方块不会响应随机刻,响应随机刻的方块使用随机刻计算下列事件:
- 各种植物(农作物、树苗等)使用随机刻控制生长、传播、枯萎和摧毁。
- 铜类方块的氧化。
- 熔岩点燃周围的方块,火的生成和蔓延。
- 耕地的湿润程度更新,草方块和菌丝的蔓延和退化。
- 冰和雪的融化。
- 下界传送门方块生成僵尸猪灵。
- 海龟蛋破裂和孵化。
- 发光的红石矿石熄灭。
- 营火冒出烟雾。
- 紫水晶母岩长出紫水晶簇。
- 滴水石锥填充正下方的炼药锅。
计划刻[编辑 | 编辑源代码]
一些方块的行为可能不会在本游戏刻立刻执行,而是延后到之后的游戏刻执行。这种情况下,方块向游戏请求一个计划在指定游戏刻后执行的任务,而规划请求的这项计划任务被称为计划刻(Scheduled Tick)。
在Java版中,计划刻分为两种,分别为方块计划刻和流体计划刻。计划刻的执行顺序取决于它的优先级,优先值越小,它的执行时间在一个游戏刻中越靠前。通常的计划刻优先级为0,对于红石比较器和红石中继器,其状态切换时的优先级更高。当中继器状态切换时指向其他比较器或中继器的侧面或后面(即输入端),则具有最高优先级-3;当中继器本身正在熄灭时,优先级为-2;当中继器正在亮起,或比较器状态切换且指向其他比较器或中继器的侧面或后面时,优先级为-1。
在Java版中,每个游戏刻内至多处理65536个计划刻。在基岩版中,每个游戏刻内,每一个区块至多处理100个计划刻。
若一个游戏刻内的计划刻数量超过了最大处理计划刻数,那么超出的计划刻将延后至下一游戏刻处理(即“计划刻堆积”
红石刻[编辑 | 编辑源代码]
红石刻(Redstone Tick),常缩写为rt,是红石系统的时间单位,它代表两个游戏刻。
在Java版中,红石刻并不存在于真正的游戏流程中,因为红石系统本质是方块更新和计划刻计算。定义红石刻的目的是为了更好解释红石系统的运行和便于交流,因为绝大多数红石元件都以两个游戏刻作为基础时间单位,有时也并不需要精准到游戏刻级别的时序分析。
在基岩版中,红石刻真实存在于游戏中,红石系统每2游戏刻启动一次,计算并更新红石系统。如增删红石元件、依赖变动(如可能被充能的红石导体,被比较器检测的容器)和红石信号在元件间的流动等。有时通过将并发线程启动的那1游戏刻称为“红石刻”,反之称为“非红石刻”来区分并发线程是否启动的游戏刻。
- 游戏源码中,红石系统的工作频率(以游戏刻为基准单位)被硬编码为2。但实际上可以通过特殊手段强制改动,以此来调整红石刻的工作频率。
历史[编辑 | 编辑源代码]
Java版 | |||||||
---|---|---|---|---|---|---|---|
1.20.2 | 23w31a | 现在区块刻处理时露天方块检查天气更新的频率受游戏规则randomTickSpeed 影响。 | |||||
1.21.5 | 25w06a | 现在区块刻不再要求距离玩家128格以内,并修改了区块刻的执行顺序与逻辑。 | |||||
25w09a | 现在区块刻要求区块加载等级为实体计算等级而非方块计算等级。 |
导航[编辑 | 编辑源代码]
[隐藏] | |||||
---|---|---|---|---|---|
版本 | |||||
开发周期 |
| ||||
技术 |
| ||||
多人游戏 | |||||
游戏订制 |
[隐藏] | |||||||
---|---|---|---|---|---|---|---|
版本 |
| ||||||
开发 |
| ||||||
技术性 | |||||||
多人游戏 | |||||||
特色功能 |