ĐIỀU CHỈNH SỐ LIỆU, TRÌNH MÔ PHỎNG & TRÌNH SOẠN THẢO
Dạo gần đây mình đau đầu vì phải điều chỉnh số liệu gameplay. Đã nghiên cứu kỹ nhiều cơ chế thiết lập trong các tựa game khác nhau, và xin chia sẻ một ví dụ nhỏ như sau:
Trong World of Warcraft, hệ thống giáp giảm sát thương vật lý theo tỷ lệ phần trăm cụ thể, áp dụng công thức: min (Giáp/(Giáp + 400 + 85 * Cấp độ đối phương) , 0.75)
Làm thế nào để hiểu được bản chất toán học ẩn sau công thức này? Tại sao lại chọn cách thiết lập như vậy?
Việc liên kết với cấp độ đối phương khá dễ hiểu - kẻ địch càng mạnh thì khả năng giảm sát thương càng thấp. Điều này giúp đơn giản hóa thiết kế công thức tính sát thương. Bởi vì khả năng chịu đựng sát thương vật lý của nhân vật phụ thuộc vào hai yếu tố cốt lõi: lượng HP và tỷ lệ hấp thụ sát thương từ giáp (chưa tính đến tỷ lệ né tránh hay kỹ năng đặc biệt).
Với tư duy phát triển lâu dài, hệ thống luôn tăng HP và giáp khi nhân vật lên cấp. Tuy nhiên, chỉ số gây sát thương đối phương lại chỉ có một biến duy nhất. Do đó, nhà thiết kế buộc phải chọn giữa: tăng mạnh khả năng gây sát thương hoặc giảm hiệu quả giảm sát thương khi đối đầu với quái vật cấp cao.
Vì WoW có sự khác biệt về loại giáp giữa các lớp nhân vật (giáp nặng, giáp vảy, giáp da…), Blizzard đã chọn giải pháp thông minh: Điều chỉnh theo cấp độ đối phương. Điều này vừa đảm bảo sự cân bằng giữa các lớp nhân vật khi lên cấp cao, vừa giữ lại không gian nâng cấp giáp. Về ngưỡng 75% hấp thụ tối đa, rõ ràng đây là ảnh hưởng từ hệ thống Dungeons & Dragons - nhằm duy trì cơ hội phản kháng cho phe yếu thế khi chênh lệch quá lớn. (Tương tự như việc tung xúc xắc ra 1 trong D&D luôn dẫn đến miss, WoW cũng áp dụng cơ chế miss nền tối thiểu tương tự)
Hãy tập trung phân tích khung công thức hấp thụ sát thương này. Tại sao lại chọn đường cong nghịch đảo mà không dùng phương pháp cộng dồn tỷ lệ phần trăm quen thuộc (như cách thiết kế tỷ lệ chí mạng trong chính WoW)?
Vấn đề nằm ở việc cân bằng khi tỷ lệ phần trăm biến động lớn. Nếu dùng kiểu cộng dồn, mỗi điểm phần trăm sẽ có giá trị khác nhau tùy vào nền tảng ban đầu. Ví dụ: Khi bạn có 98% khả năng hấp thụ, việc tăng thêm 1% thực chất gấp đôi hiệu quả so với việc tăng từ 0% lên 1%. Đây chính là lý do WoW thiết kế mối quan hệ nghịch đảo giữa điểm giáp và tỷ lệ hấp thụ.
Khi HP cố định và sát thương đối phương ổn định, số lần chịu đòn (thời gian sống sót) sẽ tỷ lệ nghịch với sát thương còn lại sau khi trừ giáp. Chính công thức chuyển đổi này đã giúp điểm giáp tuyến tính hóa khả năng phòng thủ - 200 điểm giáp mang lại hiệu quả tăng tương đương nhau dù người dùng là ai, cấp độ nào, chỉ tiêu chí duy nhất là cấp độ đối thủ. Điều này tạo nên sự nhất quán dễ cân bằng trong toàn hệ thống.
Nếu muốn thiết kế kỹ năng tăng giáp theo phần trăm (như hệ thống dạng Bear Form trong WoW), cần đặc biệt cẩn trọng. Cộng dồn nhiều nguồn tăng phần trăm giáp sẽ phá vỡ sự cân bằng tuyến tính này. Giải pháp? Thay vì dùng hàm số bậc nhất, hãy áp dụng đường cong hàm mũ để mô tả mối quan hệ giữa điểm giáp và tỷ lệ hấp thụ - tuy nhiên đây là chủ đề phức tạp hơn cần dành cho dịp khác.
Gần đây mình đang phát triển trình mô phỏng chiến đấu để kiểm thử công thức số liệu. Dù có sẵn bản C# do đồng nghiệp làm, mình vẫn muốn xây dựng phiên bản web AJAX riêng để dễ dùng hơn. Ý tưởng là tạo HTTP server đơn giản chỉ cần xử lý lệnh GET qua port local - chỉ cần đọc dòng đầu tiên của request, phân tích chuỗi URL làm lệnh điều khiển. Kết hợp với một HTTP server nhẹ cho giao diện sẽ tiết kiệm thời gian phát triển hơn.
Thú vị là có bạn đã thử nghiệm làm bằng Web Service, kết quả khá ấn tượng. Mình dự tính viết mã bằng C chỉ khoảng 200 dòng là hoàn thành khung chính.
Về phần trình soạn thảo hạt 3D, mình gợi ý nên tập trung vào giao diện web để đơn giản hóa thay vì nhúng trực tiếp vào engine. Dù vậy quá trình phát triển vẫn gặp nhiều trở ngại tâm lý…
Sau cả ngày vật lộn với đống này, mình vẫn chưa quyết định có nên tiếp tục viết hồi ký không. Thôi thì đi ngủ sớm, nghe nhạc nhẹ thư giãn vậy!