Dokumentacja Steamworks
Statystyki i osiągnięcia

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ęć:
achievements_spacewar.png

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:

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ęć.