credits.json 数据文件
基本信息
| 属性 | 值 |
|---|---|
| 资源位置 | assets/gtnhcredits/credits.json,即 ResourceLocation gtnhcredits:credits.json(CreditsRepository.java:24;路径常量 CreditsLayout.ROOT / CreditsLayout.CREDITS) |
| 实例级覆盖路径 | config/gtnh-credits/credits.json(Config.java:36) |
| 覆盖规则 | 覆盖文件 isFile() 为真时完全取代打包内的资源(CreditsRepository.java:31-37),不做合并 |
| 加载类 | net.noiraude.gtnhcredits.repository.CreditsRepository(package-private,final) |
| 解析器 | net.noiraude.libcredits.parser.CreditsParser(libCredits 子模块) |
| JSON Schema | credits.schema.json(仓库根目录),文档 credits.schema.md 由 ./gradlew generateCreditsSchemaDoc 生成 |
| 打包内文件体积 | 12 个分类 + 76 条人员记录(见下方「打包内示例数据」) |
加载失败的行为
两种失败都被吞掉并降级为空文档(CreditsRepository.java:39-45):
| 异常 | 触发条件 | 日志 |
|---|---|---|
IOException |
文件读不出来 | Failed to load credits from {路径},附异常堆栈 |
CreditsParseException |
JSON 结构非法(key 不合法、分类项既非字符串也非对象等) | Credits data from {路径} is invalid: {原因} |
界面照常打开,只是分类列表为空。本 mod 不崩溃、不弹窗。
格式
{
"version": 2,
"category": [
{ "id": "dev", "class": ["detail", "person", "role"] }
],
"person": [
{ "name": "Alice", "category": "dev" },
{ "name": "Bob", "category": { "dev": ["core-dev", "backend"] } }
]
}
| 字段 | 必填 | 类型 | 说明 |
|---|---|---|---|
version |
是 | integer | schema 约束「必须 ≥ 2」。运行期解析器不读取、不校验该字段 —— 全仓库对 "version" 的字面量引用只有 CreditsSerializer.java:42 写出时的 root.addProperty("version", 2) |
category[].id |
是 | string | 分类稳定标识,同时作为翻译键后缀与无翻译时的显示回退文本 |
category[].class |
否 | string 或 string[] | 语义标记:person / role / detail。数组内元素需唯一(credits.schema.json:67 的 uniqueItems);运行期解析器用 LinkedHashSet 接收,重复项静默合并而非报错(CreditsParser.java:79-80)。未知值静默忽略 |
person[].name |
是 | string | 显示名,schema 约束 1–80 个可打印 UTF-8 字符且不含控制字符 |
person[].category |
是 | string / object / array | 该人员的分类归属,一条记录内不得重复同一分类 id |
person[].category 的三种写法:
| 写法 | 含义 |
|---|---|
"dev" |
归属 dev,无角色 |
{"dev": "core-dev"} |
归属 dev,角色 core-dev |
{"dev": ["a", "b"]} |
归属 dev,两个角色 |
["dev", {"ops": "sre"}] |
同时归属两个分类 |
键的合法性校验
分类 id 与角色键在运行期由正则 ^[A-Za-z]([A-Za-z0-9 ._-]*[A-Za-z0-9])?$ 校验(CreditsParser.java:30,126-131):必须以字母开头,只能含字母、数字、空格、.、_、-,且必须以字母或数字结尾;schema 另加长度 1–32 的限制。违反则抛 CreditsParseException("invalid category id: \"...\"") / ("invalid role: \"...\"")。
⚠️ person[].name 在运行期完全不做校验 —— parsePerson 直接 obj.get("name").getAsString() 取值(CreditsParser.java:86-89),1–80 字符、无控制字符这些约束只存在于 credits.schema.json(:108-109)中,由构建期测试把关。
⚠️ 分类 id 唯一性、人员的分类引用有效性同样只在构建期校验。实现这两条规则的 CreditsValidator 位于 src/test/java/,只在 ./gradlew test 时运行(CreditsJsonValidationTest.bundledCreditsJsonIsValid);运行期 CreditsParser 不做这两项检查。schema 文档里标注的「build-enforced」即指此。
排序与去重
- 解析后排序:
CreditsParser解析完成后按去掉§颜色码后的名字做不区分大小写的字母序排序(CreditsParser.java:66)。 - 界面内去重:同一分类下多条同名记录会合并,角色取并集并保留首次出现顺序,合并键同样先剥掉颜色码(
CreditsController.java:107-128)。 - 索引越界保护:
getSelectedCategory()会把索引钳到size - 1(CreditsController.java:97);分类为空时返回null,界面正文不渲染任何内容(CreditsContentRenderer.java:58)。
打包内示例数据
src/main/resources/assets/gtnhcredits/credits.json(version: 2)是一份演示 / 测试夹具,不是真实名单 —— 含 loremipsum、Key Test、No-Trans Cat、Empty View、Indexed Detail、NewCat 等测试用分类。
| 分类 id | class | 人员条目数 |
|---|---|---|
Mod authors |
detail, person, role | 43 |
contrib |
detail, person, role | 19 |
support |
detail, person | 7 |
dev |
detail, person, role | 5 |
team |
detail, person, role | 2 |
Key Test |
detail, person, role | 2 |
No-Trans Cat |
detail, person | 1 |
thanks |
detail | 0 |
loremipsum |
detail | 0 |
Empty View |
detail, person | 0 |
Indexed Detail |
detail | 0 |
NewCat |
(无 class 字段) | 0 |
共 12 个分类、76 条人员记录、43 个不同角色键。人名包括 Ada Lovelace、Alan Turing、Albert Einstein 等示例人物。
真实的 GTNH 名单由整合包通过 config/gtnh-credits/credits.json 覆盖提供;en_US.lang 里已备好 credits.category.project_leadership、credits.category.original_mod_authors、credits.category.mod_development 等正式分类的翻译键,但这些分类并不在打包内的 credits.json 里。
编辑方式
- 官方推荐用同仓库的独立 Swing 桌面工具 —— 见 GTNH Credits 编辑器。
- 也可用资源包覆盖
assets/gtnhcredits/credits.json:走标准资源管理器加载,因此资源包能替换打包内文件(README.md「Resource files」节)。 - 实例级覆盖
config/gtnh-credits/credits.json优先于资源包,因为CreditsRepository先判断该文件是否存在,存在就直接FileInputStream读取,不经过资源管理器(CreditsRepository.java:31-37)。
相关条目
- lang 语言文件 - 分类名、分类描述与角色名的翻译键体系
- Credits 界面 - 消费本文件并按
class渲染的界面 - GTNH Credits 配置 - 决定覆盖文件路径的配置
- GTNH Credits 编辑器 - 可视化编辑本文件与 lang 的桌面工具