模拟调度
兴趣为一等公民、因果分级结算、实体预算显式化、可复现的时间旅行——单人与万人共用同一内核的调度设计,以及红石因果如何不被拆碎。
本章命题:重写的调度器应把「兴趣」(谁的关注驱动谁的结算)提升为一等公民——结算的粒度、频率与顺序按兴趣显式分配,单人与万人因此共用同一内核,差异只是兴趣半径与预算大小;同时为因果敏感型玩法(红石)保留「严格序区」的特别制度。若一套兴趣驱动的调度无法在万人规模下保持单人级的因果可解释性,本命题就是错的。
1问题
第 16 章把两份遗产摆在了重写面前:原版的「全局单一时钟」契约(纪律完美,预算单线程)与社区的两次越狱(Paper 的性能补丁、Folia 的区域并行——后者证明可行,代价是插件生态重写)。第 3 章则把「因果可解释」列为本章必须保住的不变量:红石玩家需要的是「整刻延迟、同刻联动」这种可以写进教程的确定性。
本章的考题由此精确:**设计一个调度器,兴趣决定资源(解决规模),因果决定顺序(保住红石),两者不打架。**答案的骨架是一句原则:**兴趣决定「算不算、多快算」,因果决定「按什么顺序算」——把这两件事从一根绳上解开。**原版把它们捆在一起(全局时钟既管频率又管顺序),这正是规模天花板的来源。
2全局 20 TPS 的限度
先把要解开的东西看清楚。全局时钟在原版里同时承担三职:节拍器(世界的时间单位)、预算表(每五十毫秒一轮)、顺序保证(同刻内事件次序确定)。第 5 章说过它的伟大,这里说它的局限:三职合一意味着三者互相牵制——为了让所有区块共享同一节拍,预算必须按最坏情况配置;为了顺序确定,计算必须串行;串行加统一节拍,等于「世界的每一部分,无论有没有人在乎,都以同样的粒度、同样的优先级被结算」。一片无人注视的沙漠里的草,和一名玩家脚下的红石钟,在同一根队列里排队。
这就是限度:**全局时钟在「因果」上是精确的,在「兴趣」上是盲的。**而绝大多数模拟工作量(草生长、僵尸游荡、远处的水)对因果精度的要求远低于对资源的要求——它们不需要「同刻」,只需要「差不多按时」。把盲目的均等当成纪律,是把稀缺的预算撒给了不需要它的地方。
三职合一的冲突,用两台服务器的对比就能看清。第一台是红石工程服:几十台大型机器昼夜运转,玩家对「同刻精度」的要求极高,而对实体数量、地形面积毫无兴趣——理想预算是「几乎全部给严格序结算」。第二台是生存挑战服:上千名玩家散布在超大地图上各自生存,没有任何一台机器在乎时序,而实体与作物的总量惊人——理想预算是「几乎全部按兴趣分配,时序放粗」。今天的全局时钟对两台服务器提供的是同一份配置,于是红石服在被无关负载稀释的预算里挣扎,生存服在用不上的时序精度上浪费——两台服主各自手搓补丁(第 16 章),把同一根绳上解不开的结,一个一个剪断在插件里。调度器的重写,就是把这场旷日持久的「剪绳结运动」一次性制度化的提案。
3兴趣管理与分片:显式化的第一步
提案的第一层是把兴趣显式化:**每个玩家声明(或系统推导)一个兴趣区域;模拟资源严格按兴趣分配。**近处全速细算,中圈降频粗算,圈外暂停并只保留存量。原版其实已有这套思想的雏形——模拟距离与渲染距离的分家(第 3 章)就是兴趣显式化的第一步——重写的提案只是把它从「两档距离参数」推广为「连续的、可声明的、按内容类型分别设定的兴趣模型」:这片农田每天结算一次,这座红石机关每刻结算,那条沙漠公路上的草——不结算。
「声明」的设计里有三个层级值得区分,因为它们对应三类真实的利益相关方。玩家位置的隐式兴趣是默认层——我在哪,哪里被结算,这是今天模拟距离的逻辑,无需任何人操作。玩家与社区的显式兴趣是中间层——服主或作者在管理界面上为特定区域设定结算档位(「这片农场每秒一拍」「这座机器每刻全速」),今天散落在各类插件配置里的手动优化,在此变成一张统一的兴趣地图。内容自带的兴趣声明是最高层——地图作者在数据包里为自家玩法写明调度需求(第 8 章的数据驱动哲学在调度层的延伸),小游戏地图声明「开局需要高频、结算需要原子」,引擎按声明供给。三层从隐到显,恰好把今天三类人的隐性劳动(引擎的内置假设、服主的插件、作者的文档)全部收编为制度。
分片(第 16 章讲过的空间切分)是兴趣模型的执行结构:世界按空间划为调度单元,每个单元持有自己的队列与时钟偏移,玩家兴趣地图决定单元的结算档位。单元之间通过显式消息通信——这里要诚实记下 Folia 的教训:单元切了,接口没设计好,生态就碎了。重写的提案因此多一条硬要求:单元间接口(消息语义、顺序保证、超时行为)必须是一等公民的文档对象,而不是实现细节。红石问题的解法就在这条要求里,下一节展开。
4因果分级:红石、流体与实体各得其所
兴趣解决了「算不算」,剩下「按什么顺序算」。提案的核心制度是因果分级结算:世界里的模拟对象按因果敏感度分三个等级,各自有各自的结算纪律。
严格序区(红石与机器):因果敏感型的模拟(红石信号、活塞联动、一切被玩家当作「程序」的东西)所在的空间,被注册为严格序单元——内部结算完全有序、原子、可复现,等效于今天全局时钟在局部的高保真复制。宽松区(世界背景):流体、作物、自然生长——按降频的批量结算,顺序近似即可,玩家无从察觉也无从依赖。背景区(无人兴趣的远处):只保存状态,不结算,或按统计模型粗算(第 6 章实体 LOD 的推广)。
分级的关键制度设计是:**等级由内容声明,不由系统猜测。**红石机器的作者(或自动的连通图分析)把机器注册为严格序区;农田的作者不在乎顺序,就不注册。这样,严格结算的预算只花在真正需要的地方——万人服务器的算力不再被均匀地浪费在无人区的草地上,而红石玩家的因果纪律得到了比原版更强的承诺(原版的「同刻」其实是全局的恩赐,严格序区把它变成了合同条款)。
「机器的边界在哪里」这个前置问题,有一个工程上成熟的答案:连通图自动发现。红石元件与被它们影响的方块构成一张图(线连着线、火把附着方块、活塞推动目标),从任何一个红石元件出发做图遍历,走到的连通区域就是一台「机器」的自然边界——今天社区画机器图纸时用的正是这张图(第 8 章讲过图纸即电路图)。自动发现不可能完美——图遍历只沿因果边走,边之外的巧合不算依赖——遇到动态扩展(活塞推出的新方块)就即时扩图。自动发现之外,玩家标记永远是兜底与覆盖:人比算法更知道「这些看起来不相连的机器其实是一套」。双重机制的目标只有一个:让「严格序」这个宝贵资源,精准地落在每台机器上,而不是撒在整张地图上。
5实体预算与 LOD:把税写进制度
第 6 章确立了「实体才是税」,提案把这笔税显式化为预算制度:每个调度单元有一个实体结算预算(按重要度加权),超支时自动降级——远处的实体冻结 AI 只留视觉壳(一只远处的牛不再「想」,只是站着),中距实体用简化结算,近处全款。第 6 章讲过的官方减税设计(合并、限期、限额)在此升格为调度器内建的实体 LOD(细节层次)——就像渲染层对远处方块减少三角形(第 9 章),模拟层对远处实体减少「想法」。
预算制度的一个附带收益:实体的性能表现从「玄学」变成「参数」。今天服主说的「实体太多会卡」,明天可以变成「这个区域的实体预算是 N,超标后自动降级为低模」——玩家甚至可以看见自己农场占了多少预算。性能从骂战话题变成资源管理界面,这是把第 16 章「兴趣管理一等公民化」落到普通玩家眼前的样子。
6时间旅行调试:因果可解释的最终形态
第 4 章的回放提案(事件溯源)在调度层的落点是:**严格序区天然可复现,宽松区可记录后复现。**严格序区的结算有序且原子,它的输入日志可以直接重放——红石机器的任何一次故障都可以「倒带」排查;宽松区把结算顺序记录下来也能重放(顺序本身入日志)。调度器由此顺手解决了它自己的调试问题:一个可复现的调度器,报障时能交出的不是玄学描述(「就是会偶尔坏」),是一段可以精确重演的历史。
对红石社区,这还有一层情感意义:第 8 章写过他们的调试器是「看信号灯、拆一半试一半」——一个可回放的调度器等于给这门民科配上了实验室。因果可解释这个不变量(第 3 章列表项)在这里兑现到了极致:不只是「顺序确定」,而是「顺序确定且可重演」。
7红石因果不被拆碎:验收方案
最后正面回答验收题:兴趣驱动的分片会不会把红石因果拆碎?答案藏在「因果所有权」这个设计里:分片的单位是空间,因果的单位是连通图,两者不要求重合。
一台红石机器(自动发现的连通图,或作者显式标记的区域)注册为一个因果单元——单元内部严格序、原子结算,分片怎么切都不影响它(一个单元永不跨结算边界被撕开)。单元之间如果必须交互(一台农场的机器推动另一台),走显式接口:消息传递,语义明确(第 3 章的「跨区语法」)。Folia 的教训由此得到修正:要并行化的不是「空间区域」,是「因果单元」——空间切分只是因果单元的放置结果的物理映射,而不是切分的依据本身。机器跨单元的罕见场景(超大型农场群)由作者显式声明为单一因果单元,调度器为其保留连续结算的领地。
这样,兴趣管理管的是「哪里算得多」,因果单元管的是「按什么顺序算」,两者各司其职:**万人规模靠兴趣省钱,红石纪律靠单元保命——一内核两制度,单人档只是「兴趣半径很小、因果单元很少」的特例。**考题答完。
8这一章留下什么
- 爱好者:你脚下的红石钟在未来引擎里可以「注册为严格序区」——听起来冷冰冰,但它意味着你机器里的每一拍,都被写进了调度器的宪法。
- 开发者:能抄走的是解耦公式——「兴趣决定频率,因果决定顺序」,以及因果所有权设计(连通图注册为原子单元,单元间显式接口);这是 Folia 教训的系统性修正。抄不走的是严格序的兼容存量:决定哪些机器必须严格序的依据,是十五年间长出来的几百万台机器——重写者要先拥有那个社区,才用得起这个制度。