diff --git a/docs/runtime/p9_1/UX_VISUAL_FLOW_SPEC.md b/docs/runtime/p9_1/UX_VISUAL_FLOW_SPEC.md new file mode 100644 index 00000000..098442f8 --- /dev/null +++ b/docs/runtime/p9_1/UX_VISUAL_FLOW_SPEC.md @@ -0,0 +1,668 @@ +# P9.1 UX And Visual Flow Specification + + + +> Status: expert candidate for PMO reconciliation +> Revision: `p91-ux-visual-r1` +> Product baseline: `dec9574405043624acee0f4f81963d829e8d40e9` +> Frozen batch: `.agent-taskgraph/spec.md` revision `p9.1-spec-r1` +> Owned output: `docs/runtime/p9_1/UX_VISUAL_FLOW_SPEC.md` + +## 1. Purpose And Authority + +This specification defines the implementation-facing landscape presentation for +the complete P9.1 first session: + +```text +choose any two -> automatic formation -> battle 1 -> diagnosis -> adaptation +-> battle 2 -> Guild response -> battle 3 -> route -> battle 4 +-> individual growth -> battle 5 -> first-session result +``` + +It preserves the accepted P9.0R8 front door, P9.0R3 combat motion/feedback +direction, P9.0R10 arbitrary-pair formation language, and the world-based +decision scenes established in P9.0R5-R7. This document owns screen hierarchy, +localized sentence structure, controls, focus, motion projection, +accessibility variants, and render evidence. It does not own formulas, option +legality, combat outcomes, rewards, or persistent rules. + +Where a value is written as `{binding}`, the gameplay/domain contract must +supply it. UI must render the supplied value and must never infer or substitute +an old standard-pair branch. Missing required bindings enter `P91-BINDING-ERROR` +and block the dependent commit. + +### 1.1 Presentation invariants + +1. The player chooses people, never front/rear slots. The system orders the + selected people and explains each responsibility before commitment. +2. No meaningful choice is preselected. Selection is reversible; only the + named commit action spends, locks, trains, rewards, or starts a battle. +3. Every decision shows current evidence, immediate gain, opportunity cost, + and the next battle consequence in the first viewport. +4. Every battle event names source, action, target, and outcome. Color, audio, + particles, and actor motion are never the only carriers. +5. Every result leads with cause, then exact changed state, then the next + action. Totals and rewards do not precede the causal read. +6. The same party identity and order remain visible from review through all + five battles; a Guild response may add a third member but cannot silently + reorder the committed starting pair. +7. Generated recruits remain mechanical participants, not fixed protagonists. + No relationship, affinity, romance, personal-arc, or character-voice framing + is introduced. + +## 2. Required Domain Presentation Bindings + +The reconciled implementation contract must expose one immutable snapshot per +screen and ordered events per battle. Names below describe required UX data, +not a runtime API decision. + +| Binding | Required fields | Presentation use | +|---|---|---| +| `P91_SESSION_SNAPSHOT` | session ID, locale, Coin, Company size, selected decisions | top status and result facts | +| `P91_PARTY_SNAPSHOT` | stable member ID, localized name, profession, order index, responsibility, current/max HP, level, source of order | persistent horizontal party line | +| `P91_CHOICE_SET` | stable option ID, title, reason, gain, cost, foregone state, legal/disabled reason, selected/committed state | adaptation, Guild, route, growth | +| `P91_BATTLE_FORECAST` | battle index/name, enemy presentation ID, known pressure, target relation, objective | battle heading and warning geometry | +| `P91_BATTLE_EVENT` | stable event ID, order/time, kind, source ID, target IDs, before/after/delta, causal source, caption | actor motion, feedback number, event ribbon/log | +| `P91_RESULT` | outcome, earliest meaningful divergence, cause, decision source, changed state, reward receipt, next action | all causal result surfaces | +| `P91_SETTINGS` | locale, text scale, reduced motion, reduced flashes, mute/captions, high contrast, low power | deterministic visual variants | + +`P91_CHOICE_SET` and `P91_RESULT` must carry already-resolved domain truth. UI +may select sentence templates by semantic state (`covered`, `partial`, `gap`, +`gain`, `cost`, `changed`, `unchanged`) but may not recompute those states. + +## 3. Screen And State Map + +Screen IDs are stable presentation IDs. Existing Godot node names may be kept +as aliases during extraction; new tests and evidence should use the P9.1 IDs. + +### 3.1 Complete path + +| Screen/state ID | New/reused | Purpose and required first read | Primary action | Back/return behavior | +|---|---|---|---|---| +| `P91-BOOT-LOADING` | reused P9.0R8 | Named asset preparation and bounded progress; no active controls beneath | none until ready | none; failure enters `P91-BOOT-ERROR` | +| `P91-BOOT-ERROR` | reused P9.0R8 | Plain affected feature and retained zero-session state | `重新检查` | none; retry retains the same boot operation identity | +| `P91-TITLE-READY` | reused P9.0R8 | Product identity, broken-road premise, current five-battle experience | `进入游戏` | none; Settings remains a tool | +| `P91-MENU-READY` | reused | Current experience status and fresh-run entry | `开始新游戏` | Title only through global Home policy | +| `P91-INTRO` | reused, copy corrected | Four beats: choose any two, inspect system order, read automatic combat, make state-based responses | none; informational | `返回主菜单`; no session mutation | +| `P91-SETTINGS` | reused | Language, text size, motion, flashes, sound/captions, contrast, and power with live value | none; each control applies its named setting | returns to exact Title/Menu/paused-Battle caller and prior focus | +| `P91-COMMISSION` | reused wording corrected | Threat targets the system lead; player will choose any two | `选择两名成员` | Main menu; no session mutation | +| `P91-RECRUIT-0` | reused P9.0R9A/R10 | Four equal candidates; `已选 0 / 2`; nothing selected | none, review disabled | Commission; selection cleared | +| `P91-RECRUIT-1` | reused | One selected, three still equal; `已选 1 / 2` | none, review disabled | Commission; selection cleared | +| `P91-RECRUIT-2` | reused | Two selected; stable source order; system-order preview appears | `查看系统编队` | Commission; selection cleared | +| `P91-FORMATION-REVIEW` | reused P9.0R9A/R10 | Exposed lead/right and second member/left, each with exact responsibility | `确认编队并出发` | `重新选择成员` returns with same two checked | +| `P91-BATTLE-1` | reused P9.0R3/R10 | Opening pressure, system order, both member responses | automatic | no Back; Pause contains Home/Restart review | +| `P91-RESULT-1` | reused, generalized | What each member did and why this order mattered | `查看下一场威胁` | no return to battle | +| `P91-ADAPT-0` | reused P9.0R10 | Two legal responses to the diagnosed pressure; no selection | none, commit disabled | Result 1, preserving snapshot | +| `P91-ADAPT-1` | reused | Selected response, gain, cost, forecast delta | `带着所选方案出发` | Result 1; selection remains reversible until commit | +| `P91-BATTLE-2` | reused, generalized | Adaptation event plus actual lead and second-member behavior | automatic | Pause review only | +| `P91-RESULT-2` | reused, generalized | Adaptation-caused difference and actual party actions | `返回公会回应这支小队` | no return to battle | +| `P91-GUILD-0` | reused P9.0R5, generalized | Current actors/Coin in yard; two state-dependent responses; no selection | none, commit disabled | Result 2 | +| `P91-GUILD-1` | reused, generalized | Selected Guild response, final Coin/Company/state, foregone alternative | `确认回应并开始第三战` | Result 2; selection can still switch | +| `P91-BATTLE-3` | reused, generalized | Retained capability or added member visibly changes the line | automatic | Pause review only | +| `P91-RESULT-3` | reused, generalized | Guild decision -> battle consequence -> current Company | `比较三条路线` | no return to battle | +| `P91-ROUTE-0` | reused P9.0R6 | Three adjacent world routes; pressure, exposure, reward, current coverage | none, review disabled | Result 3 | +| `P91-ROUTE-1` | reused | Selected route and exact current coverage reason | `查看路线确认` | Result 3; another route may replace selection | +| `P91-ROUTE-REVIEW` | reused | Frozen party/build, route pressure, coverage, reward, zero entry cost | `锁定路线并进入第四战` | `返回比较` restores selected route and focus | +| `P91-BATTLE-4` | reused, generalized | Chosen route pressure targets the actual actor(s); current response is visible | automatic | Pause review only | +| `P91-RESULT-4` | reused, generalized | Route pressure + inherited response + reward receipt | `安排一次个人历练` | no return to battle | +| `P91-GROWTH-0` | reused P9.0R7, generalized | Every actual member, current level, distinct next-battle effect; no selection | none, review disabled | Result 4 | +| `P91-GROWTH-1` | reused, generalized | Selected member, gain, unchanged members, foregone effects | `查看历练确认` | Result 4; another member may replace selection | +| `P91-GROWTH-REVIEW` | reused | Exact member/effect and one-mark opportunity cost | `确认历练并进入第五战` | `返回改选` restores selection and focus | +| `P91-BATTLE-5` | reused, generalized | Trained effect and the untrained party responsibilities under dual pressure | automatic | Pause review only | +| `P91-FIRST-SESSION-RESULT` | expanded final | Happened, why, decisive decision, committed first-session change, next step | `结束本次体验` | no return; `重新开始` is a separate confirmation | + +### 3.2 Shared key states + +| State ID | Exact player-facing behavior | +|---|---| +| `P91-CHOICE-SELECTED` | Selected contour and `已选择` label; no resource/value mutation; selecting another legal option replaces it | +| `P91-COMMIT-PENDING` | Geometry stays fixed; action label becomes `正在确认…`; duplicate input is ignored; no success cue before receipt | +| `P91-COMMIT-REJECTED` | Inline cause, unchanged state, and `重新检查` or legal alternate; focus returns to the rejected commit | +| `P91-COMMIT-COMPLETE` | Named changed state plus receipt mark; selection controls become inspect-only; commit cannot repeat | +| `P91-BINDING-ERROR` | `这项决定暂时无法显示:缺少可验证的队伍结果。你的当前进度没有改变。` Actions: `重新检查`, `安全返回` | +| `P91-PAUSE` | Frozen battle snapshot, current event, captions, Resume; Home/Restart are separated reviews, never adjacent instant exits | +| `P91-HOME-REVIEW` | Names transient first-session progress that will be cleared; initial focus is `取消`; confirm returns to accepted front door | +| `P91-RESTART-REVIEW` | Names current session and exact reset scope; initial focus is `取消`; confirm returns to Commission with no preselection | + +After any committed battle begins, no reverse navigation may reopen its prior +decision. Result pages expose the next decision and global exit tools only. + +## 4. Chinese-First Copy Contract + +### 4.1 Stable mechanical nouns + +| Stable meaning | `zh_CN` | `en` | +|---|---|---| +| Company | 小队 | Company | +| system lead / order 0 | 先行者 / 先行位 | lead / lead position | +| order 1 | 第二位成员 / 第二位 | second member / second position | +| automatic formation | 系统编队 | automatic formation | +| adaptation | 应对方案 | response | +| Guild response | 公会响应 | Guild response | +| route coverage | 路线应对 | route coverage | +| individual growth | 个人历练 | individual training | +| committed receipt | 已确认结果 | confirmed result | + +Do not call the system lead `前排` unless the domain-provided profession action +itself is explicitly a front-facing response. Do not call the other selected +member `后排` unless the event/ability actually has a rear relation. This is +required for Farstring-led and Wayrunner-second formations. + +### 4.2 Screen titles and actions + +| ID | Exact `zh_CN` | Exact `en` | +|---|---|---| +| `LOC_P91_COMMISSION_TITLE` | 第一份委托 · 守住断裂的风路 | First Commission · Hold the Broken Wind Road | +| `LOC_P91_RECRUIT_TITLE` | 组建小队 · 任意选择两人 | Build the Company · Choose Any Two | +| `LOC_P91_FORMATION_TITLE` | 系统编队 · 检查两人的职责 | Automatic Formation · Review Both Roles | +| `LOC_P91_RESULT1_TITLE` | 第一战诊断 · 这支小队如何配合 | Battle 1 Diagnosis · How This Company Worked | +| `LOC_P91_ADAPT_TITLE` | 第二战准备 · 回应刚才的压力 | Prepare Battle 2 · Answer the Pressure | +| `LOC_P91_RESULT2_TITLE` | 第二战结果 · 应对方案造成的差异 | Battle 2 Result · Difference Made by the Response | +| `LOC_P91_GUILD_TITLE` | 公会如何回应这支小队? | How Will the Guild Respond? | +| `LOC_P91_RESULT3_TITLE` | 第三战结果 · 公会响应得到验证 | Battle 3 Result · Guild Response Proven | +| `LOC_P91_ROUTE_TITLE` | 下一条路线 · 比较压力与应对 | Next Route · Compare Pressure and Coverage | +| `LOC_P91_ROUTE_REVIEW_TITLE` | 路线确认 · {route_name} | Route Review · {route_name} | +| `LOC_P91_RESULT4_TITLE` | 第四战结果 · 路线选择造成的差异 | Battle 4 Result · Difference Made by the Route | +| `LOC_P91_GROWTH_TITLE` | 个人历练 · 只能培养一人 | Individual Training · Choose One Member | +| `LOC_P91_GROWTH_REVIEW_TITLE` | 历练确认 · {member_name} | Training Review · {member_name} | +| `LOC_P91_FINAL_TITLE` | 首次远征完成 | First Expedition Complete | +| `LOC_P91_REVIEW_FORMATION` | 查看系统编队 | Review Automatic Formation | +| `LOC_P91_COMMIT_FORMATION` | 确认编队并出发 | Commit Formation and Depart | +| `LOC_P91_COMMIT_ADAPT` | 带着所选方案出发 | Depart with This Response | +| `LOC_P91_COMMIT_GUILD` | 确认回应并开始第三战 | Confirm Response and Start Battle 3 | +| `LOC_P91_REVIEW_ROUTE` | 查看路线确认 | Review Route | +| `LOC_P91_COMMIT_ROUTE` | 锁定路线并进入第四战 | Commit Route and Enter Battle 4 | +| `LOC_P91_REVIEW_GROWTH` | 查看历练确认 | Review Training | +| `LOC_P91_COMMIT_GROWTH` | 确认历练并进入第五战 | Confirm Training and Enter Battle 5 | +| `LOC_P91_FINISH` | 结束本次体验 | Finish This Experience | + +### 4.3 Formation and choice copy + +These are exact sentence templates. Substitutions must be localized, escaped, +and complete; braces are never player-facing. + +| State | Exact `zh_CN` | Exact `en` | +|---|---|---| +| selection empty | 没有预选。选择任意两人,系统会安排先行者与第二位成员。 | Nothing is preselected. Choose any two; the system assigns the lead and second member. | +| selection one | 已选择 1 / 2:{member_name}。再选择一人才能查看系统编队。 | 1 / 2 selected: {member_name}. Choose one more to review the automatic formation. | +| formation lead | 先行位 · {member_name}({profession}):{responsibility} | Lead · {member_name} ({profession}): {responsibility} | +| formation second | 第二位 · {member_name}({profession}):{responsibility} | Second · {member_name} ({profession}): {responsibility} | +| choice empty | 没有预选。比较当前证据、得到什么和放弃什么。 | Nothing is preselected. Compare current evidence, gain, and opportunity cost. | +| selected | 已选择“{option_title}”。确认前仍可更换。 | “{option_title}” selected. You can still change it before commit. | +| reason row | 当前理由:{state_evidence},因此{answered_need}。 | Why now: {state_evidence}, so {answered_need}. | +| gain row | 得到:{gain} | Gain: {gain} | +| cost row | 代价:{cost} | Cost: {cost} | +| foregone row | 放弃:{foregone} | Give up: {foregone} | +| next proof row | 下一战将验证:{next_consequence} | Next battle will test: {next_consequence} | +| legal disabled | 还不能确认:{disabled_reason} | Cannot confirm yet: {disabled_reason} | +| review unchanged | 确认前不会改变金币、队伍、路线或成员等级。 | Coin, Company, route, and member levels do not change before commit. | + +The two accepted adaptation options keep their stable object identities and use +these exact rows; the resolved names and values are not genericized: + +| Option | Exact `zh_CN` | Exact `en` | +|---|---|---| +| `EQ-002` title | 钉阵胫甲 · 稳住第一击 | Frontpin Greaves · Steady the First Hit | +| `EQ-002` reason | 当前理由:下一场威胁会重击先行者,因此先稳住她承受的第一击。 | Why now: the next threat will strike the lead, so steady her first hit. | +| `EQ-002` gain | 得到:先行者第一次受伤降为 -10。 | Gain: the lead's first damage becomes -10. | +| `EQ-002` cost | 代价:小队下一次攻击更晚。 | Cost: the Company's next strike is later. | +| `EQ-061` title | 晨钟 · 抢到先手 | Early Bell · Seize Initiative | +| `EQ-061` reason | 当前理由:下一场敌人准备重击,因此先在它行动前造成 -28。 | Why now: the next enemy prepares a heavy strike, so deal -28 before it acts. | +| `EQ-061` gain | 得到:先行者抢在敌人之前行动。 | Gain: the lead acts before the enemy. | +| `EQ-061` cost | 代价:先行者承受完整 -30 重击。 | Cost: the lead takes the full -30 strike. | + +Their `放弃` row names the other option's gain, not merely its title. Neither +choice receives a `推荐` marker, brighter surface, default focus, or initial +selection. + +The Guild response surface uses the same four rows but adds `确认后:金币 +{coin_before} -> {coin_after};小队 {company_before} -> {company_after}` / `On +commit: Coin {coin_before} -> {coin_after}; Company {company_before} -> +{company_after}`. Its stable option titles are `保留已验证装备` / `Keep the +Proven Item` and `招募第三名成员` / `Recruit a Third Member`. The first reason +must name the selected item's observed Battle 2 effect; the second must name an +actual current party gap and how the offered member answers it. Values and +reasons come from the selected option preview, not UI profession checks. + +Route reason copy is selected by a supplied coverage state: + +| Coverage | Exact `zh_CN` | Exact `en` | +|---|---|---| +| `covered` | 已覆盖:{coverage_source}能够回应“{pressure}”。 | Covered: {coverage_source} answers “{pressure}”. | +| `partial` | 部分应对:{coverage_source}会减轻结果,但不能阻止“{pressure}”。 | Partial: {coverage_source} reduces the consequence but does not stop “{pressure}”. | +| `gap` | 存在缺口:当前小队没有直接回应“{pressure}”。 | Gap: the current Company has no direct answer to “{pressure}”. | + +Coverage language predicts a relationship, not exact future HP. It may never +mark a route `推荐`, `最佳`, or visually enlarge its reward. + +Growth option copy is always: + +```text +{order_label} · {member_name} · {profession} +{level_before} -> {level_after} +得到:{growth_effect} +下一战将验证:{growth_test} +``` + +The unselected context reads `历练印记 × 1。只能培养一名实际成员;等级不会 +分享给全队。` / `Training Mark × 1. Train one actual member; levels are not +shared by the Company.` The review adds `放弃:其他成员保持 {unchanged_level}, +本轮不获得其历练效果。` / `Give up: other members stay at +{unchanged_level}; their training effects are not gained this cycle.` + +### 4.4 Cause-first result copy + +All five results use the same labeled order. Labels and punctuation are exact; +the supplied clauses must not repeat the label. + +```text +发生了什么:{outcome_clause} +为什么:{cause_clause} +决定造成的差异:{decision_clause} +现在改变了:{changed_state_clause} +下一步:{next_action_clause} +``` + +```text +What happened: {outcome_clause} +Why: {cause_clause} +Difference made by the decision: {decision_clause} +Changed now: {changed_state_clause} +Next: {next_action_clause} +``` + +For Result 1, `决定造成的差异` is renamed `系统编队造成的差异` / `Difference +made by automatic formation`. Results 2-5 must name the actual committed option +or trained member in `decision_clause`. `changed_state_clause` includes named +before/after values or explicitly says `没有永久变化` / `No persistent change`. +The final result must include all four questions requested by the batch even if +there is no future implemented chapter: + +```text +发生了什么:五场远征全部完成;{final_party_outcome}。 +为什么:{earliest_decisive_cause}。 +决定造成的差异:{decision_name}让{counterfactual_delta}。 +现在改变了:{final_changed_state}。 +下一步:首次体验到此结束;可以检查完整因果记录或重新开始。 +``` + +Do not claim a saved run, permanent inventory, chapter unlock, authoritative XP +beyond the supplied first-session state, or future availability. + +## 5. `844x390` Landscape Composition + +P9.1 uses logical pixels and reflows by track; it never scales the complete +canvas. The minimum interactive target is `48x48` (`56` high for primary +commit), exceeding the Goal's 44 px lower bound. Targets include their full +hit region and keep at least `8` px separation. + +### 5.1 Shared tracks + +| Track | `844x390` bounds | Contract | +|---|---:|---| +| top status rail | `x=12, y=10, w=820, h=54` | Home review tool, product/context, Coin/Company when relevant, Restart, Mute; one row at 100% | +| main world/decision | `x=18, y=72, w=544, h=242` | Actors, route nodes, candidate strip, or causal timeline; never nested cards | +| context rail | `x=570, y=72, w=256, h=242` | current evidence, gain/cost/foregone, selected summary; unframed or one physical surface | +| bottom action dock | `x=18, y=322, w=808, h=56` | secondary/back at left; one primary commit at right, at least `248x56` | + +At 130%, the top rail becomes `68` high and may use two bounded rows. Main +content starts at `y=84`; supporting flavor moves to Inspect. Choice options +keep title, reason, gain/cost, selection, and disabled reason visible. A +full-screen Inspect replacement may scroll, but selecting, revising, reviewing, +committing, Back, and the exact current consequence never require scrolling. + +No text ellipsizes. Labels wrap to two lines; generated names get their own +line before profession. If a localized option exceeds two body lines, its +supporting evidence moves to Inspect rather than shrinking below the functional +type token. + +### 5.2 Composition by family + +#### Recruit and formation + +- Recruit selection uses four equal `128x166` upright markers across the main + track in stable source order. The selected count is fixed above them; selection + never moves or enlarges a candidate. +- Formation review uses an unframed horizontal cord: second member at left, + lead at right nearest the enemy-facing gap. Ground labels read `第二位 · 1` + and `先行位 · 0`. Dotted source-to-target connectors sit behind text summaries. +- The context rail states why the system produced this order. It does not offer + drag, swap, front/rear buttons, or a manual order control. + +#### Adaptation and Guild response + +- The current party stays in the world at left. Two equal choice regions occupy + the physical preparation bench; the rail holds the four-row comparison. +- Equipment is shown as an object on a shallow tray. A third-member response + shows a recruit silhouette adjacent to the current line. Neither is a receipt + card or recommendation. +- Before selection, the commit occupies its final dimensions but is + policy-disabled with the visible reason `先选择一种回应。` / `Choose one + response first.` + +#### Route + +- Three equal adjacent nodes use `172x116` stable envelopes within the world + scene. Their path lengths and node sizes are equal; exposure pattern and + pressure icon differ without reward-based scale or glow. +- A comparison band below the nodes reads in this order: pressure, exposure, + reward, current coverage. The selected node connects to the rail with one + continuous `route-teal` line. +- Route review freezes the party line across the lower third and uses one + transaction surface, not three cards. + +#### Individual growth + +- Every actual party member occupies one equal-width marker on the horizontal + line. Two-person and three-person layouts use the same line width; three + markers become narrower but never below `156x148` at `844x390`. +- Actor silhouette, name/profession/current level, and exact effect remain in + each marker. The rail holds the selected effect detail and one-mark cost. +- Unselected members remain fully readable after selection. No rays, rarity + frame, or hero-scale portrait implies a canonical protagonist. + +#### Battle + +- Battlefield owns at least `68%` of usable area. Allies stage protected-left + to exposed-right; lead/order 0 is rightmost. Enemy faces the lead across the + central action gap. +- Objective and next urgent event are top-left below the global rail. Symbol + controls Pause, Speed, Inspect, and captions stay top-right. None resembles a + combat command. +- Only urgent actor data expands. HP, order marker, target relation, and one + short status attach to the actual actor; the event ribbon reserves space and + never covers actors or primary feedback. + +#### Result + +- The cause-first timeline owns the center `54%` of usable width. The first + divergence has the strongest contour; connectors join decision, source, + target, and exact changed value. +- Actual affected actors remain visible to the left of their event. Facts and + receipt occupy the context rail below the cause, never above it. +- The next action is the only primary control. Home/Restart remain secondary + global tools and never compete with continuation. + +### 5.3 Focal and focus order + +Visual/focus order is fixed: + +1. screen heading and current decision/objective; +2. current party state or earliest causal event; +3. candidate/options in stable source order; +4. selected comparison and exact consequence; +5. primary action; +6. Back/Inspect/global tools. + +Touch selection, controller focus, and keyboard focus share stable geometry. +Focused uses the accepted `3 px` white outer plus `2 px` ink inner contour and +cobalt corner marker. Selected adds a check and `已选择`; focus and selection +are never represented by hue alone. Focus returns to the invoking stable ID +after Inspect, to the selected option after review cancellation, and to the +first still-selected recruit after formation revision. It never follows actors +or animation. + +## 6. Party-Line And Battle Event Bindings + +### 6.1 Party-line projection + +For each supplied member, render: + +```text +{order_index} · {order_label} +{member_name} · {profession} +{responsibility} +{condition} +``` + +Order `0` is announced `先行位,右侧暴露位置` / `lead, exposed position on the +right`; subsequent indices are progressively left/protected. The explanation +must name the ordering source: `系统依据两人的当前职责形成此顺序。` / `The +system formed this order from both members' current responsibilities.` It must +not claim an optimal or permanent order. + +When the Guild response adds a member, the receipt animation inserts that +member at the domain-supplied order index, redraws connectors, and announces +every affected old/new number. Existing actors do not respawn. If order is +unchanged, the receipt explicitly reads `原有两人顺序未改变。` / `The original +two keep their order.` + +### 6.2 Event-to-presentation matrix + +| Event kind | Required subject motion/binding | Geometry and exact attached copy | Normal completion | Reduced/low-power completion | +|---|---|---|---|---| +| `lead_guard` | accepted guard frames on actual source | source-to-self brace edge; `{source}承受攻击:{before} -> {after}({mitigation_source})` | impact contour + one value | stepped guard pose + final value | +| `lead_evade` | accepted evade/counter frames | enemy target line breaks, counter line returns; `敌人锁定{source};闪避后结果 {before} -> {after}` | directional trail, no camera travel required | broken/returned static lines | +| `ranged_damage` | accepted draw/release and projectile | source-to-enemy line; enemy-attached `-{amount}`; `来源:{source} · 远程命中` | projectile then exact enemy value | source pose -> target contour -> value | +| `melee_damage` | accepted advance/strike | source-to-target short connector; target-attached `-{amount}` | impact response and one number | final strike pose and contour | +| `heal` | accepted lantern/heal frames | source-to-actual-target jade leaf-chevron; target-attached `+{amount}`; `来源:{source} · 恢复` | path reaches target before value | static connector then exact value | +| `protect` | supplied protector/target relation | stitched shield connector; `由{source}保护{target}:{before} -> {after}` | connector tightens, then value | persistent connector and value | +| `enemy_pressure` | accepted telegraph/attack | danger-coral split triangle at actual target(s); caption names pressure and time/order | authored warning then impact | persistent target mark, stepped poses | +| `reward` | no combat particle authority | receipt strip: `奖励已结算一次:金币 {before} -> {after}` | value travels to Coin then stamp | final Coin plus receipt only | +| `persistent_change` | option/member is the source | before/after relation: item, member count, route, or level | `180 ms` commit then `360 ms` receipt | direct final state plus receipt | + +Each HP mutation creates exactly one numeric payload. Damage uses a minus sign +and coral split-triangle; healing uses a plus sign and jade leaf-chevron. +Mitigation shows named before/after or avoided amount, never a green damage +number. Events with zero delta still name the attempted source and reason; they +do not emit `-0` or `+0`. + +The visual layer consumes ordered events. It must not derive action branches +from profession, assumed front/rear slots, current animation frame, or elapsed +render time. + +### 6.3 Causal timeline + +Every result event row contains stable event icon, event order/time, source, +target, before/after or receipt, and immediate cause. The first meaningful +divergence is the earliest event whose resolved outcome differs because of a +committed formation/adaptation/Guild/route/growth decision. If the domain +supplies no divergence, show `没有发现由本次决定造成的可验证差异。` / `No +verifiable difference from this decision was found.` Missing cause is a binding +error, not neutral success. + +## 7. Motion, Feedback, Audio, And Power Variants + +P9.0R3 battle phase timing and accepted action frames remain authoritative. +P9.1 may bind more actual actors and events but may not retime the preserved +combat language. UI uses `90 ms` select, `180 ms` commit, and `360 ms` receipt. +Layout dimensions never animate. + +| Variant | Required behavior | +|---|---| +| Standard | Source, direction, target, exact delta, and final state appear in that order; one nonessential ambient focal process and at most two background loops | +| Reduced motion | No camera travel, parallax, bobbing, continuous UI motion, or nonessential loops; accepted action becomes readable stepped poses; source/target/value order remains | +| Reduced flashes | No full-screen flash, alternating high-contrast frames, or rapid burst; impact uses contour, pattern, pose, and exact value | +| Mute | No mechanic, timing, decision, caption, geometry, or receipt changes; speaker tool reads `静音`; visual captions stay active | +| Low power | Freeze ambient loops and nonessential particles; retain essential anticipation, source pose, target mark, number, event row, and receipt; domain event order/timing does not change | + +Battle captions use `来源 -> 动作 -> 目标 -> 结果`, for example +`妮娅 -> 远程射击 -> 路线守卫 -> -28` / `Nia -> Ranged shot -> Route +Warden -> -28`. Environmental captions are visually quieter and cannot replace +urgent captions. Sound output loss raises one nonblocking notice without moving +controls. + +## 8. Localization And Accessibility + +### 8.1 English and 130% text + +- `zh_CN` and `en` use identical state order, control order, bindings, and + stable IDs. English may wrap earlier but may not shorten away cause or cost. +- At 130%, titles, option names, generated names, before/after values, disabled + reasons, and actions never ellipsize. The first viewport retains objective, + current state, cost/consequence, primary action/Back, and causal explanation. +- Tabular numerals are used for HP, Coin, Company size, level, event order, and + time. Chinese does not insert spaces between ideographs. +- Screen-reader order follows Section 5.3. Party announcements include order + index, exposed/protected direction, name, profession, condition, and current + responsibility. Battle events include source, action, target, result, and + order/time. + +### 8.2 Non-color and input equivalence + +- Safe, harmful, uncertain, selected, disabled, and complete use the accepted + shape/pattern plus text. Disabled opacity alone is forbidden. +- Touch, controller, keyboard, and mouse expose the same verbs. No essential + action requires drag, hover, double tap, or pointer precision. +- All targets are at least `48x48`; primary actions are at least `56` high. + Insets, captions, notices, target marks, and focus contours never overlap. +- A pauseable full-screen chronological event log contains every urgent + automatic battle event. Opening it preserves playback state; closing it + restores the exact prior state and focus. +- High contrast reduces texture behind text/actors while retaining scene + identity. It does not recolor semantic meanings into a single hue family. + +### 8.3 Exact disabled and error reasons + +| Situation | Exact `zh_CN` | Exact `en` | +|---|---|---| +| fewer than two recruits | 还不能查看编队:请选择两名不同成员。 | Cannot review formation: choose two different members. | +| no adaptation | 还不能出发:先选择一种应对方案。 | Cannot depart: choose one response first. | +| no Guild response | 还不能开始第三战:先选择公会如何回应。 | Cannot start Battle 3: choose a Guild response first. | +| no route | 还不能查看确认:先选择一条路线。 | Cannot review: choose a route first. | +| no growth member | 还不能查看确认:先选择一名实际成员。 | Cannot review: choose an actual member first. | +| option illegal | 这项选择当前不可用:{reason}。你的状态没有改变。 | This option is unavailable: {reason}. Your state did not change. | +| stale commit | 无法确认:队伍状态已经变化。请重新比较;你的状态没有改变。 | Cannot commit: Company state changed. Compare again; your state did not change. | +| missing result cause | 无法继续:这场结果缺少可验证原因。你的进度停在战后。 | Cannot continue: this result has no verifiable cause. Progress remains after the battle. | + +## 9. Implementation Handoff IDs + +Minimum stable controls: + +```text +P91_OpenRecruitSelection +P91_Recruit_{stable_member_id} +P91_ReviewFormation +P91_ReviseRecruits +P91_CommitFormation +P91_OpenAdaptation +P91_Adaptation_{stable_option_id} +P91_CommitAdaptation +P91_OpenGuildResponse +P91_Guild_{stable_option_id} +P91_CommitGuildResponse +P91_OpenRouteBoard +P91_Route_{stable_route_id} +P91_ReviewRoute +P91_CancelRouteReview +P91_CommitRoute +P91_OpenGrowth +P91_Growth_{stable_member_id} +P91_ReviewGrowth +P91_CancelGrowthReview +P91_CommitGrowth +P91_FinishSession +P91_Inspect +P91_Pause +P91_Captions +``` + +Compatibility aliases may retain P9.0R10 names such as +`ContinueAdaptationButton`, `Adaptation_EQ_002`, `OpenGuildReturnButton`, and +existing route/growth controls. Aliases cannot preserve old standard-pair +branching or obsolete player-facing front/rear copy. + +Each screen snapshot must record: + +```text +screen_id, state_id, viewport, safe_area, locale, text_scale, input_mode, +focus_id, selected_id, motion, flashes, mute, captions, contrast, low_power, +party_snapshot_id, decision_snapshot_id, event/result_ids, source_revision +``` + +## 10. Minimum Source-Bound Render Evidence + +All frames are normal Godot renders from the fixed candidate revision, not +mockups. Unless specified, fixture is `844x390`, `zh_CN`, 100%, standard motion, +standard flashes, captions on, sound on, standard contrast, normal power. + +| Frame | Required state and visible proof | +|---|---| +| `P91-E01` | accepted Title/front door; product, premise, entry action, settings tool | +| `P91-E02` | `P91-RECRUIT-0`; four equal candidates, `0 / 2`, no preselection, disabled reason | +| `P91-E03` | `P91-RECRUIT-2`; an exposed nonstandard pair selected, stable positions unchanged | +| `P91-E04` | formation review for Farstring + Kindhand; system lead/second labels, both reasons, revise/commit | +| `P91-E05` | Battle 1 exposed-lead pressure; actual target mark, damage number, event caption | +| `P91-E06` | Result 1 for a pair with Wayrunner second; both actions and order-caused difference | +| `P91-E07` | adaptation unselected; equal responses, gain/cost/foregone, no recommendation, commit reason | +| `P91-E08` | Battle 2 Wayrunner second-position counter; source/target/delta and selected response visible | +| `P91-E09` | Result 2; response-caused before/after, actual party actions, return-to-Guild action | +| `P91-E10` | Guild response unselected for a nonstandard starting pair; current actors/Coin and two state-dependent reasons | +| `P91-E11` | alternate Guild response selected; before/after Coin/Company, gained and foregone state | +| `P91-E12` | Battle 3 at the first event that proves the selected Guild response | +| `P91-E13` | Result 3 cause-first timeline and current Company snapshot | +| `P91-E14` | route board unselected; all three pressures/exposure/reward plus different current coverage states | +| `P91-E15` | route review; selected pressure/coverage, party snapshot, Back and commit | +| `P91-E16` | Battle 4 pressure attached to actual target(s), including a rear/split target case | +| `P91-E17` | Result 4; inherited response + route pressure + once-only reward receipt | +| `P91-E18` | growth unselected; all actual members, distinct effects, one mark, no preselection | +| `P91-E19` | growth review at `zh_CN`, 130%; exact gain, foregone effects, actions without overlap/scroll | +| `P91-E20` | Battle 5 at the event that proves the trained member's changed capability | +| `P91-E21` | final result; all five cause-first lines, final party/decision state, no unsupported future claim | +| `P91-E22` | final result for a materially different prior decision; decision clause and changed state visibly differ | +| `P91-E23` | recruit or Guild decision at `en`, 130%; longest title/reason/action fit with focus contour | +| `P91-E24` | representative battle with reduced motion + reduced flashes + mute; persistent target geometry, caption, number | +| `P91-E25` | representative three-member battle in low power; order, essential event frames, HP, caption remain readable | + +At least one evidence path must represent each of the six unordered starting +pairs across deterministic screenshots or the interaction/test matrix. The +normal-render minimum above deliberately concentrates visual proof on the most +failure-prone nonstandard roles; it does not replace six-pair domain coverage. + +### 10.1 Complete interaction recording + +Record one uninterrupted normal-render path from `P91-TITLE-READY` to +`P91-FIRST-SESSION-RESULT` using real parsed `ScreenTouch`/`ScreenDrag` input. +The recording must visibly: + +1. choose two recruits, remove one, choose a replacement, then review/commit; +2. show both Battle 1 responsibilities and read Result 1; +3. select adaptation A, switch to B, then commit; +4. select one Guild response, switch to the other, then commit; +5. select a route, open review, return to compare, select another route, commit; +6. select one member for growth, open review, return, choose another, commit; +7. reach the final result and inspect the complete causal record. + +The capture report binds video hash/path to source revision, runtime version, +fixture/settings, session seed or deterministic scenario ID, starting pair, +every committed stable option ID, final snapshot ID, and strict diagnostics. +Fallback/direct input counts must be zero. Cuts, state injection, debug-only +navigation, or test-created intermediate pages invalidate this recording. + +### 10.2 Fixture and pair coverage + +The source-bound layout suite uses these exact landscape fixtures: + +| Fixture ID | Viewport | Required coverage | +|---|---:|---| +| `P91-L-SMALL` | `844x390` | every screen/state; `zh_CN` 100% and representative `en`/130% states; no normal action scroll | +| `P91-L-SHORT` | `1280x720` | every layout family; device safe area `56` sides and `40` top/bottom | +| `P91-L-WIDE` | `1560x720` | recruit, route, three-member battle, result; extra width reveals world, not stretched controls | +| `P91-L-REFERENCE` | `1920x1080` | every layout family at canonical tracks and type tokens | +| `P91-L-LARGE` | `2560x1440` | recruit, choice, battle, result; constrained UI tracks and additional environment only | + +All six unordered pairs are named test/evidence identities and must each reach +the final result: `Hearthguard + Wayrunner`, `Hearthguard + Farstring`, +`Hearthguard + Kindhand`, `Wayrunner + Farstring`, `Wayrunner + Kindhand`, and +`Farstring + Kindhand`. For each pair, the layout/evidence manifest records the +system-supplied lead/second order and both displayed responsibility strings. +At least one normal-render frame exists for every pair; the complete minimum +frame list in Section 10 remains mandatory rather than being replaced by these +six pair frames. + +## 11. Acceptance Checklist And Residual Human Gates + +- [ ] Every screen/state in Section 3 is reachable through visible controls from the accepted front door. +- [ ] No choice is preselected; revise, review, commit, duplicate commit, disabled, stale, and binding-error states follow this contract. +- [ ] Every arbitrary starting pair uses `先行者` / `第二位成员` correctly and shows actual responsibilities rather than standard-pair assumptions. +- [ ] Guild, route, and growth values read the actual party and prior decisions; at least two supplied options change rational value by state. +- [ ] All battle events project source, target, action, exact delta, cause, and order without deriving domain truth in UI. +- [ ] All five results use cause-first order and the final result answers happened, why, decision difference, changed state, and next action. +- [ ] `844x390`, representative small/reference/large landscape fixtures, `zh_CN`, `en`, 130%, reduced motion/flashes, mute, high contrast, and low power pass without overlap or hidden actions. +- [ ] Minimum frames and the uninterrupted parsed-touch recording are revision-bound and diagnostics-clean. + +Automated tests and captures cannot approve comprehension, fun, visual feel, +listening quality, physical-device behavior, packaging, store readiness, or +release. Those remain explicit Owner/Human Gates. This candidate also cannot +authorize runtime implementation until gameplay, UX/visual, and architecture +specifications are reconciled into the frozen P9.1 implementation contract.