gamedev, News

Zredukował czas ładowania GTA Online o 70%! Rockstar dziękuje programiście

Jeden programista przedstawił łatkę, która redukowała czas ładowania GTA Online o aż 70 procent. Ostatecznie poprawka trafiła do gry, a Rockstar zapłacił mu aż 10 tysięcy dolarów. Wśród narzędzi do wykrycia problemu deweloper wykorzystał… Menedżer Zadań.

7 lat po wydaniu Grand Theft Auto: Online gra doczekała się potężnego przyspieszenia ekranu wczytywania. Rockstar wziął się do roboty? Nic z tych rzeczy. Za redukcją czasu ładowania stoi łotewski programista o pseudonimie tostercx. Rockstar oficjalnie potwierdził, że jego rozwiązanie działa i wdrożył je do gry w formie aktualizacji. Gracze? Zachwyceni.

Przyczyna długiego ładowania

Problem długiego ładowania się multiplayerowej wersji Grand Theft Auto V istniał od samego początku. Przez wiele lat gracze próbowali skracać ten czas na różne sposoby. Rozwiązania okazywały się mniej lub bardziej skuteczne. Dopiero tostercx postanowił w pełni przeanalizować problem i wykorzystać swoje umiejętności programistyczne, aby naprawić to, z czym nie mógł (albo nie chciał) poradzić sobie dział deweloperów z Rockstar Games.

GTA Online obciążenie jednego rdzenia

Analiza obciążenia systemu podczas ładowania GTA Online, fot. tostercx

Uzbrojony w potężny Menedżer Zadań tostercx rozpoczął analizę obciążenia procesora, karty graficznej, dysku oraz sieci w celu wychwycenia bottleneck’ów. Jak się okazało, przez cały proces ładowania, gra obciążała pojedynczy wątek procesora. Programista spodziewał się ujrzeć szalejących wykresów zużycia dysku twardego lub sieci, lecz nic takiego nie nastąpiło. Wniosek? To musi być bug!

Analiza procesu ładowania

Brak dostępu do kodu źródłowego wymusił stworzenie scenariusza, który pozwoliłby dokładnie zlokalizować źródło problemu. W tym celu tostercx wykorzystał profiler Luke Stackwalker (nieaktualizowany od ponad 10 lat!). Program pozwolił na zbudowanie całego drzewa wywołań instrukcji w określonych odstępach czasu. Zebranie statystyk i voila – funkcje odpowiedzialne za obciążenie CPU odnalezione.

Luke Stackwalker analiza instrukcji GTA Online

Znalezione instrukcje, obciążające procesor, fot. tostercx

tostercx zauważył, że w GTA V wykorzystano jakąś metodę szyfrowania w celu ukrycia instrukcji, co miało uniemożliwić “łamanie kodu” z wykorzystaniem inżynierii wstecznej. Skutkuje to tym, że instrukcje muszą przejść proces deszyfracji przed ich wywołaniem.

Następnym krokiem było użycie disassemblera, czyli tego, co modderzy lubią najbardziej. Do akcji wkroczyło drugie narzędzie – Process Dump. Z jego pomocą programiście udało się ze sporym prawdopodobieństwem określić pierwszą instrukcję-winowajcę. Problemem okazały się trzy funkcje – strlen, vscan_fn oraz sscanf. Instrukcje te sugerują, że mamy do czynienia z parsowaniem jakiegoś “stringa”. Z użyciem narzędzia x64dbg, tostercx ustalił, że ma do czynienia z… parsowaniem pliku JSON o wadze około 10 MB i z ponad 63 tysiącami obiektów. W pliku prawdopodobnie znajduje się lista wszystkich przedmiotów i ulepszeń, które można kupić w GTA Online.

GTA Online scanf vscan sscanf

Znalezione funkcje, odpowiedzialne za spowalnianie ekranu wczytywania, fot. tostercx

Druga część instrukcji okazała się być wywoływana przez ten sam warunek if, zagnieżdżony w kodzie widocznym poniżej. Pętla dokonywała procesu parsowania i umieszczania danego elementu w tablicy. Nie byłoby w tym raczej nic złego, gdyby nie fakt, że za każdym razem funkcja sprawdzała, czy dany obiekt nie został już wcześniej zapisany. Według wyliczeń tostercx’a pętla trwała 1 984 531 500 powtórzeń. Funkcja niepotrzebnie przepisywała obiekty z JSON’a do tablicy i dodatkowo sprawdzała, czy dany obiekt występuje, podczas gdy wszystkie obiekty były, tak czy siak, unikalne.

GTA Online - parsowanie i zapisywanie danych do tablicy C++

Czas na rozwiązanie!

Tostercx zdecydował się na stworzenie biblioteki .dll z poprawionym kodem i “wstrzyknięcie” jej do gry. Programista nie mógł bezpośrednio zastąpić Rockstarowego parsera, więc postanowił wykorzystać funkcje strlen, poczekać na otrzymanie stringa, “zacache’ować” jego początek oraz długość jeśli zostanie wywołany ponownie i zwrócić jego wartość z pamięci podręcznej.

Programista umieścił gotowy Proof of Concept na swoim GitHubie. W rezultacie czas ładowania skrócił się z około 6 minut do 4:30 min (z usunięciem sprawdzania duplikatów), do 2:50 min (z poprawieniem parsera JSON) i do zaledwie 1:50 min (z użyciem obydwóch rozwiązań). Rozwiązanie skróciło czas łącznie o aż 70 procent.

Rockstar przekazał 10 tysięcy dolarów

Robocze rozwiązanie tostercx’a szybko rozeszło się wśród deweloperów oraz graczy. Zauważyli go także pracownicy Rockstar Games i przyznali programiście nagrodę w wysokości 10 tysięcy dolarów, przeznaczaną do tej pory wyłącznie dla osób, które wykryły poważne luki w zabezpieczeniach.

16 marca Rockstar wydał oficjalną aktualizację, wprowadzającą poprawki stworzone przez tostercx’a. Gracze z całego świata informują o tym, że różnice szybkości wczytywania są naprawdę ogromne. Ta historia to kolejny dowód na to, że nawet pojedynczy programista może naprawić problem, którego nie rozwiązało potężne studio deweloperskie.

 


Zdjęcie główne artykułu pochodzi z Rockstar Games. Źródło artykułu: nee.lv / tostercx.

Podobne artykuły

[wpdevart_facebook_comment curent_url="https://justjoin.it/blog/zredukowal-czas-ladowania-gta-online-o-70-procent-rockstar-dziekuje-bug-bounterowi" order_type="social" width="100%" count_of_comments="8" ]