GodotSteaam 教學 #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,這時才能開始傳輸遊戲封包(移動、攻擊等資料)。
本篇目標:寫一個簡單的介面,讓 A 電腦按下「建立」,B 電腦可以搜尋到 A 電腦的大廳
第一步:介面準備 (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. 初始化與訊號綁定 (_ready 與 _process)
綁定訊號:當按鈕被按下或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. 建立大廳與設定 (_create_lobby 與 _on_lobby_created)
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. 搜尋大廳與過濾條件 (_find_lobbies)
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 與加入大廳 (_on_lobby_match_list)
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。

- 因為我們使用的是 GodotSteam Pre-compiled 版本,匯出時不能使用 Godot 內建的模板。請確認你已下載對應版本的 Export Templates(下載傳送門)。

- 在 Custom Template 欄位手動選擇下載好的執行檔路徑。

- 匯出完成後,你會看到
exe和pck檔案。需手動將steam_api64.dll複製到跟exe同個資料夾中。

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

小結
在這次測試中時發現一個麻煩點:每次改一點程式碼,就必須重新匯出、複製檔案、傳給另一台電腦測試。這在開發初期非常浪費時間。
因此,下一篇文章我們將介紹 Godot High Level Networking 的架構。我們將學習如何利用 Godot 內建的網路功能,先在本地端快速開發與測試多人連線邏輯,等到功能完善後,再套上 Steam 進行遠端連線。