Kısaca
Başarımları oyuncuları bazı mihenk taşlarına ulaştığı veya oyununuzla belirli şekillerde etkileşimde bulundukları için ödüllendirmek için kullanın.Entegrasyon seviyesi
10 dakika veya 10 satır koddan daha az Steamworks SDK entegrasyonu gereklidir.Giriş
Başarımlar oyununuzdaki oyuncu etkileşimlerini ve kilometre taşlarını teşvik etmenin ve ödüllendirmenin bir yolu olarak kullanılabilir. Genellikle öldürme sayısını, sürülen kilometreleri, açılan sandıkları veya oyununuzdaki diğer yaygın eylemleri işaretlemek için kullanılırlar. Ayrıca oyuncularınızın oyununuzu oynamanın farklı yollarını keşfetmelerine yardımcı olmak için de kullanılabilir. Kazanıldığında bu başarımlarımlar oyuncuların ekranının köşesinde bir pencere olarak belirecek ve o oyuncu için bir başarım sayfasında işaretlenecektir.
Teknik Genel Bakış
Aşağıda verilen adımları takip ederek 10 dakikada ve 10 satır kodla oldukça temel Steam başarımlarını uygulamanızın kod tabanına entegre edebilirsiniz.
Steamworks SDK'in beraberinde örnek bir uygulama olan ve Steam özelliklerinin kapsayıcılığını gösteren
Spacewar ile gelir. Bütün Steam özelliklerini çalışırken gözlemlemek istiyorsanız yapmanız gereken ilk şey bu uygulamayı incelemektir. Bu rehberde; Spacewar'da, İstatistikler ve Başarımlar API'ında bulunan bilgiler sadece Steam İstatistikleri ile ilgili olacak şekilde süzülmüştür. İstatistikler ve başarımlar arasında oldukça fazla kesişen nokta olduğunu lütfen aklınızda bulundurun. Yani eğer bu ikisini entegre edecekseniz birçok çağırma birleştirilebilir.
1. Adım - Oyununuzun başarımlarını tanımlamak
Başarımlar uygulamaya özgüdür ve Steamworks uygulama yöneticisi arka ucundaki
Başarım Yapılandırması sayfasında yapılır. Aşağıdaki başarımlar listesi Steamworks örnek uygulaması olan Spacewar'dan alınmıştır:

2. Adım - Başarımları hazırlamak
Aşağıdaki kod oyundan bağımsızdır ve oyununuza istediğiniz şekilde eklenebilir. Sınıf olduğu şekliyle işlevseldir fakat diğer ihtiyaçlarınıza uyum sağlayacak şekilde genişletilebilir. Bu kodun tamamı doğrudan Spacewar'un örnek
StatsAndAchievements.cpp/h
dosyalarından alınmıştır.
Üstbilgi Dosyası
Öncelikle Steam'den alınan başarım verilerini tutacak bir yapı tanımlıyoruz ve bu tür objelerin yaratılması için bir makro sağlıyoruz. Bu veri doğrudan
Başarım Yapılandırması sayfasında bulunanlarla eşleşir.
#define _ACH_ID( id, name ) { id, #id, name, "", 0, 0 }
struct Achievement_t
{
int m_eAchievementID;
const char *m_pchAchievementID;
char m_rgchName[128];
char m_rgchDescription[256];
bool m_bAchieved;
int m_iIconImage;
};
Ardından bütün Steam İstatistik API'ı çağırmalarını saracak ve bütün
Steam geri çağırmalarını yapacak yardımcı bir sınıf tanımlıyoruz.
class CSteamAchievements
{
private:
int64 m_iAppID; // Our current AppID
Achievement_t *m_pAchievements; // Başarım verileri
int m_iNumAchievements; // Başarım sayısı
bool m_bInitialized; // "Request stats" çağrımı yaptık mı? Evetse geri çağrım alındı mı?
public:
CSteamAchievements(Achievement_t *Achievements, int NumAchievements);
~CSteamAchievements();
bool RequestStats();
bool SetAchievement(const char* ID);
STEAM_CALLBACK( CSteamAchievements, OnUserStatsReceived, UserStatsReceived_t,
m_CallbackUserStatsReceived );
STEAM_CALLBACK( CSteamAchievements, OnUserStatsStored, UserStatsStored_t,
m_CallbackUserStatsStored );
STEAM_CALLBACK( CSteamAchievements, OnAchievementStored,
UserAchievementStored_t, m_CallbackAchievementStored );
};
Kod Dosyası
Kurucu
Parametreler - Kurucu, bir başarı dizininden dizinin uzunluğunu da içeren bir işaretleyici alır. Bu dizinin biçimi daha sonra ana oyunun koduyla dolacaktır.
Geri dönüş - Mevcut Değil
Eylem - Kurucu birçok üyeyi başlatır ve aynı zamanda şu anda çalıştırdığımız AppID'yi de alır. Buna ek olarak, Steam'e yapılan asenkron çağrımları işleyebilmek için geri dönüş yöntemlerine bağlanır. Son olarak, mevcut kullanıcının istatistik ve başarımlarını almak için
RequestStats()
'e ilk çağrımı yapar.
CSteamAchievements::CSteamAchievements(Achievement_t *Achievements, int NumAchievements):
m_iAppID( 0 ),
m_bInitialized( false ),
m_CallbackUserStatsReceived( this, &CSteamAchievements::OnUserStatsReceived ),
m_CallbackUserStatsStored( this, &CSteamAchievements::OnUserStatsStored ),
m_CallbackAchievementStored( this, &CSteamAchievements::OnAchievementStored )
{
m_iAppID = SteamUtils()->GetAppID();
m_pAchievements = Achievements;
m_iNumAchievements = NumAchievements;
RequestStats();
}
RequestStats()
Parametreler - Hiçbiri
Geri dönüş - çağrımın başarılı olup olmadığını temsil eden bir boole. Eğer çağrım başarısız olmuşsa bunun en muhtemel sebebi Steam'in başlatılmamış olmasıdır. Bu çağrımı yaparken Steam istemcisinin çalışıyor olduğundan ve önceden
SteamAPI_Init'in çağrıldığından emin olun.
Eylem - Bu yöntem, Steam'e asenkron çağrı yaparak mevcut kullanıcının istatistik ve başarımlarını isteyen
ISteamUserStats::RequestCurrentStats'e yapılan bir çağrıyı sarar. Bu çağrı, siz herhangi bir istatistik veya başarım belirlemeden önce yapılmalıdır. Bu yönteme yapılan ilk çağrı kurucuda yapılır. Bundan sonra eğer güncellenen istatistik veya başarımlara bakmak isterseniz bunu tekrar çağırabilirsiniz.
bool CSteamAchievements::RequestStats()
{
// Steam yüklü mü? Değilse istatistikleri alamayız.
if ( NULL == SteamUserStats() || NULL == SteamUser() )
{
return false;
}
// Kullanıcı giriş yapmış mı? Değilse istatistikleri alamayız.
if ( !SteamUser()->BLoggedOn() )
{
return false;
}
// Kullanıcı istatistiklerini iste.
return SteamUserStats()->RequestCurrentStats();
}
SetAchievement()
Parametreler - Belirlemek istediğiniz başarımın tanıtıcı dizisi (yani "ACH_WIN_ONE_GAME")
Geri dönüş - çağrımın başarılı olup olmadığını temsil eden bir boole. Eğer çağrı başarısız olursa bunun nedeni ya Steam'in başlatılmamış olması ya da
RequestStats
'e yapılan çağrı sonucu alınan geri çağrıyı henüz işlememiş olmanızdır. Bu geri çağrı alınana kadar herhangi bir başarım belirleyemezsiniz.
Eylem - Bu yöntem bir başarımı başarıldı olarak değiştirir ve sonuçlarını Steam'e gönderir. Bir başarımı birden fazla kez belirleyebilirsiniz. Böylece henüz elde edilmemiş başarımları belirlemek zorunda kalmazsınız. Bu iki geri çağrıyı tetikleyen asenkron bir çağrıdır:
OnUserStatsStored()
ve
OnAchievementStored()
.
bool CSteamAchievements::SetAchievement(const char* ID)
{
// Steam'den bir geri çağrı aldık mı?
if (m_bInitialized)
{
SteamUserStats()->SetAchievement(ID);
return SteamUserStats()->StoreStats();
}
// Almadıysak başarımları belirleyemeyiz
return false;
}
OnUserStatsReceived()
Parametreler - Mevcut Değil
Geri dönüş - Hiçbir şey
Eylem - Bu yöntem, istatistik istediğiniz zaman çağrılan bir geri çağrıdır. İstatistik ve başarımlar
RequestStats()
kullanılarak istenir. Bu yöntem üye değişken m_pAchievements'ı, Steam'den dönen en son istatistik ve başarım verilerini yansıtacak şekilde günceller.
void CSteamAchievements::OnUserStatsReceived( UserStatsReceived_t *pCallback )
{
// diğer oyunlardan gelen istatistikler için geri çağrılar alabiliriz, bunları yok say
if ( m_iAppID == pCallback->m_nGameID )
{
if ( k_EResultOK == pCallback->m_eResult )
{
OutputDebugString("Received stats and achievements from Steam\n");
m_bInitialized = true;
// başarımları yükle
for ( int iAch = 0; iAch < m_iNumAchievements; ++iAch )
{
Achievement_t &ach = m_pAchievements[iAch];
SteamUserStats()->GetAchievement(ach.m_pchAchievementID, &ach.m_bAchieved);
_snprintf( ach.m_rgchName, sizeof(ach.m_rgchName), "%s",
SteamUserStats()->GetAchievementDisplayAttribute(ach.m_pchAchievementID,
"name"));
_snprintf( ach.m_rgchDescription, sizeof(ach.m_rgchDescription), "%s",
SteamUserStats()->GetAchievementDisplayAttribute(ach.m_pchAchievementID,
"desc"));
}
}
else
{
char buffer[128];
_snprintf( buffer, 128, "RequestStats - failed, %d\n", pCallback->m_eResult );
OutputDebugString( buffer );
}
}
}
OnUserStatsStored()
Parametreler - Mevcut Değil
Geri dönüş - Hiçbir şey
Eylem - Bu yöntem, Steam'de istatistik saklamaya çalıştığınız zaman çağrılan bir geri çağrıdır.
void CSteamAchievements::OnUserStatsStored( UserStatsStored_t *pCallback )
{
// diğer oyunlardan gelen istatistikler için geri çağrılar alabiliriz, bunları yok say
if ( m_iAppID == pCallback->m_nGameID )
{
if ( k_EResultOK == pCallback->m_eResult )
{
OutputDebugString( "Stored stats for Steam\n" );
}
else
{
char buffer[128];
_snprintf( buffer, 128, "StatsStored - failed, %d\n", pCallback->m_eResult );
OutputDebugString( buffer );
}
}
}
OnAchievementStored()
Parametreler - Mevcut Değil
Geri dönüş - Hiçbir şey
Eylem - Bu yöntem, başarımları başarılı bir şekilde Steam'de sakladığınız zaman çağrılan bir geri çağrıdır.
void CSteamAchievements::OnAchievementStored( UserAchievementStored_t *pCallback )
{
//diğer oyunlardan gelen istatistikler için geri çağrılar alabiliriz, bunları yok say
if ( m_iAppID == pCallback->m_nGameID )
{
OutputDebugString( "Stored Achievement for Steam\n" );
}
}
3. Adım - Oyununuza entegre etmek
Aşağıda oyununuzun uygun yerlerine entegre etmeniz gereken kod parçalarının tam bir listesi yer almaktadır.
Tanımlamalar ve Küreseller
Aşağıda "Achievements" ile derlenmesi gereken içerikler vardır; oyunumuza özgü başarımların sıralaması ve yardımcı objemiz için küresel bir işaretleyici. Başarımların Steamworks'teki yönetici sayfasındakilerle eşleştiğini unutmayın.
...
#include "steam_api.h"
// Başarımlarımızı tanımlamak
enum EAchievements
{
ACH_WIN_ONE_GAME = 0,
ACH_WIN_100_GAMES = 1,
ACH_TRAVEL_FAR_ACCUM = 2,
ACH_TRAVEL_FAR_SINGLE = 3,
};
// Başarımlar ve durumlarıyla ilgili veri tutan başarım dizini
Achievement_t g_Achievements[] =
{
_ACH_ID( ACH_WIN_ONE_GAME, "Winner" ),
_ACH_ID( ACH_WIN_100_GAMES, "Champion" ),
_ACH_ID( ACH_TRAVEL_FAR_ACCUM, "Interstellar" ),
_ACH_ID( ACH_TRAVEL_FAR_SINGLE, "Orbiter" ),
};
// "Achievements" öğesine küresel erişim
CSteamAchievements* g_SteamAchievements = NULL;
...
Başlatma
SteamAPI_Init'e yapılan çağrı Steam'i tamamen başlatır ve bu çağrı diğer her şeyden önce yapılmalıdır. Eğer bu çağrı başarılı olursa, başarımlar dizininden geçerken dizinin boyutuyla birlikte bir yardımcı obje oluştururuz.
...
// Steam'i başlat
bool bRet = SteamAPI_Init();
// Eğer Steam başarılı bir şekilde başladıysa "SteamAchievements" objesini oluştur
if (bRet)
{
g_SteamAchievements = new CSteamAchievements(g_Achievements, 4);
}
...
Geri Çağrıların İşlenmesi
Bütün Steam geri çağrılarını işleyebilmemiz için düzenli olarak yeni mesajlar göndermeliyiz. Bunun başarılabilmesi için şu çağrıyı oyunun döngüsüne eklemelisiniz.
...
SteamAPI_RunCallbacks();
...
Başarımların Tetiklenmesi
Başarım tanımlayıcısı içeren tek bir çağrıyla bir başarım tetiklenebilir.
...
if (g_SteamAchievements)
g_SteamAchievements->SetAchievement("ACH_WIN_100_GAMES");
...
Kapatma
SteamAPI_Shutdown'a yapılan çağrı muhtemelen kodunuzda zaten mevcuttur. Steam'i kapatır ve uygulamadan çıkmadan önce çağrılması gereklidir. Son olarak da oluşturduğumuz yardımcı objeyi siliyoruz.
...
//Steam'i kapat
SteamAPI_Shutdown();
// "SteamAchievements" objelerini sil
if (g_SteamAchievements)
delete g_SteamAchievements;
...
4. Adım - Test etme ve sorun giderme
Oyununuza kod eklemeden istatistikleri ayarlamak veya silmek için Steam istemcisi konsolunu kullanabilirsiniz. "steam.exe -console" ile çalıştırın ardından:
- achievement_clear <appid> <achievement name>
- reset_all_stats <appid>