Żeby rywalizować, nie musisz być botem
Serio. :)
Ale jeśli ktoś z Was postanowił napisać bota do gry w łapanie motylków, zapewne zastanawia się jak wykrywaliśmy grające automaty. Pragnę zaznaczyć, że przenoszenie użytkowników na listę botów odbywało się na podstawie pełnej historii gier (tak, ręcznie sprawdzałem po kilkaset gier na gracza) a nie jednego, konkretnego wyniku. Zatem bez dalszego przedłużania, przed Wami wpis, który część podjętych przez nas kroków powinien przybliżyć.
By zrozumieć jak analizowaliśmy wyniki, muszę opisać następujące rzeczy: - sposób losowania układu - mechanikę gry - informacje zwrotne z przeglądarki i zapis wyników
Losowanie układu
Układ motylków na planszy jest losowy (czy jak kto woli: pseudolosowy). Serwer losuje 240 motyli, dla każdego z nich wartość punktową oraz punkty, przez które motyl przeleci. Punkty te mają (bez zaskoczenia) zestaw współrzędnych x, y oraz z (po 10 na motyla), a każda ze współrzędnych może przyjmować wartości od -1 do 1. Dodatkowo dla każdego motyla losujemy obszar, w którym może się poruszać (dwuwymiarowy prostokąt). Taki zestaw otrzymuje własny unikalny identyfikator, po czym wszystkie te informacje trafiają do przeglądarki. Dodatkowo razem z czasem startu gry (wskazywanym przez serwer) zapisywane są one do bazy, by umożliwić późniejszą analizę. Rozpoczyna się gra. :)
Mechanika
W dowolnej chwili widocznych jest dokładnie 6 motyli (chyba, że się wyczerpią, jednakże takie zdarzenie nie powinno mieć miejsca). Motyle pobierane są z listy w takiej kolejności, w jakiej zostały wylosowane. Przekazane do przeglądarki pozycje (przypomnę: po 10 na motyla) są podstawą do interpolacji pozycji w danej chwili. Trasa motyla jest zamknięta, cykl trwa około 30 sekund. Interpolowane współrzędne x oraz y wraz z uprzednio wylosowanym obszarem roboczym motyla określają jego pozycję na ekranie, podczas gdy współrzędna z steruje jego rozmiarem.
Współrzędna z odpowiada jednak za coś jeszcze: możliwość schwytania motyla. Przyjęty układ współrzędnych ma oś Z rosnącą wgłąb monitora, czyli motyl jest tym bliżej, im mniejsza wartość współrzędnej z. Wartość z = -0.85 stanowi punkt graniczny, od którego motyl otrzymuje obwiednię czerwoną i tym samym daje się złapać.
Zapis wyników
Każdy kliknięty motyl zapisuje do przechowywanej w pamięci tablicy informacje o współrzędnych kliknięcia, oraz czasie, jaki upłynął od startu gry. Te informacje wraz z wynikiem punktowym trafiają na serwer, gdzie zapisywane są wraz z czasem ukończenia gry (także według wskazań serwera).
Proste oszustwa
Oszukiwać można na wiele sposobów. Jedną z podstawowych rzeczy, jakie sprawdzaliśmy, był czas między startem a końcem gry. Dwie minuty powiększone o czas przesłania danych w obie strony powinien oscylować w okolicy 123 sekund. Większość odpowiedzi mieściła się w tej granicy, choć zdarzały się i dłuższe gry. Czy dwa zapytania mogą zająć pięć sekund? A dziesięć? Uznaliśmy, że tak. Jeśli ktoś oszukuje czas, nie będzie grał 2:10 tylko 3‑4 minuty. I tak w istocie było. Część z grających znalazła sposób na oszukanie czasu, logując gry sporo dłuższe
Najdłuższa gra? 58 minut na koncie użytkownika ipGregory. Mam wrażenie, że debugował swój automat i musiał na dłuższą chwilę odejść od komputera. ;) Jak można było oszukać czas? Okazuje się, że bardzo prosto — po starcie gry wystarczyło odłączyć sieć. Po dwóch minutach podpiąć ją ponownie, uparcie grać, po czym kliknąć Stop. Nie naprawialiśmy tego zgłoszonego już pierwszego dnia błędu, bo jest on bardzo prosty do wykrycia. A przynajmniej zostają ślady po graczach grzebiących w grze.
Inne proste (i częste) oszustwo to wpisywanie sobie wyniku w danych zwracanych do serwera. Zwracany log zawierał bowiem obok listy kliknięć sumaryczny wynik punktowy (i identyfikator gry oczywiście). Znaleźliśmy sporo gier, w których np. dwa motyle za 3 punkty dawały w sumie ponad 2000 punktów. :) Takie rzeczy są równie łatwe do wyłapania, co wspomniane wcześniej manipulacje czasem.
Zmiany w JS
Część z grających postanowiła zmodyfikować kod gry w sposób, który powodował, że rozgrywała się ona na autopilocie. Wystarczy w kodzie gry, w miejscu, w którym ustawiamy status motyli oznaczając je czerwoną obwódką, automatycznie wywołać kliknięcie na tagu canvas w określonym punkcie. Wystarczy też usunąć motyla z listy a jego współrzędne dodać do tablicy logów.
Większość z dłubiących w kodzie była na tyle czujna, by dodać tutaj odrobinę losowości. Część jednak (tutaj patrzę na użytkownika cayman3_11 ;]) przez pewien czas nie zauważyła, że zwracane są wartości całkowite a nie zmiennoprzecinkowe. To ewidentne oszustwo głównie dlatego, że nie da się kliknąć w piksel w miejscu 123.33333 x 78.128. ;) Dla pewności sprawdziliśmy jak zachowuje się przeglądarka, kiedy powiększymy lub pomniejszymy przybliżenie obrazu. Na szczęście wartości wciąż są całkowite, więc oczywiste oszustwa tego typu można bez problemu wyłapać.
Co jednak w sytuacji, gdy ktoś używa bota klikającego w okno strony? Jak wykryć coś takiego?
Za mnie klika bot
Wspomniałem wcześniej o dodawaniu do wyników automatów losowości. To dobry sposób, by nie dać się złapać. Rzecz w tym, że grający ludzie charakteryzują się pewnymi konkretnymi cechami. Na przykład: nie reagują w czasie zerowym, nie są w stanie trafić w oddalone od siebie o 200px punkty w czasie poniżej 33ms, itp. Pomocą w znajdowaniu automatów okazuje się statystyka.
Czy ktoś może mi powiedzieć, który z powyższych wykresów nie pasuje do pozostałych? Prawdopodobnie bez najmniejszych trudności każdy wskaże prawy górny wykres. Co on przedstawia? Ilość kliknięć w czasie gry (pionowa oś) które zanotowano w pewnej odległości od środka motyla (pozioma oś; odległość w przestrzeni taksówkowej, należy pomnożyć przez 2 wartości na osi). Wyraźnie daje się zauważyć, że - użytkownik/bot nigdy nie klikał daleko od centrum motyla - bardzo często trafiał ~15px od środka
Jako że redakcja także uczestniczyła w grze, dysponowaliśmy tysiącem wyników, co do których autentyczności nie było cienia wątpliwości. W redakcji grało kilkanaście osób i wyniki żadnej z nich nie cechowały się rozkładem takim, jak widoczny w prawym górnym rogu. Co więcej, jeśli znaleźliśmy intrygujące wyniki u zaufanych czytelników, wystarczyło zapytać mailowo, czy nie używają bota. Przykładowa odpowiedź na takie pytanie? „Przez kilka gier testowałem bota kolegi”. Społeczność portalu jest w przeważającej większości uczciwa. :)
To nie jedyna metryka. Inną, którą stosowaliśmy, była prędkość z jaką gracz klikał. Mam nadzieję, że wszyscy zainteresowani widzieli prezentację bota, jakiego napisał command-dos. Jeśli nie, można ją zobaczyć na YT.
Spośród tysięcy sprawdzonych gier dało się wyciągnąć proste wnioski: jeśli za monitorem siedzi człowiek, to prędkość od kliknięcia do kliknięci nie przekracza 45 pikseli na klatkę animacji (dalej: ppf). Pojedyncze, szybsze trafienia zdarzają się prawie każdemu, ale nie dominują one w statystykach gry.
Powyżej widzimy statystyki prędkości 5 graczy: trzech pierwszych to ludzie, dwa ostatnie to boty. Drugi od prawej nie pozostawia mam nadzieję najmniejszych wątpliwości. Największą trudność sprawia wykres najbardziej wysunięty na prawo.
Pierwotnie sądziliśmy, że to osoba grająca na ekranie dotykowym. Dwa palce nad ekranem dają przecież przewagę. Przeprowadziliśmy wewnętrzne testy na iPadzie oraz na tablecie uzbrojonym w Androida. Wyniki były faktycznie lepsze, ale zaledwie o kilka procent. Górna, powtarzalna granica przesunęła się z 45ppf do 50ppf. Wniosek jest jeden: jedna osoba nie ma na tyle podzielnej uwagi, by granie oburącz przynosiło takie rezultaty. A podobne wyniki widzieliśmy u kilkunastu graczy.
Są zatem dwie możliwości: bardzo dobrze napisany bot lub... dwa kursory na ekranie i dwie myszy w rękach dwóch osób. :) Da się tak grać i przynosi to niezłe wyniki. Ale granie parami to nie jest naszym zdaniem uczciwe podejście do zabawy.
Jest jeszcze jedna metryka: ilość motyli złapanych w czasie gry. Gracze z najlepszymi wynikami osiągali wynik około 120 motyli na grę. Wartości powyżej 130 nie odnotowaliśmy u żadnego gracza z górnej dwudziestki, którego wszystkie metryki były przekonywająco ludzkie. Boty i „dwumyszowcy” sporadycznie tylko schodzili poniżej 140 motyli na grę. ;)
Odtwarzanie gry
Jest jeszcze jeden typ nieprawidłowości, jakie napotykaliśmy w wynikach: klikanie w nieistniejące motyle. Może się tak dziać w trzech przypadkach: wydłużenie czasu widoczności czerwonej ramki (domyślnie: jedna sekunda), zwiększenie obszaru klikalnego motyla, oraz całkowite ignorowanie położenia motyla na ekranie. Część wyników była wybitnie absurtalna: z sześciu motyli — dajmy na to: 1, 10, 3, 20, 10, 5 — znikał nieistniejący motyl za 50 punktów. Niektóre logi składały się wręcz z samych ciem (50 punktów każda). :)
Jak to wygląda w praktyce? Znając wylosowane pozycje motyli, można interpolować ich położenie w dowolnej chwili i „przewinąć” grę do momentu, w którym nastąpiło kliknięcie.
Na zrzucie powyżej widać, że usunięto z gry motyla za 3 punkty, mimo iż ten znajdował się nieopodal środka zakresu głębokości gry (‑193 oznacza z = -0.193). Krzaczki z boku pokazują historię motyla: czarne ostatnią sekundę, różowe dwie sekundy z życia motyla. Widoczny na zrzucie motyl za trzy punkty nie przekroczył przez ostatnie dwie sekundy pozycji z = -0.85, zatem nie dało się go kliknąć.
W logach poprawnie zweryfikowanych graczy zdarzały się takie błędy: czasem jeden, czasem trzy. Historia pozycji pokazywała jednak, że jest to kliknięcie zarejestrowane 1‑5 klatek po tym, jak zniknąć miało jego zaznaczenie. Udało nam się taką sytuację zasymulować dociążając procesor. Nigdy jednak nie osiąga się szarpnięć animacji sięgających kilku sekund, więc gry, w których takich zdarzeń widać było kilkadziesiąt — odrzucaliśmy.
Wnioski
Zabawa z motylami nasuwa kilka spostrzeżeń, które podsumuję w krótkiej liście: - w każdej zabawie należy znaleźć sposób na wykazanie się zarówno graczom z doskoku („klikaczom”) jak i autorom botów, którzy chcą się zmierzyć z logiką gry, a nie wydolnością organizmu - im więcej informacji loguje się, tym lepiej: żałuję, że nie logowaliśmy chybionych kliknięć, bo dałoby nam to więcej danych do analizowania - mimo krytyki wciąż uważam, że gra która zawsze działa u konkretnej grupy użytkowników jest lepsza, niż gra która czasem działa nieokreślonym użytkownikom, zresztą... - nie ważne co zrobisz, ktoś będzie niezadowolony - canvas jest świetne, mimo kiepskiej implementacji w Chrome i Firefoksie
Słowo na zakończenie
Zgodnie z wcześniejszym ogłoszeniem, postanowiłem opublikować także listę wyników botów. Jest to Top 5 botów (i naginaczy zasad), z którego wykluczono gry niepoprawne z punktu widzenia mechaniki gry (złapane motyle, których nie ma, wynik wpisany „z palca”, itp.). Oto one:
3223 - cayman3_11 3119 - pebal 2728 - command-dos 2539 - ipGregory 2330 - damian879
Kilka osób wypadło z oficjalnej listy dziś rano, kiedy po raz ostatni sprawdzałem pierwszych 21 graczy. Okazuje się, że byli i tacy bociarze, którzy celowali w bezpieczne, 20. miejsce. ;)
Również zgodnie z wcześniejszymi zapewnieniami, postanowiliśmy wyróżnić autora jednego z botów. Wybranym przez redakcję szczęśliwcem został pebal, którego wyniki od samego początku były mechanicznie poprawne, i który przy tym nie ukrywał tego, że używa automatu. Tym samym pebal otrzymuje zaproszenie na HotZlot 2011, które (jeśli np. nie pasuje mu termin) może zamienić na garść upominków od portalu. A ja gratuluję autorom wszystkich botów i... do napisania przy okazji kolejnej gry! :]