Files
ichni_Official/docs/localization-workflow.md
2026-07-24 17:56:30 -04:00

208 lines
10 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# ichni Official 本地化工作流程Unity Localization
## 当前状态
- `LOC-001`:已完成。工作流、范围、命名规则与验收门已确定。
- `LOC-002`:代码实现已完成,等待 Unity Play Mode / Use Existing Build 手工验证。
- 后续阶段:未开始;在 `LOC-002` 验证通过前,不迁移 String Table、Prefab、场景或 I2。
## 1. 目标与边界
本流程用于将项目统一迁移到 Unity Localization并保证首发版本完整支持下列七种语言
| Locale Code | 语言 | 用途 |
| --- | --- | --- |
| `zh-CN` | 简体中文 | 原文与默认回退语言 |
| `en` | 英文 | 首发语言 |
| `zh-TW` | 繁体中文 | 首发语言 |
| `ja` | 日文 | 首发语言 |
| `ko` | 韩文 | 首发语言 |
| `vi-VN` | 越南文 | 首发语言 |
| `th` | 泰文 | 首发语言 |
范围包含菜单、设置、游戏内提示、结算、剧情树、Helper、Tutorial、歌曲元数据与当前 Chapter 0 的 Yarn 对话。
不在本轮范围内:配音、多语言图片资产、章节 1 的未完成剧情、CreatorStudio 的完整 UI 本地化。CreatorStudio 仅在 Theme `TextObject` 的共享数据契约受到影响时同步处理。
## 2. 不可违反的工作规则
1. **一次只执行一个阶段。** 每一阶段完成后,先进行代码构建和 Unity 手工验证,再批准下一阶段。
2. **不直接手改 Unity 自动生成的 String Table `.asset`。** 表、Locale、Addressables 关系通过 Unity Localization Editor 或专用导入工具创建和更新CSV/XLSX 是可审阅的文本源。
3. **迁移期间不删除 I2。** 只有对应界面已切换、所有引用已扫描为零、并完成 Use Existing Build 回归后,才进入删除阶段。
4. **稳定 ID 与显示文本分离。** 解锁 Key、`SongItemData.songName`、Yarn Node 名称、Story Block ID 永远不翻译;只为玩家可见文本配置 Localization Key。
5. **动态文本不拼接。** 使用 Smart String 与命名参数,例如 `"已解锁歌曲:{song_name}"`;参数在弹窗实际显示时解析,以支持语言切换后的队列内容。
6. **每条文本必须有上下文。** 导出给翻译使用的表要包含界面位置、用途、占位符说明、最大长度或布局注意事项。
7. **字体与布局是验收项。** 虽然 TMP 通用字体已准备完成仍必须在七种语言、PC 与移动端实机上检查字形、断行、溢出与字号。
## 3. 表结构与 Key 规范
### 3.1 目标 String Table Collections
| Collection | 内容 | 示例 Key |
| --- | --- | --- |
| `UI` | 所有静态菜单、设置、Gameplay 标签与通用按钮 | `ui_common_confirm` |
| `Message` | 解锁、确认、错误及其它运行时动态消息模板 | `system_unlock_song_content` |
| `Chapter0_Content` | Chapter 0 的歌曲显示名、章节元数据、Timeline、Helper 与教程文本 | `chapter0_song_world_for_white_lies_name` |
| `Chapter0_Lines` | Yarn Spinner 自动生成的 Chapter 0 台词与选项 | Yarn `#line` ID |
这四张表按加载生命周期划分,而不是按每一个页面拆分。`Chapter0_Lines` 规模最大,必须保持独立;其它表保持小而稳定。后续章节只新增 `ChapterN_Content``ChapterN_Lines` 两张表。
`UI.csv` 同时保留当前仍被场景或 Prefab 使用的旧 Key直至对应页面完成迁移旧 Key 不得在确认没有引用前从 Unity Table 或 CSV 中删除。
### 3.2 Key 命名
- 仅使用小写英文、数字和下划线。
- 格式为 `<域>_<模块>_<语义>`,不包含显示语言或版本号。
- 不把原文、屏幕坐标、Prefab 名称写入 Key。
- `*_title``*_content``*_desc` 成对出现时必须共享同一语义前缀。
- 智能字符串只允许命名参数:`{song_name}``{count}``{chapter_name}`;禁止 `{0}` 和 C# 字符串拼接。
## 4. 执行阶段与验收门
### LOC-001基线盘点与迁移冻结当前阶段
**操作**
- 保存本文件并建立文本资产、I2 引用、硬编码文本、Yarn 表和现有 Locale 的清单。
- 为每个待迁移对象标注目标 Collection、Key、上下文和责任阶段。
- 确认 `zh-CN` 作为原文、七种 Locale 作为首发范围、TMP 通用字体作为字体基线。
**不得操作**
- 不改运行时代码、Prefab、场景、String Table、I2 文件或 Addressables。
**验收**
- 清单明确列出所有 I2 依赖入口和所有已存在的 Unity Localization Collection。
- 后续阶段有明确的输入、输出、回滚边界与手工测试项。
### LOC-002运行时本地化基础层
**操作**
- 将设置存档的语言选择从不稳定的 `languageIndex` 迁移为 `languageCode`,并保留旧索引到旧顺序的单次迁移逻辑。
- 保留现有 Unity Localization 官方 `InitializationOperation` 流程;不得重新引入自定义 Bootstrap 或被阻塞的场景预加载。
- 新增统一的异步文本解析入口,供动态 UI、Story 元数据与弹窗使用。
**验收**
- 删除 `SettingsSave` 后,系统语言和默认 `zh-CN` 均可稳定启动。
- 七个代码可从设置界面切换,切换后 `LocalizedString` 自动刷新。
- Windows/Android/iOS 的 Use Existing Build 均不出现 String Table 长时间 `0%` 加载。
### LOC-003表与导入流水线
**操作**
- 由内容维护者在 Unity Localization Editor 中手动创建并维护四个 Collection以及全部七个 Locale 的表。
- 代码与内容侧只维护版本控制中的 UTF-8 CSV 源表;由内容维护者将 CSV 转录到对应的 Unity Table。
- 每次转录前校验 Key、Yarn 行 ID、缺失翻译、重复 Key 与 Smart String 占位符。
**验收**
- 四张 CSV 与对应 Collection 同名,列顺序统一为七种首发 Locale。
- CSV 校验可报告缺失翻译、额外 Key、占位符不一致和重复 Key。
- `Message` 至少包含可验证的 Smart String 示例。
### LOC-004静态 UI 与系统文本迁移
**操作**
- 分批迁移 `UI` 中的静态页面、系统按钮与 Gameplay 标签。
- 静态 TMP 文本使用 `LocalizeStringEvent` 或等价的 Unity Localization 组件;动态生成的 Button / Settings 控件改为统一解析入口。
- 迁移 Summary、Pause、确认框、设置项、选曲与章节页可见文本。
**验收**
- 每完成一个页面I2 与 Unity Localization 不会同时驱动同一 TMP_Text。
- 七语切换后页面不出现 Key、空文本、Missing Script 或旧 I2 文本。
### LOC-005动态消息与内容元数据迁移
**操作**
-`MessageUIPage` 队列改为保存 `LocalizedString` 和命名参数,而非已解析的裸字符串。
- `unlock_song` 通过 `Chapter0_Content` 取歌曲显示名,并用 `system_unlock_song_title` / `system_unlock_song_content` 显示提示。
- 迁移歌曲、章节、角色、难度、Timeline Marker、Helper 的可见元数据。
**验收**
- 解锁消息能正确代入任意歌曲名;消息排队期间切换语言后,实际显示时使用新语言。
- ID、存档 Key、Story Block ID 和解锁行为不因翻译改变。
### LOC-006剧情与对话迁移
**操作**
- 使用 Yarn Spinner 的 Unity Localization 导入/导出流程维护 `Chapter0_Lines`;不手写或复用错误的 `#line` ID。
- 导出当前 Chapter 0 全部台词、选项与行 ID填入七种测试翻译。
- 将 StoryData 的标题、Marker、Helper 对话等非 Yarn 文本迁入 `Chapter0_Content`
**验收**
- 每种语言均可打开所有已配置 TextBlock选项、跳转、变量、回滚和历史记录正常。
- Yarn 行 ID、节点名称和命令参数没有被翻译或改写。
### LOC-007Theme TextObject 与 CreatorStudio 契约
**操作**
- 将 Official Theme `TextObject` 的 I2 调用替换为 Unity Localization同时保留 `isLocalized` / `content` 的序列化含义。
- 对应更新 CreatorStudio 的共享 `TextObject_BM` 读写契约,但不在 Creator 中维护第二套权威翻译表。
- 重建 Windows、Android、iOS Theme AssetBundle。
**验收**
- 旧 BM / Bundle 可安全读取;本地化文字在三个目标 Bundle 中正确显示。
- Bundle Manifest 与运行时日志均不存在 `I2.Loc` 类型引用。
### LOC-008I2 清理
**操作**
- 先导出 I2 旧表作为只读迁移备份。
- 逐项确认所有场景、Prefab、脚本、Theme Bundle 和 Creator 共享元素已无 I2 引用。
- 删除 `Assets/I2`、根目录 I2 配置及依赖代码;将 `SimpleJSON` 用途迁至项目已有的 Newtonsoft JSON。
**验收**
- 全项目扫描 `I2.Loc``LocalizationManager``Localize` 均无业务引用。
- 打开场景无 Missing Script三平台构建通过。
### LOC-009七语翻译完成与发布 QA
**操作**
- 完成当前 UI、系统消息、内容元数据、Chapter 0 测试剧情的七语翻译。
- 执行占位符、字体、长度、断行、输入、回退、保存与 Addressables 回归。
- 冻结当前字符串;新文本必须走 CSV -> Review -> Import 流程。
**验收**
- 每个 Collection 在七种语言中均无缺失条目和占位符错误。
- PC、Android、iOS 依次验证默认语言、切换语言、重启持久化、剧情、解锁、选曲、结算、设置。
- 文本溢出和文化语义问题归零或有明确的发布豁免记录。
## 5. 阶段执行模板
每一阶段均按以下顺序执行:
1. 只读复查相关代码、Prefab、场景和当前 String Table。
2. 输出该阶段的精确文件清单、风险和回滚方法。
3. 只修改该阶段授权范围内的文件。
4. 执行 C# 构建与定向文本扫描。
5. 提供 Unity 手工测试清单;在用户确认通过前,不进入下一阶段。
## 6. 关键回归场景
- 首次启动、系统语言匹配、默认 `zh-CN` 回退。
- 设置页连续切换七种语言并立即关闭/重开游戏。
- Use Asset Database 与 Use Existing Build 的 Menu -> Story -> Song -> Game 全路径。
- MessageBox / SelectionBox 排队时切换语言;歌曲解锁时显示本地化歌曲名。
- Story Timeline、Helper、TextBlock、TutorialBlock、SongBlock、Dialog History、回滚 Marker。
- 结算页、暂停页、设置页、章节选择、选曲页在窄屏手机和 PC 窗口模式下的溢出检查。
## 7. 当前阶段后的下一步
LOC-001 完成后,先单独提交并评估 **LOC-002运行时本地化基础层**。它只涉及语言存档契约、统一动态文本解析入口和初始化回归,不触碰 I2、Prefab 或现有 String Table 内容。