GodotSteam 教學 #2:建立與加入大廳 (Lobby)
完整範例及程式碼點擊連結前往:
GitHub - peterho2022/godotsteam-tutorial
Contribute to peterho2022/godotsteam-tutorial development by creating an account on GitHub.
在上一篇文章中,我們成功初始化了 Steam API,讓 Godot 能順利讀取玩家的 Steam ID。今天,我們將邁出多人連線的關鍵下一步:建立大廳 (Lobby)。 你可以把「大廳」想像成遊戲的聊天室或等候室,它的運作流程非常簡單:
- 房主 (Host) 建立一個大廳。
- 玩家 (Client) 搜尋並加入這個大廳。
- 當雙方都在大廳會合並交換 Steam ID 後,才能開始傳輸實質的遊戲資料(如角色移動、攻擊等封包)。

第一步:介面準備 (UI)
首先要建立大廳的場景。新增一個 CanvasLayer 作為根節點,節點結構如下:
- CanvasLayer (LobbyRoom)
- Button (RefreshButton) : 按下刷新頁面
- VBoxContainer (LobbyListContainer) : 用來放搜尋到的房間按鈕
- Button (CreateLobbyButton) : 按下建立大廳

第二步:撰寫腳本
將腳本掛到根節點上,完整程式碼如下。
extends CanvasLayer
@onready var lobby_list_container: VBoxContainer = $LobbyListContainer
@onready var refresh_button: Button = $RefreshButton
@onready var create_lobby_button: Button = $CreateLobbyButton
func _ready() -> void:
# 初始化 Steam (建議在專案啟動時就全域執行,但寫在這裡方便教學演示)
# 設定 App ID,480 是開發用的 Spacewar
OS.set_environment("SteamAppId", str(480))
OS.set_environment("SteamGameId", str(480))
var initialize_response: Dictionary = Steam.steamInitEx()
Steam.lobby_match_list.connect(_on_lobby_match_list)
Steam.lobby_created.connect(_on_lobby_created)
refresh_button.pressed.connect(_find_lobbies)
create_lobby_button.pressed.connect(_create_lobby)
func _process(_delta: float) -> void:
Steam.run_callbacks()
func _find_lobbies():
for child in lobby_list_container.get_children():
child.queue_free()
Steam.addRequestLobbyListDistanceFilter(Steam.LOBBY_DISTANCE_FILTER_WORLDWIDE)
# 如果沒有過濾會出現所有正在測試的房間
# Steam.addRequestLobbyListStringFilter("game", "Peter's Game", Steam.LOBBY_COMPARISON_EQUAL)
Steam.requestLobbyList()
func _on_lobby_match_list(lobbies: Array):
for lobby_id in lobbies:
var lobby_name = Steam.getLobbyData(lobby_id, "name")
var btn = Button.new()
btn.text = "房間: %s" % lobby_name
btn.pressed.connect(Steam.joinLobby.bind(lobby_id))
lobby_list_container.add_child(btn)
func _create_lobby():
Steam.createLobby(Steam.LOBBY_TYPE_PUBLIC, 4)
func _on_lobby_created(connect_result: int, lobby_id: int):
if connect_result == 1:
Steam.setLobbyData(lobby_id, "name", Steam.getPersonaName())
Steam.setLobbyData(lobby_id, "game", "Peter's Game")程式碼可以拆成四個部分來理解:初始化設定、建立大廳、搜尋大廳 以及 顯示與加入大廳。
1. 初始化與訊號綁定
綁定訊號:當按鈕被按下或Steam 搜尋完成時,要執行哪個函式。
extends CanvasLayer
@onready var lobby_list_container: VBoxContainer = $LobbyListContainer
@onready var refresh_button: Button = $RefreshButton
@onready var create_lobby_button: Button = $CreateLobbyButton
func _ready() -> void:
# 初始化 Steam (建議在專案啟動時就全域執行,但寫在這裡方便教學演示)
# 設定 App ID,480 是開發用的 Spacewar
OS.set_environment("SteamAppId", str(480))
OS.set_environment("SteamGameId", str(480))
var initialize_response: Dictionary = Steam.steamInitEx()
Steam.lobby_match_list.connect(_on_lobby_match_list)
Steam.lobby_created.connect(_on_lobby_created)
refresh_button.pressed.connect(_find_lobbies)
create_lobby_button.pressed.connect(_create_lobby)
func _process(_delta: float) -> void:
Steam.run_callbacks()2. 建立大廳與設定
func _create_lobby():
# 建立一個公開大廳,人數上限 4 人
Steam.createLobby(Steam.LOBBY_TYPE_PUBLIC, 4)
func _on_lobby_created(connect_result: int, lobby_id: int):
if connect_result == 1:
Steam.setLobbyData(lobby_id, "name", Steam.getPersonaName())
Steam.setLobbyData(lobby_id, "game", "Peter's Game")當呼叫 Steam.createLobby 成功後,Steam 會觸發 _on_lobby_created。
- 關鍵步驟:我們使用
Steam.setLobbyData給房間貼上標籤。 - "name":顯示給玩家看的房名。
- "game":這是一個隱藏標籤,用來標記「這是 Peter 的遊戲」。這在下一步搜尋時非常重要。
3. 搜尋大廳與過濾條件
func _find_lobbies():
# 每次搜尋前,先把舊的清單清空
for child in lobby_list_container.get_children():
child.queue_free()
Steam.addRequestLobbyListDistanceFilter(Steam.LOBBY_DISTANCE_FILTER_WORLDWIDE)
# 如果沒有過濾會出現所有正在測試的房間
# Steam.addRequestLobbyListStringFilter("game", "Peter's Game", Steam.LOBBY_COMPARISON_EQUAL)
Steam.requestLobbyList()這裡使用了 Steam.addRequestLobbyListStringFilter。
- 由於 480 是 Steam 官方的測試 ID。如果沒有過濾,可能搜尋出幾百個房間。

4. 動態生成 UI 與加入大廳
func _on_lobby_match_list(lobbies: Array):
for lobby_id in lobbies:
var lobby_name = Steam.getLobbyData(lobby_id, "name")
var btn = Button.new()
btn.text = "房間: %s" % lobby_name
btn.pressed.connect(Steam.joinLobby.bind(lobby_id))
lobby_list_container.add_child(btn)當搜尋結果回來 (_on_lobby_match_list),我們用 for 迴圈顯示出所有房間。
第三步:匯出和測試
- 準備環境: 需要兩台電腦。兩邊都要登入 Steam 帳號。
- 匯出專案:點選
Project->Export。

- 使用指定的 template
因為我們使用的是 GodotSteam Pre-compiled 版本,必須下載對應版本的 Custom Template (下載傳送門)。

- 在 Export 視窗的 Custom Template 欄位手動選擇該檔案。

- 匯出完成後,請務必手動將
steam_api64.dll複製到與.exe同一個資料夾中,否則遊戲執行時會無法啟動 Steam API!

steam_api64.dll- 將整包資料夾傳給另一台電腦。
- 電腦 A:執行遊戲 -> 點擊「建立大廳」。
- 電腦 B:執行遊戲 -> 點擊「搜尋大廳」。
- 如果你在列表中看到了按鈕,並成功點擊加入,恭喜你!兩台電腦已經透過 Steam 成功連線了。

小結
在這次的測試過程中,你可能會發現一個麻煩的痛點:每次只要修改一點程式碼,就必須重新匯出、複製檔案、再傳給另一台電腦測試。 這在開發初期非常消耗時間。
為了解決這個問題,下一篇文章我們將介紹 Godot High Level Networking 的架構。利用 本地端 快速開發與測試多人連線邏輯,等到功能完善後,再利用 Steam 連線。