From 1d56991fadfaa6eb43d98b904db59685e77c220a Mon Sep 17 00:00:00 2001 From: "Somhairle H. Marisol" Date: Tue, 29 Sep 2026 09:27:16 +0800 Subject: p69: 中文 UI 文案统一审校(面板措辞/交易缺货口径/页脚留白与 ESC) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - 面板打开语统一:「年鉴已打开」→「年鉴面板已打开」(Interaction + requiredUiLabels) - 交易缺货口径统一:「背包不足」→「库存不足」(PlayerTrade,与对话交易失败名一致) - 分页页脚留白/大小写统一:「…页 空格 翻页 Esc 关闭」→「…页 空格 翻页 ESC 关闭」 - P69CopyAuditTests(2 例,红先)+ P61 钉住样例同步 - 只改字符串字面量与相关断言;Kernel/Sim/MapSnapshot 未动 - Desktop 338/338、Kernel 119/119;digest 953775FA…7F6C 不变 --- docs/evidence/p69-verification.txt | 40 ++++++++++++++++++++++ .../LivingVillage.Desktop.Tests.fsproj | 1 + .../P61GlyphCoverageTests.fs | 2 +- .../P69CopyAuditTests.fs | 35 +++++++++++++++++++ src/LivingVillage.Desktop/ChineseText.fs | 2 +- src/LivingVillage.Desktop/Game.fs | 2 +- src/LivingVillage.Desktop/Interaction.fs | 2 +- src/LivingVillage.Desktop/PlayerTrade.fs | 2 +- 8 files changed, 81 insertions(+), 5 deletions(-) create mode 100644 docs/evidence/p69-verification.txt create mode 100644 src/LivingVillage.Desktop.Tests/P69CopyAuditTests.fs diff --git a/docs/evidence/p69-verification.txt b/docs/evidence/p69-verification.txt new file mode 100644 index 0000000..f843552 --- /dev/null +++ b/docs/evidence/p69-verification.txt @@ -0,0 +1,40 @@ +P69(中文 UI 文案汇总审校)验证记录 +基线:commit 4aa6fab(P68)。本单未 push。 + +审校范围 +- 扫描 src/LivingVillage.Desktop 全部 .fs 的字符串字面量(HUD/任务面板/提示/菜单/对话/交易/保存失败反馈), + 逐条核对错别字、半/全角标点、状态词与留白一致。 + +清单与处置 +1. 半/全角标点:全仓中文串内无 CJK 邻接的半角 `, . : ; ! ?`(全部用全角「,:」),无需改。 +2. 状态词:待接受/进行中/已完成/已失败 一致。面板打开语不一致—— + 「需求面板已打开 / 任务面板已打开」vs「年鉴已打开」→ **改为「年鉴面板已打开」** + (Interaction.statusLabel + ChineseText.requiredUiLabels)。 +3. 交易缺货口径:对话交易失败名「库存不足」vs HUD 交易「背包不足」→ **统一为「库存不足」**(PlayerTrade.sell)。 + (PlayerTrade「背包里没有可卖物品」为「空背包」另一语义,保留。) +4. 提示大小写/留白:对话分页页脚「第 %d/%d 页 空格 翻页 Esc 关闭」用 `Esc`(其余全部 `ESC`)且三空格—— + **改为「第 %d/%d 页 空格 翻页 ESC 关闭」**(Game.DrawDialogOverlay)。 +5. 其余保留(跨文件一致,无改动):白天/夜晚/清晨/黄昏、1倍速/2倍速/5倍速、职业名、任务名、 + 剧情线文案、菜单项、按键提示 `ENTER/ESC/空格` 等。 + +红先 +- 先建 P69CopyAuditTests.fs 断言新文案;暂存 4 个实现文件后运行 → 2 例红: + 「应为 年鉴面板已打开,实际 年鉴已打开」「应为 库存不足,实际 背包不足」;恢复后转绿。 + +改动文件 +- src/LivingVillage.Desktop/Interaction.fs(年鉴面板已打开) +- src/LivingVillage.Desktop/ChineseText.fs(requiredUiLabels 同步) +- src/LivingVillage.Desktop/PlayerTrade.fs(库存不足) +- src/LivingVillage.Desktop/Game.fs(分页页脚留白 + ESC 大写) +- src/LivingVillage.Desktop.Tests/P61GlyphCoverageTests.fs(钉住的页脚样例同步) +- src/LivingVillage.Desktop.Tests/P69CopyAuditTests.fs(新,2 例)+ .fsproj 挂载 + +验收 +- dotnet build LivingVillage.sln -c Release → 0 错误,1 警告(P40ArtTests.fs FS0760,既有)。 +- dotnet test src/LivingVillage.Desktop.Tests -c Release --no-build → 338/338(336→+2)。 +- dotnet test src/LivingVillage.Kernel.Tests -c Release --no-build → 119/119。 +- --performance-baseline final_digest=953775FAEB2FDDE97289491AA260BD8D390C571E48A7A13AD2CB6FB7124F7F6C(未动 Kernel/Sim)。 + +边界 +- 只改字符串字面量与直接相关断言;未改逻辑、Kernel/Sim、MapSnapshot/渲染口径;未 push。 +- 未改职业名/任务名(由 Kernel `Occupation` 提供,属只读、且全仓一致)。 diff --git a/src/LivingVillage.Desktop.Tests/LivingVillage.Desktop.Tests.fsproj b/src/LivingVillage.Desktop.Tests/LivingVillage.Desktop.Tests.fsproj index 6d1a3e8..a404797 100644 --- a/src/LivingVillage.Desktop.Tests/LivingVillage.Desktop.Tests.fsproj +++ b/src/LivingVillage.Desktop.Tests/LivingVillage.Desktop.Tests.fsproj @@ -41,6 +41,7 @@ + diff --git a/src/LivingVillage.Desktop.Tests/P61GlyphCoverageTests.fs b/src/LivingVillage.Desktop.Tests/P61GlyphCoverageTests.fs index f5f1a10..a2c1038 100644 --- a/src/LivingVillage.Desktop.Tests/P61GlyphCoverageTests.fs +++ b/src/LivingVillage.Desktop.Tests/P61GlyphCoverageTests.fs @@ -82,7 +82,7 @@ type P61GlyphCoverageTests () = let pinned = [ HudLayout.seasonNames |> String.concat "" HudLayout.calendarLine1 { Season = "春"; DayNumber = 1L; Period = "清晨"; Clock = "06:00" } - "第 1/3 页 空格 翻页 Esc 关闭" + "第 1/3 页 空格 翻页 ESC 关闭" "背包物品×1" "鱼"; "卷轴"; "香料"; "玩家"; "回车:接受任务" ] let missing = diff --git a/src/LivingVillage.Desktop.Tests/P69CopyAuditTests.fs b/src/LivingVillage.Desktop.Tests/P69CopyAuditTests.fs new file mode 100644 index 0000000..cd5e221 --- /dev/null +++ b/src/LivingVillage.Desktop.Tests/P69CopyAuditTests.fs @@ -0,0 +1,35 @@ +namespace LivingVillage.Desktop.Tests + +open Microsoft.VisualStudio.TestTools.UnitTesting +open LivingVillage.Kernel +open LivingVillage.Kernel.Sim +open LivingVillage.Desktop + +/// P69(文案统一审校):把玩家可见中文文案里不一致的措辞/大小写/留白拉齐,并补回归断言。 +/// 本单只改字符串字面量与相关断言;不改逻辑、不改 Kernel/Sim。 +[] +type P69CopyAuditTests () = + + [] + member _.PanelStatusWordingIsUnified () = + // 「需求面板已打开 / 任务面板已打开」同一句式;年鉴原为「年鉴已打开」,统一为「年鉴面板已打开」。 + Assert.AreEqual( + "年鉴面板已打开", + M5Interaction.statusText { M5Interaction.initial with Status = "chronicle" }) + Assert.AreEqual( + "需求面板已打开", + M5Interaction.statusText { M5Interaction.initial with Status = "needs panel open" }) + Assert.AreEqual( + "任务面板已打开", + M5Interaction.statusText { M5Interaction.initial with Status = "task panel open" }) + Assert.IsTrue(ChineseText.requiredUiLabels |> List.contains "年鉴面板已打开") + Assert.IsFalse(ChineseText.requiredUiLabels |> List.contains "年鉴已打开") + + [] + member _.TradeShortageUsesStockWording () = + // 交易缺货口径统一为「库存不足」(与对话交易失败名一致),不再用「背包不足」。 + let state = { Occupation.stateOf Occupation.Farmer with Backpack = [ (Food, 1) ] } + let world = WorldBootstrap.initialWorldWithOccupation false 42UL 4 (Some state) + let outcome = PlayerTrade.sell (Some state) (NpcId 0) Food 3 world + Assert.IsFalse(outcome.Succeeded, "shortage sale must not succeed") + Assert.AreEqual("库存不足", outcome.Message) diff --git a/src/LivingVillage.Desktop/ChineseText.fs b/src/LivingVillage.Desktop/ChineseText.fs index 349bbec..7bd8bc5 100644 --- a/src/LivingVillage.Desktop/ChineseText.fs +++ b/src/LivingVillage.Desktop/ChineseText.fs @@ -119,7 +119,7 @@ module ChineseText = "请选择对话方式" "对话完成" "对话失败" - "年鉴已打开" + "年鉴面板已打开" "E 出屋" "E 进屋" "E 交谈" diff --git a/src/LivingVillage.Desktop/Game.fs b/src/LivingVillage.Desktop/Game.fs index ba925f3..63f69cd 100644 --- a/src/LivingVillage.Desktop/Game.fs +++ b/src/LivingVillage.Desktop/Game.fs @@ -3271,7 +3271,7 @@ type LivingVillageGame() as this = PixelText.draw spriteBatch pixel cjkAtlas textX y DialogOverlay.textScale palette.Value line) // 分页标记:页码 + 翻页/关闭提示;有下一页时显示箭头。 let marker = - sprintf "第 %d/%d 页 空格 翻页 Esc 关闭" current.PageNumber current.PageCount + sprintf "第 %d/%d 页 空格 翻页 ESC 关闭" current.PageNumber current.PageCount let markerWidth = FloatingPrompt.measureWidth marker DialogOverlay.textScale let markerX = lx + layout.Width - DialogOverlay.paddingX - markerWidth let markerY = ly + layout.Height - DialogOverlay.pageMarkerHeight diff --git a/src/LivingVillage.Desktop/Interaction.fs b/src/LivingVillage.Desktop/Interaction.fs index 6c62661..3a65e8e 100644 --- a/src/LivingVillage.Desktop/Interaction.fs +++ b/src/LivingVillage.Desktop/Interaction.fs @@ -591,7 +591,7 @@ module M5Interaction = let reason = value.Substring("dialogue rejected:".Length).Trim() if String.IsNullOrWhiteSpace reason then "对话失败" else sprintf "对话失败:%s" reason | value when value.StartsWith("observation") -> "观察完成" - | value when value.StartsWith("chronicle") -> "年鉴已打开" + | value when value.StartsWith("chronicle") -> "年鉴面板已打开" | "task panel open" -> "任务面板已打开" | value when value.StartsWith("task|") -> value.Substring("task|".Length) | value when value.StartsWith("inquiry|") -> value.Substring("inquiry|".Length) diff --git a/src/LivingVillage.Desktop/PlayerTrade.fs b/src/LivingVillage.Desktop/PlayerTrade.fs index 407536c..8436d9f 100644 --- a/src/LivingVillage.Desktop/PlayerTrade.fs +++ b/src/LivingVillage.Desktop/PlayerTrade.fs @@ -187,7 +187,7 @@ module PlayerTrade = | Some buyer when quantity <= 0 -> failure state world "数量必须大于零" | Some buyer -> if Occupation.backpackQuantity item occupation < quantity then - failure state world "背包不足" + failure state world "库存不足" else match quote (Some occupation) false counterparty item quantity world with | None -> failure state world "无法报价" -- cgit v1.2.3