TalexSoulTech 在 GitHub 上的简介是一句英文,到现在还是那句,大意是 PaperSpigot 的附属插件,只支持 1.12.2。

这个仓库是 2022 年 2 月 4 号建的。那天下午 5 点 33 分和 5 点 36 分有两个提交,一个叫 @initial 2.0.0,一个叫 @initial,隔了三分钟。然后它安静了四年多。2026 年 8 月 24 号我重新打开它,早上 8 点 57 分进来第一个提交,215 个文件,+17,475 -4,281;三分钟后的第二个是站点和资源包,+11,723。到 28 号一共 32 个提交(26 号那天没有)。现在 README 里写的是 Paper 26.1.2 和 Java 25,编出来的 JAR 叫 3.0.0-SNAPSHOT,简介没跟着改。

说起来,从 2.0.0 到 3.0.0 隔了四年多,这篇只讲后面这五天。

一份清单

README 的体系结构一节,开头是这么一句:一份冻结的清单生成三个目标,三者的物品身份必须一致。那份清单是个 JSON 文件,叫 catalog-runtime.json。三个目标,一个是打包进 JAR 的运行时注册表,插件读的就是这同一个文件;另外两个是资源包和站点上的目录,由同一个脚本生成。

插件之外还有一个跑在 Cloudflare Worker 和 D1 上的站点,管多租户的后台和服务器快照同步。资源包是用同一份清单确定性生成的,跑两遍结果一样(8 月 27 号那次发布的验证里,专门写了重复生成一致)。

生成出来的东西是直接提交进仓库的。8 月 27 号那个把全部目录注册进运行时的提交,一次加了十三万多行,GitHub 列出来的文件里最大的是资源包的清单,一个文件就加了 24,116 行。确定性生成大概就是为这个:生成物进了仓库,每次生成得一样,不然 diff 里全是噪音。

只留一个生成入口,我觉得这个设计挺干脆。但 README 紧跟着有一句:这个脚本还要把编好的 JAR 复制到站点的下载目录,JAR 不存在它就失败,发布站点之前必须先编一遍插件。一致性的代价,是发布站点之前得先有一个编好的 JAR。这笔账划不划算,我现在还说不准。

两套 ID

数字我是对着 8 月 27 号那次发布记的:810 条规划条目全部落到运行时,计划中的是 0;运行时记录 926 条;27 个学科,270 个族,9 个战役波次。

810 和 926 差了 116。CHANGELOG 里有三个数:新注册的运行时物品 776 条,显式的旧 ID 映射 34 条,原来的基线记录 150 条保持不变。776 加 34 是 810,776 加 150 是 926,所以我算出来,有 116 条运行时记录在规划里没有对应的条目(150 减 34)。CHANGELOG 里没有这样写,是我自己算的。

README 里还有一句:规划身份和运行时身份是两套 ID,点分的规划 ID 不是命令 ID,真正的运行身份要从站点的 /runtime 拿。我猜这两套 ID 就是这么来的:有一部分东西先于清单存在,只能映射,没法改名。README 没说为什么。

还有一个小数字:站点上的目录状态,在发布那天从 49 条已实现、761 条计划中,改成了 810 条已实现、0 条计划中。49 加 761 也是 810。清单是同一份,站点上显示的进度却可以落后,这件事也在同一天修了。

记账

32 个提交里,10 个叫 chore(task): archive(8 月 25 号 5 个,27 号 5 个),2 个是 journal,这 12 个都是在记账,占了三分之一多。27 号晚上 9 点 52 分,同一分钟里进了 5 个提交,4 个是 archive。标着 feat 或 fix 的一共 10 个。

CHANGELOG 里每次都有一张「发布身份」的表,源码修订,JAR 的哈希,资源包的哈希。三次发布的版本号都是 3.0.0-SNAPSHOT,靠这张表区分,下一次起才会改成正式的语义化版本号。8 月 25 号那次加了 50 条电力条目,47 件便携的,3 个无线充电的多方块;27 号那次,真实的 26.1.2 客户端抓到 834 个自定义模型,一个缺纹理的都没有。

简介还停在 1.12.2。