Thiết Kế Hệ Thống Kiểm Tra Vật Phẩm Trong Trò Chơi Trực Tuyến - nói dối e blog

Thiết Kế Hệ Thống Kiểm Tra Vật Phẩm Trong Trò Chơi Trực Tuyến

Thiết kế hệ thống xác thực vật phẩm trong game online

Để một trò chơi trực tuyến có thể vận hành hệ thống kinh tế ổn định, nền tảng server cần được xây dựng trên cơ sở dịch vụ dữ liệu đáng tin cậy. Việc thiết kế giao thức dữ liệu hiệu quả không phải điều dễ dàng - đặc biệt là phải đảm bảo không xảy ra tình trạng mất mát hoặc nhân bản vật phẩm/tiền tệ khi gặp sự cố phần cứng hoặc lỗi phần mềm.

Dù sử dụng cơ sở dữ liệu có hỗ trợ giao dịch (transaction) là lựa chọn khả dĩ, nhưng yêu cầu đặt ra cho lập trình viên rất cao. Họ không chỉ cần tính toán kỹ lưỡng từng thao tác dữ liệu đảm bảo an toàn giao dịch, mà còn phải xử lý các tác vụ bất đồng bộ. Điều này càng trở nên khó khăn hơn với yêu cầu thay đổi nhanh chóng và khối lượng dữ liệu lớn trong game.

Sau nhiều lần chỉnh sửa và hoàn thiện, tôi đã xây dựng được hệ thống như sau:

Tách biệt lưu trữ và xác thực dữ liệu Thay vì gộp chung, tôi đề xuất tách riêng dịch vụ lưu trữ dữ liệu và hệ thống xác thực. Dịch vụ dữ liệu chỉ cần thực hiện chức năng đọc/ghi/thay đổi cơ bản, có thể dùng cách lưu trữ key/value đơn giản (tự phát triển hoặc sử dụng Redis). Không cần thiết phải dùng cơ chế transaction.

Tuy nhiên, hệ thống xác thực phải đủ mạnh để kiểm tra toàn bộ các giao dịch phát thưởng và chuyển giao vật phẩm. Mọi hoạt động đều phải trải qua quá trình kiểm toán hậu kỳ để sửa chữa các lỗi phát sinh.

Nguyên tắc sở hữu vật phẩm

  • Mỗi vật phẩm hoặc tiền tệ luôn có chủ sở hữu duy nhất: người chơi hoặc hệ thống
  • Tránh tuyệt đối tình trạng “bốc hơi” (mất không lý do) hoặc nhân bản vật phẩm
  • Mối quan hệ sở hữu là đường tính, không xây dựng cấu trúc cây phức tạp
  • Mỗi thực thể (Entity) và vật phẩm (Goods) đều có ID 64bit riêng biệt, không trùng lặp
  • Entity và Goods là hai khái niệm độc lập (không thể đồng thời là nhau), với mối quan hệ n:1 từ Goods đến Entity

Thiết kế API tối giản Dưới đây là tập hợp các API cốt lõi của hệ thống:

ApplyID(số_lượng) Yêu cầu cấp phát một loạt ID dự phòng. API này trả về giá trị cụ thể, thường được gọi khi khởi động dịch vụ. Hệ thống dữ liệu sẽ cấp số lượng ID trống theo yêu cầu. Khi gần hết ID, hệ thống tự động yêu cầu cấp thêm. Các ID từ 0-1023 được dành riêng, trong đó 0 đại diện cho hệ thống.

CreateEntity(id) Tạo mới một thực thể với ID đã được cấp. Nếu ID hợp lệ (được cấp qua ApplyID), API này gần như luôn thành công.

CreateGoods(id) Tạo vật phẩm với ID trống, mặc định thuộc sở hữu hệ thống (ID 0).

ExchangeGoods( { entity1 , funds , [danh sách_vật_phẩm] } , … ) API thực hiện giao dịch giữa nhiều nhóm vật phẩm và tiền tệ. Mỗi nhóm gồm: ID thực thể, số tiền thay đổi, và danh sách vật phẩm nhận được. Lưu ý:

  • Tất cả vật phẩm giao dịch phải thuộc quyền sở hữu của các thực thể trong danh sách
  • Tổng lượng tiền tệ trong giao dịch luôn bằng 0

Ví dụ: Người chơi A dùng 1000 tiền tệ đổi vật phẩm 12345 từ người chơi B, đồng thời đóng 10 tiền thuế. Ta gọi:

1
2
3
4
5
ExchangeGoods(
  { A, -1010, [12345] }, 
  { B, 1000, [] }, 
  { 0, 10 }
)

Việc phát thưởng vật phẩm có thể thực hiện bằng cách kết hợp CreateGoods và ExchangeGoods.

VerifyGoods(thực_thể, [danh_sách_vật_phẩm]) Xác minh tính hợp lệ của vật phẩm thuộc sở hữu một thực thể. Đầu vào là danh sách ID vật phẩm cần kiểm tra. Hệ thống sẽ thông báo lỗi nếu phát hiện thiếu hụt hoặc dư thừa vật phẩm. API này thường dùng cho bảo trì định kỳ hoặc kiểm tra khi người chơi đăng nhập.

QueryGoods(thực_thể) Truy vấn toàn bộ vật phẩm và số dư tiền tệ của thực thể. API chỉ dành cho mục đích gỡ lỗi, chức năng tương tự VerifyGoods nhưng không thực hiện xác thực.

Giải pháp tối ưu cho vật phẩm số lượng lớn Trong thực tế, nhiều vật phẩm không cần tính duy nhất (như huyết dược, nguyên liệu…). Việc cấp ID riêng cho từng vật phẩm sẽ gây lãng phí bộ nhớ. Có 3 phương án giải quyết:

  1. Loại bỏ khỏi xác thực: Các vật phẩm phổ biến không cần theo dõi chính xác trong hệ thống xác thực.

  2. Cơ chế hoán đổi thông minh: Khi đạt ngưỡng số lượng nhất định (ví dụ 10 vật phẩm), có thể đổi lấy vật phẩm đại diện cho số lượng lớn hơn. Cách này không cần thay đổi giao thức, chỉ cần thỏa thuận bên sử dụng. Ví dụ: 10 vật phẩm ID thường đổi lấy 1 vật phẩm ID đặc biệt đại diện cho 10 đơn vị. Các ID bị hoán đổi không cần lưu vào CSDL, chỉ cần ghi log.

  3. Phân vùng ID đặc biệt: Các ID 1-1023 dành riêng cho vật phẩm có số lượng. Mỗi ID đại diện cho một loại vật phẩm cụ thể, cho phép các thực thể sở hữu nhiều bản sao. Hệ thống xác thực lưu trữ theo cấu trúc (ID + số lượng), đồng thời cần điều chỉnh API ExchangeGoods để xử lý danh sách vật phẩm ra/không vào.

Kiến trúc phân tầng ưu việt Hệ thống xác thực và lưu trữ hoạt động độc lập hoàn toàn. CSDL vẫn ghi lại mối quan hệ sở hữu vật phẩm giữa người chơi, nhưng logic game không dựa vào dữ liệu này. Thay vào đó, nó đảm bảo hệ thống giao dịch và rơi rớt vật phẩm từ quái vật vận hành chính xác, đồng thời cung cấp cơ sở phục hồi dữ liệu khi xảy ra sự cố.

Lợi ích thiết kế phân tách

  1. Tính linh hoạt: Dễ dàng mở rộng quy mô hệ thống khi cần
  2. Hiệu năng ổn định: Giảm tải cho CSDL chính nhờ tách biệt xác thực
  3. Dễ bảo trì: Giao dịch có thể kiểm tra định kỳ mà không ảnh hưởng trải nghiệm game thủ
  4. Khả năng phục hồi: Dữ liệu tổn thất có thể khôi phục nhanh chóng nhờ hệ thống xác thực

Thiết kế này cho thấy sự cân bằng giữa tính kỹ thuật và hiệu quả vận hành, đặc biệt phù hợp với các tựa game có nền kinh tế phức tạp và lượng người chơi đông đảo.

0%