[轉(zhuǎn)載] 原文鏈接:https://partner.steamgames.com/doc/features/achievements
概覽
Steam 統(tǒng)計和成就為您的游戲提供了一種簡便的方式,持續(xù)并動態(tài)追蹤用戶的成就與統(tǒng)計數(shù)據(jù)。 用戶的數(shù)據(jù)將與 Steam 帳戶相關(guān)聯(lián)阐斜,而每項成就與統(tǒng)計數(shù)據(jù)皆可依固定的格式顯示于用戶的 Steam 社區(qū)個人資料之中牢硅。
有什么好處
除了向您的游戲玩家提供高價值的獎勵之外宙枷,成就也很適合用于鼓勵和獎勵團(tuán)隊合作或玩家互動送挑、加深游戲目標(biāo)的層次千元,并且玩家會因在游戲上花更多時間得到獎勵屯远。
統(tǒng)計數(shù)據(jù)則記錄了許多精細(xì)的信息蔓姚,像是游戲時間、使用的能量增強(qiáng)物品的數(shù)量等等慨丐。 您可將它們僅用于記錄內(nèi)部游戲數(shù)據(jù)坡脐,以便從多臺電腦收集多重會話的游戲統(tǒng)計數(shù)據(jù),為用戶授予成就房揭。
實(shí)現(xiàn)概覽
定義游戲的統(tǒng)計與成就
成就專屬于各個應(yīng)用程序备闲,必須使用 Steamworks 合作伙伴站點(diǎn)的應(yīng)用管理頁面進(jìn)行設(shè)置晌端。
您可直接從 此處 前往統(tǒng)計配置頁面,或從 此處 前往成就配置頁面浅役。
可儲存的統(tǒng)計類型有三種:
INT - 32 位(帶正負(fù)號的)整數(shù)(例如游戲次數(shù))
FLOAT - 32 位的浮點(diǎn)值(例如駕駛里程數(shù))
AVGRATE - 移動平均數(shù)斩松。 詳見:AVGRATE 統(tǒng)計類型
Steamworks 合作伙伴站點(diǎn)的接口可供您定義和更新游戲統(tǒng)計和成就,具體用途為:
定義初始統(tǒng)計與成就
增加額外統(tǒng)計與成就
更新成就名稱觉既、描述惧盹,和圖標(biāo)
更新統(tǒng)計的參數(shù)與限制(最大 / 最小值、移動平均窗口大小等等)
統(tǒng)計具有下列屬性:
ID - 每項統(tǒng)計自動產(chǎn)生的數(shù)字 ID
類型 此項統(tǒng)計的類型 - INT 瞪讼、 FLOAT 钧椰,或 AVGRATE
API 名稱 - 用來訪問此項成就的 API 字符串
設(shè)置人- 設(shè)定誰能修改這項統(tǒng)計,默認(rèn)為客戶端符欠。 更多信息請見 游戲服務(wù)器統(tǒng)計數(shù)據(jù) 文檔嫡霞。
僅限增量– 設(shè)置后,此統(tǒng)計數(shù)值便只能隨著時間增加
最大變更- 設(shè)置后希柿,每次調(diào)用一個 SetStat 到下一個 Setstat 時诊沪,此項統(tǒng)計的數(shù)值能改變的最大值
最小值- 設(shè)置后,此項成就能接受的最小數(shù)值曾撤,默認(rèn)最小值是基本數(shù)值類型的最小值( INT_MIN 或 -FLT_MAX )端姚。
最大值- 設(shè)置后,此項成就能接受的最大數(shù)值挤悉,默認(rèn)最大值是基本數(shù)值類型的最大值( INT_MAX 或 FLT_MAX )渐裸。
默認(rèn)值- 設(shè)置后,新用戶初始設(shè)置的默認(rèn)統(tǒng)計數(shù)值装悲。 如果沒有設(shè)置昏鹃,默認(rèn)值則為零。
合計– 設(shè)置后诀诊, Steam 將記錄此項統(tǒng)計的全球統(tǒng)計洞渤。 更多信息,請見下方的全球統(tǒng)計属瓣。
顯示名稱- 顯示于 Steam 社區(qū)的統(tǒng)計名稱您宪。 可本地化。
AVGRATE 具有以下額外的屬性:
- 窗口 - 用來計算平均值的”滑動窗口”的大小
AVGRATE 統(tǒng)計由 Steam 自動平均得出奠涌。 請參見下文的的 AVGRATE 一節(jié),了解更多信息磷杏。
成就具有下列屬性:
ID - 每項統(tǒng)計自動產(chǎn)生的數(shù)字 ID
API 名稱- 用來訪問此項成就的 API 字符串
進(jìn)度狀態(tài)- 指定一項統(tǒng)計數(shù)據(jù)溜畅,作為此項成就在社區(qū)中的顯示進(jìn)度指示器。 當(dāng)統(tǒng)計數(shù)值達(dá)到解鎖值時极祸,成就將自動解鎖
顯示名稱- 出現(xiàn)于客戶端彈出通知和社區(qū)的顯示名稱慈格。 可本地化
**描述 **- 社區(qū)中關(guān)于此項成就的描述怠晴。 可本地化
設(shè)置人- 設(shè)定誰能解鎖此項成就。 默認(rèn)是客戶浴捆。 請參見 游戲服務(wù)器統(tǒng)計數(shù)據(jù) 蒜田,了解更多信息。
隱藏- 如勾選选泻,”隱藏”成就在達(dá)成之前則完全不會顯示于用戶的社區(qū)頁面中
已達(dá)成圖標(biāo)- 達(dá)成成就后顯示的圖標(biāo)
未達(dá)成圖標(biāo)- 未達(dá)成成就時顯示的圖標(biāo)
以下是 Steamworks API 示例應(yīng)用程序(SpaceWar) 的成就列表:
使用方法
在游戲中訪問統(tǒng)計和成就:
初始化 Steamworks API 后冲粤,您便可開始使用 ISteamUserStats 中的統(tǒng)計與成就 API 。
游戲會話開始時页眯,調(diào)用 ISteamUserStats::RequestCurrentStats 從 Steam 后端調(diào)出用戶的統(tǒng)計與成就數(shù)據(jù)梯捕。 數(shù)據(jù)準(zhǔn)備完成后,將會收到 ISteamUserStats::UserStatsReceived_t 的回調(diào)窝撵。
使用 ISteamUserStats::GetStat 和 ISteamUserStats::GetAchievement 迭代每項數(shù)據(jù)并初始化游戲狀態(tài)
如想在游戲中顯示成就傀顾,可使用 ISteamUserStats::GetAchievementDisplayAttribute 來獲取一般可讀的成就屬性,包括名稱(” name ”)和描述(” desc ”)碌奉。 這些屬性可從 Steamworks 合作伙伴站點(diǎn)的此處進(jìn)行本地化短曾, 系統(tǒng)將根據(jù)用戶在游戲中使用的語言返回不同的數(shù)據(jù)。 您可使用 ISteamUserStats::GetAchievementIcon 取得每項成就的圖標(biāo)赐劣,或用ISteamUserStats::GetAchievementAndUnlockTime 取得每項成就的解鎖時間
每當(dāng)統(tǒng)計數(shù)值的變更呈現(xiàn)給用戶之前嫉拐,調(diào)用 ISteamUserStats::SetStat 或 ISteamUserStats::UpdateAvgRateStat 。 此調(diào)用只會改變 Steam 的內(nèi)存狀態(tài)隆豹,消耗的資源很少椭岩。即便在發(fā)生游戲崩潰的狀況下,這樣做也可以讓 Steam 保持會話之間的變更一致璃赡。
在游戲中適當(dāng)?shù)臅r候(例如檢查點(diǎn)或等級轉(zhuǎn)換)判哥,調(diào)用 ISteamUserStats::StoreStats 上傳變更。 完成后碉考,即會收到一個 ISteamUserStats::UserStatsStored_t 回調(diào)
如果成就有進(jìn)度指示器塌计,在重要時點(diǎn)可使用 ISteamUserStats::IndicateAchievementProgress 彈出進(jìn)度狀態(tài)的通知信息。 例如侯谁,如果需要20 場勝利即可達(dá)成成就锌仅,您可能需要在完成 10 場時調(diào)用此 API,提示用戶已經(jīng)完成一半了
每當(dāng)解鎖一項或幾項成就時墙贱,針對每項未解鎖成就热芹,調(diào)用 ISteamUserStats::SetAchievement 然后使用 ISteamUserStats::StoreStats 立刻上傳。 您的游戲?qū)⑹盏?ISteamUserStats::UserStatsStored_t 回調(diào)惨撇,并對每項未解鎖成就外加一個 ISteamUserStats::UserAchievementStored_t回調(diào)伊脓。 Steam 游戲界面則會向用戶顯示一個通知面板
AVGRATE 統(tǒng)計類型
此統(tǒng)計類型提供了獨(dú)特且非常有用的功能,但需要一些詳細(xì)說明魁衙。
假如您想追蹤某項平均統(tǒng)計數(shù)據(jù)报腔,例如”每小時平均得分”株搔。 一種辦法是設(shè)置兩項統(tǒng)計數(shù)據(jù),一個 INT 的”總得分”纯蛾,和 FLOAT 的”總游玩時數(shù)”纤房,然后將得分除以游玩時數(shù),得到每小時平均得分翻诉。
這個方法這的缺點(diǎn)是炮姨,一但玩家的游戲時數(shù)達(dá)到某個程度,計算出的平均值將變動得非常緩慢米丘。 實(shí)際上剑令,玩家玩得越多,平均值的反應(yīng)就越不明顯拄查。 如果玩家花了 100 個小時在游戲上吁津,得出的平均將會”延遲”大概 50 個小時。 即便他們提高了技術(shù)水平堕扶,也不會如期看到每小時平均得分的增加碍脏。
AVGRATE 統(tǒng)計類型則能讓您設(shè)置一個可影響平均值的”滑動窗口”。 舉例來說稍算,您可使用幾小時前的游戲時間數(shù)據(jù)典尾,讓統(tǒng)計數(shù)值更精確地反應(yīng)玩家目前的技術(shù)水平。
現(xiàn)在來設(shè)置一個 AVGRATE 統(tǒng)計來實(shí)現(xiàn)”每小時平均得分”糊探,而且只有過去 20 個小時的游戲才能影響數(shù)值钾埂。 方法是:
由于平均值以”每小時”計算,與此統(tǒng)計相關(guān)的時間參數(shù)的單位都是”小時”科平,例如統(tǒng)計本身的窗口屬性褥紫,和傳給
UpdateAvgRateStat
的 dSessionLength 參數(shù)創(chuàng)建一個名為” AvgPointsPerHour ”的 AVGRATE 統(tǒng)計,并將窗口屬性設(shè)置為 20.0 (謹(jǐn)記:以”小時”為單位)
-
在游戲中適當(dāng)?shù)臅r候瞪慧,調(diào)用 ISteamUserStats::UpdateAvgRateStat 并傳入下列參數(shù):
pchName – ” AvgPointsPerHour ”
flCountThisSession - 自從上次調(diào)用 UpdateAvgRateStat 后髓考,玩家所獲得的分?jǐn)?shù)
dSessionLength - 自從上次調(diào)用 UpdateAvgRateStat 后,玩家的游玩時數(shù)必須使用與窗口屬性相同的單位弃酌,在此例中氨菇,以”小時”為單位。
例如妓湘,玩家在過去 0.225 小時( 13.5 分鐘)獲得了 77 分查蓉,就會變成
SteamUserStats()-> UpdateAvgRateStat( " AvgPointsPerHour", 77, 0.225 )
在上述實(shí)例中, Steam 會將這回合的平均每小時 342.2 分( 77 除以 0.225 )與先前的數(shù)值一起計算榜贴,結(jié)果便是玩家過去 20 個小時游戲時間的平均得分奶是。 如果這是第一次為此玩家更新數(shù)據(jù),那么目前的值就是 342.2。
此實(shí)例用”小時”作為單位聂沙,但您也可使用任何其他的時間單位。請記住初嘹,您必須始終使用該單位作為”dSessionLength”的基礎(chǔ)及汉,以及窗口屬性。
取得其他玩家的統(tǒng)計數(shù)據(jù)
您可使用 ISteamUserStats::RequestUserStats 取得其他玩家的統(tǒng)計數(shù)據(jù)屯烦,然后使用 ISteamUserStats::GetUserStat 坷随、 ISteamUserStats::GetUserAchievement ,和ISteamUserStats::GetUserAchievementAndUnlockTime 取得用戶的其他數(shù)據(jù)驻龟。 由于其他玩家會不斷上傳新的統(tǒng)計數(shù)據(jù)温眉,您取得的數(shù)據(jù)并不會自動更新。 再次調(diào)用 ISteamUserStats::RequestUserStats 即可刷新數(shù)據(jù)翁狐。
為避免使用過多的內(nèi)存类溢,系統(tǒng)會維持一個近來最少使用( LRU )緩存,并會偶爾加載其他用戶的統(tǒng)計露懒。 這種狀況發(fā)生時將自動發(fā)送一個 ISteamUserStats::UserStatsUnloaded_t 回調(diào)闯冷。 發(fā)出回調(diào)后,再次調(diào)用ISteamUserStats::RequestUserStats 之前懈词,都無法使用該用戶的統(tǒng)計數(shù)據(jù)蛇耀。
離線模式
Steam 會將統(tǒng)計與成就數(shù)據(jù)保存于本機(jī)緩存之中,以便在離線模式中也能正常使用 API 坎弯。 這段時間無法上傳的統(tǒng)計皆會被保存至下次聯(lián)機(jī)至網(wǎng)絡(luò)纺涤。 如在多臺機(jī)器上都有過修改,Steam 會自動合并成就抠忘,并選擇進(jìn)度最多的一組統(tǒng)計數(shù)據(jù)撩炊。 由于 Steam 已經(jīng)在本機(jī)緩存上保存了統(tǒng)計數(shù)據(jù),游戲便沒有必要再將數(shù)據(jù)緩存于磁盤上褐桌。 這兩種緩存常乘ヒ郑互相沖突,當(dāng)他們這樣做時荧嵌,用戶就會認(rèn)為他們的進(jìn)度已經(jīng)復(fù)原了呛踊。
游戲服務(wù)器統(tǒng)計數(shù)據(jù)
與 ISteamUserStats 性質(zhì)相近的便是游戲服務(wù)器的 ISteamGameServerStats 了,可以使用與客戶端相同的方式取得用戶的統(tǒng)計數(shù)據(jù)啦撮。 但只有在”設(shè)定人”是 GS(游戲服務(wù)器)或Official GS (官方游戲服務(wù)器)的情況下谭网,才可以用它來設(shè)置統(tǒng)計和成就。 游戲服務(wù)器和官方游戲服務(wù)器的差別在于赃春,官方服務(wù)器是您自己主持并控制的愉择。 使用官方服務(wù)器設(shè)定統(tǒng)計數(shù)據(jù)能夠杜絕作弊行為,因?yàn)槿绱艘粊硗婕冶銦o法變更自己的游戲服務(wù)器,或假扮游戲服務(wù)器锥涕。 如要設(shè)置官方服務(wù)器衷戈,可從此處輸入服務(wù)器的 IP 范圍。
游戲服務(wù)器可設(shè)定的統(tǒng)計與成就不能由客戶端更改层坠。 游戲服務(wù)器只能為正在服務(wù)器上游玩的玩家設(shè)定統(tǒng)計與成就殖妇。 當(dāng)用戶離開了服務(wù)器,會有一小段寬限期可設(shè)置最終的統(tǒng)計破花,之后所有上傳都會被拒絕谦趣。 這是為了保持?jǐn)?shù)據(jù)的一致性,以及避免惡意的服務(wù)器隨時隨意更改任何人的統(tǒng)計座每。 鑒于這項限制前鹅,盡量不要等到回合結(jié)束時才設(shè)置統(tǒng)計。 要持續(xù)地設(shè)置統(tǒng)計峭梳,當(dāng)用戶退出游戲時便能順利儲存舰绘。
游戲服務(wù)器變更統(tǒng)計時,客戶端便會自動獲得更新延赌。 但是除盏,像客戶端一樣,加載其他用戶的數(shù)據(jù)后不會自動更新挫以,有可能不正確者蠕。
重設(shè)統(tǒng)計數(shù)據(jù)
開發(fā)過程中,常常會有為了測試希望清除某個帳戶所有統(tǒng)計與成就的狀況掐松。 要清除帳戶所有統(tǒng)計踱侣,調(diào)用 ISteamUserStats::ResetAllStats,而將 bAchievementsToo
設(shè)置為 **true[/ b] 即可一同清除成就大磺。 調(diào)用后抡句,記得要重新逐一查看統(tǒng)計與成就,并重設(shè)內(nèi)存中游戲狀態(tài)杠愧。 無法統(tǒng)一清除所有用戶的統(tǒng)計與成就待榔。 這是因?yàn)榫退憬y(tǒng)一清除了數(shù)據(jù),運(yùn)行中的游戲可能也不會注意到這次清除流济,而寫入內(nèi)存中的值锐锣。 所幸有一個簡單的辦法,可以在您的游戲中建立一個統(tǒng)一清除系統(tǒng)绳瘟。 具體方法是:
定義一項成就雕憔,名稱可以用” Versoin ”
在游戲中放入一個硬編碼統(tǒng)計版本編號
加載統(tǒng)計后,對比” Version ”和硬編碼的版本編號
如不相符糖声,調(diào)用 ISteamUserStats::ResetAllStats 然后將”Version”設(shè)為硬編碼號碼
這樣一來斤彼,無論何時您想要統(tǒng)一清除分瘦,只需改變硬編碼的統(tǒng)計版本號碼就可以了。 其他人拿到新生成版本時琉苇,便會統(tǒng)一清除數(shù)據(jù)嘲玫。只需確保統(tǒng)一清除代碼不會在最終生成版本中出現(xiàn)。
統(tǒng)計一致性
最好的做法是考慮相關(guān)的統(tǒng)計數(shù)據(jù)會如何變得不一致并扇。 舉例來說趁冈,您有三項統(tǒng)計”GamesWon”、”GamesLost”拜马,和“GamesPlayed”。 即使考慮得再周到沐绒,統(tǒng)計數(shù)據(jù)之間也會確實(shí)出現(xiàn)無法同步的情況俩莽。此種情況下,勝場和敗場數(shù)加起來有可能不到總游戲場數(shù)乔遮。 假如您將“GamesLost”去掉扮超,而使用“GamesPlayed”-“GamesWon”來計算敗場的話,數(shù)據(jù)不一致時便會導(dǎo)致”GamesLost”變成負(fù)數(shù)蹋肮。 這種狀況下出刷,最好的辦法是不要使用“GamesPlays”而使用 “GamesWon”+ “GamesLost”進(jìn)行計算。
全球統(tǒng)計數(shù)據(jù)
可在管理頁面中標(biāo)出統(tǒng)計的合計坯辩, Steam 便會保存所有用戶的該項統(tǒng)計的總值馁龟。 這可以用來記錄經(jīng)濟(jì)體中所有的金錢、總擊殺數(shù)漆魔、最受歡迎的武器或地圖坷檩,或哪個隊伍的表現(xiàn)更佳。 另一方面改抡,此方法不能用在像是“MostKills”的統(tǒng)計中矢炼,因?yàn)閷⒍鄠€用戶的最高擊殺數(shù)加起來沒有任何意義。 由于統(tǒng)計是掌握在玩家手上阿纤,這些數(shù)據(jù)便有遭到操縱的可能句灌。 因此,使用合計時欠拾,設(shè)置最小值胰锌、最大值、僅限增量(如有需要)與最大變更便至關(guān)重要清蚀。 最大變更對合計統(tǒng)計來說意義特殊匕荸。 每當(dāng)上傳了新的值,合計值的改變不會超過最大變更值枷邪。 如此便能限制一個作弊者影響全球總數(shù)的快慢榛搔。
要訪問全球統(tǒng)計诺凡,先調(diào)用 ISteamUserStats::RequestGlobalStats 然后再調(diào)用 ISteamUserStats::GetGlobalStat 取得每項統(tǒng)計。 也可向 ISteamUserStats::RequestGlobalStats 要求一段特定時間內(nèi)的歷史記錄践惑,這些歷史記錄了這項統(tǒng)計每天的變更量腹泌。 使用 ISteamUserStats::GetGlobalStatHistory 便可訪問歷史紀(jì)錄。
您也可從客戶端要求全球成就完成百分比尔觉。 首先調(diào)用 ISteamUserStats::RequestGlobalAchievementPercentages凉袱。 然后調(diào)用 ISteamUserStats::GetMostAchievedAchievementInfo 和ISteamUserStats::GetNextMostAchievedAchievementInfo 以最多完成到最少完成的順序逐一查看每項成就。 您也可調(diào)用 ISteamUserStats::GetAchievementAchievedPercent 取得某項成就的完成百分比侦铜。
Steam 社區(qū)
游戲發(fā)行之后专甩,有關(guān)個人與全球的成就進(jìn)度便會顯示于 Steam 社區(qū)中。每個玩家都將從他們的社區(qū)資料中獲得一個鏈接钉稍,此鏈接會顯示他們已經(jīng)取得的成就涤躲,以及他們還未解鎖的內(nèi)容。
備注:在您的應(yīng)用在社區(qū)曝光以前贡未,您的成就不會顯示出來种樱。
每項成就都會與在 Steamworks 控制面板中設(shè)置的圖標(biāo)、名稱和描述一起列出俊卤。 如果成就的名稱和內(nèi)容已被本地化為用戶所選語言嫩挤,便會以該語言顯示。
此頁面和游戲的 Steam 主頁面皆會有一個鏈接連至全球成就統(tǒng)計數(shù)據(jù)的頁面消恍,顯示每一項成就的 Steam 玩家全球達(dá)標(biāo)率岂昭,按最常見到最罕見的順序排列。 這對于玩家來說很有趣哺哼,對開發(fā)者來說也是項很有用的資源佩抹;特別挑戰(zhàn)夠不夠難? 或是難度太高了取董? (這些信息也可在 Steamworks 合作伙伴站點(diǎn)上找到)棍苹。**