From aeefa68f7bab003322efae4a272c507075622a6a Mon Sep 17 00:00:00 2001 From: "Somhairle H. Marisol" Date: Mon, 28 Sep 2026 09:01:48 +0800 Subject: docs: P36 情境提示证据与维护说明 MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit docs/evidence/p36-prompt-approach-1..4.png 为实际运行帧序列 (靠近无提示→E 交谈出现→对话层打开提示消失→走远提示消失), check-no-white-blocks 4 帧 0 命中;维护说明补 P36 小节(契约/测试/复现)。 --- docs/evidence/p36-prompt-approach-1.png | Bin 0 -> 105667 bytes docs/evidence/p36-prompt-approach-2.png | Bin 0 -> 107466 bytes docs/evidence/p36-prompt-approach-3.png | Bin 0 -> 123114 bytes docs/evidence/p36-prompt-approach-4.png | Bin 0 -> 106601 bytes ...273\264\346\212\244\350\257\264\346\230\216.md" | 51 +++++++++++++++++++++ 5 files changed, 51 insertions(+) create mode 100644 docs/evidence/p36-prompt-approach-1.png create mode 100644 docs/evidence/p36-prompt-approach-2.png create mode 100644 docs/evidence/p36-prompt-approach-3.png create mode 100644 docs/evidence/p36-prompt-approach-4.png (limited to 'docs') diff --git a/docs/evidence/p36-prompt-approach-1.png b/docs/evidence/p36-prompt-approach-1.png new file mode 100644 index 0000000..92ebe03 Binary files /dev/null and b/docs/evidence/p36-prompt-approach-1.png differ diff --git a/docs/evidence/p36-prompt-approach-2.png b/docs/evidence/p36-prompt-approach-2.png new file mode 100644 index 0000000..2d51a13 Binary files /dev/null and b/docs/evidence/p36-prompt-approach-2.png differ diff --git a/docs/evidence/p36-prompt-approach-3.png b/docs/evidence/p36-prompt-approach-3.png new file mode 100644 index 0000000..19947e3 Binary files /dev/null and b/docs/evidence/p36-prompt-approach-3.png differ diff --git a/docs/evidence/p36-prompt-approach-4.png b/docs/evidence/p36-prompt-approach-4.png new file mode 100644 index 0000000..fb782c1 Binary files /dev/null and b/docs/evidence/p36-prompt-approach-4.png differ diff --git "a/docs/\347\273\264\346\212\244\350\257\264\346\230\216.md" "b/docs/\347\273\264\346\212\244\350\257\264\346\230\216.md" index c095914..972af87 100644 --- "a/docs/\347\273\264\346\212\244\350\257\264\346\230\216.md" +++ "b/docs/\347\273\264\346\212\244\350\257\264\346\230\216.md" @@ -1109,3 +1109,54 @@ late pass),故「灯笼光晕 + 水面」以生成器夜帧为准,「炊 ``` - 范围:仍为切片,不做全村;动画全套与更多中式元素补绘留待后续。 + +## P36 星露谷式情境提示系统(交互硬要求) + +对齐 `docs/overnight-quality-brief.md`「交互新增硬要求」整段的验收口径:取消常驻键位清单 / +大型帮助面板;只在靠近**可达**可交互目标时显示匹配的短提示;一帧只高亮一个目标;提示对象与 +按键对象一致;对话/菜单开启时隔离世界交互,Esc 关闭当前层;保存等操作给短暂中文反馈;提示 +布局不遮场景、不越界。 + +- **常驻 HUD 审计**:常驻只有顶部窄信息条(时段/时间/倍速/体力/钱币,`HudLayout`),无任何 + 常驻全键位清单或大型帮助面板——世界面板 `M5Interaction.panelLines` 为世界态时不含键位行 + (现有用例 `WorldPanelDoesNotRenderA永久KeyList` 断言为空)。完整键位只放在由 `P` 打开的 + 暂停帮助页(`MenuState.enterPauseHelp`/`exitPauseHelp`,打开时暂停、退出恢复原倍速)。 +- **情境提示**:`InteractionResolver.resolve` 选出唯一目标(`InteractionTarget`:动作 + + 位置 + 中文短文本 `E 交谈`/`E 进屋`/`E 出屋`);`M5Interaction.refreshPrompt` 仅在 + `Panel = WorldPanel` 时把文本/坐标写入视图;离开范围(`Sim.chatRangePx`=96px)立即清空; + 隔墙不触发(`hasClearPath` 采样玩家到目标的连线,命中 `WhiteWallDarkTileHome` 墙体瓦片即 + 判不可达,见 `blockingTiles`)。 +- **确定性优先级**:`resolve` 按 `(DistanceSquared, stableId)` 排序取首个;stableId 村民用 + `NpcId`、民居用 `HomeId`,距离平局按 ID 稳定裁决;一帧只产出一个目标。 +- **提示对象=按键对象**:渲染的提示与 `Interact`(E)都调用同一个 `InteractionResolver.resolve`, + 不存在第二套选择逻辑;`Escape` 面板内先走 `M5Interaction.apply ClosePanel`(对话/需求/观察/ + 年鉴/任务 → 世界面板),世界面板时才打开主菜单。 +- **输入隔离**:`M5Interaction.worldInputAllowed`(仅 `WorldPanel` 为真)与 `commandAllowed` + 双重门禁;对话层打开时 `Interact`/`Observe` 等世界命令被拒绝;`Game.Update` 只在 + `menu.Page = Playing` 时调用 `UpdatePlaying`,主菜单/设置/操作页打开时世界输入整体不处理。 +- **保存反馈**:`F6/F7` 成功或失败写入 `m5View.Status`(`save succeeded`/`save failed`), + 经 `statusText` 映射为「保存成功/保存失败」,由 `transientStatusLine` 在 150 tick(≈2.5s)内 + 以顶部条下小药丸短暂显示后自动消失。 +- **布局**:`FloatingPrompt.layout` 把提示水平居中于目标并夹在视口内,永不覆盖顶部状态条与 + 左下 HUD 带;回归覆盖 800x600 / 1024x576 / 1280x720 / 1920x1080。 +- **回归测试**:新增 `src/LivingVillage.Desktop.Tests/P36PromptTests.fs`(10 例:距离边界、 + 就近切换、离开消失、隔墙不触发、对话层输入隔离、提示=按键对象一致、Esc 关闭当前层、 + 暂停帮助 Esc 回上层、保存 toast、布局多尺寸不遮 HUD),并复用既有 + `PrototypeTests` 的浮动提示/选择确定性用例。Release 全量 Desktop 174/174、Kernel 119/119。 +- **证据**(`docs/evidence/`,`git add -f`;`check-no-white-blocks.py` 4 帧 0 命中): + - `p36-prompt-approach-1.png`:进入靠近村民阶段(`stage=ApproachNpc`,pos≈(923,753)), + 面板=world,`prompt=`(尚未进入范围,无提示)。 + - `p36-prompt-approach-2.png`:进入交谈范围(pos≈(933,729)),`prompt=E 交谈`;帧内 x[634,697] + y[199,200] 的 2px 强调线即目标上方提示药丸(宽 64 = 文本 52 + 边距),顶部 HUD 完整。 + - `p36-prompt-approach-3.png`:按 E 后 `panel=dialogue`、`prompt=`——浮动提示消失 + (世界交互被隔离),左下对话层出现(强调线落于 x[18,395] y[516,518])。 + - `p36-prompt-approach-4.png`:关闭并走远后(`stage=WalkAway`,pos≈(985,790),距最近村民 + > chatRange+24px)`panel=world`、`prompt=`,提示已消失。 +- **复现**(确定性钩子 `LV_P36_SHOT=1`,复用 sample 脚本走位/互动并抓 4 帧后退出): + + ```bash + LV_P36_SHOT=1 LV_RECORD_DIR=/tmp/opencode/lv-p36-evidence LV_AUTOPLAY_START_HOUR=9.0 \ + xvfb-run -a -s "-screen 0 1280x720x24" \ + dotnet src/LivingVillage.Desktop/bin/Release/net8.0/LivingVillage.Desktop.dll + # 运行日志逐帧打印 panel/prompt/home 对照点,末行 p36-shot=done + ``` -- cgit v1.2.3