补充描述文本
本节为本章已制作的舰船、战机与武器补上描述文本。您将先处理 CSV 的列边界和文本转义,再把描述行登记到对应对象上,在游戏界面中确认它们已经被读取。
本节预期阅读时间:~15 分钟。
本节预期操作时间:~30 分钟。
学习目标
- 正确书写 CSV 的空列、英文逗号、双引号和多行文本;
- 使用表头、行首注释与 UTF-8 无 BOM 保存描述文件;
- 根据船体 ID 和武器 ID 注册
SHIP、WEAPON描述行; - 在舰队、装配、货舱和数据库界面验证描述文本。
前置知识
- [C1-S1] 的 MOD 目录、
gear_in与GearIn_数据前缀; - [C1-S2] 的
.ship、ship_data.csv与 CSV 分隔符; - [C1-S3] 的战机船体、装配和联队 ID;
- [C1-S4] 的相位舰船体 ID;
- [C1-S5] 的
weapon_data.csv、武器 ID 与控制台获取方法。
保持 CSV 的列边界
CSV 用半角逗号分隔字段,首行的列名决定后面每个字段的含义。descriptions.csv 使用下面的表头:
id,type,text1,text2,text3,text4,text5,notes
每条描述记录必须与这个表头保持相同的列数。两个分隔逗号之间为空时,该列留空;末尾留空的列也必须保留分隔逗号。例如,只有 id、type 和 text1 有内容的局部片段:
GearIn_durin,WEAPON,拥有可怕射速的自动炮,成箱地发射高爆弹药。,,,,,
这里 text2、text3、text4、text5、notes 均为空。判断一条记录有多少列时,要看引号外的分隔符;文本本身也可能包含逗号。
用双引号包住含逗号的字段
字段内含英文逗号时,必须用一对半角直双引号包住整个字段。引号内的逗号属于文本,引号外的逗号才分隔列。守炉人的局部描述片段如下:
GearIn_artizan,SHIP,"对锤头-级驱逐舰进行部件替换的尝试,它搭载了比想象中更高端的武器配备,和一副实验性抵抗力场。",这是一艘驱逐舰。,,,,
text1 中的英文逗号被保留为正文。中文逗号属于普通文本,可以直接书写。
把文本里的双引号写成两个
字段内需要显示一个双引号时,必须把它写成两个连续的双引号 "",并用一对双引号包住整个字段。乌里光束的局部片段可以这样写:
GearIn_uri,WEAPON,"这门武器偶尔也被称为 ""热熔枪""。",,,,,
界面显示的名称两侧各有一个双引号。外层引号负责字段边界,内层的双写引号负责文本字符,它们承担不同职责。
把多行文本放进同一个字段
字段内含换行时,必须用一对双引号包住整个多行字段。工匠的局部片段如下:
GearIn_furnaceman,SHIP,"守炉人-级轻型航母以两座甲板提供持续空中掩护,自身保留可观的结构。
即使略显无趣,但依然可堪一用。",这是一艘中坚航母。,,,,
这段内容仍是一条描述记录。text1 保留换行,界面可将正文分段显示;引号外的换行才结束当前记录。
文本转义必须先于对象检查
含英文逗号、双引号或换行的字段必须按 CSV 规则包络与转义。字段边界写错后,文本可能被截断、进入其他列或造成加载失败;排错时先确认字段边界,再核对对象 ID。
用行首井号写注释
行首第一列的 # 表示整行注释,可以保存说明或暂时停用一条描述。局部片段如下:
# 齿轮工业的武器描述
GearIn_durin,WEAPON,拥有可怕射速的自动炮,成箱地发射高爆弹药。,,,,,
注释行被跳过,后面的武器行正常读取。多行描述字段中的字符属于该字段的文本,整行注释写在描述记录之间。
保存文本编码
文件必须使用 UTF-8 无 BOM,CSV 的包围引号必须使用半角直双引号 "。BOM 会污染首列表头,错误编码会让中文显示异常;弯引号的转换也不能代替正确的字段转义。
编者在编写描述时会统一给正文加上外层引号,再按需要转义其中的引号。文字可以继续改,字段边界先保持清楚。
创建描述文件
在 MOD 内创建 data/strings/descriptions.csv,写入表头。游戏会自动读取这个固定路径,合并描述数据,再按 id 与 type 查询文本。
id 与 type 共同确定一条描述。两列必须有内容,type 必须逐字符匹配类型名,大小写属于名称的一部分;空键行会被跳过,非法类型会中止加载。
同一文件中的 id + type 必须唯一,重复组合会造成加载失败。MOD 自有描述必须使用自己的对象键,严禁重复登记原版或其他 MOD 已有的同键描述。
描述缺失可能只显示占位文本
对象已有数据而描述行缺失时,界面可能显示 No description... yet。加载成功只说明文件可以读取;确认描述属于哪个对象,还要检查 id、type 和实际显示位置。
为已有对象登记描述
舰船和战机都使用 SHIP。本章的基础船体使用 .ship 中的 hullId 作为描述键,武器使用 weapon_data.csv 的 id 并填写 WEAPON。
战机联队通过装配找到战机船体,再读取船体描述。[C1-S3] 的炉渣联队 GearIn_slag_wing 使用 GearIn_slag_normal 装配,该装配的 hullId 为 GearIn_slag,因此描述行的 id 必须填写 GearIn_slag。
既有对象描述注册速查表
| 对象 | 描述行的 id | type | ID 来源 |
|---|---|---|---|
| 工匠-级驱逐舰 | GearIn_artizan | SHIP | [C1-S2] 的船体 |
| 守炉人-级轻型航母 | GearIn_furnaceman | SHIP | [C1-S3] 的船体 |
| 炉渣-级战机 | GearIn_slag | SHIP | [C1-S3] 的战机船体 |
| 锻件-级相位护卫舰 | GearIn_forging | SHIP | [C1-S4] 的船体 |
| 都林自动炮 | GearIn_durin | WEAPON | [C1-S5] 的武器 |
| 乌里光束 | GearIn_uri | WEAPON | [C1-S5] 的武器 |
| 德瓦林发射架 | GearIn_dwalin | WEAPON | [C1-S5] 的武器 |
text1 保存详细描述,舰船可以用 text2 写一句简略引言。本节的船体说明同时填写这两列,武器说明填写 text1,其余文本列保持空值。
舰船引言在 text2 有内容且 text3 为空时使用 text2;数据库详情读取 text1,战机详情读取对应船体的 text1。文本列的完整用途和描述键扩展由 [C3-S5] 讲解。
描述在界面中的显示位置
在武器 tooltip 中,观察详细说明与数据面板的相对位置:

数据面板上方的段落是详细说明,面板中的定位文字与数值来自武器数据。确认注册结果时,用您写入的正文核对说明区域。
在舰船详情中,观察船体标题下方的正文:

船体详情读取详细描述,舰队悬停引言则按文本列选择简略说明。观察两处内容可以分别确认 text1 和 text2。
完整最小例
将以下内容写入 gear_in 的 data/strings/descriptions.csv。文本和上述示例并不完全相同,因为上述示例虽然能够一定程度上讲清机制,但作为文本而言并不怎么能看:
id,type,text1,text2,text3,text4,text5,notes
GearIn_durin,WEAPON,"都林自动炮是一门口径小、射速极快的近距实弹炮。密集的破片在短距离内对护盾有不错的压制效果,但离开射程就毫无用处。",,,,,
GearIn_uri,WEAPON,"乌里光束在中距离持续照射目标,产生稳定的能量伤害与幅能负担。光束本身没有击退力,需要持续瞄准。",,,,,
GearIn_dwalin,WEAPON,"德瓦林发射架向远距离目标倾泻高爆火箭。备弹有限,装填缓慢,但每一发都对装甲构成实质威胁。",,,,,
GearIn_artizan,SHIP,"工匠-级是一艘以导弹见长的驱逐舰。它把锤头-级的中实弹槽位换成了中通用,可以安装强力的导弹武器。",这是一艘中坚驱逐舰,,,,
GearIn_furnaceman,SHIP,"守炉人-级轻型航母以两座甲板提供持续空中掩护, 自身保留可观的结构。",这是一艘轻型航母,,,,
GearIn_slag,SHIP,"炉渣-级是一款廉价的重型战机,装备双管轻型自动炮。",这是一种重型战机,,,,
GearIn_forging,SHIP,"锻件-级相位护卫舰围绕一门中型实弹槽位设计,用相位机动躲避火力。",这是一艘相位护卫舰,,,,
验证方案
前置数据:已启用 Console Commands,并完成 [C1-S2] 至 [C1-S6] 的船体、联队、武器和内置配置。
- 保存描述文件并启动游戏,在
starsector.log中查找Loading descriptions,确认描述文件加载阶段完成。 - 打开生涯控制台,分别执行
Addship GearIn_artizan、Addship GearIn_furnaceman、Addship GearIn_forging和Addwing GearIn_slag_wing。 - 执行
Addweapon GearIn_durin、Addweapon GearIn_uri、Addweapon GearIn_dwalin,在货舱中逐个悬停武器,核对详细描述。 - 在舰队界面依次悬停工匠、守炉人和锻件,核对简略引言。
- 进入守炉人的装配界面,悬停炉渣联队,核对显示的是炉渣船体的描述。
- 打开数据库 (codex),分别查看工匠、守炉人、锻件、炉渣及三门武器的详情,核对
text1。 - 给工匠的
text1加入一段文字并保存,重启后打开工匠详情,核对新增段落。
预期结果:
- 描述文件加载完成,日志中本节对象的描述数据没有解析异常;
- 货舱中的三门武器显示各自
WEAPON行的正文; - 工匠、守炉人和锻件的舰队引言显示各自
text2; - 炉渣联队读取
GearIn_slag,SHIP的正文; - 数据库各对象详情显示与其描述行一致的
text1; - 保存并重启后,工匠详情显示新增段落。
故障分析
加载时报
Mismatched quotes in the string; last quote: [...]:字段包围引号或内部双引号转义不完整。- 解决方案:用一对直双引号包住整个字段,字段内的每个双引号写成
"",保存后重启。
- 解决方案:用一对直双引号包住整个字段,字段内的每个双引号写成
文本截断或进入其他列:英文逗号或多行文本改变了字段边界。
- 解决方案:为整个字段补齐包围引号,使记录与表头列数一致。
加载时报
Key [type] has invalid value [...]:类型名称的拼写、大小写或首尾空格与枚举名不一致。- 解决方案:舰船和战机填写
SHIP,武器填写WEAPON,保存后重启。
- 解决方案:舰船和战机填写
加载时报
Duplicate key [...] while loading [data/strings/descriptions.csv ...]:同一文件中重复登记了相同的id + type。- 解决方案:每个对象与类型组合只保留一条描述记录,保存后重启。
加载时报
JSONObject["id"] not found:BOM 或错误表头改变了首列名称。- 解决方案:恢复标准表头并以 UTF-8 无 BOM 保存,重启。
对象显示
No description... yet或其他对象的文字:描述键、类型或text1与目标对象不对应。- 解决方案:从船体的
hullId或武器数据的id开始,核对描述行的id、type与正文。
- 解决方案:从船体的
舰船引言显示长描述的第一段:
text2为空,或text3已有内容。- 解决方案:把简略引言写入
text2,并保持本节船体行的text3为空。
- 解决方案:把简略引言写入
修改描述后显示内容保持原样:游戏仍使用启动时加载的文本,或当前查看的对象使用其他描述键。
- 解决方案:保存并重启,再核对该对象实际使用的描述行。
总结
CSV 的表头与分隔符确定列,包围引号保护文本里的逗号和换行,双写引号保留正文中的引号。描述注册把对象 ID、类型和文本放在同一条记录中,界面再按对象读取它。
本章的舰船与战机使用船体 ID 的 SHIP 行,武器使用武器 ID 的 WEAPON 行。文件能够加载之后,还要亲自打开每个对象的详情;有文字出现和出现您刚写的文字,是两件值得分别确认的事。
建议参考项
data/strings/descriptions.csv:对象描述的固定注册路径和标准表头;data/hulls/ship_data.csv:舰船与战机船体 ID;data/hulls/wing_data.csv:战机联队与装配的对应关系;data/weapons/weapon_data.csv:武器 ID。