Jaka technologia umożliwia programowanie w grze?

27

Istnieje kilka gier, które pozwalają graczowi pisać / tworzyć skrypty w grze, na przykład: inżynierów kosmicznych lub Psi .

Chcę użyć czegoś podobnego do jednego z nich, ale miałem trudności ze znalezieniem informacji, więc moje pytanie brzmi:

Czy istnieje gałąź programowania, która obejmuje zdolność skompilowanego oprogramowania do uruchamiania nowego kodu utworzonego przez użytkownika?

Przez gałąź programowania rozumiem coś w stylu PTG (Procedural Terrain Generation).

Aby uniknąć zbyt szerokiego pytania lub opinii , pozwól mi jasno powiedzieć, że nie szukam przewodników ani miejsc do nauki, chcę nazwę lub definicję (jeśli taka istnieje) zastosowanej technologii.

Westside Tony
źródło
22
Cóż, prawdopodobnie „pisanie tłumaczy”?
MatthewRock
2
Odpowiedziałem ostatnio na podobne pytanie , omawiając „ maszynę wirtualną ” jako termin dla systemu, który uruchamia kod użytkownika, a także odwołując się do artykułu Wzorce programowania gier na temat wzorca kodu bajtowego jako sposobu na wdrożenie tego szybciej niż konwencjonalny interpreter.
DMGregory
3
Zwykle nazywa się to „skryptowaniem”. Znajdziesz mnóstwo materiałów na temat implementacji skryptów w grze, a także mnóstwo (różnie) przykładowego kodu źródłowego i prawdziwego kodu. W szerszym zakresie istnieje cała dziedzina programowania kompilatora (która obejmuje leksykację, parsowanie, kompilację, łączenie, interpretację ...). W najszerszym zakresie (niekoniecznie przydatnym) oznacza to praktycznie dowolną interakcję użytkownika z aplikacją - silnik skryptowy jest naprawdę o wiele bardziej złożonym sposobem wybierania z menu.
Luaan,
2
Program w języku Python może obsługiwać skrypty w języku Python. To się nazywa metaprogramowanie. Większość języków interpretowanych ma to.
user6245072,
1
AFAIK w Space Engineers, kod jest skompilowany kod C # w środowisku piaskownicy (gra przeszła na open source, więc możesz sprawdzić, jak to działa online: github.com/KeenSoftwareHouse/SpaceEngineers ). Zasadniczo gra jest dostarczana z kompilatorem C #, a kod pozwala tylko na dostęp do funkcji API gry, więc zakres programu jest ograniczony tylko do ciebie. A jeśli grasz w trybie wieloosobowym, kod działa tylko na twoim komputerze (inni gracze / serwer widzą konsekwencje w grze)
Florian Castellane

Odpowiedzi:

42

Skrypty napisane w językach skryptowych / osadzonych / interpretowanych, takich jak „Lua”, „Lisp” lub „AngelScript” ( więcej tutaj ), mogą być aktualizowane podczas gry [*], a następnie interpretowane (= wykonywane) w locie.

Możesz powiązać elementy z tych skryptów z natywnym skompilowanym kodowaniem (C ++ itp.), Aby skrypty mogły następnie wykonywać logikę z aplikacji. Np. specyficzne polecenie, które użytkownik może wprowadzić do skryptu, w wyniku czego porusza się postać w grze o określoną odległość w świecie gry.

Niektóre powiązane pytania powiązane:


[*] albo przez użytkownika w ramach gry, albo przez programistów do szybkiej iteracji / testowania bez ponownego uruchamiania aplikacji

Philip Allgaier
źródło
14
Byłbym ostrożny, nazywając coś „językiem interpretowanym”. W najlepszym razie jest to termin bardzo dyskusyjny.
wondra
1
Computercraft (mod Minecraft) używa LUA jako języka skryptowego do programowania zadań w grze.
Tikeb
20
Naprawdę nie rozumiem zamieszania. Lisp może być interpretowany i kompilowany. Nie jesteśmy tutaj po to, aby omówić, jak klasyfikować języki i czy interpretedjest to dobra klasyfikacja; mówimy OP, który nie jest świadomy tego faktu, że języka nie trzeba kompilować, ale można go interpretować - i podajemy niektóre języki jako przykład. Czy Lisp jest interpretowany? Tak. Czy to jest skompilowane? Też tak! Ale to nie wchodzi w zakres. Odpowiedź może być niedokładna w sformułowaniu, ale jest odpowiednia do tego celu; popycha OP we właściwym kierunku i to się liczy. Tutaj weź moje +1.
MatthewRock,
1
Cóż, nawet jeśli język jest przeznaczony tylko do kompilacji, co powstrzymuje Cię przed osadzeniem IDE, kompilatora i środowiska uruchomieniowego w grze? To znaczy oprócz budżetu.
Ordous,
3
@DanielJour Chociaż zgodziłbym się, że teoretycznie język może różnić się od jego implementacji (skompilowany do kodu maszynowego vs skompilowany do kodu bajtowego dla vm), nadal jest to użyteczne, oszczędzające czas założenie, że C jest kompilowany, chyba że określono inaczej (i możesz sobie wyobrazić wygląd, który można uzyskać, gdy za każdym razem pytasz: „czekaj, skompilowałem C lub zinterpretowałem C?”. Dla celów PO musi on spojrzeć na języki, które wspierają tłumaczenie; kwestia, czy można je również skompilować, nie stanowi problemu, ponieważ nie tak by tego używał.
Blackhawk
12

Język osadzony jest właściwym terminem technicznym. W praktyce języki używane w innych aplikacjach (takich jak gry) są często nazywane językami skryptowymi lub nawet tłumaczonymi , chociaż niekoniecznie należy je interpretować lub wykorzystywać do automatyzacji rutynowych zadań. Googling „języki skryptowe do gier” prawdopodobnie przyniosłyby bardziej przydatne wyniki niż wyszukiwanie „języków osadzonych”.

interphx
źródło
11

Szukasz sposobu na zmianę kodu w niektóre akcje. To właśnie robią tłumacze .

Spójrz na Python. Uruchom to i bam! Lądujesz w REPL ( R ead E val P rint L oop).

Definiujesz funkcję „hello”, która wypisuje „Hello, world”. I masz to!

Zauważ, że nic nie skompilowałeś; interpreter zrobił magię, aby stworzyć funkcję w locie (w czasie wykonywania), a teraz możesz ją wywołać.

To samo dotyczy gier. Zamiast posiadania REPL, masz grę z modułem REPL. Gra prawdopodobnie uruchamia REPL, a następnie uruchamia wszystko inne w tej REPL, więc masz dostęp do danych i możesz aktywnie je modyfikować.

Jeśli pracujesz z dużymi językami, takimi jak C ++, są one zwykle mniej dynamiczne i prawdopodobnie skompilowane. Chcesz trochę łatwiej. Albo tworzysz własny język, albo używasz już istniejących (takich jak CoffeScript, Squirrel, Lua, Scheme, ...)

Są one często nazywane językami skryptowymi , ponieważ używasz ich do pisania skryptów opartych na silniku gry opracowanym w innym języku (np. C ++).

MatthewRock
źródło
2

Jeśli język programowania w grze został zaprojektowany wyłącznie do celów gry, to jest to język specyficzny dla domeny .

Zaletą (i wadą) języków specyficznych dla domeny jest to, że sam język może ograniczać to, co użytkownik może zrobić (tzn. Można zabronić łączenia się z Internetem). Możesz zaprojektować język, który sprawia, że ​​typowe zadania gry są łatwiejsze niż w języku ogólnego przeznaczenia. Wadą jest to, że użytkownik musi nauczyć się nowego języka.

Po prostu uruchamianie niezaszyfrowanego kodu użytkownika w języku ogólnego przeznaczenia (takim jak python lub perl) z poziomu gry, może pozwolić użytkownikowi na bałagan z rzeczami, z którymi nie powinien zadzierać. Ale to zależy od twojej gry. Jeśli nie masz nic przeciwko użytkownikom, którzy robią takie rzeczy, jak otwieranie nowych okien w grze lub cokolwiek im się podoba, możesz użyć języka ogólnego przeznaczenia i ujawniać powiązania z niektórymi funkcjami twojego świata gry.

TheEspinosa
źródło
1

Są dwa przykłady, które mogę wymyślić z czubka głowy. Oba wydają się robić dokładnie to, o co prosisz.

Pierwszym z nich są piargi. https://screeps.com/ Możesz przeczytać wiele o tym, jak osiąga ten cel na http://support.screeps.com/hc/en-us/articles/205960931-Server-side-architecture-overview

Drugi to ComputerCraft http://www.computercraft.info/ Nie podają one tak wielu szczegółów, jak to działa, ale trochę można zobaczyć na ich wiki http://www.computercraft.info/wiki/Main_Page

Zasadniczo główna gra uruchamia interpreter w osobnym wątku, a następnie pozwala temu wątkowi manipulować światem gry za pomocą wywołań interfejsu API.

W obu przykładach, gdy język jest prawie nieograniczony (tylko niektóre połączenia są blokowane ze względów bezpieczeństwa), manipulacje są ograniczone przez wywołania API, które można wykonać.

Zwykle potrzeba bardzo niewiele pracy, aby zacząć coś takiego. Potrzebujesz

  • menedżer wątków, który chroni pętlę gry (nie pozwala wątkowi zablokować pętli ani zużyć wielu zasobów). Oba przykłady wykorzystują ogranicznik czasowy.
  • tłumacz języka obcego. LUA jest obecnie dość powszechne.
  • zestaw wywołań API, które modyfikują świat gry. Cóż to za zabawa w język programowania, jeśli nie możesz nic z tym zrobić.
  • wdrożenie zarządzania zasobami. Innymi słowy sposób na przechowywanie plików kodu i odwoływanie się do nich w grze.

Nie ma jednej gałęzi programowania, która rozwiązałaby wszystkie te problemy. Ale będziesz potrzebować mocnych podstaw w wielowątkowości i ogólnej wiedzy o tym, jak działa tłumacz.

Coteyr
źródło
0

Skompilowany plik wykonywalny musi zawierać analizator składni, który jest w stanie odczytać kod programu zewnętrznego . Kod programu nie musi wyglądać jak C, Python lub Xyz - mogą to być dowolne dane opisowe odpowiednie dla danego celu. Na przykład szwedzki lub Morse.

Zewnętrzny kod programu musi mieć składnię , aby parser zrozumiał go podczas wczytywania znak po znaku. Składnia może opisywać (a kod może zawierać) identyfikatory, wartości liczbowe, operatory itp .

Analizator składni jest naprawiony (skompilowany), ale działa na elastycznym, zewnętrznym kodzie.

Skompilowany plik wykonywalny musi mieć wewnętrzny interfejs API zapewniający odpowiednią funkcjonalność. aby analizator składni mógł wykonywać działania. Najprawdopodobniej musi istnieć również (dwukierunkowy) dostęp do wewnętrznych danych pliku wykonywalnego, lub parser musi zapewnić pewnego rodzaju przechowywanie danych i porządkowanie.

Parser może odczytać zewnętrznego kodu programu w pliku wykonywalnego na starcie , lub można go odczytać (części) to ad hoc , lub może ponownie przeczytać go na każdej ramce (byłoby nieefektywne) lub kod może być nawet ręcznie wpisane i wysyłane do parsera, gdy jest gotowy (jak: „przesuń jednostkę X do przodu o 5 kroków” [enter]).

Zasadniczo kod zewnętrzny nie jest ustalony - można go zmienić w dowolnym roku, dniu lub minucie, ale mimo to plik wykonywalny nie musi być ponownie kompilowany. Zmienia się tylko wynikowe zachowanie hostowane przez plik wykonywalny.

Tekst, który właśnie czytasz, jest (w pewnym sensie, a nawet więcej, jeśli został wymówiony) interpretowany, ponieważ „wykonujesz” go w swoich mózgach podczas czytania, nie wiedząc, co powie następne zdanie (lub nawet jeśli może, podstępnie zmienia się w prawo teraz). W przeciwieństwie do Stack Overflow (pre) kompilującego całą historię do kodu bajtowego w twoich mózgach, który następnie ją wykonuje - i często nie może już się zmienić.

W Fenomen będące w toku jest interpretion. Skrypty to tylko czynność tworzenia OPISU lub pisania . Całe kodowanie komputerowe to skrypty imo - opisujemy, co chcemy się wydarzyć. Słowo „skryptowanie” ma nieco pochylone znaczenie, ale bądź w porządku. Wiemy, co mamy na myśli.

W tłumaczonych językach nie ma absolutnie nic nadzwyczajnego i nie jest to termin dyskusyjny . Istnieje ich wiele, a niektóre z najstarszych są interpretowane w przeciwieństwie do kompilacji. W tłumaczonym języku można na przykład ręcznie wpisać:

sock = Socket.New (AddressFamily.InterNetwork, SocketType.Stream ProtocolType.Tcp) [ENTER]

... a potem idź na 30 ... nie, 45-minutową przerwę na kawę :-). Po powrocie „skarpeta” istnieje i jest gotowa do dalszego użycia, pisząc więcej ręcznie lub pozwalając na kontynuację automatyzacji tłumacza.

Stormwind
źródło
Istnieje powszechne nieporozumienie, że tłumaczony język musi być wolny. To nie prawda. W zależności od różnych czynników, które powodują, że dyskusja jest zbyt szeroka dla komentarzy, interpretowany język może być o wielkości lub mniejszy, tak szybki, a nawet dla niektórych operacji szybszy niż język kontrolny uważany za szybki (zwykle C). Przykład z gniazdem prawdopodobnie działałby mniej więcej tak jak w C, więc przykład jest mylący. Możesz także przedefiniować skompilowane funkcje w środowisku wykonawczym w niektórych językach, a tłumaczenie nie oznacza po prostu „wykonania jednej instrukcji naraz”.
MatthewRock
Jasne, język interpretowany może również działać szybciej - w końcu to wykonywany jest kod bajtowy, a wykonanie może być znacznie lepiej zoptymalizowane, w zależności od automatyzacji tłumacza. Dodatkowo, niektórzy tłumacze mogą skompilować, z kodu, części kodu do kodu bajtowego (i wykonać), ad hoc. Przykład jest tylko przykładem wolności, „Jednoczesne wykonywanie jednej instrukcji”? To nadmierne uproszczenie, może dodać „podczas gdy przyszły kod jest elastyczny”.
Stormwind
Pomyśl o „skrypcie” bardziej jak o skrypcie filmowym - wciąż potrzebujesz aktorów, a ci są zdefiniowani bezpośrednio w kategoriach biologii i socjologii, a nie nauk teatralnych (choć ostatecznie są one oparte na biologii i socjologii), ponieważ te języki są bardziej nadaje się do tego celu, ale nie do drugiego :)
rackandboneman