Po co umieszczać konfigurację encji poza skryptami?


11

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.

Odpowiedzi:


13

Główną zaletą, jaka przychodzi mi na myśl, jest to, że pozwala ona edytować / zarządzać konfiguracją przez programistę bez konieczności dotykania żadnego ze skryptów gry.


Można to osiągnąć, po prostu posiadając dwa pliki (równe .h, a następnie .cpp). Zastanawiam się, kto byłby osobą, która chciałaby stworzyć obiekt (poza tym, że to nic nie robi jak wazon, a nic nie wygląda jak motyl), który również nie chciałby dodawać do niego logiki (jak jeśli osoba pokryta pyłkiem z kwiatów w wazonie, przyciągnij motyla). Czytelność dla ludzi jest świetna i jedną z moich przemyśleń na temat tego, dlaczego tak jest, ale znowu przesuwam, że JSON, tabele Lua i XML mają podobny poziom czytelności dla ludzi przez programistów.
James

2
Glest to gra zmodyfikowana za pomocą xml. Wielu nie-programistów tworzy dla niego mody. Zdecydowanie łatwiej jest mieć xml / json niż skrypt.
Czy

6

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.


5
Kiedy lepsze było tworzenie oprogramowania głównego nurtu, było to znane jako zasada najmniejszej mocy : w dzisiejszych czasach musimy docenić powody, dla których wybraliśmy nie najmocniejsze rozwiązanie, ale najmniej wydajne. Powodem tego jest to, że im słabszy język, tym więcej możesz zrobić z danymi przechowywanymi w tym języku.

1
@Joe To właściwie całkiem dobrze opisuje jeden z powodów, dla których również stosuję to podejście. Na początku próbowałem skonfigurować moje byty w skryptach, ale trudno mi było wdrożyć gry save (nie mogłem śledzić relacji między komponentami). Korzystanie z zewnętrznego pliku konfiguracyjnego bardzo mi pomaga.
Paul Manta,

Rzeczywiście widzę to na odwrót, jeśli już używasz interfejsu skryptowego, musisz teraz podać metodę sprawdzania danych dla pliku konfiguracyjnego zamiast używać już zdefiniowanego interfejsu skryptowego, aby to zrobić za Ciebie.
James

2

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.


1

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.

  • maksimum zdrowia = 10
  • obrażenia = 3 obrażenia na sekundę
  • ucieczka = prawda
  • uciekł gdy = zdrowie <10
  • agresywny = prawda

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.


2
Skrypty są również danymi według większości definicji
Will

1
-1. Pytanie nie dotyczy danych sterowanych a kodowania na sztywno, ale dynamicznych skryptów vs. deklaracji statycznych.

@Christopher Dodałem długą odpowiedź w moim OP. Proszę sprawdź to.
Paul Manta,

0

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.

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.