diff options
| author | Somhairle H. Marisol <[email protected]> | 2026-09-29 04:58:29 +0800 |
|---|---|---|
| committer | Somhairle H. Marisol <[email protected]> | 2026-09-29 04:58:29 +0800 |
| commit | fd40d78fd7506a95f0c5ad3295adfeb0a636e815 (patch) | |
| tree | a948f264a7924e52d804d12735c66ed2cb529b6d /src/LivingVillage.Desktop/Game.fs | |
| parent | f274ed8c920bbea383a4bf0e2ffe1219f7fe30b5 (diff) | |
| download | living-village-fd40d78fd7506a95f0c5ad3295adfeb0a636e815.tar.gz | |
p61: G1 字形图集补齐 16 个 UI 用字(红→绿),中文界面完整
红:新增 src/LivingVillage.Desktop.Tests/P61GlyphCoverageTests.fs——扫描 Desktop 源码
字符串字面量内的全部 CJK 字,断言 100% 在 CjkGlyphAtlas 内;并逐字钉 G1 缺的
16 字(冬包卷品夏料春玩秋第背车轴页香鱼)、requiredUiLabels、以及运行期文案
(日历「春·第1天」/页脚「第 1/3 页…翻页」/「V 卖出 背包物品×1」/鱼卷轴香料玩车回)。
实现前实测 3 失败:缺字形 16。
绿:向 CjkGlyphAtlas.characterTable 补入 16 字(保持有序、去重),同步
Assets/cjk-glyphs.txt,并跑 scripts/generate-cjk-glyph-atlas.sh 用既有 Noto Sans CJK
重生成预生成 PNG:384x504(16x21 格,+16 字),16 个新字格均有真实字体墨迹
(ink_px 148-233,非程序几何伪字形)。更新 PrototypeTests 的图集几何常量
(307→323、rowCount 20→21、pixelHeight 480→504)。
证据:LV_P61_SHOT=1 拍 2 帧(p61-calendar 右上日历「春 · 第1天」;p61-dialog-footer
真实 Interact 开对话,页脚「第 1/3 页…翻页」+ 选项「V 卖出 背包物品×1」)。
analyze(p61-analysis.txt):缺字空白位=0、黑块=0、白块=0/2;全部抽检文案
missing_glyph_slots=0。钩子为 Game.fs 纯追加(53 行,0 删除),未动 HUD 结构。
回归(p61-verification.txt):Desktop 308/308(+4 P61)+ Kernel 119/119;
--performance-baseline ×3 digest 953775FAEB2F… 不变,determinism PASS。
未改 Kernel/Sim,未引外部素材(沿用既有 Noto 字体来源),未 push。
Diffstat (limited to 'src/LivingVillage.Desktop/Game.fs')
| -rw-r--r-- | src/LivingVillage.Desktop/Game.fs | 53 |
1 files changed, 53 insertions, 0 deletions
diff --git a/src/LivingVillage.Desktop/Game.fs b/src/LivingVillage.Desktop/Game.fs index b51c7f0..cdfc06b 100644 --- a/src/LivingVillage.Desktop/Game.fs +++ b/src/LivingVillage.Desktop/Game.fs @@ -318,6 +318,12 @@ type LivingVillageGame() as this = let mutable p44Step = 0 let mutable p44PendingName = "" let mutable p44Pending = false + // P61 证据钩子(G1 字形补齐):拍「右上日历(春夏秋冬·第N天)/ 对话页脚(第N/3页 + V 卖出 背包物品×1)」 + // 两帧,证明新补 16 字在真实游戏 UI 中完整可辨。 + let p61ShotMode = Environment.GetEnvironmentVariable("LV_P61_SHOT") = "1" + let mutable p61Step = 0 + let mutable p61PendingName = "" + let mutable p61Pending = false // P45 证据钩子:LV_P45_SHOT=1 时拍角色 idle / 行走朝下 / 行走朝右 三帧(真实游戏截图)。 let p45ShotMode = Environment.GetEnvironmentVariable("LV_P45_SHOT") = "1" let mutable p45Step = 0 @@ -961,6 +967,43 @@ type LivingVillageGame() as this = (m5View.Prompt |> Option.defaultValue "<none>") p44Step <- p44Step + 1 + /// P61 证据(G1):真实世界里拍「右上日历」与「对话页脚/背包文案」两帧。 + member private this.PrepareP61Shot () = + let setHour (hour: float) = + let tick = M6Presentation.resolveStartTick (Some hour) false + world <- { world with Tick = tick; Time = float tick * Sim.dtSeconds } + if not p61Pending then + match p61Step with + | 0 -> + setHour 12.0 + let npc = world.Npcs.[0] + world <- { world with Avatar = { world.Avatar with Pos = npc.Pos } } + this.CenterCamera() + p61PendingName <- "p61-calendar" + p61Pending <- true + | 1 -> + let nextWorld, nextView = M5Interaction.apply M5Command.Interact world m5View + world <- nextWorld + m5View <- nextView + this.CenterCamera() + p61PendingName <- "p61-dialog-footer" + p61Pending <- true + | _ -> + printfn "p61-shot=done" + this.Exit() + + /// P61 证据:落盘并打印日历读数(春夏秋冬·第N天)与面板名,供 analyze 核验。 + member private this.CaptureP61Shot () = + if p61Pending then + p61Pending <- false + System.IO.Directory.CreateDirectory recordDirectory |> ignore + this.SaveBackBuffer(sprintf "%s/%s.png" recordDirectory p61PendingName) + let reading = HudLayout.calendarReading world.Tick + printfn + "p61-shot=%s tick=%d calendar=%s panel=%s" + p61PendingName world.Tick (HudLayout.calendarLine1 reading) (M5Interaction.panelName m5View) + p61Step <- p61Step + 1 + member private this.PrepareP45Shot () = let baseTick = M6Presentation.resolveStartTick (Some 12.0) false let setTick (tick: int64) = @@ -1942,6 +1985,14 @@ type LivingVillageGame() as this = else this.DispatchMenuInput Confirm elif menu.Page = Playing then this.PrepareP44Shot() + elif p61ShotMode then + if menu.Page = MainMenu then + this.DispatchMenuInput Confirm + elif menu.Page = OccupationSelect then + if menu.Selected <> 0 then this.DispatchMenuInput Down + else this.DispatchMenuInput Confirm + elif menu.Page = Playing then + this.PrepareP61Shot() elif p45ShotMode then if menu.Page = MainMenu then this.DispatchMenuInput Confirm @@ -2412,6 +2463,8 @@ type LivingVillageGame() as this = this.CaptureP43Shot() if p44ShotMode && menu.Page = Playing then this.CaptureP44Shot() + if p61ShotMode && menu.Page = Playing then + this.CaptureP61Shot() if p45ShotMode && menu.Page = Playing then this.CaptureP45Shot() if p46ShotMode then |
