無所屬單位

首頁 文獻與幫助
Steamworks 文獻庫
Steamworks API 總覽

英文原文已更新

本頁原文在翻譯完成後已再次更新。\r
點擊這裡檢視最新的英文版本。

總覽

透過 Steamworks API,您的遊戲可最大限度地善用 Steam 附帶的系統,包括開啟 Steam 內嵌介面時暫停遊戲、邀請好友加入遊戲、解鎖 Steam 成就、在 Steam 排行榜上互相較量,和更多豐富的功能。

Steamworks API Reference中分類並紀錄了 API 支援的所有介面、函式、回呼,和型別的資訊。

將產品送上 Steam 時,並不要求必須整合 Steamworks API,但我們依然強烈建議整合,因為當中包含許多 Steam 使用者預期會有的互動功能。

準備開始

備註:Steamworks API 正式支援 Microsoft Windows 上 Visual Studio 2008+ 的 C++,以及在 macOS 和 SteamOS / Linux 上的 GCC 4.6 + 以及 Clang 3.0+。如果您使用的是 C++ 以外的第三方引擎或程式語言,請先參閱對商業引擎和非 C++ 語言的支援了解您所選的引擎或語言是否需要特別的準備措施。根據個別的情況,可能有許多步驟能省略。

  • 如果尚未下載,請先下載 Steamworks SDK 並解壓縮檔案
  • 將 Steamworks API 標頭資料夾 public/steam 複製至您的應用程式來源樹中適當的位置
  • 將下列其中一個標頭檔引入您的 C++ 專案中
    • steam_api.h – 引入所有 Steamworks 標頭,以及提供初始化 Steamworks API 所需的進入點
    • steam_gameserver.h - 只有在使用 Steam 遊戲伺服器 API 時才需要引入此檔案。由於內部已引入了 steam_api.h,所以不須兩份都引入
  • redistributable_bin 複製相關的可轉散發檔案至您的專案資料夾中適當的位置
    • Windows
      您須將 steam_api[64].lib 連結至您的 Visual Studio 專案。可以連結至主要的執行檔或使用 Steam 的模組。這讓您可以使用 steam_api[64].dll 中由 Steamworks API 標頭開放取用的功能。相關文章,請參閱將可執行檔連結至 DLL(MSDN)一文。

      另外,您必須將 steam_api[64].dll 放入執行階段路徑中(在程式執行檔旁邊,或是在 DLL 搜尋路徑中)才能發行程式。
    • macOS
      libsteam_api.dylib 提供了 x86 和 x64 兩種版本的 Steam API。您須將此檔案連結至 XCode 專案,並與執行檔一同釋出。
      相關文章,請參閱:Using Dynamic Libraries(使用動態程式庫)
    • Linux
      您需將 libsteam_api.so 連結至執行檔,並一同釋出。

初始化與關閉

SteamAPI_Init

在您的專案內設置好 Steamworks API 後,便可開始呼叫 SteamAPI_Init 函式來初始化 API 了。這將建立全域狀態並填入介面指標,隨後便可使用與介面名稱相同的全域函式存取介面指標了。要使用任何 Steamworks 介面之前,必須先呼叫該函式並傳回成功!

若 Steamwork API 不知道您遊戲的 App ID,便無法初始化。如果是從 Steam 本身啟動應用程式,便會自動取得有效的 App ID。開發過程中,您會需要以文字檔向 Steam 提示 App ID。請在您的執行檔旁邊建立一個名為 steam_appid.txt 的文字檔,當中除了 App ID 以外不要輸入任何文字。這將覆寫 Steam 所提供的值。請確保不要將此檔案與組建一同釋出。檔案範例:
480

如果傳回 False 則代表發生了下列其中一種狀況:
  • Steam 用戶端不在運作中。必須執行 Steam 才可實作各種 Steamworks 介面
  • Steam 用戶端無法得知遊戲的 App ID。如果您是直接從執行檔或偵錯程式啟動應用程式,則必須在遊戲路徑中的執行檔旁邊放置一個 steam_appid.txt,當中除了 App ID 以外不要輸入任何文字。Steam 將從目前執行的路徑中尋找此檔案。如果您是從別的路徑開啟執行檔,steam_appid.txt 也必須跟著移動
  • 應用程式所執行的作業系統使用者內容與 Steam 用戶端不相符,例如不同的使用者或管理員存取權限
  • 請確定您目前使用中的 Steam 帳戶持有該 App ID 的授權。您的遊戲必須出現於 Steam 收藏庫中
  • 您的 App ID 並未設置完全,也就是說尚在發行狀態:無法使用的階段,或是缺失了預設套件
如果您在初始化時遇到了問題,有關各種偵錯方法的資訊請參閱 Steamworks API 偵錯一文。

SteamAPI_RestartAppIfNecessary

SteamAPI_RestartAppIfNecessary 將檢查您的執行檔是否是由 Steam 啟動的,若不是便改從 Steam 重新啟動。

雖然非必要,但我們強烈建議這麼做,假如使用者直接從執行檔啟動,便沒辦法設置應用程式相關的 Steam 內容(包括 App ID)。如此一來,SteamAPI_Init 便會失敗,也就無法使用 Steamworks API。
若您決定要檢查,這則須是您第一個呼叫的 Steamworks 函式,於 SteamAPI_Init 之前。

如果傳回了 True,有需要的話便會開啟 Steam 用戶端,並通過用戶端再次啟動遊戲,您則必須盡快退出處理程序。此函式有效利用了 steam://run/<AppID>,所以並不一定會再次啟動呼叫它的執行檔(例如說,從偵錯工具啟動的)。此函式永遠會重新啟動 Steam 收藏庫資料中的版本。

相反地,如果傳回了 False,則表示您的遊戲是從 Steam 用戶端啟動的,不須採取任何動作,除了一項例外。如果 steam_appid.txt 檔案存在,那麼無論如何都會傳回 False。如此一來,開發和測試遊戲時便不需要從 Steam 用戶端啟動遊戲。將遊戲上傳至 Steam Depot 時,記得要把 steam_appid.txt 移除!

備註:如果您在主要的執行檔上包裝了 DRM,便不需要如此進行檢查了,因為 DRM 的包裝函式會在內部進行檢查。

SteamAPI_Shutdown

使用完 Steamworks API 後,您應呼叫 SteamAPI_Shutdown 來釋放您的應用程式在 Steam 內部使用的資源。如果適當的話,您應在關閉過程中呼叫此函式。

此舉並不會取消您的遊戲掛勾 Steam 內嵌介面,因為無法保證您的渲染 API 不再需要內嵌介面。

Steamworks 介面

Steamworks API 是由多個介面所組成,各個介面皆帶有數量有限的特定功能。

成功初始化 Steamworks 後,便可透過各自的全域函式取用 Steamworks 介面。而全域函式的名稱永遠會與介面相同。例如,通過 SteamApps() 存取子即可使用 ISteamApps、而 SteamFriends() 便是連結至 ISteamFriends

利用這些介面,可如此進行呼叫:
// 取得目前使用者的 Steam 名稱 const char *name = SteamFriends()->GetPersonaName();

如需介面的完整列表,請參閱 Steamworks API Reference,或查閱 Steamworks API 的標頭檔。

回呼

回呼是 Steamworks 中極其重要的一部份,能在不鎖定遊戲的狀況下,以非同步的方式從 Steam 取得資料。回呼的目的是用來提供一個簡易、輕便、能夠避免型別與執行序錯誤的方式,在任何登記為監聽程式的物件上引發非同步的事件。

回呼通常是由 Steam 上的事件觸發,例如好友登入或登出 Steam,或是從 API 函式傳來的非同步結果。每個回呼的結構皆包含了一個唯一識別碼和少許的資料。回呼會在 ISteam*.h 中宣告,與最相近的介面組成一組。

要監聽回呼,宣告結構或類別時須使用 STEAM_CALLBACK( :classname, :functionname, :callbackname ) 巨集。
  • :classname 須為定義時所在的結構或類別名稱(例:CGameManager
  • :functionname 為接收回呼的函式名稱(例:OnGameOverlayActivated
  • :callbackname 為回呼的名稱(例:GameOverlayActivated_t
如此便在該類別中定義了區域成員,而原型將被自動設置為 void :functionname( :callbackname *pCallback )。建立了物件的新執行個體,便會導致成員函式將自己登錄為監聽 Steamworks API;毀滅物件便會取消登錄。

備註:建立監聽回呼的物件前,請先確定 Steam 已初始化。

呼叫 SteamAPI_RunCallbacks 即可將回呼分配給其下的監聽程式。由於呼叫的間隔越長,收到事件或 Steamworks API 結果的延遲就越長,所以最好經常呼叫。絕大部分遊戲是每次渲染影格便呼叫一次,而我們強烈建議您至少每秒要呼叫一次。該呼叫會一次叫用所有登錄的監聽函式,從呼叫 SteamAPI_RunCallbacks 的執行序內容層面發出。

範例

有一個很可能會用到的回呼是 ISteamFriends::GameOverlayActivated_t。如同其名所表示,每當使用者開啟或關閉 Steam 內嵌介面,便會傳送一個回呼給您。

class CGameManager { private: STEAM_CALLBACK( CGameManager, OnGameOverlayActivated, GameOverlayActivated_t ); }; void CGamemanager::OnGameOverlayActivated( GameOverlayActivated_t* pCallback ) { if ( pCallback->m_bActive ) printf( "Steam overlay now active\ " ); else printf( "Steam overlay now inactive\ " ); }

ISteamFriends::GameOverlayActivated_t 常見且推薦的用法是開啟內嵌介面時要暫停遊戲。

CallResults(呼叫結果)

許多 Steamworks 方法不使用回呼,而是使用呼叫結果來非同步地傳回呼叫函式的結果。回呼與呼叫結果的差別是,回呼會廣播給所有監聽程式,而呼叫結果只會傳給一個特定的監聽程式。和回呼一樣,您的遊戲須呼叫 SteamAPI_RunCallbacks 將呼叫結果分配給各個監聽程式。

您可透過傳回的值來判斷函式是否提供的是呼叫結果。如果傳回的是有 CALL_RESULT() 屬性的 SteamAPICall_t,那麼便必須登錄為獲取呼叫結果。

備註:回呼與呼叫結果無法通用。事件只會通過一種方式傳來,而不會兩種一起使用。您須確認自己登錄了正確的事件類型!

呼叫結果須使用 CCallResult 型別,建立為某個結構或類別的成員,用來接收回呼的成員函式也須一起建立。
void func( :callresultname *pCallback, bool bIOFailure ); CCallResult< :classname, :callresultname > m_callresultname;
  • :classname 須為定義時所在的結構或類別名稱(例:CGameManager
  • :callresultname 為回呼的名稱(例:NumberOfCurrentPlayers_t

您可依自己的想法任意命名函式、函式參數,和 CCallResult 型別。

範例

下為使用 ISteamUserStats::GetNumberOfCurrentPlayers API 的實際範例,產生的呼叫結果為 ISteamUserStats::NumberOfCurrentPlayers_t
// 在類別定義中 class CGameManager { public: void GetNumberOfCurrentPlayers(); private: void OnGetNumberOfCurrentPlayers( NumberOfCurrentPlayers_t *pCallback, bool bIOFailure ); CCallResult< CGameManager, NumberOfCurrentPlayers_t > m_NumberOfCurrentPlayersCallResult; }; // 發出不同步要求,以取得目前的玩家人數 void CGameManager::GetNumberOfCurrentPlayers() { printf( "Getting Number of Current Players\ " ); SteamAPICall_t hSteamAPICall = SteamUserStats()->GetNumberOfCurrentPlayers(); m_NumberOfCurrentPlayersCallResult.Set( hSteamAPICall, this, &CGameManager::OnGetNumberOfCurrentPlayers ); } // 呼叫 SteamAPI_RunCallbacks() 並收到 SteamUserStats()->GetNumberOfCurrentPlayers() 的不同步傳回時,進行此呼叫 void CGameManager::OnGetNumberOfCurrentPlayers( NumberOfCurrentPlayers_t *pCallback, bool bIOFailure ) { if ( bIOFailure || !pCallback->m_bSuccess ) { printf( "NumberOfCurrentPlayers_t failed!\ " ); return; } printf( "Number of players currently playing: %d\ ", pCallback->m_cPlayers ); }

備註:如果您無法使用 CCallResult 系統,或許可以改用 ISteamUtils::IsAPICallCompletedISteamUtils::GetAPICallResult,和 ISteamUtils::GetAPICallFailureReason 來追蹤呼叫結果的狀態。

Steam 遊戲伺服器

Steamworks API 可像一般支援用戶端一樣地支援遊戲伺服器。在 Steamworks API 中,遊戲伺服器是系統中的一個實體,讓一般使用者可與其連線並遊玩多人遊戲。方法可以是從網路連線至遠端的遊戲伺服器,或連線至本地、與用戶端在同一個處理程序的遊戲伺服器。遊戲伺服器有自己的 API 函式,以及讓使用者可以查詢到的唯一 Steam ID。

要使用 Steam 遊戲伺服器 API,您須先引入 steam_gameserver.h 而非 steam_api.h

遊戲伺服器 API 的初始化與使用方法與一般 API 非常相似:

初始化完成後,便可使用兩個遊戲伺服器專用的介面,ISteamGameServerISteamGameServerStats

另外,遊戲伺服器也可使用下列的一般介面:
  • ISteamClient,將改用此全域介面:SteamGameServerClient()
  • ISteamUtils,將改用此全域介面:SteamGameServerUtils()
  • ISteamNetworking,將改用此全域介面:SteamGameServerNetworking()
  • ISteamHTTP,將改用此全域介面:SteamGameServerHTTP()
  • ISteamInventory,將改用此全域介面:SteamGameServerInventory()
  • ISteamUGC,將改用此全域介面:SteamGameServerUGC()
  • ISteamApps,將改用此全域介面:SteamGameServerApps()

如果是專屬遊戲伺服器(沒有用戶端要素),便只需要初始化遊戲伺服器 API,不須初始化一般的使用者 API。

如需遊戲伺服器 API 的完整實例,請參閱 Steamworks API 範例應用程式(SpaceWar)

對商業引擎和非 C++ 語言的支援

如果您使用的是商業引擎或 C 或 C ++ 以外的語言,便需要先知道對 Steamworks API 的支援程度。
部分引擎自己便提供了內建支援,另外則可能得使用第三方的解決方式。

如果您的引擎沒有原生支援,可改從 Steam Web API 取用 Steam 所支援的功能。

無論您的引擎如何實作 Steamworks SDK,當中都需要有最新版本的 Steamworks SDK,才能將應用程式上傳至 Steam

備註 :如果您要放上 Steam 的部分軟體適用於受限的開源授權條款,請參閱於 Steam 上分銷開源應用程式一文。

以下為 Steam 上遊戲常用的引擎,以及如何在當中使用 Steamworks SDK 的相關文檔。

備註:Valve 不會以任何形式替下列任何引擎或第三方解決方案背書。清單僅依照名稱排列,資訊並不全面,僅用來當作初次著手的指南。只有帶有原生支援或符合規範的第三方解決方案的引擎會出現在列表中。而第三方解決方案必須與 Steamworks SDK 保持合理程度的更新、可於寬鬆的授權條款下自由使用(請參閱:於 Steam 上分銷開源應用程式一文),並且在 Steamworks 討論區已有討論串。我們建議您向社群諮詢您的情況最適用何種選項。

引擎:

引擎原生支援?資訊
CRYENGINE✔️
GameMaker Studio 2✔️Using The Steamworks SDK With GameMaker: Studio
Godot第三方:GodotSteam - Steamworks 開發者討論區支援討論串
Haxe第三方:SteamWrap - Steamworks 開發者討論區支援討論串
Leadwerks Game Engine✔️Leadwerks API Reference › Steamworks
RPG Maker MV第三方:Greenworks - Steamworks 開發者討論區支援討論串
Source 2013✔️分銷 Source 引擎遊戲
Unity第三方:Facepunch.Steamworks - Steamworks 開發者討論區支援討論串
第三方:http://steamworks.github.io - Steamworks 開發者討論區支援討論串
Unreal Engine 4✔️Steam, Using the Steam SDK During Development
Visionaire Studio✔️Publish on Steam

程式語言:

技術細節

Steam 使用了各種層面的技術讓您的應用程式能接觸到各式功能。雖然瞭不瞭解 Steamworks API 實際的運作方式並不關鍵,但本身其實並不複雜,而在計畫如何編寫您的遊戲並整合 Steam 功能時,可能派得上用場。

連結至 steam_api[64][.dll/.so/dylib] 便可取用公開於 steam_api.hsteam_gameserver.h 之中、前置為 S_API 巨集的少數 C 函式steam_api 模組本身非常小,只有初始和關閉 Steamworks API 的基本功能。

Steamworks API 初始化時會找到正在運作的 Steam 用戶端處理程序並從其路徑中載入 steamclient.dll,也就是 Steam 用戶端的引擎核心,當中承載並管理著執行 Steam 所需的資訊。Steam 用戶端使用者介面便是利用類似的函式存取 steamclient.dll 提供的資料。由於資料是存於 Steam 處理程序之中,所有 Steam API 呼叫皆是透過 RPC/IPC 機制(一個交叉處理管道,ISteamClient::HSteamPipe)透明地封送。

Steam 處理程序透過 steamclient.dll 與 Steam 後端伺服器保持不斷的連線,進行所有授權、遊戲配對、好友名單,和 VAC 的相關通訊。如果使用者的網路出現問題,或連線的 Steam 伺服器收到了更新,該連線便會中斷。每當連線中斷或重新連線時,便會將回呼發送給所有執行中的應用程式。Steam 用戶端會自動嘗試重新連線,以正在執行應用程式的用戶端為最優先,所以一般來說重新連線的時間不會超過 10 秒,雖然在某些罕見的狀況下是有長達 5 分鐘的可能。

Steamworks API 的版本是通過類似 COM 的機制來管理的。也就是說將一個字串名稱和介面版本傳入 steamclient.dll,隨後便會將介面的正確版本傳回給呼叫者。steamclient.dll 中有介面所有已釋出版本的配接器,可以將舊的呼叫重新導向或解讀成符合最新版本介面的形式。配接器是存於 Steam 用戶端中,方便出現問題時更新。