r.

Technicznie o skillshotach

Czyli o nowym systemie pocisków i skillshotów od kuchni. Dużo spraw technicznych.

Witajcie po raz kolejny! Dzisiaj przyjrzymy się nowemu oraz staremu systemowi skillshotów i pocisków – a wszystko dzięki pracownikowi Riotu – Brianowi “Penrifowi” Bossé – który postanowił podzielić się publicznie kilkoma szczegółami technicznymi przeprowadzonej niedawno zmiany. Jak zaznaczył – jeśli wszystko poszło jak trzeba, to gracze nawet nie zauważą różnicy. Mimo wszystko, chciałby przekazać nam kilka informacji i wytłumaczyć, dlaczego system był potrzebny.

 

Krótko mówiąc: stary system okazał się tak skomplikowany, że praca z nim była prawie niemożliwa. Nowy za to jest tak fajny w obsłudze, że w ramach prezentacji i kilku godzin pracy (działając na tabletkach przeciwbólowych, więc w trochę “rozproszonym” stanie) postanowił zrobić coś takiego:

Pociski – nadzwyczaj skomplikowana sprawa

Żeby ludzie mogli lepiej zrozumieć pracę, z jaką zmierzyli się programiści Riotu, powinni zapoznać się z działaniem pocisków w trybie klatka-po-klatce:

 

missile_flow_before
Można byłoby pozwolić Wam obejrzeć wersję z zoomem, ale sytuacja jest tutaj taka sama, jak w przypadku muzyki elektronicznej – słowa nie mają znaczenia.

Wprawdzie nie jest to tak skomplikowane, jak w systemach naprowadzania prawdziwych rakiet, ale sami widzicie, że przepływ informacji tutaj jest diabelnie skomplikowany i ryzykowny. Krótko mówiąc, to, na co tu patrzymy, to hierarchia rodzajów pocisków, a każda skupia inny ich zestaw. Funkcjonalność, którą zapewniają różne typy, czasami jest współdzielona, czasem – duplikowana, a najczęściej doprowadza do stanu kompletnego zdumienia. Diagram rozbija typy z podobną funkcjonalnością oznaczoną danym kolorem poziomo. Przykładowo: żeby sprawdzić, jak pociski radzą sobie z wykrywaniem kolizji, musielibyście przeanalizować cały różowy kod – wygodnie rozmieszczony wszędzie dookoła.

Górny kwadrat w diagramie zawiera coś, co można nazwać “podstawowym pociskiem”, klasą-korzeniem w hierarchii. To są najprostsze pociski – lecą w kierunku pozycji albo jednostki i aktywują się tylko po zakończeniu ruchu. Autoataki i strzały od wież znajdują się właśnie w tej grupie, tak jak m.in. [Q] Corkiego i [R] Ziggsa. Ich przepływ jest całkiem prosty – śledzą cel, oceniają, gdzie pocisk powinien się poruszyć, a następnie sprawdzają, czy trafiły w odpowiednie miejsce. Prościutto.

Następnym wielkim prostokątem w diagramie są “pociski liniowe” zawierające większość z tego, co gracze nazywają “skillshotami” – [Q] Luxanny, [W] Ashe czy praktycznie wszystko, co robi Ezreal. Jest także kilka zaskakujących umiejętności, przykładowo Windwall Yasuo – jest on pociskiem liniowym. Ironiczne aż do bólu.

Pociski liniowe są w swoim zachowaniu o niebo bardziej skomplikowane niż podstawowe pociski. Przykładowo, mogą trafić cele podczas lotu, mogą wrócić do postaci która je rzuca ([R] Dravena) lub przyczepić się do ziemi (Grasping Roots od Zyry). Wrzucenie wszystkich tych rodzajów umiejętności w jedno miejsce jest samo w sobie wielkim grzechem, ale pociski liniowe są jeszcze bardziej złożone przez bycie potomkiem podstawowych pocisków. Z tego powodu, pociski liniowe domyślnie dziedziczą wszystkie funkcjonalności pocisków podstawowych, ale używają ich w różny sposób. To sprawiło, że Riot znalazł się we frustrującej sytuacji, w której zmiany wprowadzane do pocisków podstawowych niosły ryzyko popsucia pocisków liniowych.

 

Małe grupy na dole to trzy pociski “okręgowe”: [Q] i [W] Diany oraz [W] Ahri. Zachowują się bardzo podobnie do pocisków liniowych, ale wędrują po okręgu. Dziedziczą z pocisków podstawowych oraz są we wszystkim uderzająco podobne do pocisków liniowych – poza ich ruchem. W trakcie tworzenia tego diagramu Penrif znalazł kilka bugfixów w pociskach liniowych, które nie trafiły do tych okręgowych. Duplikowanie kodu duplikuje także błędy – taki ból niesie właśnie copy-pastowanie.

 

Alternatywny sposób przedstawienia tego diagramu

 

Krótko mówiąc, system pocisków w LoL-u był niepotrzebnie skomplikowany, strasznie zagmatwany i raczej łatwy do uszkodzenia. Jako że pociski reprezentują sobą ważną część gry, pracownicy Riotu musieli sprawić, by prace przy nich były dużo łatwiejsze. Metodą, którą wybrano, było kompletne zniszczenie obecnego systemu i napisanie go od zera. To był jedyny sposób, by mieć pewność, że wszystko działa, jak należy.

 

 

Stan czysty

Przepisanie systemu miało opierać się na czterech zasadach:

  • Jak funkcjonalność powinna zostać rozmieszczona na nowo w kodzie, by łatwiej można było ją rozumieć?
  • Współzależności między różnymi grupami powinny być możliwie małe i zrozumiałe
  • Zrozumienie, co robią pociski (ogólnie), powinno być łatwe
  • Nietypowo zachowujące się pociski powinny być w czysty sposób odseparowane od głównej ścieżki.

Drużyna zmieniająca ten system zaczęła od zidentyfikowania głównych celów pocisków i zaplanowała pisanie komponentów, które adresowałyby każdy z tych problemów niezależnie od siebie. Najwidoczniej Penrif lubi różnych rodzajów listy, bo stworzył także taką, która opisuje, co robią pociski:

  • Ruch: pociski gdzieś lecą.
  • Kolizje: pociski w coś trafiają.
  • Namierzanie celu: pociski lecą w kierunku czegoś, co też może się poruszać.
  • Interfejs skryptowy: pociski potrzebują designerów, by powiedzieli im, co mają robić.
  • Widoczność: pociski muszą być widziane przez jedne rzeczy, ale nie przez inne.
  • VFX oraz dźwięki: musicie widzieć i słyszeć, co się dzieje.

Zaczęto od przepisania powyższej listy, zyskując komponent dla każdej grupy, który mógł zostać stworzony w locie lub nawet zmieniony w trakcie lotu. Z każdym krokiem głębiej w pracę nad tym systemem, wszystkie te kawałki były przeanalizowywane na nowo i otrzymywały odpowiednie zmiany, kiedy ich abstrakcje nie spełniały już swojego zadania. Przykładowo, wrzucono namierzanie celu do jednego worka z kodem odpowiadającym za poruszanie pocisku, kiedy zauważono, jak blisko są ze sobą powiązane, czy też wrzucono interfejs skryptowy do podstawowej klasy bazowej Pocisku, kiedy stwierdzono, że niepotrzebne jest rozróżnianie go między różnymi rodzajami pocisków.

 

Ostatecznie otrzymano system wyglądający tak:

 

Pierwszy diagram został nazwany "tęczowym rzygiem", a ten po prostu jest zbudowany z tęczy.
Pierwszy diagram został nazwany “tęczowym rzygiem”, a ten po prostu jest zbudowany z tęczy.

 

 

Tęcze są zajebistym materiałem budulcowym.

 

 

Co to oznacza dla League?

Tak więc, kiedy udało się zmienić system, pracownicy zyskali dwie główne korzyści. Po pierwsze, kod pocisków nie powinien już przerażać programistów, jako że błędy są dużo łatwiejsze do odnalezienia i naprawienia. To już zaowocowało możliwością naprawienia kilku błędów, które uważano od dawna za nienaprawialne.

Przykładowo, pracownicy od dawna drapali się po głowach, oglądając filmiki, w których pociski przelatywały przez ich cele. Mimo że to było coś niesamowicie rzadkiego, ten błąd głęboko wpływał na grę, kiedy się pojawiał. Bez sposobu na reprodukcję problemu i bez sensownych śladów, gdzie mielibyśmy szukać problemów, jedyne, co można było z tym zrobić, to zapamiętać takie zdarzenie i zająć się czymś innym. Jednakże, po zebraniu całej detekcji kolizji w jedno miejsce i oczyszczeniu tej części kodu, nagle bardzo szybko odkryto kilka scenariuszy, w których kolizja nie następowała. Po naprawieniu tej części pracownicy są prawie całkowicie pewni, że pociski będą trafiały w to, w co powinny.

(W celu uniknięcia części flame’u, autor tłumaczonego przeze mnie tekstu stwierdził, że nadal mogą istnieć pojedyncze przypadki, gdzie pocisk przeleci przez swój cel. Podejrzewa jednak, że to może wynikać z błędów w synchronizacji pozycji między jednostkami niż z powodu detekcji kolizji samych pocisków).

Wprawdzie posiadanie szczęśliwszych programistów i mniejszej liczby błędów jest dobre i w ogóle fajne, ale drugim i większym sukcesem jest fakt, że pracownicy są teraz w stanie zrobić więcej nowych rzeczy z pociskami w szybszy sposób. Nie ma już potrzeby tworzenia całej nowej klasy pocisku w celu wprowadzenia pocisku, który zachowuje się całkiem inaczej, więc można zająć się dzikimi pomysłami.

Na zakończenie pojawiło się też kilka pomysłów. Nie są one żadnymi propozycjami, które mają zostać wykorzystane w przyszłości; są one tylko wynikiem pracy inżynierów z pewną dozą wolnego czasu i chęcią zabawienia się.

 

“Mieliśmy trochę zabawy z robieniem pętelek w trakcie lotu pocisków, a w przypadku Dravena wyglądało to fenomenalnie.”

 

“A na skutek pewnej zmiany mogliśmy dać Varusowi nieco więcej miłości.”

 

“Sześciokąty to najlepszokąty.”

 

Lista gości, którym można podziękować za nowe pociski:

  • Brian “Riot Penrif” Bossé
  • Anoop “Noopmoney” Kamboj
  • Kevin “kbox” Borer
  • Vasiliki “vLemon” Siakka
  • Abe “Riot Meyea” Nguyen
  • Jessica “Safelocked” Nam
  • Richard “Riot Asyrite” Henkel

 

 

 

Spaghetti alla chitarra by Jessica Spengler is licensed under CC BY 2.0
Rainbow by Steve Snodgrass is licensed under CC BY 2.0

Źródło: Tekst opublikowany przez Briana Bossé