1Giới thiệu & bản đồ tài liệu
Mục đích: đặc tả TOÀN BỘ input và camera của Bladewake bản 1.0 (PC Steam, tay cầm trước, bàn phím/chuột đủ, Steam Deck): action map theo ngữ cảnh, bảng nút đầy đủ cho 4 thiết bị (tay cầm ABXY · tay cầm ký hiệu hình · Steam Deck · bàn phím + chuột) ở combat/menu/bản đồ/hub, override theo hero, chế độ ngắm + trợ ngắm, buffer + chạm/giữ theo tick, luật remap + preset, glyph + Steam Input, camera (bám, nhìn trước, khung boss, giới hạn, rung, pixel-perfect, hồ sơ theo nút bản đồ/boss), rung tay cầm, ghi chú chạm cho bản mobile sau. Phụ thuộc: 00-Design-Bible.md §1.1 (bản đồ nút khoá), INV-06/07/09/11/12, §4.3, §10.4 (camera pixel) + data/_bible.json (input_map, meta.mercy, meta.accessibility); 10-Combat-Core.md §1.1–§1.6, §6.1–§6.3, §9; 11-Defense-Tells.md §2.1, §3, §4; 12-Hero-Framework.md §1.1–§1.5, §3.2–§3.5, §11; 30-Art-Direction.md §2.1–§2.2; 40-UI-UX-HUD.md §0.1, §1.5, §3.1, §5.2–§5.6, §6.2–§6.3; 43-Steam-Platform.md §7.1, §8, §10; 01-Roadmap.md §3.12, §5.1–§5.2; data/tuning.json (combat.*, platform.*, run.death_cam_s); GDD demo GDD/01-Camera-Controls.md (lịch sử). Được dùng bởi: code Input (InputActions, InputFrame, InputBuffer, RebindService, InputGlyphs, DeviceTracker), Presentation (PixelCamera, CameraDirector, ShakeService, Haptics), AimService; doc 42 (Trợ năng); doc UI 40 (màn remap, thanh nhắc nút); QA (checklist input/Deck); agent sinh tuning.json section platform/camera; cổng port console/mobile.
Mục lục chi tiết (## và ###)
- 0. Phạm vi & thứ bậc
- 1. Ngữ cảnh input (action map)
- 2. Bảng nút — Combat (map Gameplay)
- 3. Bảng nút — UI (map UI; canon trình bày 40 §3.1)
- 3.1 Điều hướng chung (mọi màn Screens)
- 3.2 Draft (13 §2–§4, 40 §5.3; World ×0.15 + hero bất tử ở phòng thường)
- 3.3 Bản đồ (Map, 16 §2.1, 40 §5.2)
- 3.4 Màn khác trong run
- 4. Bảng nút — Hub (map Hub, HUB_BELL_TOWER, sân 960×544 px)
- 5. Override theo hero (chỉ field 12 §1.4; không hero nào thêm nút)
- 6. Ngắm & trợ ngắm
- 6.1 Chế độ ngắm (aim_mode, 12 §1.3)
- 6.2 Trợ ngắm (10 §9 + PlatformTuning 01 §5.1)
- 6.3 Đặt vật & reticle
- 7. Buffer & ưu tiên (INV-07, 12 §1.5, §3.3)
- 8. Remap, preset, Steam Input
- 8.1 Luật remap (Bible §1.1 "remap toàn bộ")
- 8.2 Preset (input_preset)
- 8.3 Một lớp input (01 §5.2)
- 8.4 Steam Input (1.0)
- 9. Glyph
- 10. Rung tay cầm (haptics)
- 11. Camera
- 11.1 Độ phân giải, zoom, vùng an toàn (khoá: Bible §10.4, 30 §2.2)
- 11.2 Bám theo (PixelCamera + CameraDirector, 50 §2; mọi ngữ cảnh có world)
- 11.3 Giới hạn sân
- 11.4 Khung theo trận / boss (zoom = §11.1 ở MỌI ngữ cảnh; chỉ khác đích & lệch)
- 11.5 Rung màn (trauma; số canon 10 §6.2, tuning.combat.shake_)
- 11.6 Pixel-perfect (khoá 30 §2.1–§2.2, 50 §4.3)
- 11.7 Đồng hồ & thứ tự cập nhật (10 §1.1, 50 §2.3)
- 11.8 Mũi tên & khung ngoài màn
- 12. Chạm (ghi chú cho bản mobile sau, 01 §3.12 — KHÔNG làm ở 1.0)
- 13. Khoá tuning (số trong doc → tuning.json; khoá có sẵn trích nguyên, khoá mới agent tuning thêm theo 51 §4)
- 14. Kiểm thử (QA + CI)
- Quy tắc cho dev/AI
- Quyết định đã chốt
20. Phạm vi & thứ bậc
- Canon: Bible +
_bible.json> doc nền (10–17, 20, 30–32, 51) > doc này. Doc này không đổi bản đồ nút Bible §1.1, cửa sổ ĐÁP, buffer 0.15 s, thứ tự ưu tiên INV-07, luật trợ ngắm10§9; chỉ trình bày đầy đủ, điền chỗ trống (nút phụ, menu, hub, camera chi tiết) và chốt số[ASSUMED]mới. - Tên nút trong doc: tay cầm bố cục chữ = A/B/X/Y, LB/RB (vai), LT/RT (cò), LS/RS (cần), L3/R3 (bấm cần), View/Menu (2 nút giữa), d-pad. Bố cục ký hiệu hình = ✕/○/□/△, L1/R1, L2/R2, L3/R3, nút giữa trái/phải, bấm bàn cảm ứng. Steam Deck = A/B/X/Y, L1/R1, L2/R2, View/≡, L4/L5/R4/R5 (nút lưng), trackpad trái/phải. Không viết tên hãng/sản phẩm tay cầm.
- Đơn vị: tick = 1/60 s (
10§1.1); px sàn = px gameplay trên mặt sàn; art px = px màn trước phóng (480×270 ở 1080p); UI px =40§0.1. [ASSUMED]= số lượt đầu, chỉnh trongtuning.json(sectionplatformcho số theo nền tảng; khoácam_*/input_*mới ghi ở §13), không cần DEC nếu không chạm INV.- Mọi đọc thiết bị nằm trong thư mục
Input/(CI grepKeyboard.current,Gamepad.current,Mouse.current,Touchscreen.currentngoài thư mục → lỗi; Roadmap §5.2). Gameplay chỉ đọcInputFrame.
31. Ngữ cảnh input (action map)
Map (InputActions) | Bật khi | Hành động | Đồng hồ |
|---|---|---|---|
Gameplay | CombatHud trong phòng (CMB/ELT/CHL/MBS/BOS/RSC/FINALE), Sân Tập Sân Tập ST_YARD khi không mở menu nổi | MOVE AIM ATTACK ANSWER_HOLD DASH SKILL_1..3 ULT INTERACT POTION ASH_INSPECT MAP PAUSE BOSS_LOCK | mẫu theo tick sim 60 Hz |
Hub | HubHud ở HUB_BELL_TOWER (không giao tranh) | MOVE DASH INTERACT (cũng = ATTACK, Bible §1.1 DEC-2026-11-07-06) MAP (= HubTravel) PAUSE ASH_INSPECT (mở Sổ Thù nhanh, 40 §6.8) | Real |
UI | mọi màn Screens (Draft, Map chọn nút, Reward, Shop, Rest, Event, Pause, Settings, menu trạm, Dialogue, Title) | NAV CONFIRM BACK TAB_L/R PAGE_L/R DETAIL ALT_1/ALT_2 PAUSE (40 §3.1) | Real |
Text | ô nhập chữ (seed CUSTOM, tên preset remap) | nhập chữ; tay cầm → bàn phím ảo nổi của Steam (43 §8.1) | Real |
- Luôn bật đúng 1 map + map nền
System(chỉPAUSEvà phát hiện thiết bị). Mở mànScreens→ tắtGameplaytrong cùng frame; mọi nút đang giữ được xả (coi như nhả, không bắn sự kiện thả) → ATTACK đang giữ không ra đòn nạp khi đóng màn. - Đóng màn về
Gameplay: nút còn đang giữ bị bỏ qua tới khi nhả (chống A xác nhận thẻ biến thành Lướt; chống X giữ Xoá thành nạp). - Map chỉ đổi qua
InputContextService.Push/Pop; ngăn xếp ≤ 4 (vd Gameplay → Pause → Settings → Confirm).
42. Bảng nút — Combat (map Gameplay)
Canon Bible §1.1 + 12 §1.1. Cột KB/M "phụ" = ô thứ 2 mặc định (dùng cho người không có chuột, preset KBM_KEYS §8.2).
action_id | ABXY | Ký hiệu hình | Steam Deck | KB/M chính | KB/M phụ | Chạm / Giữ |
|---|---|---|---|---|---|---|
MOVE | LS | LS | LS | WASD | phím mũi tên | analog 360°; vùng chết LS 0.20 (0.10–0.40) |
AIM | RS | RS | RS (trackpad phải = con trỏ chỉ trong menu) | con trỏ chuột | — (ngắm theo MOVE, AIM_MOVE) | §6 |
ATTACK | X | □ | X | LMB | J | chạm = combo kế · giữ ≥ attack_hold_ticks = attack_hold_action hero (§5) |
ANSWER_HOLD | RB | R1 | R1 | RMB | L | chạm = ĐÁP · giữ tới hết W = verb giữ hero |
DASH | A | ✕ | A | Space | K | Lướt; hướng = MOVE, không có → hướng ngắm |
SKILL_1 | LB | L1 | L1 | Q | U | cast_mode TAP/HOLD theo kỹ năng |
SKILL_2 | LT | L2 | L2 | E | I | như trên |
SKILL_3 | RT | R2 | R2 | F | O | ô 3 mở khi hạ BS_B2 (Bible §2.2) |
ULT | Y | △ | Y · R4 (bản sao) | R | P | chỉ khi Dư Âm (ULT_GAUGE) = 100 |
INTERACT | B | ○ | B · R5 (bản sao) | G | Enter | chỉ khi có nhắc (r24, vật ready); giữ 0.5 s = hành động huỷ được |
POTION | d-pad ↓ | d-pad ↓ | d-pad ↓ · L4 (bản sao) | 1 | H | uống bình (10 §8.3) |
ASH_INSPECT | View (giữ) | nút giữa trái (giữ) | View (giữ) · L5 (bản sao) | Tab (giữ) | Y (giữ) | nhả = đóng (Bible §8.4) |
MAP | d-pad ↑ | d-pad ↑ | d-pad ↑ | M | N | mở Map chế độ xem; World dừng như Pause |
PAUSE | Menu | nút giữa phải | ≡ | Esc | Backspace | không remap được ô chính (§8.1) |
BOSS_LOCK | R3 | R3 | R3 | chuột giữa | Z | chỉ khi bật "Khoá boss cứng" (10 §9) |
- d-pad ←/→ trong combat: không gán (để trống cho preset 1 tay
42§7.2 và tránh bấm nhầm). Bấm cần trái L3: không gán. - Cò (LT/RT, L2/R2) đọc như nút số: nhấn ở 0.35, nhả ở 0.25 (trễ chống rung tay)
[ASSUMED]; không dùng độ sâu cò cho gameplay. - Bàn phím: không dùng Shift+Tab, Ctrl+Alt, F12 (overlay/ảnh chụp Steam,
43§10). Mọi gán mặc định là 1 phím, không tổ hợp. - Chuột: nút bên M4 =
DASHphụ, M5 =ANSWER_HOLDphụ khi có (gán sẵn trong ô thứ 3 ẩn chỉ cho nút chuột, không tranh 2 ô người chơi)[ASSUMED].
53. Bảng nút — UI (map UI; canon trình bày 40 §3.1)
3.1 Điều hướng chung (mọi màn Screens)
| Lệnh | ABXY | Ký hiệu hình | Steam Deck | KB/M | Luật | ||
|---|---|---|---|---|---|---|---|
NAV di chuyển focus | d-pad / LS | d-pad / LS | d-pad / LS | mũi tên / WASD / rê chuột | giữ hướng: lặp sau 0.35 s, 12 bước/s; LS kích ở 0.50, nhả ở 0.35; UiNavigate (focus đổi; cooldown 40 ms khi giữ hướng) SFX_UI_nav_move cách ≥ 40 ms | ||
CONFIRM | A | ✕ (đảo: ○) | A | Enter / Space / LMB | đảo xác nhận/huỷ chỉ cho bộ glyph ký hiệu hình (42 §7) | ||
BACK | B | ○ (đảo: ✕) | B | Esc / RMB (ngoài vùng kéo) | gốc màn trong run: đóng về game; gốc menu trạm: về hub | ||
TAB_L · TAB_R | LB · RB | L1 · R1 | L1 · R1 | Q · E / bấm tab | vòng quanh | ||
PAGE_L · PAGE_R | LT · RT | L2 · R2 | L2 · R2 | PgUp · PgDn / con lăn | danh sách > 1 trang | ||
DETAIL | View | nút giữa trái | View | Tab | tooltip mở rộng / so sánh / bảng từ khoá (42 §8) | ||
ALT_1 · ALT_2 | X · Y | □ · △ | X · Y | theo màn (ghi ở thanh nhắc nút) | — | ||
| Cuộn nội dung dài | RS | RS | RS / trackpad phải | con lăn | 240 UI px/s ở | RS | = 1.0 |
PAUSE | Menu | nút giữa phải | ≡ | Esc (khi không có màn mở) | — |
- Thanh nhắc nút
UI_C_PromptBar(40§3.1): ≤ 5 cặp glyph + nhãn ≤ 12 ký tự; nhãn dùng token{btn:ACTION_ID}(§8.1). - Con trỏ chuột chỉ hiện khi thiết bị cuối = KBM; ẩn sau 3 s không rê (focus giữ nguyên). Tay cầm: không có con trỏ ảo; trackpad phải Deck = chuột chỉ trong menu (
43§8.1). - Khoá xác nhận 0.30 s đầu ở màn mở do sự kiện (draft, thưởng, cổng boss, chết, recap):
CONFIRMbị nuốt,NAVvẫn nhận (40§3.1). - Lệnh nguy hiểm (Bỏ run, Xoá dữ liệu, Xoá Sổ Thù, Xoá thẻ draft, Bỏ qua draft) =
UI_C_Hold(giữ, vòng tiến trình; thời lượng × "Thời gian giữ"42§7) hoặc hộp xác nhận 2 bước theoconfirm_style(42§7). Không lệnh nguy hiểm nào nằm trênCONFIRMchạm đơn.
3.2 Draft (13 §2–§4, 40 §5.3; World ×0.15 + hero bất tử ở phòng thường)
| Lệnh | ABXY | Ký hiệu hình | Steam Deck | KB/M |
|---|---|---|---|---|
| Trỏ thẻ | d-pad ←/→ / LS | d-pad / LS | d-pad / LS | ←/→ · A/D · rê chuột |
| Chọn | A | ✕ | A | Enter · LMB · phím 1/2/3 (/4 khi LV04) chọn thẳng |
| Đổi | Y | △ | Y | R |
| Xoá | X giữ 0.5 s | □ giữ 0.5 s | X giữ 0.5 s | Del · RMB giữ 0.5 s |
| Giữ (lock) | LB | L1 | L1 | G |
| Bỏ qua (+15 Vàng Mã) | B giữ 0.5 s | ○ giữ 0.5 s | B giữ 0.5 s | Backspace giữ 0.5 s |
| Xem build | View | nút giữa trái | View | Tab |
- Đồng hồ tự chọn 6.0 s (chỉ draft phòng thường); mọi input điều hướng đặt lại 6.0 s (
draft.auto_pick_reset_on_input); tạm dừng dừng đồng hồ. Tuỳ chọn kéo dài/tắt ở42§8. - Xoá Edge là nửa công thức Tiến Hoá →
UI_C_Confirm, focus mặc định Huỷ (40§5.3).
3.3 Bản đồ (Map, 16 §2.1, 40 §5.2)
| Lệnh | ABXY | Ký hiệu hình | Steam Deck | KB/M | Luật |
|---|---|---|---|---|---|
| Trỏ nút | d-pad ←/→ | d-pad ←/→ | d-pad ←/→ | A/D · ←/→ · rê chuột | giữa các nút có thể đi của hàng kế |
| Xem hàng khác | d-pad ↑/↓ · RS | như trái | như trái | W/S · con lăn | focus "xem": CONFIRM khoá + UiError (hành động không được phép: thiếu tiền, khoá, ô đầy) SFX_UI_nav_error |
| Chọn nút | A | ✕ | A | Enter · LMB | chỉ ở trạng thái MAP (phòng xong) |
| Đổi làn (UP_DOCK_2, R4, 1 lần/run) | X | □ | X | R | 16 §2 |
| Chi tiết nút / Act Mutator (MUT01–MUT12) | View | nút giữa trái | View | Tab | thưởng, loại, cảnh báo Thử Lửa |
| Đóng (khi xem) | B · d-pad ↑ | ○ · d-pad ↑ | B · d-pad ↑ | Esc · M | trả về đúng tick đã dừng |
- Mở
MAPgiữa phòng chưa sạch = dừng World + Hero nhưPAUSE(không ai trúng đòn vì đọc bản đồ); tiếp tục → đếm 0.3 s như43§10. Bản đồ là lớp UI, camera world đứng yên phía sau (§11.4).
3.4 Màn khác trong run
| Màn | Lệnh riêng (ABXY → KB/M) | Nguồn |
|---|---|---|
Reward / Rest / Secret / Shop / Dock | A chọn/mua → Enter · X hành động phụ (đổi/xoá thẻ dịch vụ) → R · B rời → Esc | 40 §5.5 |
Event | A chọn lựa → Enter; lựa có hệ quả xấu = UI_C_Confirm | 40 §5.5 |
SkillPick / LinchpinPick (Then Chốt H01_E37–E40…) | như Draft, không Đổi/Xoá/Giữ | 40 §5.4 |
Pause | cột lệnh: Tiếp tục · Build · Chỉ số · Relic · Bản đồ · Cài đặt · Thoát về tiêu đề · Bỏ run (UI_C_Hold 1.0 s, run.abandon_hold_s); B/Menu = Tiếp tục | 40 §5.6 |
DeathRecap (INV-16) | A tiếp · View mở log 5 nguồn sát thương cuối | 40 §5.7 |
RunSummary | LB/RB đổi tab · Y "Thức Lại" → R · A về hub → Enter | 40 §5.7 |
Dialogue | A hiện hết dòng / dòng kế → Space · giữ B 0.5 s bỏ qua beat → giữ Esc | 40 §6.2 |
64. Bảng nút — Hub (map Hub, HUB_BELL_TOWER, sân 960×544 px)
| Lệnh | ABXY | Ký hiệu hình | Steam Deck | KB/M | Luật |
|---|---|---|---|---|---|
| Đi | LS | LS | LS | WASD | tốc = tốc chạy gốc hero đang chọn (Bible §5) |
| Lướt | A | ✕ | A | Space | anim Lướt thường, không i-frame có nghĩa (hub 0 sát thương), không tốn lượt [ASSUMED] |
| Tương tác trạm/NPC | B hoặc X | ○ hoặc □ | B hoặc X · R5 | G hoặc LMB | nhắc khi tâm hero trong r24 của trạm (40 §6.2) |
Dịch chuyển nhanh (HubTravel) | d-pad ↑ | d-pad ↑ | d-pad ↑ | M | chỉ khi ≥ 4 trạm mở (18 §12) |
| Sổ Thù nhanh | View giữ | nút giữa trái giữ | View giữ · L5 | Tab giữ | mở tab Sổ Thù của Ledger (ST_LEDGER) |
| Tạm dừng / Cài đặt | Menu | nút giữa phải | ≡ | Esc | — |
- Xuất phát: tương tác ST_DOCK (Calla NPC_CALLA) →
DockDepart(mapUI). - ST_YARD (Sân Tập): bật
Gameplayđầy đủ (hitbox thật trên dummy) + menu nổiYard(World chạy,40§6.11) mở bằngINTERACT(B hoặc X · KB/M G hoặc LMB) khi đứng tại NPC Răm; trong menu: đổi dummy tell Y/P/N × hạng S/M/L/XL, replay 10 s, bảng frame data, mọi tuỳ chọn42xem trước sống. Trong Sân Tập, khi menuYardđang đóng, Menu/Esc vẫn là lệnh "Tạm dừng / Cài đặt" của hub (hàng Menu bảng trên) như mọi chỗ khác trong hub — Menu không mở menuYard. Khi menuYardđang mở, B/Esc đóng nó → về mapGameplay. - Mọi menu trạm mở
UIchồng lênHub; B/Esc đóng → hero đứng đúng chỗ cũ, camera giữ (§11.4).
75. Override theo hero (chỉ field 12 §1.4; không hero nào thêm nút)
W = ngưỡng giữ của ANSWER_HOLD = ceil(cửa sổ ĐÁP × 60) tick (chưa cộng Thương Xót/Edge/Relic/nền tảng). Remap của người chơi theo action_id, áp chung mọi hero.
| Hero | Giữ ATTACK (attack_hold_action · tick) | charge_marks · đi khi nạp | ĐÁP · W | Verb giữ: luật input | Ngắm / reticle / đặt vật | ||
|---|---|---|---|---|---|---|---|
| H01 Varek | AUTO_CHAIN · 12 | — | Gạt 0.16 s · 10 | Thủ: hướng chặn 180° = vectơ ngắm, xoay theo RS/chuột khi giữ (≤ 720°/s); Phản đòn = ATTACK trong 1.0 s | cận chiến, trợ ngắm §6.2 | ||
| H02 Bodan | CHARGE · 12 | 0.35 / 0.7 / 1.1 s · ×0.6 | Chặn Nắp 0.18 s · 11 | Dựng Quan: tường 64 px dựng vuông góc vectơ ngắm tại tick W | cận chiến | ||
| H03 Halka | AUTO_CHAIN · 12 | — | Gõ Chuông 0.16 s · 10 | Nhảy Sào: hướng = MOVE ( | LS | ≥ 0.20), không có → ngắm; thời gian hồi chiêu 1.2 s; giữ tiếp sau khi đáp không lặp | cận chiến (tầm giáo) |
| H04 Sậu | STANCE · 15 | — | Khép Compa 0.15 s · 9 | Kẻ Vòng: vẽ 0.5 s rồi giữ ≤ 3 s; thả = xoá vòng; đi ×0.5 | cận chiến; reticle LINE 64 px khi giữ ĐÁP (Trợ năng aim_reticle) | ||
| H05 Oska | CHANNEL · 12 | — · ×0.6 | Quay Chắn 0.16 s · 10 | Quỹ Đạo: vòng r56 bám thân, đi ×0.6, ném/giật theo vectơ ngắm | cận chiến; xoay kênh ≤ 720°/s | ||
| H06 Ruvan | CHARGE · 12 | 1 mốc 0.30 s (Tôi) | Bắt Đòn 0.15 s · 9 | Hấp Nhiệt: đứng yên (MOVE bỏ qua), xoay mặt theo ngắm; Lướt/ĐÁP huỷ tức thì (12 §3.5) | cận chiến | ||
| H07 Veyra | CHARGE · 12 | 0.35 / 0.7 / 1.0 s · ×0.5 | Bắn Ngắt 0.16 s · 10 | Lùi Lắp: lùi 40 px ngược vectơ ngắm + tự kéo 0.35 s | tầm xa; reticle LINE khi nạp; Đỉnh Hơi (Thương Xót +0.04 s) | ||
| H08 Dov | CHARGE · 12 | 0.25 / 0.50 / 0.75 s = Đinh / Muối / Ma Trơi (nhả ở mốc = chọn viên nạp) | Nổ Chặn 0.15 s · 9 | Tì Báng Nạp: miễn đẩy lùi + nạp 1 viên/0.4 s, không giảm sát thương (DEC-2026-11-07-10); đi theo hold.move_mult doc hero | tầm gần nón; reticle ARC | ||
| H09 Kessa | AUTO_CHAIN · 12 | — | Quăng Vòng Xu 0.16 s · 10 | Lưới Xu: thả tại chân hero ở tick W (1 lưới) | tầm xa; reticle LINE (dây) | ||
| H10 Ingra | AUTO_CHAIN · 12 | — | Màn Khói 0.18 s · 11 | Hoá Khói: chỉ bật khi hero trong vùng Khói; MOVE chỉ đi trong/giữa vùng | vùng; place 32 / 72 / 160 px; reticle CIRCLE tại place_point | ||
| H11 Wenna | DIG · 24 | — | Hất Đất 0.15 s · 9 | Cắm Xẻng: bất động, MOVE bỏ qua; mỗi đòn nhận đội hố nông dưới kẻ tấn công (DEC-2026-11-07-10) | cận chiến; hố đặt ở place_point (§6.3) | ||
| H12 Ambrin | AUTO_CHAIN theo phách · 12 | — | Thổi Dội 0.16 s (+0.04 đúng phách) · 10 (12 đúng phách) | Nốt Ngân: vòng r60 giữ đạn Y, phóng lại thành nốt theo vectơ ngắm ở phách kế (DEC-2026-11-07-10) | vùng/tầm xa; rhythm_clock; cửa sổ phách ±0.12 s (Thương Xót ±0.16) |
- Kỹ năng
cast_mode = HOLD(nạp/ngắm): giữ nút ô → reticle hình hitbox thật, thả = tung; Lướt/ĐÁP huỷ không mất thời gian hồi chiêu (12§1.2). Tuỳ chọninput.skill_hold_mode= Chạm-chạm (42§7.1): chạm 1 = bắt đầu ngắm, chạm 2 = tung, ngắm tối đa 3.0 s rồi tự tung. - H12: máy nhịp chỉ hiển thị (Bible §1.1);
audio.latency_ms(42§5) chỉ dời hình/âm hiển thị nhịp, không dời mốc chấm phách — dời mốc chấm = "Hiệu chỉnh trễ" của Thương Xót (11§4.1).
86. Ngắm & trợ ngắm
6.1 Chế độ ngắm (aim_mode, 12 §1.3)
aim_mode | Mặc định cho | Luật | ||||
|---|---|---|---|---|---|---|
AIM_TWIN | PAD_ABXY, PAD_SYMBOL, DECK | hướng = RS nếu | RS | ≥ 0.30; không → LS nếu | LS | ≥ 0.20; không → giữ hướng cũ |
AIM_CURSOR | KBM | hướng = điểm chuột trên sàn − tâm hero; luôn bật | ||||
AIM_MOVE | KBM_KEYS (bàn phím không chuột), preset 1 tay (42 §7.2) | chỉ theo hướng đi; RS/chuột bỏ qua | ||||
AIM_AUTO | Thương Xót "tự ngắm" | khoá mục tiêu ưu tiên 360° trong 140 px (cận) / 300 px (xa) (combat.mercy_autoaim_r); LS chỉ di chuyển |
- Vectơ ngắm 360° liên tục; sprite chọn 1/8 hướng. Cận chiến khoá hướng ở tick đầu startup; tầm xa khoá ở tick nhả, xoay ≤ 720°/s khi nạp (
10§1.6). - Con trỏ chuột trong
Gameplay: dấu ngắm 7×7 art px màu#e8e4f0viền 1 px#15131d(không vàng/tím, INV-01a), vẽ lớp screen trên HUD; cỡ 1×/2×/3× (42§2).
6.2 Trợ ngắm (10 §9 + PlatformTuning 01 §5.1)
| Khoá | Cận chiến (H01–H06, H11) | Tầm xa/vùng (H07–H10, H12) |
|---|---|---|
| Ứng viên | nón 100° · 90 px (combat.aim_assist_cone/range) | nón 20° · 260 px (combat.aim_assist_ranged) |
| Xoay tối đa | aim_assist_cone × aim_assist_strength = 100° × 0.35 = 35° (PC_PAD, DECK) · KBM 0 (tắt) | aim_assist_cone_deg = 12° (PC_PAD, DECK) · chuột 6° chỉ M/L/XL (combat.aim_assist_mouse_turn) |
| Ưu tiên | M/L/XL đang windup > dấu Phản ✦ > gần nhất > quái tầm xa; hoà → góc nhỏ hơn | M/L/XL > gần nhất trong nón |
| Bước lao | mục tiêu 24–60 px → lao tới step_max của đòn | — |
| Hệ số người chơi | thanh "Trợ ngắm" 0–100% (mặc định 100%) nhân vào xoay tối đa | như trái |
- Trợ ngắm chỉ đổi hướng (và quãng lao), không đổi hitbox/sát thương; không bao giờ kéo vị trí hero.
- Khoá boss mềm: L/XL trong vùng an toàn luôn là ứng viên nếu lệch ≤ 30° so với hướng nhập, tầm ×1.5. Khoá boss cứng (
BOSS_LOCK, tắt mặc định): khi khoá và không có input ngắm, hướng = boss; vòng khoá 1 px#e8e4f0quanh vòng chân boss. - Ví dụ (H01, tay cầm): ngắm 0°; quái M đang windup ở 30°/70 px, quái S ở 5°/40 px → cả hai trong nón ±50°/90 px; M thắng ưu tiên → hướng đòn 30° (≤ 35°). M ở 70 px > 60 → không lao thêm. Nếu M ở 45° → hướng = 35° (kẹp), cung A1 r44 vẫn chạm M nếu nằm trong cung.
- Ví dụ (H07, chuột): ngắm 0°; Tinh Anh L ở 4°/200 px → hướng 4° (≤ 6°); quái S ở 3° → không hút (chuột chỉ M/L/XL).
6.3 Đặt vật & reticle
place_point(12§1.3): tay cầmplace_dist = place_min + (place_max − place_min) × |RS|, |RS| < 0.30 →place_default; chuột = điểm chuột kẹpplace_max, ngoài vùng an toàn → mép vùng an toàn − 16 px;AIM_MOVE→place_defaulttheo hướng đi.- Reticle sàn màu slot hero α 0.40, hình = hitbox thật (
LINE/ARC/CIRCLE), chỉ khi đang nạp/ngắm hoặcaim_reticle = ALWAYS; vẽ DƯỚI lớp tell, không bao giờ đè tell (Bible INV-02,31R2). - Ví dụ H10 tay cầm: |RS| = 0.5 → 32 + (160 − 32) × 0.5 = 96 px; |RS| = 0.2 → 72 px (
place_default).
97. Buffer & ưu tiên (INV-07, 12 §1.5, §3.3)
| Luật | Giá trị |
|---|---|
| Độ dài | 9 tick (0.15 s, combat.input_buffer) cho MỌI hành động Gameplay; 1 hàng chờ/action (bấm lại cùng action = làm mới tick) |
| Cùng tick | Lướt > ĐÁP > Ult > Kỹ năng > Đánh (combat.input_priority) |
| Tiêu thụ | tick đầu trạng thái huỷ được: chạy input ưu tiên cao nhất còn hạn, xoá phần còn lại; ATTACK đang giữ → tiếp nối combo/nạp |
| ĐÁP trong buffer | chạm rồi thả trước khi chạy → vẫn ra ĐÁP, W tính từ tick chạy; còn giữ lúc chạy → ngưỡng giữ W tính từ tick chạy |
Giữ ATTACK trong buffer | tick giữ tính vào charge_marks |
DASH_ATTACK | ATTACK trong 9 tick cuối Lướt hoặc ≤ 9 tick sau Lướt → đòn sau Lướt |
COUNTER | ATTACK trong W chưa Answered → vào buffer; ĐÁP cận chiến thành công trong 9 tick đó → Phản ngay khi hết hitstop |
| Không vào buffer | kỹ năng đang hồi chiêu · Ult khi Dư Âm < 100 · INTERACT (chạy tức thì hoặc không) · lệnh UI |
| Xoá buffer | đổi map (§1.2), mở draft, chết, chuyển phòng |
Ví dụ thời gian (tick):
- H01 đang hồi sau A2, cửa huỷ cho Lướt (ma trận
12§3.2) mở ở t105. BấmDASHở t100 → Lướt chạy ở t105 (trong 9 tick). - Bấm
ATTACKt100,DASHt102; cửa huỷ t105 → chạy Lướt (ưu tiên),ATTACKbị xoá. - Bấm
DASHt90, cửa huỷ t105 → t90 + 9 = t99 < t105 → hết hạn, không Lướt (người chơi phải bấm lại). - H01 bị trúng ở t99 → 7 tick đầu Hurt khoá ĐÁP (t99–t105,
11§2.1). Chạm RB t100 (thả t103) → ĐÁP chạy t106, W = 10 tick → cửa sổ t106–t115. - Giữ RB từ t100 lúc rảnh (H02, W = 11): ĐÁP chạy t100, còn giữ ở t111 → Dựng Quan bắt đầu t111.
108. Remap, preset, Steam Input
8.1 Luật remap (Bible §1.1 "remap toàn bộ")
| Luật | Giá trị |
|---|---|
| Đơn vị | theo action_id × map (Gameplay / UI / Hub) × họ thiết bị (KBM, PAD; PAD_ABXY, PAD_SYMBOL, DECK chung 1 bộ theo vị trí vật lý) |
| Số binding | 2 ô/action/họ thiết bị (chính + phụ, 40 §6.3); PAD ô phụ trống mặc định; nút lưng Deck = bản sao qua Steam Input (§8.4), không chiếm ô |
| Trùng trong 1 map | 1 nút vật lý → tối đa 1 action; gán nút đã dùng → tự HOÁN ĐỔI 2 action + toast 2 s "Đã đổi: <A> ↔ <B>" |
| Trùng khác map | cho phép (vd X = ATTACK ở Gameplay, X giữ = Xoá ở draft) |
| Bắt buộc | mọi action Gameplay có ≥ 1 binding trên họ thiết bị đang dùng; thiếu → không lưu được: viền action #e8e4f0 nháy 2 lần + chữ "Chưa gán" (không dùng đỏ/vàng/tím) |
| Cố định | KBM: Esc luôn = PAUSE/Quay lại (thêm được phím khác, không gỡ Esc); PAD: Menu luôn = PAUSE; nút hệ thống (Home, Quick Access, ảnh chụp) không bao giờ đọc |
| Cấm | tổ hợp 2 nút đồng thời (chord); nhấn đúp (double-tap) làm binding; lăn chuột cho action có giữ (ATTACK, ANSWER_HOLD, kỹ năng HOLD, ASH_INSPECT, INTERACT) |
| Lăn chuột | được cho action chạm: 1 nấc = 1 lần chạm (SKILL_* chạm, POTION, ULT, MAP) |
| Ngữ nghĩa | chạm/giữ đi theo action, không theo nút: dời ANSWER_HOLD sang RT → chạm RT = ĐÁP, giữ RT = verb giữ; cò làm nút kích ở 0.35, nhả ở 0.25 (§2) |
| Trục | MOVE ↔ AIM đổi cần (LS ↔ RS) bằng 1 nút "Đảo cần"; đảo trục Y riêng từng cần (mặc định tắt); KBM MOVE gán lại 4 phím |
| Bàn phím | binding lưu theo mã vị trí phím (scan code), glyph hiện nhãn theo bố cục bàn phím đang dùng (vd vị trí WASD hiện ZQSD trên bố cục Pháp) |
| Màn remap | chọn action → "Nhấn nút…" 5 s; giữ Menu/Esc 1.0 s = huỷ nghe (chạm B vẫn gán được; Esc/Menu không gán cho action khác); áp dụng ngay, thử ở ST_YARD |
| Khôi phục | theo map hoặc toàn bộ, hỏi xác nhận 2 bước |
| Lưu | save/settings_shared.json (Steam Cloud, 43 §7.1), khoá bindings.<family>.<map>.<action_id>[0..1]; đổi máy giữ binding; phiên bản schema binding tăng → binding cũ chuyển đổi, action mới lấy mặc định |
- Prompt trong chuỗi loc dùng token
{btn:ACTION_ID}(vd "Nhấn {btn:INTERACT} để mở", "Giữ {btn:ANSWER_HOLD} để Thủ"); runtime thay bằng glyph binding hiện tại của thiết bị cuối. Cấm viết tên nút cứng trong chuỗi loc.
8.2 Preset (input_preset)
| Preset | Thiết bị | Nội dung |
|---|---|---|
PAD_DEFAULT | PAD/DECK | §2 cột ABXY/ký hiệu/Deck |
PAD_SOUTHPAW | PAD/DECK | đảo cần (LS ngắm, RS đi) + đảo vai: ANSWER_HOLD LB, SKILL_1 RB; còn lại giữ |
PAD_LEFT_ONLY · PAD_RIGHT_ONLY | PAD/DECK | chế độ 1 tay, bảng đủ ở 42 §7.2 |
KBM_DEFAULT | KBM | §2 cột KB/M chính |
KBM_KEYS | KBM | §2 cột KB/M phụ làm ô chính (không chuột), aim_mode = AIM_MOVE |
KB_LEFT_ONLY | KBM | 1 tay trái trên bàn phím, 42 §7.2 |
CUSTOM | mọi | tự động khi người chơi sửa bất kỳ binding nào của preset |
- Chọn preset ở màn khởi động lần đầu (
42§1.2) và Cài đặt › Điều khiển; preset 1 tay tự bậtaim_mode = AIM_MOVE(đổi lại được).
8.3 Một lớp input (01 §5.2)
- 1 asset
InputActions(mapGameplay·UI·Hub) → dựngInputFramemỗi tick; Autopilot, replay ST_YARD và test chỉ ghi/đọcInputFrame. - CI cấm đọc thiết bị trực tiếp ngoài thư mục Input (grep
Keyboard.current,Gamepad.current,Mouse.current,Touchscreen.current). InputFrame= {move vec2, aim vec2 (đã quaaim_mode), bitmask nhấn/giữ/nhả 16 action, device_class, tick}; trợ ngắm chạy SAUInputFrametrongCombat, không trong lớp input.
8.4 Steam Input (1.0)
| Khoá | Luật |
|---|---|
| Chế độ | game đọc tay cầm qua lớp input của engine; không bắt buộc Steam Input (43 Q S8); Steam Input giả lập tay cầm khi người chơi bật — remap trong game là nguồn sự thật |
| Cấu hình xuất xưởng | 1 cấu hình chính thức "Bladewake — mặc định" (mẫu Gamepad, 43 §8.1): nút giữ đúng vị trí §2; Deck thêm nút lưng = bản sao: L4 → d-pad ↓ (POTION), R4 → Y (ULT), L5 → View (ASH_INSPECT), R5 → B (INTERACT) [ASSUMED] (43 §8.1); trackpad phải = chuột chỉ trong menu; gyro: tắt |
| Mẫu gợi ý thêm | "Gyro ngắm": gyro → RS khi chạm cần phải (bật/tắt bằng chạm), độ nhạy 1.0; "Trackpad ngắm": trackpad phải → RS vị trí tuyệt đối (tâm = hero) |
| Nhận loại tay cầm | ưu tiên API Steam Input (loại tay cầm thật kể cả khi giả lập) → chọn glyph ABXY/SYMBOL/DECK; không có Steam → layout thiết bị của Unity; không xác định → ABXY |
| Cấu hình người chơi tự sửa | game không đọc được ánh xạ vật lý → glyph theo nút ảo; Cài đặt › Điều khiển hiện dòng "Glyph theo nút ảo khi dùng cấu hình Steam Input tuỳ chỉnh" |
| Deck | không launcher, chữ đọc được ở 1280×800 (42 §6), tạm dừng khi suspend/resume, bàn phím ảo chỉ ở ô nhập seed CUSTOM (gọi bàn phím hệ thống) |
119. Glyph
| Khoá | Luật |
|---|---|
| Bộ | KBM · ABXY · SYMBOL · DECK · TOUCH (5, 01 §5.2, TOUCH chỉ bản mobile) |
| Đổi bộ | đổi ở frame kế input "thật" đầu tiên của thiết bị mới (43 §8.1: ≤ 1 frame): phím/nút bấm, cần lệch ≥ 0.50, cò ≥ 0.35, chuột dời > 8 px màn hoặc bấm; đổi ngược lại sớm nhất sau 0.5 s (12 §1.1, chống nhấp nháy khi cầm cả hai) |
| Cỡ | ô 11×11 UI px cùng dòng FNT_BW_M (40 §1.5); cỡ chữ 150% (vai button dùng FNT_BW_L) → bộ glyph 15×15 vẽ riêng [ASSUMED]; phím chữ rộng (Space, Shift, Esc, Tab, Backspace) rộng theo nhãn + đệm 2 px |
| Màu | đơn sắc #e8e4f0 trên nền #15131d, viền 1 px; KHÔNG tô màu nút mặt (✕ ○ □ △ chỉ khác hình), KHÔNG vàng/tím (INV-01a) |
| Giữ | glyph + vòng 1 px quanh glyph (hiện tiến trình khi đang giữ) + chữ "giữ" |
| Cần / trục | LS/RS vẽ vòng tròn có chữ L/R; d-pad vẽ chữ thập, tô hướng dùng |
| Chuột | LMB/RMB/giữa/lăn vẽ hình chuột tô nút |
| Thiếu glyph | hộp chữ với tên phím theo bố cục đang dùng; log cảnh báo 1 lần/phiên |
| Prompt trong world | chỉ INTERACT (trên vật ready, cách đỉnh vật 6 art px); mọi prompt khác ở HUD |
1210. Rung tay cầm (haptics)
| Sự kiện | Mô tơ trầm · cao | Thời lượng | Đồng hồ | Ghi chú |
|---|---|---|---|---|
| Tell Y (glint 2) | 0 · 0.6 | 40 ms | World (đúng 0.12 s trước va chạm) | 11 §4.2; tắt riêng bằng input.haptic_tells |
| Tell P (đầu windup) | 0→0.7 tăng dần · 0 | 300 ms | World | 11 §4.2 |
| Vỡ Thế (Elite/Boss) | 0.8 · 0.8 | 2 × 80 ms, cách 60 ms | thật | 11 §4.2 |
| ĐÁP thành công | 0.4 · 0.8 | 60 ms | thật | |
| Né Hoàn Hảo | 0 · 0.5 | 50 ms | thật | |
| Hero trúng đòn | 0.6 · 0.2 | 120 ms | thật | |
| Ult kích hoạt | 0.9 → 0 · 0.3 | 400 ms | thật | |
| Hạ boss | 1.0 → 0 · 0.5 | 600 ms | thật | đồng thời run.boss_kill_hitstop 0.4 s |
| Uống bình | 0.3 · 0 | 40 ms | thật | |
| Chọn thẻ draft | 0 · 0.2 | 20 ms | thật |
- Trần: mỗi mô tơ = min(1.0, Σ mẫu đang chạy); ≤ 3 mẫu cùng lúc; vượt → bỏ mẫu ưu tiên thấp nhất. Ưu tiên: tell > ĐÁP/Né > Vỡ Thế > trúng đòn > còn lại. Quái chết/trúng đòn của hero: không rung (bầy 250 quái = rung liên tục vô nghĩa).
input.haptic_strength0–100% nhân mọi mẫu (42§7.1);PC_KBM= 0 (platform.haptics). Tạm dừng/mất focus → dừng mọi rung trong 1 frame.
1311. Camera
11.1 Độ phân giải, zoom, vùng an toàn (khoá: Bible §10.4, 30 §2.2)
zoom = số nguyên lớn nhất z thoả H/z ≥ 266 và W/z ≥ 426 · view = (min(640, ceil(W/z)), min(360, ceil(H/z))) art px · phần thừa = viền void #15131d. Không bao giờ zoom lẻ.
| Màn | zoom | View (art px) | Ghi chú |
|---|---|---|---|
| 1920×1080 | 4 | 480×270 | chuẩn thiết kế, mọi mockup |
| 1280×800 (Deck) | 3 | 427×267 | 1281×801, cắt 1 px |
| 1280×720 | 2 | 640×360 | thấy rộng hơn; luật công bằng vẫn theo 427×267 |
| 1920×1200 | 4 | 480×300 | |
| 2560×1440 | 5 | 512×288 | |
| 3440×1440 | 5 | 640×288 | trần ngang 640, viền 2 × 80 px màn |
| 3840×2160 | 8 | 480×270 |
- Vùng an toàn gameplay = 427×267 art px giữa view: spawn công bằng (INV-14), quái chỉ windup Y/P nhắm hero khi trong vùng này + 16 px (
11§5.3), HUD neo theo vùng này, bất kể view thật rộng hơn. - Camera chiến đấu: không zoom, không xoay (
30§2.2). Zoom chỉ đổi khi đổi độ phân giải/cửa sổ (tính lại ngay, không chuyển mượt).
11.2 Bám theo (PixelCamera + CameraDirector, 50 §2; mọi ngữ cảnh có world)
| Khoá | Giá trị (480×270 → art px) | Công thức |
|---|---|---|
| Vùng chết | 6% × 8% nửa view = 14.4 × 10.8 | hero lệch tâm trong vùng → camera đứng |
| Giảm chấn | đóng 99% khoảng cách sau 0.55 s (ngang) / 0.60 s (dọc) | cam += (target − cam) × (1 − e^(−k·dt)), k = ln(100)/T = 8.37 / 7.68 s⁻¹ |
| Giới hạn cứng | hero cách tâm ≤ 55% nửa view = 132 × 74 | vượt → camera dịch tức thì đủ để giữ hero trong khung (Lướt 96 px không bao giờ đưa hero ra mép) |
| Lệch dọc | hero ở 52% chiều cao view từ trên (tâm camera cao hơn hero 0.02 × Vh = 5 art px) | quái từ phía trên (đi quãng sàn dài gấp đôi) thấy sớm hơn |
| Nhìn trước | la = v_intent × 0.22 s, kẹp ngang 36, dọc ×0.6 (kẹp 21.6) | v_intent = MOVE × tốc chạy (px màn/s), làm mượt: tăng đạt 99% sau 1.2 s, giảm sau 0.4 s |
| Không tính vào nhìn trước | Lướt, đẩy lùi, kéo, lao đòn, dịch chuyển | chỉ ý định đi (MOVE), nên Lướt không kéo camera |
- Ví dụ: H01 chạy phải đều 135 px/s →
la= 135 × 0.22 = 29.7 → 30 art px. Chạy lên Bắc 135 px sàn/s = 67.5 px màn/s → 67.5 × 0.22 × 0.6 = 8.9 → 9 art px. a11y.reduce_motion(42§2): nhìn trước = 0, giảm chấn T = 0.80 / 0.85 s, vùng chết 10% × 12%.
11.3 Giới hạn sân
- View không vượt viền phòng + 40 art px lề (ngoài viền = void/tile rìa). Phòng có cạnh ≤ view + 80 art px theo 1 trục → khoá trục đó ở tâm phòng (sân boss nhỏ đứng yên, không trượt lắc).
- Vùng P/tell cắt mép view: phần trong vùng an toàn phải chứa mọi điểm hero có thể đứng trong 0.45 s tới (
11§5.3) — camera không được tự kéo để "cứu" tell; luật là của bộ đạo diễn/quái.
11.4 Khung theo trận / boss (zoom = §11.1 ở MỌI ngữ cảnh; chỉ khác đích & lệch)
| Ngữ cảnh | Đích | Lệch khung (bias) | Nhìn trước | Trần trauma | Ghi chú |
|---|---|---|---|---|---|
Phòng CMB / CHL / RSC | hero | 0 | có | 1.0 | 150–250 quái; mũi tên ngoài màn F9 (15 §4) |
Cổng ELT | hero | 0.15 × (Tinh Anh − hero), kẹp ±40 ngang / ±20 dọc | có | 1.0 | Tinh Anh mục tiêu = đang windup > gần nhất |
Cổng MBS | hero | 0.20 × (mini − hero), kẹp ±48 / ±24 | có | 1.0 | |
Boss BOS (BS_B1–BS_B4, BS_FINAL, BS_TRUE) | hero | 0.25 × (boss − hero), kẹp ±64 / ±32 | có | 1.0 | boss cách > 400 px sàn hoặc ngoài view → bias 0 + mũi tên mép ≥ 0.45 s trước đòn |
| Intro boss (nếu doc boss có) | boss → hero | — | không | 0.3 | World ×0, hero bất tử: lia tới boss 0.6 s (ease in-out bậc 3), giữ 1.2 s (thẻ tên), về 0.4 s; bỏ qua (A/Space) từ lần thứ 2 |
| Đổi pha boss | hero | như BOS | có | 1.0 | pha chuyển = boss bất tử; không lia camera |
| Draft trong phòng | đứng yên | — | không | 0 | World ×0.15, hero bất tử; trauma đặt về 0 |
| Chuyển phòng | hero (cắt) | — | — | 0 | mờ sang #15131d 0.20 s → cắt → hiện 0.20 s; camera đặt thẳng vào vị trí hero |
| DOCK | tâm đò | — | không | 0.2 | camera đi cùng đò, hero đi tự do trên đò |
| Hub | hero | gần trạm (r48 quanh NPC): 0.30 × (NPC − hero), kẹp ±32 / ±16 | 0.15 s, kẹp 24 | 0.3 | vùng chết 10% × 12%, giảm chấn 0.80 s; dịch chuyển nhanh = mờ 0.25 s |
| ST_YARD | hero | 0 | có | 1.0 | như phòng chiến |
| Chết (hết Lửa Gửi) | hero → giữa hero & nguồn kết liễu (kẹp 48 art px từ hero) | — | không | 0 sau tick chết | run.death_cam_s 1.5 s: 0.5 s đầu World ×0.3 (combat.death_slowmo), 1.0 s giữ; rồi recap INV-16 |
- Hero luôn thắng bias: nếu
target + biasđẩy hero ra ngoài giới hạn cứng §11.2 → bias rút ngắn tới khi hero vào lại. - Ví dụ boss: hero (0, 0), BS_B1 ở (+200, −80) art px màn → 0.25 × (200, −80) = (50, −20) → trong kẹp ±64 / ±32 → tâm camera lệch (50, −20 + 5) về phía boss.
- Bản đồ (
MAP), tổng kết, Sổ Tang, menu: lớp UI riêng, camera world đứng yên phía sau (mờ 50% + tối 40%).
11.5 Rung màn (trauma; số canon 10 §6.2, tuning.combat.shake_*)
| Khoá | Giá trị |
|---|---|
| Nhiễu | offset = 7 px × trauma^1.5 × shake_opt, nhiễu 22 Hz, trauma giảm 2.2/s, cộng dồn, trần 1.0 |
| Cú đẩy lò xo | 5 px × trauma theo hướng đòn, trần 4 px, hồi 7 Hz; không xoay, không zoom |
| Trần offset tổng | ≤ 7 + 4 = 11 art px (1080p = 44 px màn); reduce_motion: nhiễu ≤ 2 px, cú đẩy 0 |
| Bậc theo nguồn | T0 0 (LIGHT, quái S chết, DoT) · T1 0.18–0.22 · T2 0.25–0.30 (HEAVY, ĐÁP, trúng đòn) · T3 0.45–0.55 (Phản, Vỡ Thế) · T4 0.80 (cú nổ cuối Ult, hạ boss) |
| Trần theo khung giờ | trauma nạp thêm ≤ 1.2 mỗi cửa sổ 1.0 s; vượt → bỏ nguồn T1/T2, giữ T3/T4 (bầy 250 quái không làm màn rung liên tục) [ASSUMED] |
| Thanh người chơi | "Rung màn" 0–100% (bước 10, mặc định 100; 42 §2) nhân shake_opt; 0% = tắt cả cú đẩy |
| Làm tròn | offset cộng vào vị trí camera TRƯỚC khi snap 1 art px (§11.6) |
| Đồng hồ | Real (rung vẫn chạy khi World chậm; hitstop không dừng rung) |
- Ví dụ: Phản (0.45) + Vỡ Thế cùng tick (0.50) → trauma 0.95 → nhiễu 7 × 0.95^1.5 = 6.48 → 6 art px; sau 0.2 s còn 0.95 − 0.44 = 0.51 → 2.6 → 3 px.
- Ult: chỉ "đá" camera (cú đẩy ≤ 4 px), không zoom/đẩy khung (
30§2.2 thắng demo "punch 1 px/khung").
11.6 Pixel-perfect (khoá 30 §2.1–§2.2, 50 §4.3)
- Render world vào RT
view(§11.1), filter Point, phóng nguyên ×zoom;PixelPerfectCameraassetsPPU 16,orthographicSize = viewH / 32, upscaleRT bật. - Vị trí camera làm tròn tới 1 art px (1/16 unit) mỗi frame sau mọi cộng dồn (bám + nhìn trước + bias + rung). Sprite/FX snap 1 art px trong shader; hero vẽ tại vị trí sim làm tròn cùng quy tắc → hero không rung lệch 1 px so với camera khi camera đuổi (chênh lệch hero–camera tính trên số nguyên).
- Toạ độ sàn → màn:
screenX = x − camX·screenY = (z − camZ) × 0.5 + y(50§4.3, tilt 0.5). Chuột → sàn (h = 0):x = mouseArtX + camX,z = (mouseArtY − camSY) × 2 + camZvớimouseArt = mousePx / zoom − viền. - Cấm: zoom lẻ, xoay camera, sub-pixel camera, blur/bloom toàn màn làm mềm pixel, chuyển mượt zoom khi đổi độ phân giải.
- UI (HUD/Screens) canvas riêng (
40§0.2), không chịu rung màn.
11.7 Đồng hồ & thứ tự cập nhật (10 §1.1, 50 §2.3)
| Thành phần | Đồng hồ | Ghi chú |
|---|---|---|
Đọc input → InputFrame | Real, mẫu theo tick sim | input đến giữa 2 tick gán vào tick kế; trễ đích: input → khung đầu phản hồi ≤ 3 khung 60 fps (50 ms) không tính màn hình |
| Hero/World sim | Hero / World | slow-mo, hitstop cục bộ (10 §6.1, §6.3) |
| Camera bám, nhìn trước, bias, rung | Real | camera không chậm theo World ×0.15–×0.3 → không gây chóng mặt khi Né Hoàn Hảo; tạm dừng = camera đứng |
| Rung tay cầm | §10 cột "Đồng hồ" | tell rung theo World để khớp glint |
- Thứ tự mỗi frame:
InputFrame→ Sim (tick) →CameraDirector.Update(Real dt)→ snap →Presentation.Sync()(50§2.3).
11.8 Mũi tên & khung ngoài màn
- Camera không bao giờ tự lia để "cứu" tell. Thông tin ngoài view do UI vẽ: mũi tên báo beat ngoài khung ngà 0.8 s trước khi quái vào khung (
15§4 F9, luôn bật) · mũi tên đòn boss khởi phát ngoài màn ≥ 0.45 s (11§5.3, luôn bật) · mũi tên mọi tell Y/P ngoài màn (Trợ năng "Mũi tên ngoài màn",42§2). - 21:9 / 1280×720: view rộng hơn 427×267 → thấy thêm, nhưng spawn/tell/token luôn tính theo vùng an toàn 427×267 (không lợi thế cạnh tranh trên bảng DAILY).
1412. Chạm (ghi chú cho bản mobile sau, 01 §3.12 — KHÔNG làm ở 1.0)
| Khoá | Luật |
|---|---|
| Hướng màn | NGANG; canvas như PC 16:9 (view theo §11.1 công thức zoom; điện thoại 2400×1080 → zoom 4, view 600×270) |
| Thiết bị | MOBILE_TOUCH (PlatformTuning): cửa sổ ĐÁP +0.03 s, aim_assist_cone_deg 20°, aim_assist_strength 0.50, trần quái 150, FX 900 hạt (01 §5.1) |
| Di chuyển | cần ảo nổi nửa trái: chạm đâu tâm ở đó, bán kính 72 UI px, vùng chết 8% |
| Ngắm | AIM_TWIN biến thể: kéo nút ĐÁNH/kỹ năng HOLD = ngắm hướng kéo; không kéo → hướng đi + trợ ngắm |
| Nút phải | ĐÁNH 88 px màn @1080p lớn nhất dưới ngón cái; Lướt dưới-trái ĐÁNH (vuốt trên Lướt = Lướt theo hướng vuốt); ĐÁP/giữ bên trái ĐÁNH (chạm = ĐÁP, giữ = verb giữ — ngữ pháp Bible §1.1 giữ nguyên); 3 kỹ năng vòng cung trên ĐÁNH; Ult trên cùng; bình máu + tương tác cạnh trái nút Ult; tạm dừng góc trên-phải |
| Kích thước | mọi nút ≥ 9 mm vật lý, cách nhau ≥ 2 mm; vị trí/kích thước/độ mờ nút chỉnh được (trình sửa layout) |
| Cấm | tự đánh (Roadmap §3.12 "Không làm"), màn dọc, cử chỉ nhiều ngón cho hành động combat |
| Cổng | prototype chạm: tỉ lệ ĐÁP thành công ≥ 70% so với tay cầm cùng người, test 5 s đúng (01 §3.12); trượt → huỷ mobile |
| Glyph | bộ TOUCH (§9): icon nút ảo, không chữ phím |
- Lệch demo: GDD demo
01§3.3 cho "Tự đánh" mặc định bật trên mobile → bỏ theo Roadmap §3.12 (canon cao hơn GDD demo). - Tay cầm Bluetooth trên mobile: dùng nguyên bảng §2 (
01§3.12 "tay cầm không dây hỗ trợ đầy đủ").
1513. Khoá tuning (số trong doc → tuning.json; khoá có sẵn trích nguyên, khoá mới agent tuning thêm theo 51 §4)
| Khoá | Giá trị | Có sẵn? | Nguồn |
|---|---|---|---|
combat.input_buffer · combat.input_priority | 0.15 s · DASH > ANSWER > ULT > SKILL > ATTACK | có | INV-07 |
combat.aim_rs_deadzone · combat.aim_ls_deadzone | 0.30 · 0.20 | có | 10 §1.6 |
combat.aim_assist_cone/range/max_turn · aim_assist_ranged · aim_assist_mouse_turn | 100° / 90 px / 35° · [20°, 260 px, 12°] · 6° | có | 10 §9 |
combat.soft_boss_lock_deg · soft_boss_lock_range_mult · mercy_autoaim_r | 30° · ×1.5 · [140, 300] px | có | 10 §9 |
combat.shake_* · trauma_cap | 7 px, ^1.5, 22 Hz, 2.2/s, kick 5/4 px 7 Hz · 1.0 | có | 10 §6.2 |
platform.aim_assist_cone_deg · aim_assist_strength · haptics · answer_window_bonus_s | theo cột nền tảng | có | 01 §5.1 |
run.death_cam_s · combat.death_slowmo · run.boss_kill_hitstop | 1.5 s · ×0.3 / 0.5 s · 0.4 s | có | 16 §7–§8 |
platform.cam_deadzone_px | [14, 11] art px | mới | §11.2 (demo 6% × 8% nửa view) |
platform.cam_damping_s | [0.55, 0.60] | mới | §11.2 |
platform.cam_softzone_px | [132, 74] | mới | §11.2 |
platform.cam_hero_bias_y_px | 5 | mới | §11.2 |
platform.cam_lookahead | {t 0.22 s, max_x 36, mult_y 0.6, rise_s 1.2, fall_s 0.4} | mới | §11.2 |
platform.cam_bounds_margin_px | 40 | mới | §11.3 |
platform.cam_bias | {ELT [0.15, 40, 20], MBS [0.20, 48, 24], BOS [0.25, 64, 32], HUB [0.30, 32, 16]} (hệ số, kẹp x, kẹp y) | mới | §11.4 |
platform.shake_window_cap | 1.2 trauma/1.0 s [ASSUMED] | mới | §11.5 |
platform.trigger_threshold | [0.35, 0.25] (nhấn, nhả) [ASSUMED] | mới | §2 |
platform.ui_nav_repeat | [0.35 s, 12 bước/s] | mới | 40 §3.1 |
- Khoá mới thuộc section
platform(đọc theo cột nền tảng,01§5.1); cột ngoài DEFAULT/PC/DECK =[ASSUMED]tới cổng port.
1614. Kiểm thử (QA + CI)
| # | Ca | Đạt khi |
|---|---|---|
| CT-01 | Buffer 9 tick | bot InputFrame: bấm DASH ở 9 tick trước cửa huỷ → Lướt chạy đúng tick; 10 tick → không chạy (5/5 ví dụ §7) |
| CT-02 | Cùng tick | 5 action cùng tick → chỉ Lướt chạy |
| CT-03 | Chạm/giữ ĐÁP | 12 hero: thả trước W → ĐÁP; giữ tới W → verb giữ đúng tick W (bảng §5); Thương Xót "Verb giữ: bật" → chạm 1 vào, chạm 2 ra |
| CT-04 | Đổi map xả nút | giữ X qua lúc mở/đóng Draft → 0 đòn nạp, 0 Lướt sau khi đóng |
| CT-05 | Remap | dời ANSWER_HOLD sang RT → chạm/giữ đúng; gán trùng → hoán đổi + toast; thiếu binding → chặn lưu |
| CT-06 | Glyph | đổi tay cầm ↔ chuột: glyph đổi ở frame kế input thật; chuột rung 3 px không đổi; Deck: 0 glyph bàn phím/ABXY trên mọi màn (43 §8.2) |
| CT-07 | Trợ ngắm | 2 ví dụ §6.2 ra đúng góc ±0.5°; KBM cận chiến = 0° xoay |
| CT-08 | Camera giới hạn | Lướt liên tục 2 lượt mọi hướng: hero luôn trong soft zone 132 × 74; 0 frame hero ra ngoài vùng an toàn |
| CT-09 | Pixel snap | quay 10 s camera đuổi: hero lệch vị trí màn so với tâm ≤ 0 px dao động thừa (không rung 1 px) ở zoom 2/3/4/5 |
| CT-10 | Rung | 250 quái + Ult: offset camera ≤ 11 art px mọi frame; "Rung màn 0%" → offset 0 |
| CT-11 | Trễ input | đo bằng quay 240 fps: input → khung phản hồi ≤ 50 ms (P95) trên Deck và PC |
| CT-12 | Tạm dừng | mất focus / Deck suspend / overlay / rút tay cầm → Pause trong cùng frame (43 §8.3) |
| CT-13 | Hub | mở/đóng mọi trạm: hero đúng vị trí, camera không giật |
| CT-14 | Preset 1 tay | đi hết 1 run Hồi I bằng mỗi preset 1 tay (§8.2), 0 hành động cần 2 nút cùng lúc |
| CT-15 | Steam Input bật/tắt | 4 loại tay cầm × Steam Input bật/tắt: bảng §2 đúng, glyph đúng loại |
17Quy tắc cho dev/AI
- Gameplay chỉ đọc
InputFrame; không đọc thiết bị ngoài thư mụcInput/(CI grep). Hero không thêm nút, không đổi ngữ nghĩa chạm/giữANSWER_HOLD, không đổi hướng Lướt, không đổi thứ tự INV-07 (12§1.1). - Override hero chỉ qua field
input_override12§1.4; remap người chơi theoaction_id, chung mọi hero. - Mọi chuỗi có nút dùng token
{btn:ACTION_ID}; cấm tên nút cứng trong loc; cấm tên hãng tay cầm trong chuỗi và glyph. - Camera: zoom nguyên theo độ phân giải, không zoom/xoay trong combat, snap 1 art px sau mọi cộng dồn, đồng hồ Real; không lia camera để cứu tell; mọi số camera mới vào
tuning.jsonsectionplatform(§13), không hard-code. - Luật công bằng (spawn, windup, token, mũi tên) luôn tính theo vùng an toàn 427×267, không theo view thật.
- Glyph, reticle, con trỏ, vòng khoá boss: không dùng
#ffd84a/#b14cffhay dải hue tell (INV-01a); vẽ dưới lớp tell. - Thêm action mới = sửa Bible §1.1 (DEC) +
12§1.1 + bảng §2–§4 doc này + màn remap40§6.3 cùng lượt. - Bản mobile chỉ khác qua
PlatformTuning+ layout §12; không tự đánh, không đổi ngữ pháp nút.
18Quyết định đã chốt
| # | Câu hỏi | Quyết định | Lý do |
|---|---|---|---|
| C1 | Khoá platform.aim_assist_cone_deg/strength (Roadmap §5.1) khớp 10 §9 thế nào? | 2026-11-07 — đọc lại: xoay tối đa cận chiến = 100° × aim_assist_strength (PC_PAD/DECK 0.35 → 35°, KBM 0); xoay tối đa tầm xa = aim_assist_cone_deg (12°); nón ứng viên giữ 10 §9 (100°/90 px · 20°/260 px). Ghi chú lệch tên khoá, số khớp 100% doc 10 | doc 10 (nền) > Roadmap; giữ cả hai file số không đổi |
| C2 | Nút lưng Deck? | bản sao theo 43 §8.1: L4 POTION · R4 ULT · L5 ASH_INSPECT · R5 INTERACT [ASSUMED]; không chiếm ô remap | doc 43 đã chốt; giữ nút chính |
| C3 | Đổi glyph khi nào? | frame kế input thật đầu tiên; đổi ngược sớm nhất sau 0.5 s | hợp 43 §8.1 (≤ 1 frame) + 12/40 (0.5 s) |
| C4 | Camera view? | 480×270 ×4 (Bible §10.4); vùng chết/soft zone demo đổi % → px cố định 14 × 11 / 132 × 74 | demo 640×360 lỗi thời |
| C5 | Zoom theo trận/boss? | không; khác biệt chỉ bằng bias khung + giới hạn sân (§11.4) | 30 §2.2 khoá pixel nguyên |
| C6 | Mở bản đồ giữa giao tranh? | dừng World + Hero như PAUSE, tiếp tục đếm 0.3 s | không ai trúng đòn vì đọc bản đồ; 40 §5.2 chỉ nói "xem" |
| C7 | Trần rung khi 250 quái? | thêm ≤ 1.2 trauma/1.0 s [ASSUMED], ưu tiên giữ T3/T4 | chống rung liên tục, giữ cú lớn |
| C8 | Cò analog? | nút số, 0.35/0.25 [ASSUMED]; không dùng độ sâu | 1 ngữ pháp mọi tay cầm, Deck/chạm port |
| C9 | Tự đánh trên mobile (demo bật)? | bỏ | Roadmap §3.12 "Không làm" > GDD demo |
| C10 | Steam Input bắt buộc? | không; cấu hình chính thức mẫu Gamepad + nút lưng bản sao | 43 S8 |
| C11 | Preset 1 tay? | 3 preset: tay cầm trái · tay cầm phải · bàn phím trái (bảng 42 §7.2), tự bật AIM_MOVE | Bible §4.3 "chế độ 1 tay"; không chord |