Files
aibis-dream/Docs/HuoShan/HuoshanStage6LocalizationPlan.md
T

16 KiB
Raw Blame History

火山 Stage6 本地化完整实施计划

1. 目标与边界

Stage6 继续使用项目现有的两套本地化入口:

  • 固定 UIUnity Localization 的现有 UIText String Table Collection。
  • Stage6 玩法及演出内容:新增独立的 HuoshanStage6 String Table Collection。
  • Yarn 普通对白:继续沿用项目 Yarn Spinner 本地化体系,但本轮不启用 FP_Huoshan1 的整章对白翻译。
  • params.csv 继续只用于 l10n.* 通用短语替换,不承载 Stage6 玩法文本。

本轮纳入:

  • 表达小游戏目标、输出、整合率、干扰数量等固定 UI。
  • 三轮语言粒子的目标句和干扰 token。
  • LOG3 释放演出中的攻击词、稳定词、失稳词等动态文字。
  • 相关程序接口、Yarn 命令协议和使用文档。
  • 中、英、日三种语言数据;英日文首版标记为待母语审校。

本轮明确暂缓:

  • 普通角色对白。
  • Task 面板中的“释放表达模块的阻塞 log”和 LOG1/2/3 任务提示。
  • “左键排斥、右键吸引”等 Yarn 操作教学。
  • Yarn line tag 和 Yarn 本地化 CSV。
  • 调试日志、Inspector Tooltip、对象名、节点名等开发文本。

因此,本轮完成后核心小游戏及释放演出可以多语言运行,但任务面板与操作教学仍会显示中文,等待之后随对白本地化统一处理。

2. 本地化数据结构

2.1 固定 UIUIText

继续使用现有键,不新建重复条目:

Key 用途 中文示例 英文草稿 日文草稿
huoshan_expression_objective 小游戏目标 目标:分离红色干扰,连接蓝色真心 OBJECTIVE: ISOLATE RED INTERFERENCE. CONNECT THE BLUE TRUTH. 目標:赤い干渉を分離し、青い本音をつなげる
huoshan_expression_output 输出按钮 输出 OUTPUT 出力
huoshan_expression_integration 整合率 语言整合率:{0}% LANGUAGE INTEGRATION: {0}% 言語統合率:{0}%
huoshan_expression_interference 干扰数量 干扰思绪:{0} INTERFERENCE SIGNALS: {0} 干渉思考:{0}

要求:

  • 保留 {0} 参数,程序继续通过格式化参数填入数值。
  • 英文和日文目前的中文占位必须替换。
  • 固定 UI 继续使用现有 LocalizeStringEventStringDatabase 绑定。
  • 切换 Locale 时立即刷新这些固定 UI。

2.2 玩法内容:HuoshanStage6

新增 String Table Collection

HuoshanStage6
├─ zh-Hans
├─ en
└─ ja-JP

键名只表达语义,不包含语言、行号或 Yarn 节点名。

语言粒子数据

round.log1.target
round.log1.interference_tokens

round.log2.target
round.log2.interference_tokens

round.log3.target
round.log3.interference_tokens

中文源数据:

Key 中文值
round.log1.target 我就是个笑话
round.log1.interference_tokens 哈哈|嘿嘿|呵呵
round.log2.target 不要离开我
round.log2.interference_tokens 哈哈哈|嘿嘿嘿|呵呵呵|笑死了|好好笑
round.log3.target 不要那样看我
round.log3.interference_tokens 哈哈哈哈|笑死我了|太好笑了|绷不住了|笑不活了|真的太搞笑

interference_tokens 的表值使用 | 分隔。解析规则:

  • | 拆分。
  • 对每项执行 Trim。
  • 丢弃空项。
  • 至少保留一个有效 token,否则视为数据错误。
  • token 由本地化人员针对语言重新创作,不要求与中文逐字对应。
  • 英文示例:HA|HAHA|LOL|JK
  • 日文示例:ハハ|笑|冗談|ウケる

LOG3 释放演出数据

按语义建立以下键;重复演出复用同一个键:

release.attack.why
release.attack.dont_believe_me
release.attack.i_know_im_last
release.attack.bad_weather
release.attack.cannot_sell
release.attack.try_to_explain
release.attack.refuse_to_believe
release.attack.a_little_trust
release.attack.had_enough
release.attack.damn
release.attack.useless
release.attack.prove_myself
release.attack.cannot_do_anything
release.attack.catch_up
release.attack.help_yingli
release.attack.no_courage
release.attack.say_it
release.attack.trash
release.attack.hopeless
release.attack.why_loop

release.settle.want_to_win_once
release.destabilize.dont_look_at_me

映射规则:

中文文本 Key
为什么 release.attack.why
不相信我 release.attack.dont_believe_me
我明白我垫底 release.attack.i_know_im_last
天气真的不行 release.attack.bad_weather
卖不出去 release.attack.cannot_sell
努力解释 release.attack.try_to_explain
不愿意相信我 release.attack.refuse_to_believe
一点信任 release.attack.a_little_trust
受够了 release.attack.had_enough
真该死 release.attack.damn
真没用 release.attack.useless
证明自己 release.attack.prove_myself
什么都做不到 release.attack.cannot_do_anything
追上你 release.attack.catch_up
帮到英理 release.attack.help_yingli
没有勇气 release.attack.no_courage
说出来 release.attack.say_it
废物 release.attack.trash
烂泥扶不上墙 release.attack.hopeless
为什么为什么 release.attack.why_loop
我想赢一次 release.settle.want_to_win_once
不要那样看我 release.destabilize.dont_look_at_me

Yarn 中重复出现的“受够了”“废物”“为什么为什么”继续保持原来的重复次数和演出参数,只复用同一条本地化键,不能因去重而改变演出节奏。

未来如果 Stage6 使用 expression_system_message 或其他会显示字符串的释放命令,也必须新增对应的 release.* 键,不能直接写玩家可见文本。

2.3 表格元数据

英日文第一版可以直接投入开发测试,但每个非中文条目增加统一备注:

DRAFT / NEEDS NATIVE REVIEW
Context: HuoShan Stage6 expression minigame

释放演出条目应额外注明:

  • 显示形式,例如瞬间闪现、连续攻击或最终稳定文字。
  • 建议长度。
  • 是否允许创译。
  • 重复次数由 Yarn 控制,本地化值本身不要手工重复。

3. 程序接口和数据流

3.1 本地化引用协议

Yarn 命令参数支持两种输入:

@h6.<entry-key>   从 HuoshanStage6 String Table 解析
普通字符串         按原始字符串使用,保持旧内容兼容

示例:

<<start_expression
    "@h6.round.log1.interference_tokens"
    "@h6.round.log1.target"
    "LOG1梳理完成"
    16>>

<<expression_truth_attack "@h6.release.attack.why" 0.30 0.32>>
<<expression_truth_settle "@h6.release.settle.want_to_win_once" 0.55>>
<<expression_truth_destabilize
    "@h6.release.destabilize.dont_look_at_me"
    1.6
    0.05
    22
    "FF304D">>

其中:

  • 前两个 start_expression 参数是本地化内容。
  • 完成节点 LOG1梳理完成 是 Yarn 流程标识,不做本地化。
  • 粒子数量、持续时间、颜色、Timeline、memory preset 等均为结构参数,不做本地化。

3.2 建议公共数据结构

public readonly struct Stage6TextReference
{
    public string RawValue { get; }
    public bool IsLocalized { get; }
    public string EntryKey { get; }
}

public sealed class Stage6RoundText
{
    public string TargetText { get; init; }
    public IReadOnlyList<string> InterferenceTokens { get; init; }
}

public sealed class Stage6LocalizationContext
{
    public const string TableName = "HuoshanStage6";
    public const string ReferencePrefix = "@h6.";

    public Locale RoundLocale { get; private set; }

    public IEnumerator BeginRound(Locale locale);

    public IEnumerator Resolve(
        string textReference,
        Action<string> completed);

    public IEnumerator Resolve(
        string textReference,
        Locale locale,
        Action<string> completed);

    public IEnumerator LoadRound(
        string roundId,
        Locale locale,
        Action<Stage6RoundText> completed);
}

职责划分:

  • Stage6TextReference:判断参数是本地化引用还是兼容用原始字符串。
  • Stage6LocalizationContext:统一访问 HuoshanStage6,避免每个 Yarn 命令各写一套解析逻辑。
  • Stage6RoundText:向粒子系统提供已经解析完成的数据;粒子系统不直接访问 String Table。
  • LanguageYarnCommand:在启动小游戏前等待本地化解析完成,再把纯文本数据交给 LanguageParticleManager
  • Log 释放相关 Yarn Command:显示前通过同一 resolver 解析字符串,再交给 LogReleasePresentationController
  • LanguageParticleManagerLogReleasePresentationController 最终只接收已解析的文本,不关心键、表名或 Locale。

3.3 解析和错误处理

解析规则必须集中实现:

  1. 参数不以 @h6. 开头时,直接返回原字符串。
  2. 参数以 @h6. 开头时,取后半部分作为 Entry Key。
  3. Entry Key 为空时记录错误,并显示可识别的错误占位。
  4. 优先获取指定 Locale 的条目。
  5. 当前语言缺失时回退到 zh-Hans 的同名条目。
  6. 中文源条目也缺失时:
    • 输出明确错误日志,包含 Table、Key、Locale 和调用命令。
    • 玩家画面显示 ⟦缺失的键名⟧
    • 不得直接显示 @h6.xxx,也不能静默返回空字符串。
  7. interference_tokens 解析后为空时终止该次 start_expression,输出数据错误,避免粒子生成阶段产生难以定位的异常。

3.4 Locale 切换行为

固定 UI

  • objectiveoutputintegrationinterference 监听 SelectedLocaleChanged
  • 切换语言后立即刷新。
  • 当前数值必须保留,只替换格式模板。

语言粒子:

  • 每次 start_expression 开始时捕获当前 Locale。
  • 同一轮的目标句、目标粒子和干扰 token 全部使用该快照。
  • 轮次进行中切换 Locale,不重建、不替换现有粒子。
  • 下一次 start_expression 使用新的 Locale。
  • 异步解析结束前不得开始生成粒子。

LOG 释放命令:

  • 每条命令执行时解析其文字参数。
  • 如果该命令属于仍在进行的表达轮次,沿用该轮的 Locale 快照。
  • 没有活动轮次时使用命令执行时的当前 Locale。
  • 单次命令解析完成后再启动对应演出,避免先显示 key、后替换文字。

3.5 Unicode 与粒子拆分

目标句不能按 UTF-16 charstring.Length 拆分,必须使用 Unicode 文本元素/字素簇。

规则:

  • 中文汉字、日文假名、拉丁字母、组合音标均按完整文本元素处理。
  • 英文空格不生成粒子,但在成功连接后的排版中形成单词间距。
  • 标点是否生成粒子沿用当前玩法规则,但不能被拆成代理项。
  • 有效目标粒子数量、完成判断和候选粒子数量都基于同一套文本元素结果。
  • 干扰 token 是本地化短词;生成粒子时再按同样的文本元素规则取字符。
  • 不使用英文 string.Length 直接决定粒子数量。

4. 具体改动安排

4.1 Unity Localization 资源

  • 补齐 UIText 中四个现有火山 UI 键的英日文。
  • 新建 HuoshanStage6 Collection 及中、英、日三张表。
  • 将 Collection 按项目现有 Localization Addressables 方式纳入构建。
  • 配置英日文字体或 TMP fallback,覆盖拉丁字符、日文假名、常用标点。

4.2 语言粒子系统

  • LanguageYarnCommand 接入统一的 @h6. resolver。
  • start_expression 在调用 LanguageParticleManager 前解析目标句和 token。
  • LanguageParticleManager 接收 Stage6RoundText 或等价的纯数据参数。
  • 保留现有原始字符串调用方式,避免其他测试场景和旧 Yarn 立即失效。
  • 将固定 UI 的中文常量仅作为开发兜底,不作为正式语言数据来源。

4.3 LOG 释放演出

  • 所有接受玩家可见字符串的释放命令接入相同 resolver。
  • 将 Stage6 中的攻击、settle、destabilize 参数改为 @h6. 引用。
  • 不修改数值演出参数、调用顺序和重复次数。
  • LogReleasePresentationController 保持表现层职责,只接收最终显示文本。

4.4 Yarn 内容

  • 仅替换本地化范围内的 Yarn 命令参数。
  • 不添加或修改 #line: 标签。
  • 不配置 FP_Huoshan1.yarnproject 的整章 localization。
  • 不生成 Stage6 Yarn 翻译 CSV。
  • 被注释的示例命令不需要建立正式本地化条目;若未来启用,必须先补键。
  • Task 行、鼠标教学和普通对白保持原样。

4.5 Prefab、图片与文档

  • ExpressManager.prefab 当前没有确认的运行时玩家文本,也不是 Stage6 正式文本数据源,本轮不向其中写多语言文案。
  • ExpressionScreen_NoText.png 已确认无烘焙文字,不制作多语言 Sprite。
  • 场景或 Prefab 中诸如“输出”的序列化 TMP 文本只作为编辑器预览;运行时必须由 UIText 覆盖。
  • 更新 LogReleaseYarnCommands.md
    • 说明 @h6. 引用格式。
    • 列出哪些参数可本地化、哪些是结构参数。
    • 提供 attack、settle、destabilize 示例。
    • 记录回退与错误显示规则。
  • 同步更新语言系统说明文档中的 start_expression 示例,展示本地化键和旧原始字符串两种写法。

5. 测试与验收

5.1 数据完整性测试

  • HuoshanStage6 的中、英、日表拥有相同键集合。
  • 中文源条目不得为空。
  • 英日文不得残留中文占位;允许通过备注标记待审校。
  • 所有 interference_tokens 至少包含一个有效 token。
  • 所有 Stage6 中实际执行的本地化命令参数都能解析。
  • 结构参数没有被误当成本地化键。
  • 扫描 Stage6 后,剩余硬编码玩家文本必须全部属于已声明的暂缓范围。

5.2 编辑模式测试

  • @h6.key 能解析指定 Locale。
  • 普通字符串保持原值。
  • 缺少目标语言时回退中文。
  • 三种语言都缺失时显示 ⟦key⟧ 并记录错误。
  • token 能正确 Trim 和过滤空项。
  • Unicode 文本元素拆分能处理中文、英文、日文和组合字符。
  • 英文空格不生成粒子,但结果排版保留词间距。
  • 重复攻击词引用同一 Key 时仍能按 Yarn 调用次数重复播放。

5.3 PlayMode/场景验收

分别使用 zh-Hansenja-JP 运行 LOG1、LOG2、LOG3

  • 固定 UI 显示正确,格式参数正确。
  • 每轮目标句和干扰 token 使用对应语言。
  • 粒子连接、排斥、吸引和完成判断不受文本长度影响。
  • LOG3 attack、settle、destabilize 全部显示对应语言。
  • 演出调用顺序、节奏、颜色和持续时间与改造前一致。
  • 中途切换语言时,固定 UI 立即更新,当前轮粒子不变,下一轮使用新语言。
  • 字体无缺字方框。
  • 英文长文本和日文文本没有溢出、异常换行或关键画面遮挡。

5.4 回归验收

  • 使用旧的原始字符串调用 start_expression 仍然可以运行。
  • languageTest 等测试内容不因新增 resolver 失效。
  • Yarn 编译无错误。
  • Stage6 的完成节点跳转保持不变。
  • Task 完成逻辑和 Yarn line ID 不受影响。
  • Addressables/Localization 构建包含新增表格。
  • 在 Unity Editor 中完成最终视觉检查;当前无法通过 Unity MCP 自动进行场景级检查。

6. 交付判定

满足以下条件后视为本轮完成:

  • Stage6 固定小游戏 UI 已具备中英日数据。
  • 三轮粒子内容和全部正式 LOG 释放文本均从 HuoshanStage6 获取。
  • Yarn 中相关硬编码文本已替换为 @h6. 引用。
  • 原始字符串调用保持兼容。
  • Locale 快照、回退、缺键和 Unicode 拆分规则均有测试覆盖。
  • 文档足以让后续策划直接新增本地化键并在 Yarn 命令中使用。
  • 任务提示、操作教学和普通对白仍明确列为后续 Yarn 本地化工作,不被误报为已完成。