Tách Phần AOI Ra Riêng - nói dối e blog

Tách Phần AOI Ra Riêng

Đây có lẽ là lần thứ hai tôi thảo luận về chủ đề AOI trên blog, chưa kể đến một bài viết khác đã hoàn thành nhưng chưa công khai. Sau khi trở về từ chuyến công tác hôm qua, buổi tối tôi có trao đổi với một cựu kỹ sư phụ trách server chính tại Đại Đường. Trong cuộc trò chuyện, tôi đã đề xuất một giải pháp tách biệt module AOI và muốn ghi lại ý tưởng này.

Chức năng chính của AOI bao gồm hai khía cạnh: Thứ nhất, khi các nhân vật (người chơi hoặc NPC) thực hiện hành động trên server, module này sẽ phát tán thông tin đến những người chơi gần về mặt địa lý trong game. Khi số lượng người chơi trong tiến trình không quá lớn, cách xử lý đơn giản nhất là phát tán thông tin đến toàn bộ kết nối trong tiến trình. Tuy nhiên, với sự phát triển của phần cứng, phương pháp này có thể trở thành xu hướng trong tương lai. Hiện tại, để giảm tải lượng dữ liệu xử lý, đặc biệt là băng thông mạng, chúng ta thường cần module AOI thực hiện lọc dữ liệu.

Thứ hai, khi người chơi tiếp cận một NPC và bước vào vùng cảnh giới của nó, AOI sẽ gửi tín hiệu thông báo đến NPC để kích hoạt phản ứng AI phù hợp.

Có nhiều thuật toán triển khai AOI khác nhau, nhưng tôi sẽ không đi sâu vào phần này. Điều tôi quan tâm hiện nay là: Nếu AOI đóng vai trò quan trọng trong game (đặc biệt là các game MMO thế giới mở với chiến đấu thời gian thực), liệu có thể tách module này thành một tiến trình độc lập không?

Hãy bắt đầu với yêu cầu đầu tiên. Thực tế, phần lớn thông tin cần phát tán trong game không quá nhạy cảm với thứ tự nhận. Ví dụ, việc A di chuyển trước hay B di chuyển trước không quan trọng; hay thứ tự giữa tấn công và di chuyển cũng không ảnh hưởng nhiều. Tôi muốn nhấn mạnh rằng thứ tự này chỉ xét về phía client nhận dữ liệu. Dù khoảng cách ảnh hưởng đến việc phát động tấn công, nhưng server logic đã kiểm tra tính hợp lệ trước khi xử lý lệnh. Nói cách khác, mọi thông tin từ server đều hợp lệ, client không cần quá quan tâm thứ tự thay đổi vị trí và hành động tấn công.

Vì vậy, việc tách riêng chức năng phát tán AOI sang một tiến trình độc lập sẽ không cần đồng bộ thứ tự gói tin với tiến trình logic. Đây là một tin vui. Chúng ta có thể thiết kế một tiến trình AOI riêng biệt, nơi logic server gửi gói tin thông báo mỗi khi đối tượng thay đổi vị trí. Điều này đồng nghĩa với việc sao chép trạng thái vị trí của các đối tượng sang tiến trình AOI. Khi đối tượng cần phát tán thông tin trạng thái, chỉ cần gửi tin nhắn đến tiến trình AOI, nơi sẽ thực hiện lọc (xác định các đối tượng lân cận) và phát tán nhóm (multicast).

Cần lưu ý rằng do các tin nhắn đều bất đồng bộ, client cần lọc các ID đối tượng lỗi thời khi nhận dữ liệu. Ví dụ, có thể server logic đã xóa một đối tượng, nhưng tiến trình AOI vẫn gửi tin nhắn liên quan đến nó với độ trễ nhất định. (Việc giao nhiệm vụ chuyển tiếp tin nhắn xóa đối tượng cho AOI là một ý tưởng tồi, vì điều này làm tăng độ phức tạp và trách nhiệm của module này).

Về vấn đề thông báo cảnh giới, AOI server có thể gửi tín hiệu đến logic server khi phát hiện đối tượng xâm nhập vùng cảnh giới. Tin nhắn này không cần phản hồi tức thì. Ví dụ, nếu thiết kế yêu cầu NPC có vùng cảnh giới 20m, không nhất thiết phải kích hoạt chính xác tại ranh giới 20m. Một độ trễ 0.5 giây là chấp nhận được, thậm chí độ trễ có thể tăng theo bán kính vùng cảnh giới.

AOI server độc lập có thể sắp xếp độ ưu tiên theo bán kính vùng cảnh giới, từ đó gửi các thông báo một cách có hệ thống. So với module AOI tích hợp, việc tách biệt thành tiến trình độc lập giúp giảm độ liên kết (coupling). Sự tương tác chỉ thông qua giao thức chứ không qua interface, điều này giúp dễ bảo trì và tối ưu trong tương lai. Việc không chia sẻ trạng thái với logic server cũng giảm thiểu nguy cơ phát sinh bug.

Lưu ý: Gần đây tôi có chia sẻ một buổi học với các đồng nghiệp mới. Nội dung không đi sâu vào kỹ thuật, mà tập trung vào lịch sử ngành game, sự phát triển của phần cứng máy tính, tiến hóa của game và một số bước tiến trong phát triển phần mềm. Tôi tin rằng lịch sử đã chứng minh: Chỉ những thiết kế đơn giản mới có thể phát triển bền vững. Nếu thiết kế quá phức tạp, chúng ta sẽ phải trả giá bằng việc loại bỏ hoặc sửa chữa. Hy vọng điều này mang lại bài học cho các bạn trẻ vừa tốt nghiệp.

Hai hôm trước, trước buổi họp tôi tranh thủ đọc một giờ mã nguồn server Đại Đường 2. Tôi phát hiện một bug ẩn rất sâu. Nghe nói dự án này vừa ra mắt gặp nhiều trục trặc, server thường xuyên sập. Các lập trình viên nên hiểu rằng, đôi khi không phải do nhiều bug, mà chỉ cần một lỗi nghiêm trọng cũng đủ gây thảm họa. Code server Đại Đường 2 được viết khá “tinh vi”, với sự đan xen phức tạp giữa C++ và Lua, gần như làm tôi chóng mặt. Thật sự quá phức tạp…

0%