VFX không được nói dối luật
Preview dùng nét trong/mờ để phân biệt hướng đang chọn; vùng capture chỉ sáng khi move hợp lệ; reward chỉ bay vào ví sau khi server/local state đã xác nhận. Không dùng màu thắng cho trạng thái chỉ “có khả năng”.
VNG Prompt To Play 2026 · Summer Puzzle Jam
VFX là ngôn ngữ phản hồi của gameplay: giúp người chơi đọc được nước đi, cảm nhận nhịp rải, nhận ra khoảnh khắc “aha”, tận hưởng capture chain và muốn thử thêm một lần mà không che board hoặc làm sai lệch luật.
VFX promise: route preview tạo anticipation; từng quân chạm ô tạo nhịp; STOP và critical-empty tạo căng thẳng; capture nén rồi bung; rescue/combo giải phóng cảm xúc; reward bay về đúng đích UI để người chơi hiểu mình vừa đạt gì.
Mỗi hiệu ứng phải làm ít nhất một việc: giải thích state, tăng anticipation, xác nhận impact hoặc trả reward. Hiệu ứng chỉ để “trang trí cho đẹp” bị cắt trước khi làm giảm khả năng đọc board.
Glow có kiểm soát, route line và STOP marker làm lựa chọn nhìn thấy được trước khi commit.
Pulse chậm, item lift và đường sóng tích năng lượng tạo cảm giác “nước này có thể hay”.
Hit ring, splash, micro-shake và hit-stop cực ngắn làm từng lần rải/capture có trọng lượng.
Rescue burst, combo title và reward travel giải phóng cảm xúc rồi trả focus về board/CTA kế tiếp.
Preview dùng nét trong/mờ để phân biệt hướng đang chọn; vùng capture chỉ sáng khi move hợp lệ; reward chỉ bay vào ví sau khi server/local state đã xác nhận. Không dùng màu thắng cho trạng thái chỉ “có khả năng”.
Sau fail, replay 2–3 giây giữ lại critical-empty, route sai và objective còn thiếu; dùng ghost trail ngắn để gợi vùng cần quan sát, không vẽ đáp án hoàn chỉnh.
Danh mục theo đúng trình tự một lượt chơi. Timing là ngân sách mục tiêu để animation có lực nhưng không làm puzzle chậm.
| ID · Hiệu ứng | Trigger & hình ảnh | Mục tiêu hấp dẫn | Timing / quy tắc | Ưu tiên |
|---|---|---|---|---|
| GP-01 · Cup Select | Viền Sea Glass nổi lên, item lift 4–6 px, vòng cát co nhẹ. | Xác nhận input tức thì; tạo cảm giác chạm được. | 80–120 ms; hủy ngay khi bỏ chọn. | Must |
| GP-02 · Dual Route Preview | Hai đường sóng chạy từ cup; hướng active sáng và dày, hướng phụ mờ; hạt nước tiến dần theo thứ tự rải. | Biến suy luận thành hình ảnh và tạo anticipation trước commit. | 150–250 ms xuất hiện; loop ≤1,2 s; không che số quân. | Must |
| GP-03 · STOP Marker | Marker san hô/cờ bọt tại ô dừng, nảy một lần; đổi vị trí mượt khi đổi hướng. | Làm kết quả nước đi dễ hiểu trong 3 giây. | 120–180 ms; chỉ một marker active. | Must |
| GP-04 · Critical Empty | Ô trống then chốt thở sáng theo nhịp thấp; vòng capture tiềm năng rung nhẹ phía sau. | Tạo khoảnh khắc “aha” mà không giải hộ. | Pulse 700–900 ms; tắt khi commit/cancel. | Must |
| GP-05 · Commit Wave | Sóng ngắn quét từ cup theo hướng chọn, khóa màu route thành màu hành động. | Đánh dấu ranh giới giữa dự đoán và kết quả thật. | 100–160 ms; sau đó route preview tan nhanh. | Must |
| GP-06 · Sow Tick | Mỗi item đi theo arc thấp, chạm ô tạo ring cát/nước và squash nhẹ. | Tạo nhịp đếm thỏa mãn, giúp theo dõi luật rải. | 70–100 ms/item; tăng tốc nhưng không teleport; âm/VFX đồng bộ. | Must |
| GP-07 · Last Seed Accent | Item cuối sáng hơn một bậc, arc cao hơn nhẹ, landing ring rõ hơn. | Dồn chú ý vào nơi luật capture được kiểm tra. | Thêm tối đa 80 ms; không dùng screen flash. | Should |
| GP-08 · Capture Anticipation | Ô trống hút sáng vào tâm 60–90 ms, cụm sau ô trống co 3% trước khi bung. | Tạo nén trước payoff; người chơi hiểu vì sao capture xảy ra. | Tổng ≤120 ms; vẫn khóa input theo state logic. | Must |
| GP-09 · Capture Splash | Vòng nước lan, vệt bọt kéo item về vùng thu, số lượng bật lên tại nguồn. | Làm capture có lực và có giá trị. | 220–320 ms; particle tránh tâm số quân. | Must |
| GP-10 · Chain Link | Một dải sóng nối capture hiện tại sang capture kế; màu tăng dần theo chain. | Giữ căng thẳng giữa các nhịp combo thay vì payoff rời rạc. | 120–180 ms/link; không reset camera. | Should |
| GP-11 · Combo Tier | Splash / Wave Combo / Tidal Rush / Great Rescue hiện tên, crest và ring tăng cấp. | Đặt tên cho thành tích để người chơi muốn tái tạo và khoe. | 450–700 ms; không modal; tier cao mới dùng micro-shake. | Must |
| GP-12 · Creature Rescue | Bubble shell nứt, sinh vật bật khỏi cát, trail nước bay về objective HUD; board nở màu trong khoảnh khắc. | Payoff cảm xúc cốt lõi: “mình vừa cứu được một sinh vật”. | 600–900 ms nhưng board nhận input lại ≤450 ms; phần trail có thể chạy tiếp. | Must |
| GP-13 · Objective Complete | Icon objective phát sáng, check bằng vệt nước, HUD chuyển từ đếm sang hoàn tất. | Xác nhận mục tiêu rõ trước win transition. | 250–400 ms; live region đọc một lần. | Must |
| GP-14 · Near-miss Echo | Desaturate board nhẹ, giữ màu ở objective thiếu và critical area; ghost trail phát lại đoạn quyết định. | Chuyển thất bại thành hiểu biết và động lực retry. | Replay 2–3 s; skip được; tuyệt đối không full-solution. | Must |
| GP-15 · Coach Arrival | Bubble portal nhỏ ngoài vùng board, portrait Tide Coach slide/fade, attention ray trỏ vùng liên quan. | Tạo cảm giác đồng hành, giảm frustrate sau fail lặp lại. | 250–350 ms; không che cup; không xuất hiện giữa sow/capture. | Should |
| GP-16 · Coach Skill | Ripple Preview dùng sóng kính trong; Shell Swap dùng hai arc giao nhau; Rescue Wave dùng crest ôm mục tiêu. | Phân biệt trợ giúp có chủ ý với kết quả của kỹ năng người chơi. | Màu Coach riêng; luôn có trạng thái trước/sau; không giả combo mastery. | Should |
| GP-17 · Perfect Tide | Mặt board yên 120 ms rồi phản chiếu ánh trời, crest hoàn hảo mở quanh objective. | Tưởng thưởng mastery bằng nhịp tương phản, không chỉ nhiều particle. | 700–1.000 ms; chỉ first clear/perfect thật. | Could |
| GP-18 · Win Tide | Sóng phục hồi quét qua board, cát sạch dần, sinh vật/prop trở lại rồi chuyển kết quả. | Kết nối thắng puzzle với fantasy phục hồi bãi biển. | 800–1.200 ms; cho phép skip sau 400 ms. | Must |
UI motion phải chỉ rõ dữ liệu nào vừa đổi, vì sao đổi và hành động tiếp theo ở đâu; không pulse mọi thứ cùng lúc.
| ID · Hiệu ứng | Trigger & hình ảnh | Mục tiêu | Timing / quy tắc | Ưu tiên |
|---|---|---|---|---|
| UI-01 · Button Press | Scale 0,97 + highlight chạy ngắn theo viền kính. | Input chắc tay trên chuột và touch. | 70–100 ms; disabled không glow. | Must |
| UI-02 · Panel / Modal | Backdrop fade, panel trượt 12–20 px và settle một lần. | Giữ hierarchy, không làm người chơi mất phương hướng. | 180–260 ms; focus chuyển sau khi panel ổn định. | Must |
| UI-03 · Turn Counter | Số cross-fade/slide; 3 lượt cuối đổi viền amber, 1 lượt cuối pulse một lần. | Tăng căng thẳng có kiểm soát, không gây hoảng loạn. | 150–220 ms; không loop đỏ liên tục. | Must |
| UI-04 · Objective Counter | Rescue trail chạm icon, icon squash/pop và số cộng có nguồn. | Nối hành động trên board với tiến triển HUD. | 180–280 ms sau rescue hit. | Must |
| UI-05 · Combo Score | Score tick lên theo chunk, multiplier crest giữ 0,6–1 s rồi thu gọn. | Làm mastery có giá trị mà không che core. | Không đếm kéo dài quá 800 ms. | Should |
| UI-06 · Nhân Phẩm Earn | Đốm sáng từ receipt/result bay về ví; số dư tăng sau khi đốm chạm. | Giải thích nguồn thưởng và tạo cảm giác tích lũy. | 500–800 ms; gom thành 3–7 đốm, không spawn theo từng đơn vị. | Must |
| UI-07 · Nhân Phẩm Spend | Ví giảm một lần, vệt sáng chảy từ ví tới item mua, receipt xác nhận. | Làm giao dịch minh bạch, tránh cảm giác mất currency bí ẩn. | 350–550 ms; chỉ chạy sau confirm; không celebratory quá mức. | Should |
| UI-08 · Reward Reveal | Card lật/mở vỏ sò, silhouette → màu, rarity bằng shape + color. | Tạo suspense ngắn nhưng không giả loot box. | 600–900 ms; tap để skip; reward đã xác định trước. | Should |
| UI-09 · Level Node Unlock | Nước sạch chạy dọc path tới node mới; node nở sáng, prop quanh node hồi phục. | Kết thúc level bằng tiến triển hữu hình và CTA rõ. | 800–1.200 ms; camera chỉ pan nếu node ngoài viewport. | Must |
| UI-10 · Tide Bond XP | Thanh XP lấp bằng sóng; qua mốc tạo crest quanh portrait Agent. | Gắn rescue với quan hệ đồng hành dài hạn. | 400–700 ms; level-up có beat riêng. | Should |
| UI-11 · Agent Unlock | Bubble silhouette tan, portrait Agent bước ra, tên/skill xuất hiện theo thứ tự. | Tạo mốc sưu tầm đáng nhớ. | 1,2–1,8 s; chỉ full sequence lần đầu; skip được. | Could |
| UI-12 · Result Sequence | Đã cứu → combo tốt nhất → Nhân Phẩm → CTA tiếp theo, mỗi mục settle trước mục sau. | Cho người chơi hiểu thành tích trước khi bấm tiếp. | Tổng 1,2–2 s; CTA hiện ≤1,2 s; tap để hoàn tất ngay. | Must |
| UI-13 · Retry | Board rút theo xoáy cát nhỏ rồi dựng lại state ban đầu. | Retry có nhịp nhưng cực nhanh để giữ “one more try”. | Tổng <500 ms; không reload page. | Must |
| UI-14 · Error / Offline | Toast ripple xám, icon Coach mất kết nối nhẹ; local fallback sáng lên. | Trấn an rằng gameplay vẫn tiếp tục. | Không screen shake, không modal nếu core vẫn chơi được. | Must |
Dùng cùng một grammar để người chơi học ý nghĩa của motion qua vài lượt đầu.
Thông tin chưa commit dùng sóng kính trong, alpha thấp và chuyển động đều. Không dùng burst, shake hoặc màu reward.
Hành động đã commit dùng ring/splash ngắn, item arc đọc được và âm tick đồng bộ.
Combo/rescue/reward dùng màu ấm có tiết chế; chỉ payoff cao mới chạm toàn màn hình.
Lượt thấp và trạng thái nguy cơ dùng amber, shape và text; đỏ chỉ dành cho lỗi không thể tiếp tục.
Small: select, tick, counter; tối đa 1 vùng. Medium: capture, combo, rescue; tối đa 30% board. Hero: perfect, level win, Agent unlock; tối đa một lần mỗi level/mốc. Hero effect không được chồng Hero effect khác.
Không zoom liên tục. Micro-shake 1–2 px trong 80–120 ms chỉ cho Tidal Rush/Great Rescue; tắt hoàn toàn khi bật Reduce Motion. Camera pan chỉ dùng trên map progression hoặc reveal ngoài viewport.
Shell Tide chỉ dùng PixiJS v8 ParticleContainer làm particle renderer. Vanilla JavaScript giữ vai trò điều phối event, timeline, pooling và accessibility; không đưa thêm particle framework khác vào runtime.
| Công nghệ | Đánh giá | Quyết định |
|---|---|---|
| Vanilla JavaScript | VfxDirector, event bus, timeline, object pool, Reduce Motion và quality tier. Đây là code orchestration, không phải particle framework thứ hai. | Dùng |
| PixiJS v8 ParticleContainer | Đã cùng scene graph và ticker với game; render nhiều particle nhẹ, khai báo rõ property dynamic/static và không cần đồng bộ tọa độ giữa hai canvas. | Chọn làm renderer duy nhất |
| @pixi/particle-emitter | Config emitter tiện nhưng tài liệu/release hiện nhắm PixiJS cũ; thêm rủi ro duplicate Pixi major và không cần thiết khi catalog có thể dựng bằng pool nội bộ. | Không dùng |
| Proton | Một particle engine độc lập sẽ trùng ticker, renderer, lifecycle và object pool với PixiJS. | Không dùng |
| tsParticles | Phù hợp background website nhưng không phù hợp VFX phải bám board, camera và gameplay event của PixiJS. | Không dùng |
Prototype hiện dùng pixi.js@8.6.6. ParticleContainer v8 là API experimental nhưng thuộc chính PixiJS; pin exact version, bọc API sau adapter nội bộ và có visual regression test để việc nâng Pixi không lan ra toàn catalog.
app.ticker cập nhật VfxDirector, particle pool và mọi timeline gameplay. Ticker tự pause khi tab ẩn; không tạo thêm requestAnimationFrame cho particle.
Nếu import hoặc WebGL particle lỗi, event gameplay vẫn resolve; adapter trả về tween/ring tĩnh bằng Pixi Graphics hoặc CSS. Reward/state được commit trước VFX và không phụ thuộc callback onComplete của emitter.
VFX dùng chính pixi.js đã có trong game. Texture primitive được gom trong một atlas nhỏ; behavior alpha, scale, color, velocity và lifetime nằm trong config nội bộ của VfxDirector.
| Nhóm | Renderer / kỹ thuật mặc định | Lý do |
|---|---|---|
| Selection, STOP, counter, modal | Vanilla JS + Pixi Graphics/Sprite hoặc CSS transition | Deterministic, ít object, cần bám state và accessibility. |
| Route, trail, sow arc, reward travel | Vanilla timeline + Pixi Graphics/Mesh; ParticleContainer chỉ thêm mote | Đường đi phải chính xác theo board, particle chỉ làm giàu hình ảnh. |
| Splash, bubble, sand, combo burst | PixiJS ParticleContainer + object pool nội bộ | Nhiều sprite nhẹ, cần alpha/scale/color/velocity theo thời gian. |
| Ambient menu/map | PixiJS ParticleContainer ở layer background | Dùng chung renderer, quality tier và lifecycle với game. |
| VFX Lab | Cùng VfxDirector và PixiJS adapter production | Preset được duyệt trong Lab chạy đúng bằng runtime sẽ ship. |
pixi.js@8.6.6, ParticleContainer, Pixi Graphics/Sprite và VfxDirector Vanilla JS. Không cài Proton, @pixi/particle-emitter hoặc tsParticles. Nếu API experimental của ParticleContainer gây lỗi, fallback vẫn là Pixi Sprite pool—không đổi sang framework khác.VFX nghe event gameplay và render phản hồi; không tự quyết định score, reward, capture hoặc state machine.
| Nhóm event | Payload tối thiểu | VFX tiêu thụ |
|---|---|---|
move_previewed | sourceCup, direction, route, stopCup, captureCandidates | GP-01 → GP-04 |
move_committed / item_sown | moveId, stepIndex, from, to, isLast | GP-05 → GP-07 |
capture_started / capture_resolved | chainIndex, sourceCup, count, rescuedIds | GP-08 → GP-13 |
level_failed | reason, objectiveRemaining, decisionSnapshot | GP-14, UI-13 |
coach_triggered / booster_used | agentId, reason, targetRegion, boosterId | GP-15, GP-16 |
reward_granted | transactionId, rewardType, amount, source, balanceAfter | UI-06 → UI-12 |
pointer-events: none; modal/result chỉ mở sau khi state gameplay đã settle.VFX tốt phải giữ game đọc được trên mobile, máy yếu và với người nhạy cảm chuyển động.
Thay travel bằng fade/cross-fade, bỏ shake/zoom/loop pulse, rút animation còn 80–150 ms. STOP, objective, warning và reward vẫn phải có shape/text tĩnh để truyền đủ thông tin.
Mục tiêu 60 FPS; chấp nhận 30 FPS ổn định trên máy test thấp. Pool particle, giới hạn 80 particle đồng thời, tối đa 2 blur layer, không tạo DOM node theo từng hạt, dừng loop khi tab ẩn.
| Gate | Go | No-go |
|---|---|---|
| Clarity | 5/5 tester chỉ đúng cup chọn, hướng, STOP và objective trong 3 giây. | Particle che số quân hoặc preview bị hiểu là kết quả đã commit. |
| Responsiveness | Phản hồi press/select <100 ms; board nhận input lại ≤450 ms sau rescue. | Animation làm mất tap, double-trigger hoặc buộc chờ payoff. |
| Engagement | Tester nhận ra combo tier, rescue và lý do near-miss; retry median <2 giây. | Fail chỉ là màn đỏ; combo/rescue không khác sow thường. |
| Performance | Không có frame spike lặp lại >50 ms trong capture chain chuẩn. | Great Rescue làm drop frame rõ hoặc memory tăng sau mỗi retry. |
| Accessibility | Reduce Motion chơi đủ 10 level; mọi state quan trọng có shape/text ngoài màu. | Shake/flash bắt buộc hoặc reward chỉ hiểu được qua chuyển động. |
Ưu tiên hiệu ứng làm rõ core và tạo payoff trực tiếp; không sản xuất mọi biến thể trước khi gameplay ổn định.
GP-01 → GP-06, GP-08 → GP-09, GP-12 → GP-14, GP-18; UI-01 → UI-04, UI-06, UI-09, UI-12 → UI-14. Dùng shape/ring/trail tái sử dụng trước.
GP-07, GP-10, GP-15, GP-16; UI-05, UI-07, UI-08, UI-10. Chỉ làm sau khi timing sow/capture vượt clarity gate.
GP-17, UI-11 và biến thể Hero theo chapter. Cắt trước nếu ảnh hưởng QA, input, loading hoặc đủ 10 level.
Chuẩn bị 6 primitive: ring, ripple line, bubble burst, sand puff, reward mote, crest. Đổi màu, scale, curve và timing theo event thay vì tạo asset riêng cho mọi dòng catalog.