Jakie są zalety i wady włączenia Lua do gry w C ++?


37

Mam książkę do programowania w C ++ i mam w niej sekcję Lua. Zacząłem czytać sekcję Lua i brzmi to interesująco, ale nie mogę określić zalet i wad używania Lua w mojej grze C ++. Jedyną korzyścią, o której obecnie myślę, jest to, że możesz dokonywać aktualizacji kodowania za pośrednictwem Lua bez konieczności ponownej kompilacji. Poza tym nie mogę nic wymyślić. Jakie są zalety i wady dodawania Lua do gry w C ++?

Przykłady będą mile widziane.




Zgadzam się, że jest podobny do tych pytań, ale ważne są tutaj „minusy”.
Jonathan Dickinson

@JonathanDickinson odpowiedzi nie wskazują jednak tego kierunku ... w zasadzie są takie same, jak w powiązanym pytaniu.
bummzack

Odpowiedzi:


33

Jedyną korzyścią, o której obecnie myślę, jest to, że możesz dokonywać aktualizacji kodowania za pośrednictwem Lua bez konieczności ponownej kompilacji.

Nie lekceważ użyteczności tego tak łatwo. Nigdy nie zrozumiesz, jak będziesz produktywny, dopóki nie usuniesz kroku ponownej kompilacji.

„Płynąć” jest dość dobrze rozumieć pojęcie psychologiczne, jeśli chodzi o pracę. Płynie z tego uczucie, gdy koncentrujesz się na aktywności, kiedy analizujesz i rozwiązujesz problemy prawie bez zastanowienia itp. Jesteś najbardziej wydajny, kiedy „płyniesz”.

Czasy kompilacji wszystko psują. Trudno jest pozostać w ruchu, jeśli masz 10-sekundową kompilację między testowaniem czegoś.

Kiedy rozwijasz rozgrywkę, zwykle masz „ciasną pętlę”. Masz pomysł, kodujesz test, aby sprawdzić, czy działa, a następnie wypróbowujesz. Jeśli to nie działa, zmodyfikuj go i spróbuj ponownie. Czas „testowania kodu” jest bardzo ważny dla utrzymania przepływu. Kluczowe znaczenie ma zmniejszenie jej do minimum.

Lua (lub dowolny wbudowany język skryptowy) pozwala ci testować zmiany, nie tylko bez „kompilacji”, ale także w grze . W zależności od tego, jak zbudujesz grę, możesz uruchomić polecenie, które uruchomi ponownie grę z nowymi skryptami, bez konieczności zatrzymywania i ponownego ładowania danych itd. Nie tylko nie musisz ponownie kompilować, nie musisz ponownie uruchamiać.

Zdolność do tego, przy odpowiednim wsparciu silnika, może znacznie zwiększyć wydajność.


Kolejną ważną zaletą skryptów jest możliwość po prostu nie dbania. Jeśli spędziłeś dużo czasu na pisaniu C ++, byłbyś zaskoczony, ile czasu spędzasz w ciągu kilku minut. Gdzie pamięć jest usuwana. Gdzie to się uwalnia. Nawet jeśli używasz shared_ptrwszędzie, wystarczy samo wpisanie wszystkich tych nazw zmiennych spowalnia cię.

W dynamicznie pisanym języku skryptowym nie musisz się tym przejmować. Określanie zakresu jest proste. Funkcje są pierwszorzędnymi obiektami; nie musisz ręcznie budować funktorów. Tak łatwo jest robić pewne rzeczy.

To ma negatywne strony, jeśli nie jesteś zdyscyplinowanym programistą. W Lua bardzo łatwo jest używać globałów (choć istnieją sposoby, aby temu zapobiec). Brak opieki oznacza, że ​​możesz być bardzo niechlujny podczas pisania kodu.

Ale z drugiej strony bycie bardzo niechlujnym może mieć zalety .


Kolejną zaletą Lua jest to, że tworzy ładny język opisu danych. Podobnie jak JSON to tylko plik JavaScript, który buduje i zwraca tablicę / tabelę, możesz tworzyć skrypty Lua zwracające tabele.

Jest to przydatne w przypadku plików konfiguracyjnych; Format tabeli Lui jest znacznie lepszy niż format .ini. Format jest nadal dość czysty, kompaktowy i rozszerzalny.

Aha, i wciąż jest to skrypt Lua, więc może wykonywać logikę. Minusem tego jest ... cóż, jest to skrypt Lua, więc może on wykonywać rzeczywistą logikę . To może być katastrofalne w grze, ponieważ użytkownik może potencjalnie zacząć coś popsuć.

Ale tak naprawdę łatwo sobie z tym poradzić. Lua została zaprojektowana do osadzania, co oznacza, że ​​izolacja jest w rzeczywistości dość łatwa. Rzeczywiście, nowy stan Lua domyślnie nie zapewnia niczego ; musisz zrobić coś, aby odsłonić nawet najbardziej podstawowe ze standardowych bibliotek Lua. Dostęp do plików, dostęp do stanu gry itp. Jest wyłącznie opt-in, a nie opt-out. I każdy stan Lua jest odrębny od siebie. Stan Lua używany przez skrypty AI nie musi być stanem Lua używany przez pliki konfiguracyjne.

Mam trochę kodu, który pozwala ci zarejestrować wiele standardowych bibliotek Lua, ale przechodzi i usuwa wszystkie pliki IO. Ostatecznie najgorsze, co może zrobić plik konfiguracyjny oparty na skryptach Lua, powoduje awarię gry natychmiast po uruchomieniu, powodując brak pamięci. A ponieważ nie udostępniasz ręcznie tych plików konfiguracyjnych, haker nie byłby zbyt zabawny.


Powiedziałbym, że największym minusem każdego języka skryptowego jest debugowanie. Większość języków skryptowych nie ma debuggerów, a Lua nie jest inaczej. Lua ma wszystkie narzędzia potrzebne do zbudowania narzędzi do debugowania. Ale tak naprawdę nie ma wbudowanego debugera. Musisz go połączyć. A to będzie wymagało rozsądnego poziomu pracy.

Lub możesz zrobić to z „debugowaniem printf”. To zależy od tego, ile kodu Lua piszesz.


1
płynięcie nie zawsze jest dobrą rzeczą; robienie rzeczy automatycznie oznacza czasami brak czasu na zastanawianie się nad alternatywami projektowymi.
lurscher 9.10.11

10
@lurscher: Projektowanie to to, co robisz, zanim usiądziesz do pisania kodu. Powinieneś był wypracować wszystkie te alternatywne rozwiązania, zanim zaczniesz pisać, testować i debugować swój kod.
Nicol Bolas,

23

Gdzie pracuję:

Plusy:

  • ulepszenia czasu iteracji . Nasza gra jest skonfigurowana do sondowania systemu plików hosta w poszukiwaniu zmian i automatycznego „slurpowania” zmian. (Działają tylko przy następnym otwarciu pliku, ale w praktyce jest to znaczna poprawa: przeładuj poziom, a twoje nowe zmiany lua pojawią się natychmiast.)
  • integracja konsoli . Wszelkie funkcje debugowania można podłączyć do tradycyjnej konsoli w stylu Quake z REPL. W przypadku wewnętrznych wersji możemy nawet podłączyć REPLA lua do prostego gniazda, które obsługuje telnet, i mamy kontrolę sieci nad naszą grą.
  • zmniejszone API i niższa krzywa uczenia się . Nietechniczni artyści i projektanci mogą dołączyć do niektórych zadań, które zwykle byłyby wąskie gardłem programisty.
  • specjalistyczna analiza kodu statycznego . Łatwo jest przeanalizować dane wyjściowe luac -li zerknąć na kod bajtowy, aby przeprowadzić analizę; bardzo łatwo jest również parsować większość plików źródłowych lua, szczególnie jeśli masz konwencję kodowania. Możemy egzekwować lokalną konwencję. Możesz także zajrzeć do metalua, aby uzyskać jeszcze więcej mocy.
  • obsługa błędów . Jeśli nasze API jest wolne od awarii, nawet jeśli lua robi coś głupiego, możemy go złapać i odzyskać za pomocą lua_pcall.
  • łatwe rozszerzenie API . Napisanie nowej funkcji dla Lua <-> C ++ API nie jest zbyt trudne. Istnieją również pakiety, które pomogą to zautomatyzować.
  • proste źródło . Wprowadzanie zmian, aby np. Uniknąć matematyki zmiennoprzecinkowej w interpreterie lua (ważne na niektórych wbudowanych platformach) lub zoptymalizować pod kątem konkretnych systemów, nie jest zbyt trudne!
  • metatable . To są niesamowite. Tyle możliwości robienia interesujących rzeczy w czasie wykonywania. Mamy „wirtualne tabele”, które w rzeczywistości nie zawierają żadnej zawartości, i wyszukujemy skomplikowaną strukturę danych po stronie naszych gier w języku C ++.
  • coroutines . Możliwość zatrzymania i wznowienia np. Skryptów zachowania AI jest niesamowita. Jednak ze strony Lua Scriptera wymaga to nieco więcej rozumu - wciąż pracujemy nad tym, jak uczynić to bardziej „bezpiecznym” dzięki naszemu silnikowi.

Cons:

  • nieprzewidywalny GC . Dostrajanie tego, co steppowinno być, zmienia się drastycznie w każdej grze. Niektóre działają lepiej z pełnym GC na każdej ramce (mały zestaw roboczy). Niektóre pracują lepiej przy znacznie mniejszych przepustkach rzadziej. Pamiętaj, że jest wiele pracy nad ulepszeniem GC w nowszych wersjach Lua i niektórych łatkach (których nie powinieneś się obawiać!)
  • wyższe koszty ogólne . Trzymamy wiele naszych dużych struktur danych po stronie C, aby uniknąć narzutu pamięci na tabelę. C ++, C i asembler generalnie generują szybszy kod. Jest to więc 90% silnika gry, który nie jest krytyczny pod względem wydajności, i czasami migrujemy rzeczy z lua do C (lub odwrotnie).
  • fragmentacja . Być może największy problem w małych systemach pamięci. Zwykle używamy puli małych obiektów i całkowicie oddzielnej sterty dużych obiektów dla lua. Umieszczamy pełne podania GC w strategicznych punktach gry. lua_StateW niektórych przypadkach rozładowujemy skrypty lub całkowicie je wyrzucamy . Nadal czasami mamy problemy. Strojenie wielkości pul małych obiektów (są one ustalone dla uproszczenia i obniżenia kosztów ogólnych) oraz wielkości stosu dużych obiektów specyficznych dla lua może być uciążliwe. Ale w systemach większych niż około 4 MB nie zawracaliśmy sobie głowy specjalistycznymi stertami i pulami.
  • brak bezpieczeństwa typu . Jeśli nie masz zbudowanego dobrego zestawu narzędzi do analizy kodu statycznego, powrócisz do sprawdzania błędów w czasie wykonywania (być może przy użyciu __indexi __newindex). Lepiej jest, jeśli można wykryć błędy w czasie kompilacji. Istnieją różne rzeczy, które możesz zrobić, aby to złagodzić.

Gorąco polecam Luę, po prostu trochę z nią popracuj! Możesz także sprawdzić Squirrel , chociaż uważam, że ma mniejszą bazę użytkowników.


Chciałbym móc głosować wiele razy. Bardzo wszechstronny, bardzo wnikliwy, jasno skonstruowany. +1
Koarl

5

W rzeczywistości istnieją 3 wielkie zalety:

Czynniki te pozwalają ci jako twórcy gier na włączenie funkcji, które przyspieszą rozwój i poprawią jakość twojej gry.

Na przykład:

  • Będziesz mógł zmienić logikę gry, po prostu aktualizując grę z pliku lub gniazda sieciowego.
  • Możesz zezwolić użytkownikom na tworzenie własnych skryptów (dla botów lub modów)
  • Twoi projektanci i artyści gier będą mogli aktualizować i testować części gry bez konieczności korzystania z zestawu narzędzi do kompilacji.
  • Nie będziesz musiał dokonywać ponownej kompilacji za każdym razem, gdy zmienisz kilka skryptów.
  • Nie będziesz musiał przepisywać całej gry, jeśli zmienisz platformy / silniki / języki.

1
„Nie będziesz musiał przepisywać całej gry, jeśli zmienisz platformy / silniki / języki”. Chyba że zmienisz język z Lua na inny język. A jeśli piszesz swoją „całą grę” w Lua, jeśli zmieniasz silniki, to ta zmiana musi zostać ujawniona Lua (lub potrzebujesz pewnej abstrakcji między Luą a silnikiem, aby ukryć szczegóły). Więc nie rozumiem, jak Lua pomaga w takich przypadkach.
Nicol Bolas,

3

Z mojego doświadczenia trochę sprowadziłem.

Plusy

  • Wstępna integracja jest naprawdę łatwa. Istnieją narzędzia pomagające w generowaniu powiązań, ale mechanizm wiązania jest tak prosty, że można napisać własną wersję z własnymi niestandardowymi funkcjami w mgnieniu oka
  • Otrzymujesz znacznie szybszą iterację w logice gry (przy założeniu, że zaimplementujesz ponowne ładowanie środowiska wykonawczego)
  • Otrzymasz wyzwalające środowisko do eksperymentowania: wypróbujesz więcej rzeczy, ponieważ koszty z tym związane znacznie spadną
  • Znajoma składnia: pomimo wszystkich różnic, jako programista C trudno będzie ci się czuć komfortowo w ciągu kilku godzin
  • Lepsze oddzielenie logiki gry od „silnika”: silnik staje się usługodawcą, który musi udostępnić przyzwoity interfejs API klientowi Lua. Bariera językowa sprawia, że ​​myślisz o tym więcej, zamiast po prostu sięgać i manipulować zmienną składową

Cons

  • Zarządzanie pamięcią Lua nie jest idealne do gier. Poradzisz sobie z tym, nie podoba ci się
  • Debugowanie Lua jest od razu okropne. Będziesz musiał pracować, aby poprawić wrażenia
  • Przechowywanie danych w Lua oznacza, że ​​będziesz musiał debugować w Lua: sprawdzenie ich z C będzie początkowo trudne
  • Lua ma spory zastrzyk w składni stóp, podobnie jak wszystkie zmienne są domyślnie globalne
  • Lua jest językiem programowania, tak jak każdy inny. Nie oczekuj, że nieprogramiści magicznie zamieniają się w programistów tylko dlatego, że usunąłeś kompilator
  • Umiejętność integracji i wsparcia Lua to spory kawałek pracy. Nie oczekuj, że będzie mruczeć zaraz po wyjęciu z pudełka. Można założyć, że faktycznie trzeba będzie amortyzować ten koszt w kilku grach

Ostateczny, osobisty werdykt: jeśli budujesz przyzwoitą grę i nie masz jeszcze języka skryptowego, zdobądź Luę. To będzie tego warte.


1

Garry's Mod to jeden przykład gry wykorzystującej Luę i C ++. Używają Lua do wszystkich modów, co znacznie ułatwia ich tworzenie. C ++ jest używany do wszystkich elementów wewnętrznych. Jedynym oszustwem, o którym mogę pomyśleć, jest fakt, że Lua nie jest tak szybki jak C ++.

Korzystając z naszej strony potwierdzasz, że przeczytałeś(-aś) i rozumiesz nasze zasady używania plików cookie i zasady ochrony prywatności.
Licensed under cc by-sa 3.0 with attribution required.