Vấn Đề Về Thành Phần Phân Cấp - nói dối e blog

Vấn Đề Về Thành Phần Phân Cấp

Gần đây tôi đã dành thời gian suy ngẫm về một số thách thức trong kiến trúc ECS. Trong các tình huống nghiệp vụ cụ thể, cấu trúc dữ liệu thường mang tính phân cấp phức tạp, điều mà mô hình bảng hai chiều truyền thống khó biểu diễn hiệu quả. Vấn đề này còn liên quan đến câu hỏi quan trọng: Liệu có nên cho phép một thực thể (entity) chứa nhiều thành phần (component) cùng loại? Chẳng hạn như cách biểu diễn các ô trang bị trên nhân vật hay hệ thống hiệu ứng kỹ năng cần được quản lý ra sao?

Tôi đã hình thành một số ý tưởng ban đầu nhưng vẫn chưa triển khai cụ thể, xin ghi lại để

Hiện tại tôi đang quản lý dữ liệu trong ECS dưới dạng cơ sở dữ liệu trong bộ nhớ, với cách nhìn mỗi Entity/Component như một bảng thưa hai chiều. Mỗi hàng đại diện cho một Entity, mỗi cột ứng với một loại Component, và toàn bộ dữ liệu này tạo thành một “thế giới” (world).

Tuy nhiên qua quá trình phản tư, tôi nhận ra rằng việc gộp toàn bộ dữ liệu vào một bảng duy nhất là không hợp lý. Lấy ví dụ về hệ thống hành trang (Inventory) - mỗi nhân vật đều có một Inventory gồm nhiều ô chứa đồ (slot). Đây rõ ràng là cấu trúc phân cấp ba tầng: Nhân vật -> Hành trang -> Ô chứa đồ.

Nếu bỏ qua lớp trừu tượng Inventory, chúng ta sẽ phải gắn nhiều Component kiểu “ô chứa đồ” trực tiếp lên Entity nhân vật. Khi xây dựng hệ thống xử lý hiệu ứng từ đồ trang bị, việc tập hợp toàn bộ vật phẩm trên cùng một nhân vật để xử lý liên kết sẽ rất cần thiết.

Một giải pháp tối ưu hơn có thể là tạo bảng riêng cho các ô chứa đồ. Trong bảng này, mỗi Entity đại diện cho một ô chứa đồ cụ thể, có thể sở hữu nhiều Component và Tag khác nhau. Một Component đặc biệt sẽ lưu trữ ID tham chiếu đến Entity nhân vật trong bảng chính.

Trong bảng nhân vật, chúng ta chỉ cần lưu trữ số lượng ô chứa đồ hiệu lực, trong khi dữ liệu chi tiết được chuyển sang bảng chuyên dụng. ID của mỗi ô chứa đồ có thể được tạo theo cấu trúc ghép: kết hợp ID nhân vật với số thứ tự trong Inventory của họ.

Lợi dụng cơ chế “sắp xếp chọn lọc” (ordered select) đã có trong ECS, chúng ta có thể nhóm các ô chứa đồ của cùng một nhân vật lại để duyệt theo thứ tự mong muốn. Việc đánh dấu Tag cho các ô chứa đồ cũng cho phép lọc dữ liệu theo mục đích sử dụng (vật phẩm tấn công, phòng thủ, v.v).

Việc hỗ trợ đa bảng không đòi hỏi thay đổi kiến trúc LuaECS hiện có, chỉ cần điều chỉnh cách đặt tên. Thay vì gọi bảng chính là “world”, chúng ta cần thêm một tầng quản lý tổng thể cũng mang tên “world” để điều phối nhiều bảng con.

Việc phân tách dữ liệu này còn mở ra cơ hội tối ưu底层. Cơ chế sắp xếp hiện tại tuy cho phép duyệt Entity theo thứ tự tùy chỉnh, nhưng độ phức tạp truy vấn có thể tăng từ O(1) lên O(log N). Giải pháp là thêm phương thức cho phép người dùng chủ động tái tổ chức bố cục bộ nhớ của từng bảng theo Tag định kỳ, giúp tăng hiệu suất truy cập tuần tự. Dù quá trình này tốn kém, việc chia nhỏ dữ liệu thành nhiều bảng sẽ giảm đáng kể chi phí bảo trì tổng thể.

0%