Wprowadzenie
Osiągnięcia i statystyki Steam są łatwym sposobem, aby zapewnić użytkownikom stałe śledzenie ich osiągnięć i statystyk. Dane użytkownika są skojarzone z jego kontem Steam, a osiągnięcia i statystyki każdego użytkownika mogą zostać sformatowane i wyświetlone w ich profilach Społeczności Steam.
Zastosowanie
Oprócz oferowania cennych nagród dla graczy, osiągnięcia są przydatne w zachęcaniu i nagradzaniu pracy zespołowej oraz interakcji między graczami, rozszerzając ideę celów gry i nagradzając użytkowników za ich czas spędzony w grze.
Statystyki śledzą nawet pomniejsze informacje takie jak czas gry, liczbę wykorzystanych wzmocnień, itp. Jeśli wolisz, statystyk można używać po prostu do śledzenia wewnętrznych danych w grze. Na przykład użytkownik może otrzymać osiągnięcie na podstawie statystyk zebranych w trakcie grania przez kilka sesji na różnych komputerach.
Wprowadzenie do implementacji
Określ statystyki i osiągnięcia w twojej grze
Każda aplikacja ma swoje własne osiągnięcia i ich konfiguracja ma miejsce w sekcji administratora aplikacji na stronie partnerskiej Steamworks.
Istnieją trzy rodzaje statystyk, które twoja gra może przechowywać:
- INT — 32-bitowa liczba całkowita ze znakiem (na przykład liczba rozegranych gier).
- FLOAT — 32-bitowa liczba zmiennoprzecinkowa (na przykład liczba przejechanych kilometrów).
- AVGRATE — średnia ruchoma. Zobacz: Typ statystyki AVGRATE.
Strona partnerska Steamworks zapewnia interfejs do definiowania oraz aktualizowania statystyk i osiągnięć twojej gry. Używając go, możesz:
- Zdefiniować początkowe statystyki i osiągnięcia.
- Dodać kolejne statystyki i osiągnięcia.
- Zaktualizować nazwy, opisy i ikony osiągnięć.
- Zaktualizować parametry i ograniczenia statystyk (minimalne/maksymalne wartości, długość ram czasowych dla średniej itd.).
Statystyki mają następujące właściwości:
- ID — automatycznie generowane ID numeryczne dla każdej statystyki.
- Typ — typ tej statystyki: INT, FLOAT albo AVGRATE.
- Nazwa API — używana do uzyskania dostępu do tej statystyki z użyciem API.
- Ustawiane przez — ustala, kto może modyfikować statystykę. Domyślnie jest to klient. Jeśli chcesz uzyskać więcej informacji, przejdź tutaj.
- Tylko przyrost? — ustawienie tej opcji sprawi, że z biegiem czasu wartość tej statystyki będzie mogła tylko rosnąć.
- Maksymalna zmiana — ustawienie tej opcji sprawi, że zostanie nałożony limit na liczbę zmian wartości statystyki między jednym wywołaniem SetStat a kolejnym.
- Min Value — jeśli ustawione określa minimum dla wartości statystyki. Domyślnie jest to minimum określane przez dany typ liczby (INT_MIN lub -FLT_MAX).
- Maksymalna wartość — ustawienie tej opcji sprawi, że zostanie określona maksymalna wartość tej statystyki. Domyślnie jest to maksimum określane przez dany typ liczby (INT_MAX lub FLT_MAX).
- Wartość domyślna — ustawienie tej opcji sprawi, że ta statystyka będzie posiadać domyślną wartość dla nowego użytkownika. Jeśli nie zostanie ustawiona, domyślną wartością jest zero.
- Zestawione — ustawienie tej opcji sprawi, że Steam będzie przechowywał globalną sumę tej statystyki. Zobacz „Globalne statystyki” poniżej, aby uzyskać więcej informacji.
- Wyświetlana nazwa — nazwa tej statystyki, gdy jest wyświetlana w twojej aplikacji.
AVGRATE: ten typ statystyki ma następujące dodatkowe właściwości:
- Okno — rozmiar „okna przesuwnego” służącego do uśredniania.
Statystyka
AVGRATE jest automatycznie uśredniana przez Steam. Przeczytaj
AVGRATE, aby uzyskać więcej informacji.
Osiągnięcia mają następujące właściwości:
- ID — automatycznie generowane ID numeryczne dla każdego osiągnięcia.
- Nazwa API — używana do uzyskania dostępu do tego osiągnięcia z użyciem API.
- Statystyka postępu — określa statystykę, która jest używana jako pasek postępu dla tego osiągnięcia w Społeczności Steam. Osiągnięcie zostanie automatycznie odblokowane, kiedy statystyka osiągnie wartość odblokowującą.
- Wyświetlana nazwa — nazwa osiągnięcia, która będzie wyświetlana w Społeczności Steam i w wyskakujących powiadomieniach. Może być lokalizowana.
- Opis — opis tego osiągnięcia wyświetlany w Społeczności Steam. Może być lokalizowana.
- Ustawiane przez — ustala, kto może odblokować osiągnięcie. Domyślnie jest to klient. Jeśli chcesz uzyskać więcej informacji, przejdź tutaj.
- Ukryte? — jeśli wartość to „true”, to „ukryte” osiągnięcie wcale nie pojawi się na stronie społeczności użytkownika do czasu odblokowania osiągnięcia.
- Achieved Icon — ikona wyświetlana, kiedy osiągnięcie zostanie zdobyte.
- Unachieved Icon — ikona wyświetlana, kiedy osiągnięcie nie zostało zdobyte.
Poniżej znajduje się lista
przykładowych osiągnięć:
Specjalne uwagi
- Nazwy i ikony osiągnięć powinny być odpowiednie dla wszystkich grup wiekowych.
- Domyślnie gry mają początkowo limit 100 osiągnięć. Once your app reaches the threshold for Funkcje profilu, you will be able to add more achievements.
Jak ich używać
Uzyskiwanie dostępu do statystyk i osiągnięć z poziomu twojej gry:
- Po inicjalizacji API Steamworks możesz zacząć używać API statystyk i osiągnięć znajdujących się w ISteamUserStats.
- Na początku sesji gry wywołaj ISteamUserStats::RequestCurrentStats, aby pobrać dane statystyk i osiągnięć użytkownika z back-endu Steam. Otrzymasz wywołanie zwrotne ISteamUserStats::UserStatsReceived_t, kiedy dane będą gotowe.
- Użyj ISteamUserStats::GetStat oraz ISteamUserStats::GetAchievement, aby iterować dane i inicjalizować stan gry.
- Jeśli chcesz wyświetlać osiągnięcia w swojej grze, możesz użyć ISteamUserStats::GetAchievementDisplayAttribute, aby uzyskać zrozumiałe właściwości osiągnięć, w tym nazwę („name”) i opis („desc”). Możesz zlokalizować te właściwości na stronie partnerskiej Steamworks i wtedy zwrócone dane będą zależne od języka, w którym użytkownik gra w grę. Możesz również uzyskać ikonę osiągnięcia za pomocą ISteamUserStats::GetAchievementIcon lub czas, w jakim każde osiągnięcie zostało odblokowane, używając ISteamUserStats:: GetAchievementAndUnlockTime.
- Ilekroć statystyka zostaje zmieniona, szczególnie zanim zmiany zostaną wyświetlone użytkownikowi, wywołaj ISteamUserStats::SetStat albo ISteamUserStats::UpdateAvgRateStat. Te wywołania modyfikują tylko stan pamięci Steam i potrzebują niewielu zasobów. Dzięki temu Steam może zapisywać zmiany między sesjami nawet w przypadku nieoczekiwanego zamknięcia gry.
- W odpowiednich miejscach w grze (na przykład przy zmianie poziomów) wywołaj ISteamUserStats::StoreStats, aby przesłać zmiany. Po zakończeniu otrzymasz wywołanie zwrotne ISteamUserStats::UserStatsStored_t.
- Dla osiągnięć, które mają pasek postępu, użyj ISteamUserStats::IndicateAchievementProgress w ważnych momentach, aby wyświetlić wyskakujące powiadomienie z postępem. Jeśli na przykład potrzebujesz 20 zwycięstw, możesz wywołać tę funkcję po 10, aby pokazać użytkownikowi, że już jest w połowie.
- Ilekroć przynajmniej jedno osiągnięcie zostanie odblokowane, wywołaj ISteamUserStats::SetAchievement dla każdego odblokowanego osiągnięcia, a następnie ISteamUserStats::StoreStats, aby je natychmiast przesłać. Twoja gra otrzyma wywołanie zwrotne ISteamUserStats::UserStatsStored_t i dodatkowo ISteamUserStats::UserAchievementStored_t dla każdego odblokowanego osiągnięcia. Nakładka Steam wyświetli użytkownikowi powiadomienie.
Typ statystyki AVGRATE
Ten typ statystyki zapewnia unikalną i bardzo przydatną funkcjonalność, ale wymaga objaśnienia kilku szczegółów.
Załóżmy, że chcesz śledzić średnią statystykę, na przykład „Punkty na godzinę”. Jedną możliwością byłoby posiadanie dwóch statystyk, INT „TotalPoint” oraz FLOAT „TotalPlayTimeHours”, a później podzielić punkty przez czas, aby uzyskać liczbę punktów na godzinę.
Minusem tego podejścia będzie bardzo wolna zmiana obliczonej w ten sposób średniej w momencie, gdy użytkownik spędził bardzo dużo czasu w grze. Im więcej użytkownik będzie grał, tym wolniej ta średnia będzie się zmieniać. Jeśli gracz spędził w grze 100 godzin, obliczona średnia będzie około 50 godzin „do tyłu”. Jeśli gracz podniesie swoje umiejętności, to nie zobaczy on oczekiwanej zmiany w punktach na godzinę.
Typ statystyki AVGRATE pozwala zaimplementować efekt ram czasowych dla średniej. Na przykład możesz korzystać tylko z kilku ostatnich godzin spędzonych w grze danego użytkownika, aby dokładniej odzwierciedlić jego obecne umiejętności.
Spróbujmy zaimplementować statystykę AVGRATE dla liczby punktów na godzinę w taki sposób, by na wartość wpływało tylko ostatnie 20 godzin rozgrywki. Aby to zrobić, musisz:
- Zwrócić uwagę na to, że z racji tego, iż średnia będzie „na godzinę”, to jednostką czasu dla wszystkich parametrów powiązanych z tą statystyką będzie „godzina”. Dotyczy to zarówno właściwości „Ramy czasowe” statystyki, jak i parametru „dSessionLength” przekazywanego do
UpdateAvgRateStat
poniżej.
- Utworzyć statystykę AVGRATE o nazwie „AvgPointsPerHour”, gdzie wartość dla właściwości o nazwie „Ramy czasowe” wynosi 20.0 (pamiętaj, że wartość jest podana w „godzinach”).
- W odpowiednim momencie gry wywołać ISteamUserStats::UpdateAvgRateStat z następującymi parametrami:
- pchName — „AvgPointsPerHour”
- flCountThisSession — liczba punktów zdobytych przez gracza od ostatniego wywołania funkcji UpdateAvgRateStat.
- dSessionLength — czas gry od ostatniego wywołania funkcji UpdateAvgRateStat. Jednostka powinna być taka sama jak jednostka w przypadku właściwości o nazwie „Ramy czasowe” statystyki. W tym przypadku to „godziny”.
- Jeśli przykładowo gracz zdobył 77 punktów w ostatniej rundzie, która trwała 0,225 godziny (13,5 minuty), będzie to
SteamUserStats()->UpdateAvgRateStat("AvgPointsPerHour", 77, 0.225 )
.
W powyższym przykładzie Steam weźmie średnią wartość obecnej rundy równą 342,2 punktu na godzinę (77 podzielone przez 0,0225) i złączy z poprzednią wartością. Wynik będzie odzwierciedlać łączną średnią z ostatnich 20 godzin danego użytkownika w grze. Jeśli byłby to pierwszy raz, kiedy ta statystyka zostałaby zaktualizowana dla danego użytkownika, wartość wynosiłaby 342,2.
W tym przykładzie „godziny” są jednostką czasu, ale możesz użyć jakiej tylko chcesz. Pamiętaj tylko, że musisz konsekwentnie używać wybranej jednostki jako swojej bazy dla „dSessionLength” oraz jako wartości właściwości o nazwie „Ramy czasowe”.
Uzyskiwanie statystyk dla innych użytkowników
Możesz użyć
ISteamUserStats::RequestUserStats, aby uzyskać statystyki dla innego użytkownika. Następnie możesz użyć
ISteamUserStats::GetUserStat,
ISteamUserStats::GetUserAchievement i
ISteamUserStats::GetUserAchievementAndUnlockTime, aby uzyskać dane dla tego użytkownika. Te dane nie są aktualizowane automatycznie w momencie, kiedy inny użytkownik przesyła nowe statystyki, więc odśwież je, wywołując
ISteamUserStats::RequestUserStats ponownie.
Aby nie zużywać zbyt dużo pamięci, wykorzystuje się algorytm stronicowania (LRU), a inne statystyki użytkownika będą czasami zwalniane z pamięci. Kiedy to się stanie, wywołanie zwrotne
ISteamUserStats::UserStatsUnloaded_t zostanie wysłane automatycznie. Gdy to wywołanie zwrotne zostanie wysłane, statystyki określonego użytkownika będą niedostępne aż do kolejnego wywołania
ISteamUserStats::RequestUserStats.
Tryb offline
Steam przechowuje lokalną pamięć podręczną statystyk i osiągnięć danych, by można było normalnie wykorzystać API w trybie offline. Wszelkie statystyki, których nie da się przesłać, zostają zapisane do kolejnego momentu, gdy użytkownik będzie online. W przypadku, gdy dane zostaną zmodyfikowane na większej liczbie urządzeń, Steam automatycznie połączy osiągnięcia i wybierze ten zestaw statystyk, w przypadku których postęp był większy. Z racji tego, iż Steam przechowuje lokalną kopię pamięci podręcznej danych statystyk, nie jest konieczne, aby gra również przechowywała pamięć podręczną tych danych na dysku. Takie przypadki często powodują konflikt, który u użytkownika może wyglądać, jakby jego postęp został cofnięty, co jest frustrującym doświadczeniem.
Statystyki serwerów gry
Równolegle do
ISteamUserStats istnieje
ISteamGameServerStats dla serwerów gry. Mogą one uzyskiwać statystyki dla użytkowników w ten sam sposób co klienty (tak jak opisano wyżej). Mogą one również ustawiać statystyki i odblokowywać osiągnięcia, ale tylko wtedy, gdy właściwość „Ustawiane przez” posiada wartość „Serwery gry” lub „Oficjalne serwery gry”. Różnica między serwerem gry a oficjalnym serwerem gry jest taka, że oficjalne serwery są hostowane i kontrolowane przez ciebie. Korzystanie z oficjalnych serwerów gier zapewnia lepszą ochronę przed oszustami, jako że użytkownicy mogą być w stanie modyfikować swoje własne serwery gier albo podszyć się za serwer gry. Aby zdefiniować oficjalne serwery gier, wpisz zakresy IP serwerów
tutaj.
Statystyki i osiągnięcia ustawiane na serwerach gier nie mogą być ustawiane przez klientów. Serwery gier mogą ustawiać statystyki i osiągnięcia tylko dla użytkowników grających obecnie na serwerze. Jeśli użytkownik opuści serwer, istnieje krótki okres, w którym można ustawić końcowe statystyki, ale po tym przesłanie nowych danych nie będzie możliwe. Zapewnia to spójność i pomaga uniknąć sytuacji, w której to szkodliwy serwer gier może w dowolnym momencie ustawiać statystyki dowolnego użytkownika. Biorąc pod uwagę to ograniczenie, ważną rzeczą jest, aby nie czekać do końca rundy z ustawieniem statystyk. Definiuj je w ciągły sposób tak, można było je przechowywać, kiedy użytkownik opuści grę.
Klienci otrzymają automatyczną aktualizację, kiedy serwer gry zmieni ich statystyki. Aczkolwiek podobnie jak w przypadku klientów, statystyki wczytywane przez serwer dla innych użytkowników nie są odświeżane automatycznie i mogą nie być aktualne.
Resetowanie statystyk
Podczas rozwoju produktu często istnieje potrzeba całkowitego wyczyszczenia statystyk i osiągnięć z konta lub wszystkich kont dla testów. Aby to zrobić, wywołaj
ISteamUserStats::ResetAllStats wraz z
bAchievementsToo
z wartością
true, aby wyczyścić również osiągnięcia. Po wywołaniu musisz iterować przez wszystkie osiągnięcia i statystyki oraz zresetować swój stan gry w pamięci. Nie ma możliwości globalnego wyczyszczenia statystyk i osiągnięć dla wszystkich użytkowników. Jednym z powodów, dla których nie można tego zrobić, jest to, że nawet gdyby miało dojść do globalnego wyczyszczenia, to gry w toku mogłyby tego nie zauważyć i zapisać ponownie wartości znajdujące się w pamięci. Na szczęście istnieje prosty sposób na stworzenie systemu globalnego czyszczenia statystyk w twojej grze. Aby to zrobić:
- Zdefiniuj statystykę przykładowo o nazwie „Version”.
- Umieść w grze określony sztywno numer wersji w grze.
- Gdy statystyki zostaną wczytane, porównaj statystykę „Version” z określonym sztywno numerem wersji.
- Jeśli nie zgadzają się, wywołaj ISteamUserStats::ResetAllStats, po czym zmień wartość statystyki „Version” na numer określony na sztywno.
W ten sposób za każdym razem, gdy zechcesz dokonać globalnego wyczyszczenia, po prostu zmień określoną na sztywno wersję statystyk. Globalne wyczyszczenia nastąpi, gdy użytkownicy otrzymają nową kompilację produktu.
Spójność statystyk
Zaleca się wziąć pod uwagę fakt, jak powiązane statystyki mogą stać się niespójne. Na przykład możesz mieć trzy statystyki o nazwach „GamesWon”, „GamesLost” i „GamesPlayed”. Pomimo dobrych intencji te statystyki mogą przestać być zsynchronizowane ze sobą. W takim przypadku może to doprowadzić do sytuacji, w której suma wygranych i przegranych gier nie jest równa liczbie rozegranych gier. Jeśli problem zostałby rozwiązany poprzez usunięcie „GamesLost” i zastąpienie tego obliczaniem według wzoru „GamesPlayed” - „GamesWon”, to niespójność mogłaby spowodować, że wartość „GamesLost” byłaby ujemna. Dlatego lepiej porzucić statystykę „GamesPlayed” i obliczać ją jako „GamesWon” + „GamesLost”.
Statystyki globalne
Statystyki można oznaczyć jako zestawione na stronie administratora, by Steam zachowywał globalną sumę wartości wszystkich użytkowników dla danej statystyki. Może to służyć w celu uzyskania danych o ilości wydanych pieniędzy, całkowitej liczbie zabójstw, ulubionej broni, ulubionych mapach oraz informacji o tym, która drużyna radzi sobie lepiej. Z drugiej strony nie powinno się tego używać do statystyk takich jak „MostKills”, ponieważ suma tych wyników dla wielu użytkowników byłaby bez znaczenia. Jako że statystyki są w rękach użytkowników, będą oni mogli manipulować danymi. Dlatego ważne jest, by przy użyciu zestawionych statystyk ustawić dobre granice dla wartości minimalnych, maksymalnych, przyrostu (jeśli ma to sens) i maksymalnej zmiany. Maksymalna zmiana ma specjalne znaczenie dla zestawionych statystyk. Gdy nowa wartość zostanie przesłana, to wartość globalna nie zmieni się o więcej niż wartość maksymalnej zmiany. Ogranicza to szybkość, z jaką oszust może mieć wpływ na statystyki globalne.
Aby uzyskać dostęp do globalnych sum, wywołaj
ISteamUserStats::RequestGlobalStats, a następnie
ISteamUserStats::GetGlobalStat dla każdej statystyki globalnej. Możesz również wywołać
ISteamUserStats::RequestGlobalStats, aby uzyskać określoną liczbę dni historii. Historia to inaczej liczba, o którą zmieniła się statystyka każdego dnia. Możesz uzyskać dostęp do tej historii poprzez
ISteamUserStats::GetGlobalStatHistory.
Możesz również zażądać globalnych wartości procentowych zdobytych osiągnięć od klienta. Aby to zrobić, musisz najpierw wywołać
ISteamUserStats::RequestGlobalAchievementPercentages. Następnie iteruj po osiągnięciach od najczęściej zdobytego do najmniej zdobytego, wywołując
ISteamUserStats::GetMostAchievedAchievementInfo i
ISteamUserStats::GetNextMostAchievedAchievementInfo. Możesz również uzyskać dane odnośnie procentu zdobycia konkretnego osiągnięcia, wywołując
ISteamUserStats::GetAchievementAchievedPercent.
Testowanie
Zanim twoja aplikacja zostanie wydana, nie będziesz w stanie zobaczyć zdobytych osiągnięć w Społeczności Steam ani w bibliotece. Twoja aplikacja musi posiadać sposób wypisania użytkownikowi, jakie osiągnięcia zostały zdobyte.
Aby wyczyścić osiągnięcie lub statystykę bez dodawania kodu do twojej gry, możesz użyć konsoli klienta Steam. Uruchom steam.exe z parametrem -console, a następnie:
- achievement_clear <appid> <achievement name>
- reset_all_stats <appid>
Społeczność Steam
Gdy twoja gra zostanie wydana, to informacje o indywidualnych oraz globalnych postępach w zdobywaniu osiągnięć będą wyświetlane w Społeczności Steam. Każdy gracz będzie posiadał link na swoim profilu społeczności, który będzie prowadził do strony wyświetlającej zdobyte oraz nieodblokowane osiągnięcia.
UWAGA: twoje osiągnięcia nie będą wyświetlane do momentu, kiedy aplikacja nie będzie częściowo widoczna dla społeczności.
Każde osiągnięcie ma odpowiednią ikonę, nazwę i opis, tak jak ustawiono w panelu kontrolnym Steamworks. Jeśli nazwa i opis osiągnięcia zostały zlokalizowane na język wybrany przez użytkownika, zostaną wyświetlone w tym języku.
Na tej stronie oraz na stronie twojej gry w sklepie pojawi się odnośnik do statystyk globalnych osiągnięć dla twojej gry. Te statystyki będą wyświetlać procent użytkowników Steam danej gry, którzy odblokowali to osiągnięcie w kolejności od najczęstszego do najrzadszego. Gracze mają z tego uciechę, a ty jako producent gry możesz zadać sobie pytanie: czy moje specjalne wyzwania są wystarczająco trudne? A może jednak za trudne? Te informacje są również dostępne na stronie raportów ze sprzedaży i aktywacji.
Masz inne pytania?
Jeśli masz jakieś pytania, możesz je zadać na
forum dyskusyjnym dotyczącym statystyk i osiągnięć.