Widziałem wiele gier, które definiują komponenty encji w plikach skryptów, ale kiedy konfigurują każdą encję i określają jej komponenty, używają innego formatu pliku (np. XML). Dlaczego oni to robią?
Pragnę głównie zobaczyć, jakie były uzasadnienia innych. Ja również skonfigurować moje podmioty spoza skryptów (choć nie wybrałem JSON XML). Moim powodem jest ułatwienie implementacji zapisywania gier, a także dlatego, że myślę, że tego rodzaju konfiguracja jest lepiej zorganizowana w coś takiego jak XML lub JSON.
@ Odpowiedź Christophera Larsena: Za długo, aby opublikować komentarz
Obawiam się, że mogłeś nieco odstąpić od tematu pytania. Opisywane przez ciebie problemy są bardziej związane z podmiotami opartymi na hierarchii; uwaga w moim pytaniu, o którym wspominałem, mówiłem o jednostkach opartych na komponentach.
Oto przykład tego, o co chciałem zapytać. Poniżej znajdują się dwa alternatywne sposoby konfiguracji encji: za pomocą skryptu i zewnętrznego pliku JSON. Moje pytanie brzmiało: dlaczego tak wiele osób woli konfigurować byt poza skryptami?
Podstawowa klasa jednostek:
class Entity:
def __init__(self, name):
pass
def addComponent(self, comp):
pass
Podejście skryptowe:
orc = Entity('Orc')
orc.addComponent(PositionComponent(3.4, 7.9))
Podejście JSON:
{
"name" : "Orc",
"components":
{
"PositionComponent": {
"x" : 3.4,
"y" : 7.9
}
}
}
Podałem już powody, dla których stosuję to podejście, które mają charakter techniczny i organizacyjny. Chciałem wiedzieć, dlaczego tak wielu innych (z tego, co widziałem) korzysta z tego.
źródło
Jednym z powodów, dla których zwykle używam do tego pliku konfiguracyjnego zamiast skryptu, jest:
Jedynym sposobem na sprawdzenie poprawności skryptu, np. Określenie wszystkich wartości, jest uruchomienie go.
Pisanie kodu w celu umożliwienia skryptom skonfigurowania wartości oznacza pisanie kodu do tworzenia szkieletowych obiektów dla skryptów w celu wypełnienia wartości, a następnie sprawdzenie, czy skrypt to zrobił i tak dalej. Ma więcej kodu i kodu buggera niż ładowanie z płaskiego pliku konfiguracyjnego, często przy użyciu biblioteki obsługującej pewien rodzaj mechanizmu sprawdzania poprawności.
źródło
Konfiguracja encji może być po prostu serializacją konkretnej encji. Dzięki temu możesz przetwarzać dane wyjściowe narzędzi do edycji i modowania mniej więcej tak samo, jak w przypadku zapisywania gry. W szczególności w przypadku gier, w których nie można przewidzieć, w jakim stanie będzie dana jednostka podczas zapisywania gry - na przykład ze względu na jej sztuczną inteligencję lub ponieważ są one częściowo generowane proceduralnie w pierwszej kolejności - warto zrzucić całość dane określające, czym „jednostka” jest (w przeciwieństwie do tego, co „robi”) jako strumień bajtów do zapisania.
źródło
Opisany przez Ciebie wzorzec jest implementacją systemu opartego na danych.
Systemy oparte na danych są powszechnie stosowane w tworzeniu gier, ponieważ pozwalają na enkapsulację definicji zawartości zewnętrznej względem źródła. Tę zewnętrzną reprezentację można następnie łatwo zmodyfikować (a nawet zaktualizować w czasie rzeczywistym przez aplikację obserwującą zmiany), aby zmienić sposób zachowania się jednostki.
Po zewnętrznym zdefiniowaniu danych masz wiele możliwości interakcji z projektantami, od bezpośredniej edycji plików tekstowych (ugh!) Do zaawansowanych interfejsów użytkownika, które kierują wyborami projektantów w sposób logiczny, spójny, a nawet zweryfikowany pod kątem poprawności (od perspektywa równowagi gry) sposób.
Gdyby dane zostały osadzone bezpośrednio w kodzie, wszelkie zmiany wymagałyby przebudowania aplikacji, co w przypadku dużych projektów zajmuje średnio dużo czasu, a także czasu potrzebnego na wdrożenie plików binarnych (np. Nowe pliki binarne muszą zostać wdrożone i zainstalowane na serwer).
Weźmy przykład sterotypowego bytu „orka” ...
Jednym ze sposobów implementacji dla naszego orka byłoby napisanie pełnego opisu w kodzie wszystkich cech i logiki dla orka.
Kiedy tworzymy instancję orków, wszystkie ich wartości są inicjalizowane dokładnie tak samo (a może są statyczne). Pojawia się problem, że pojawi się jakiś projektant i powie: „Potrzebujemy innego rodzaju orka dla obszarów początkujących, który ma mniej zdrowia, nigdy nie ucieka i nie jest agresywny. Pozwoli to nowym graczom przyzwyczaić się do walki bez zwiększone trudności i zamieszanie podczas nauki systemu walki ”.
Świetnie, teraz potrzebujesz innej klasy lub (może spoglądaliśmy w przyszłość) dostosować wartości, które wprowadzamy do „fabryki”, która tworzy orki podczas tworzenia ich w obszarze „nowicjusza”. Wprowadzamy więc zmiany, wdrażamy nowe pliki binarne. Tylko po to, by testerzy wrócili i powiedzieli, że nowe wartości zdrowia są zbyt niskie, gdy zabijamy orki jednym uderzeniem.
Jeśli nasze systemy były oparte na danych (i punktach premiowych dla aplikacji, które obsługują przeładowywanie po dokonaniu modyfikacji), wówczas modyfikacje niezbędne do zadowolenia projektanta i testerów odtwarzania są prostymi zmianami danych bez konieczności ponownej kompilacji / wdrożenia. To sprawia, że projektanci są szczęśliwi, ponieważ nie tkwią w oczekiwaniu na zmiany w kodzie, a programiści są szczęśliwi, ponieważ stale modyfikujemy kod źródłowy, aby poprawić wartości.
Doprowadzenie systemów opartych na danych do granic możliwości pozwala na wdrażanie wszystkiego, od poziomów gry, zaklęć, a nawet zadań poprzez proste zmiany danych, które nie wymagają żadnych zmian w kodzie. Ostatecznie chodzi o ułatwienie tworzenia, poprawiania i powtarzania zawartości gry.
źródło
W twoim przykładzie używasz już dwóch języków skryptowych. Tak powiedziałbym na dłuższą metę, ale działa lepiej, ale sugeruję ujednolicenie używanego języka skryptowego. Jeśli podany przykład skryptu został wykonany w Lua, zamiast Jsona, powiedziałbym, że użyj tabel Luy do zbudowania swojego obiektu. Składnia byłaby w rzeczywistości podobna i umożliwiłaby obsługę jednego interfejsu do eksponowania komponentów.
Dotknięcie, dlaczego ludzie decydują się to robić zwykle w XML, a następnie w logice, oznacza, że ma to sens, kiedy to mówisz. Oto moja definicja obiektu w danych, jaki jest dobry format przechowywania danych? Prawie zawsze jest to XML (chociaż ja również korzystam z JSON;). A kiedy chcą dodać logikę, dobrze jest albo zakodowane, albo umieszczone w pliku skryptu.
To nie jest złe myślenie, ale w moich oczach ludzie po prostu nie idą do następnego kroku. Spójrz na dowolny pełny język, c / c ++ / c # ,. Możesz zdefiniować obiekty i ich logikę w jednym języku, dlaczego nie zrobić tego samego w interfejsie skryptowym ... To prawie tak, jakbyśmy powiedzieli, że powinniśmy definiować nasze klasy w XML i nasze metody w c #, kiedy o tym pomyślisz. Być może starsze języki skryptów gry nie były wystarczająco mocne i nadal działa tak, jak zostało to zrobione.
źródło