Tài liệu Steamworks
Hệ thống xếp trận & phòng chờ của Steam

Tổng quan

Xếp trận peer-to-peer của Steam được phát triển dựa trên khái niệm phòng chờ. Phòng chờ (lobby) là một thực thể (entity) hoạt động trên máy chủ backend của Steam, tương tự như phòng trò chuyện. Người dùng có thể tạo phòng chờ mới; liên kết dữ liệu với phòng chờ; tìm phòng chờ dựa trên dữ liệu đó; tham gia vào phòng chờ; và chia sẻ thông tin với người dùng khác trong phòng chờ. Một phòng chờ có thể chứa tới 250 người dùng, dù thông thường trò chơi có khoảng từ 2-16 người chơi. Xếp trận dựa theo kỹ năng (SBMM) được phát triển trên nền tảng hệ thống này.

API xếp trận peer-to-peer của Steam là một nhóm chức năng cho phép người dùng tìm nhau để cùng chơi. Các hàm xếp trận đều hoạt động trong ISteamMatchmaking, trong chứa thêm các tham số chi tiết hơn cho mỗi hàm. Phòng chờ được nhận dạng không trùng khớp, dựa trên các SteamID, như tên nhận diện người dùng hoặc máy chủ trò chơi. Ví dụ Steamworks minh họa việc triển khai đầy đủ các chức năng phòng chờ.

Quy trình xếp trận

Mô hình thường thấy khi gộp hai nhóm vào để tiến hành chơi được thực hiện như sau:
  1. Người dùng chọn chế độ trong trò chơi mà họ muốn chơi nhiều người, và kiểu/loại chơi nhiều người mà họ muốn (luật lệ, tình huống, v.v...)
  2. Trò chơi sẽ tìm các phòng thỏa mãn các yêu cầu tương tự nhau, thông qua API tìm kiếm phòng chờ.
  3. Nếu thấy phòng chơi, thì trò chơi sẽ tham gia vào phòng đó; nếu không thì nó sẽ tự tạo ra một phòng chờ
  4. Người dùng sẽ ở trong phòng chờ cho tới khi đủ người chơi để tiến hành bắt đầu trận đấu. Dữ liệu được trao đổi giữa các thành viên trong phòng chờ, về nhân vật họ muốn chơi hoặc thiết lập dựa trên người chơi khác. Nếu có một số luật bắt buộc phải áp dụng trong phòng chờ (ví dụ, chỉ 1 người dùng được chơi 1 nhân vật nhất định), thì duy nhất chủ phòng mới có thể đưa ra quyết định.
  5. Có thể có hoặc không có giao diện thiết kế liên kết tới phòng chờ; nếu có, tính năng giao tiếp dữ liệu trong phòng chờ có thể dùng để gửi thông báo trò chuyện giữa các thành viên bên trong. Dữ liệu đàm thoại cũng có thể gửi đi, nhưng sẽ cần tới API Mạng lưới Steam.
  6. Khi trận đấu sẵn sàng triển khai, tất cả người dùng vào máy chủ trò chơi, hoặc kết nối tới người chơi được đề cử làm máy chủ, rồi sau đó rời phòng chờ. Sau khi tất cả người dùng rời khỏi phòng chờ, nó sẽ tự hủy.

Tìm phòng chờ

Để trò chơi tìm phòng chờ, bạn sẽ cần gọi: ISteamMatchmaking::RequestLobbyList
Đây là chức năng không đồng bộ, trả về một handle SteamAPICall_t mà bạn có thể dùng để theo dõi trạng thái của yêu cầu. Tùy theo kết nối người dùng đến back-end Steam, lệnh gọi này có thể mất từ 300 mili giây tới 5 giây để hoàn thành, và hết thời gian sau 20 giây.
Số lượng kết quả trả về nằm trong kết quả gọi LobbyMatchList_t, mà bạn sau đó có thể dùng ISteamMatchmaking::GetLobbyByIndex để lặp lại chúng và lấy ID của chúng.
Có thể trả về tới 50 kết quả, nhưng thông thường thì chỉ có vài kết quả. Kết quả trả về được xếp theo khoảng cách địa lý và dựa trên bộ lọc cận kề. Mặc định, chúng tôi sẽ không trả về các phòng đã đầy, và bộ lọc khoảng cách được đặt là k_ELobbyDistanceFilterDefault (gần đó). Để thêm bộ lọc, trước khi gọi RequestLobbyList bạn cần phải gọi một hoặc vài chức năng lọc sau:

Tạo một phòng chờ

Nếu không thể tìm phòng để người dùng tham gia, đây là lúc bạn sẽ cần phải tạo phòng. Chỉ cần dùng lệnh gọi
ISteamMatchmaking::CreateLobby và đợi nó hoàn thành. Kết quả lệnh gọi cho biết nó có thành công hay không, nếu có, nó sẽ trả về steamID phòng chờ trong cấu trúc LobbyCreated_t để dùng đặt metadata cho phòng chờ. Điều đầu tiên bạn sẽ muốn làm sau khi tạo phòng chờ là đặt dữ liệu cho nó để các client trò chơi khác dùng cho việc tìm kiếm (xem bên dưới).

Tham gia phòng

Nếu đã tìm thấy phòng tốt, dù do tự tìm kiếm hay thông qua bạn bè, bạn có thể dùng ISteamMatchmaking::JoinLobby và đợi kết quả của lệnh gọi LobbyEnter_t. Khi đã vào phòng, bạn sẽ muốn dùng API dữ liệu phòng để lấy thông tin chi tiết về nó và tính toán xem nên hiển thị những gì (nếu có).

Khi người dùng vào hoặc rời phòng, lệnh callback LobbyChatUpdate_t được gửi đến mọi thành viên trong phòng, kể cả chủ phòng.

Để lặp lại tin người dùng nào hiện trong phòng chờ, dùng:

Để lấy thêm thông tin về người dùng khác trong phòng chờ, bạn sẽ cần đến API bạn bè, xem Bạn bè, lời mời, và phòng chờ để biết thêm thông tin.

Metadata của phòng chờ

Metadata của phòng chờ cho phép bạn thiết lập trạng thái phòng chờ, bao gồm tên phòng, màn chơi hiện tại, chế độ, tình trạng trận đấu, hoặc bất kỳ thứ gì khác bạn có thể nghĩ đến.

Người dùng sẽ tự động có dữ liệu mới nhất của phòng chờ mà họ là thành viên. Với phòng chờ được trả về qua kết quả tìm kiếm, người dùng sẽ có dữ liệu phòng tại thời điểm họ thực hiện tìm kiếm. Nếu đó là phòng chờ của bạn bè, sẽ không có dữ liệu nào cho đến khi ISteamMatchmaking::RequestLobbyData được gọi và thực hiện thành công.

Nếu phòng thay đổi dữ liệu, mọi thành viên trong phòng sẽ nhận lệnh callback LobbyDataUpdate_t (lệnh callback này giống như cách bạn biết lệnh gọi ISteamMatchmaking::RequestLobbyData đã hoàn tất).

Đây là bộ chức năng bạn có thể dùng để lấy và đặt dữ liệu phòng chờ. Chỉ chủ phòng mới có thể đặt hoặc xóa dữ liệu phòng.

Các chức năng cho phép bạn lặp lại qua metadata, (thông thường dùng cho mục đích gỡ lỗi):

Với các chức năng sau, phòng chờ cho phép thành viên tự đặt metadata mà thành viên có thể nhận cập nhật từ đó.

Giao tiếp bên trong phòng chờ

Để gửi thông tin trong phòng chờ (tin nhắn trò chuyện, tín hiệu bắt đầu trận, v.v...) bạn cần gọi ISteamMatchmaking::SendLobbyChatMsg, hành động này gửi một thông điệp nhị phân đơn giản đến toàn bộ người dùng trong phòng. Thành viên trong phòng cần phải nghe lệnh callback ISteamMatchmaking::LobbyChatMsg_t. Sau khi nhận lệnh callback, bạn có thể dùng ISteamMatchmaking::GetLobbyChatEntry để lấy
nội dung của thông điệp.

Bạn bè, lời mời, và phòng chờ

Đây là API bạn bè để tìm mọi phòng chờ mà bạn bè của người dùng đang tham gia:
int cFriends = SteamFriends()->GetFriendCount( k_EFriendFlagImmediate ); for ( int i = 0; i < cFriends; i++ ) { FriendGameInfo_t friendGameInfo; CSteamID steamIDFriend = SteamFriends()->GetFriendByIndex( i, k_EFriendFlagImmediate ); if ( SteamFriends()->GetFriendGamePlayed( steamIDFriend, &friendGameInfo ) && friendGameInfo.m_steamIDLobby.IsValid() ) { // friendGameInfo.m_steamIDLobby là một phòng chờ hợp lệ, bạn có thể tham gia phòng đó hoặc dùng RequestLobbyData() để lấy metadata của nó } }

Bạn có thể mời một người bạn vào phòng chờ với ISteamMatchmaking::InviteUserToLobby
Người dùng đó sẽ nhận hộp thoại với liên kết để tham gia trận đấu. Nếu người dùng nhấp vào liên kết, và đang không đang chạy trò chơi, nó sẽ khởi chạy trò chơi với dòng lệnh sau:
+connect_lobby <64-bit lobby id>. Hãy đảm bảo ứng dụng của bạn thực hiện ISteamApps::GetLaunchCommandLine để bạn có thể tắt cảnh báo popup khi khởi chạy qua một dòng lệnh.

Nếu người dùng đã ở trong phiên chơi, hệ thống sẽ gửi callback (gọi lại) ISteamFriends::GameLobbyJoinRequested_t, bao gồm thông tin SteamID của phòng chờ mà người chơi muốn tham gia. Trò chơi của bạn sẽ quyết định có tuân thủ lệnh đó hay không.

Nếu bạn muốn người dùng chọn từ danh sách bạn bè để mời vào phòng chờ, bạn có thể gọi ISteamFriends::ActivateGameOverlayInviteDialog.
Nó sẽ kích hoạt lớp phủ Steam trong trò chơi với hộp thoại được thiết kế để mời bạn bè vào phòng hiện tại.

Xác thực

Người dùng nào trong phòng chờ Steam cũng đã được xác thực đầy đủ với back-end của Steam. Thường thì không cần thiết thực hiện thêm các khâu xác thực khác với người dùng phòng chờ, trừ khi để kiểm tra xem họ có bị cấm VAC hay không (xem tài liệu về công nghệ Valve Anti-Cheat). Nếu một người dùng tìm cách đăng nhập từ địa điểm thứ hai với cùng tài khoản, đăng nhập trước đó sẽ tự động bị gỡ bỏ khỏi bất kỳ phòng chờ nào hiện có.

Dọn dẹp

Khi trận đấu bắt đầu, mỗi người dùng có thể rời phòng chờ với:
ISteamMatchmaking::LeaveLobby
Khi toàn bộ người dùng đã rời đi, phòng chờ tự động hủy trên back-end.

Mẹo về phòng chờ

  • Nói chung, chỉ tạo phòng chờ khi cần. Ví dụ, nếu người dùng mời bạn bè vào chơi, hoặc kích hoạt một thao tác thủ công cần đến phòng chờ
  • Đừng cập nhật metadata trên phòng chờ với tần suất cao. Chỉ thêm vào metadata và các giá trị được dùng cho việc tìm kiếm (ví dụ, loại trò chơi hoặc trạng thái trận đấu). Bạn sẽ không cần thêm vào số lượng người chơi, vì chức năng kiếm phòng đã tìm các phòng với số ô còn trống
  • Đừng vào phòng chờ chỉ để tìm metadata của chúng. Metadata phòng chờ của mọi phòng chờ có thể được tải về riêng biệt, sau đó trò chơi có thể dùng nó để hiện danh sách phòng chờ cho người dùng chọn, hoặc trò chơi có thể tự động quyết định kết quả tìm kiếm nào được đưa vào

Bạn còn thắc mắc?

Hãy gửi thắc mắc lên [ url=http://steamcommunity.com/groups/steamworks/discussions/5]diễn đàn thảo luận xếp trận & phòng chờ Steam[/url].