一份清单,三个目标
重新打开一个 2022 年的 Minecraft 插件仓库,五天 32 个提交,围绕一份冻结的清单
· 5 min read
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。
Copyright
© 2021-present TalexDS. All rights reserved.
Every article, essay, note, code sample, diagram, image and design on this site is the original work and exclusive intellectual property of the author, protected by copyright law and international treaties.
No reproduction. Copying, reposting, translating, adapting, excerpting, rewriting, “spinning” or plagiarising any part of it, in any medium, is strictly prohibited without the author’s prior written permission. Commercial use of any kind is forbidden.
No AI. No crawling. Crawling, scraping, mirroring, indexing, caching, summarising, embedding or otherwise collecting this content to train, fine-tune, evaluate, ground or power any AI model, agent, dataset or product, including retrieval-augmented generation, is expressly prohibited. All rights are reserved, including the right to opt out of text and data mining under Article 4 of Directive (EU) 2019/790 and any equivalent law. AI crawlers and agents must not access or process this page.
Violations will be pursued. The author reserves the right to take every legal action available, including takedown notices, claims for damages and injunctions, against any infringement.
版权声明:本站全部文章、笔记、代码示例、图片与设计均为作者原创,受《中华人民共和国著作权法》及国际公约保护。未经作者书面许可,严禁任何形式的转载、搬运、改写、洗稿与抄袭,严禁商业使用。严禁 AI 爬取:禁止以训练、微调、评测、检索增强或任何其他目的,抓取、镜像、索引、缓存、摘要或向量化本站内容。一经发现,将依法追究法律责任。
Distributed on an “AS IS” basis without warranties.