Wskazówki dotyczące wdrażania mechaniki zadań MMO?

14

Jakie narzędzia, wzorce lub najlepsze praktyki poleciłbyś wdrożyć mechanikę zadań podaną poniżej wymienionych wymagań?

Mówię o architekturze oprogramowania (jaka powinna być ogólna) oraz możliwościach okablowania obiektów, subskrypcji zdarzeń i reprezentacji warunków. Wzmianki o narzędziach / bibliotekach, które z powodzeniem wykorzystałeś są mile widziane. Edycja: jeśli używasz skryptów, jaką konfigurację polecasz?

Wymagania:

  • proste 2D mmo (rpg)
  • wszystkie dane gry, w tym misje, są przechowywane w relacyjnej bazie danych
  • dowolne wydarzenie w grze może uruchomić nową misję dla graczy lub rozwinąć istniejące misje
  • misja może mieć dowolną liczbę warunków, które muszą zostać spełnione, zanim misja będzie dostępna dla graczy
  • misja może składać się z dowolnej liczby zadań podrzędnych / kroków o dowolnych warunkach
  • zadania będą się różnić od prostych:

    porozmawiaj z A - zabij 5 B - porozmawiaj z A - trwale zwiększ zdrowie

  • dość zaangażowany:

    użyj przedmiotu w obszarze X - idź do obszaru Y - bot odrodzi się - zabij bota nie otrzymując więcej niż 10% obrażeń - bot upuszcza przedmiot - podnieś przedmiot - portal odblokowuje - dostarcz przedmiot do J za portalem - zdobądź złoto i doświadczenie - zezwól jeszcze raz na przejście portalu - zablokuj portal dla tego odtwarzacza

  • instancje poziomów są możliwe (gracze mogą ukończyć określone zadania w drużynach lub izolacji, które odradzają lokalizację poziomu tylko dla tych uczestników)

  • Zadania powinny być możliwe do zarządzania za pomocą edytora światowego bez wiedzy na temat skryptów lub programowania ( edycja: jednak nie zaleca się pisania skryptów w ogóle)
  • Przyjmuję C ++ jako język implementacji

Myślałem, że jeśli uda mi się połączyć dowolny łańcuch wydarzeń i warunków, możemy stworzyć bardziej złożone, a tym samym bardziej wciągające zadania. Eksperymentowałem z uruchomieniem własnego silnika ECA (zdarzenia-warunki-działania), ale może to być przesada. Szczególnie trudne było modelowanie ogólnych warunków bez użycia jakiegokolwiek skryptu.

jmp97
źródło
Czy jest jakiś konkretny powód, dla którego zdecydowałeś się pominąć jakieś skrypty? (takie jak lua / gamemonkey itp.).
Simon
Głównie z powodu braku doświadczenia i (prawdopodobnie niesłusznych) założeń, jak może to negatywnie wpłynąć na wydajność. Chciałem też, aby edycja świata była jak najprostsza. Jestem jednak otwarty na używanie skryptów.
jmp97,
1
Zgadzam się, bez wsparcia skryptowego trudno będzie urozmaicić zadania bez angażowania programistów silnika.
drxzcl,
1
Języki skryptowe są zazwyczaj wystarczająco szybkie, aby nie stanowiły problemu. Zdecydowanie polecam ich użycie. To powiedziawszy, większość skryptów WoW opiera się na wyzwalaniu zaklęć i zdarzeń. „Rozmowa z A” za kulisami spowodowałoby, że A „rzuciłoby zaklęcie” na gracza, a zadanie byłoby zakodowane „to się powiedzie, gdy zaklęcie nr 55728 zostało rzucone na gracza”. Następnie potrzebujesz tylko małego kodu AI, aby stworzenia rzucały zaklęcia na gracza i jesteś gotowy.
ZorbaTHut,
1
Nowoczesne języki skryptowe (takie jak Lua Vm) są prawdopodobnie wystarczająco szybkie. Są łatwe w użyciu, łatwe do wdrożenia, możesz ponownie ładować skrypty w środowisku wykonawczym, możesz debugować i wkraczać skrypty w środowisku wykonawczym oraz możesz iterować DUŻO szybciej podczas tworzenia treści. Zdecydowanie sugeruję zajrzenie do silnika skryptowego (przykłady: lua i klucz gamemon) w celu pisania skryptów.
Simon

Odpowiedzi:

6

Najpierw ostrzeżenie, a potem rada.

Ostatnim razem, gdy potrzebowałem wdrożyć taki system, nie używałem silnika pierwotnie przeznaczonego do aplikacji podobnych do MMO. System zadań, z którym został dostarczony, był nastawiony na starania dla jednego gracza i nie mógł być używany.

Skończyło się na tym, że musiałem nakładać skrypty na wszystkie obiekty związane z zadaniami mniej więcej ręcznie, takie jak ten (pseudokod):

Lever004_on_activate() {
    if isOnQuest(player, QUEST_0012) do_something();
    if isOnQuest(player, QUEST_0015) do_something_else();
}

To kompletny koszmar. Nie ma sposobu, aby dowiedzieć się, jak działa to zadanie bez przeszukiwania całej gry. Nie rób tego.

Poleciłbym stworzenie systemu, w którym cała misja (linia) jest reprezentowana jako skończona maszyna stanu, ze zdarzeniami sprawdzającymi przejścia i skryptami reagującymi na to przejście. Ułatwia to śledzenie miejsca, w którym przebywasz w danym zadaniu (linii) i utrzymuje porządek w stanie wszystkich zadań.

Jeśli chcesz, możesz utworzyć bibliotekę skryptów / szablonów skryptów w edytorze światów dla typowych zdarzeń (gracz rozmawia z NPC, gracz zabija mob itp.)

Nie martwiłbym się zbytnio wydajnością skryptu, o ile nie uruchamiasz zbyt często skryptów zdarzeń. Zasadniczo skrypty powinny wystrzelić co najmniej o rząd wielkości mniej niż „podstawowa” logika gry (animacja, fizyka itp.). Powinny reagować na zdarzenia, zamiast okresowo strzelać, aby sprawdzić, czy warunek został spełniony.

drxzcl
źródło
3
Ostrzegamy jednak, że statemachines bardzo szybko się zawracają, jeśli chcesz, aby na ścieżki zadań wpływały czynniki zewnętrzne lub jeśli twoje misje są stosunkowo złożone. Również wiele statystyk misji (jeśli wiele misji może być aktywnych) może być koszmarem. Ponieważ jednak w zasadzie każdy program jest statemachine, można to zrobić. Ale złożone problemy pozostają złożone bez względu na to, jak je obudujesz. Dobrym przykładem (imo) jest Oblivion, w którym niektóre mody powstrzymują inne mody od działania - twoje warunki wstępne i dodatkowe dla stanów muszą być albo dość solidne, albo wyjątkowo wybaczające / tolerancyjne na błędy.
Kaj
Tak, kaj ma rację. Wystarczy udać się teraz na fora WoW i przeczytać o ludziach narzekających na niedokończone zadania. Zdarza się to cały czas, nawet w dużej lidze. Naprawdę trudno jest wszystko zrobić dobrze.
drxzcl
3

Nasz system zasadniczo polega na uruchomieniu wyrażenia (niestandardowy język skryptowy, ale tcl / lua / python równie dobrze działałby lub zrobił coś samodzielnie) dla każdej ramki serwera dla każdego kroku misji. Dotyczy to „misji osobistych” związanych z określonym graczem. Każdy podetap jest następnie częścią FSM (skończonej maszyny stanów) dla samej misji (która może być tylko podetapem innej misji). Istnieją również „misje na mapie”, które mają jeden FSM i są powiązane z mapą zamiast gracza (pomyśl o zadaniach publicznych WAR), ale podetapy działają w zasadzie tak samo.

Te wyrażenia faktycznie patrzą na zdarzenia transmitowane przez system, takie jak „NPC umarł” lub „interakcja zakończona”. Oznacza to, że możesz nieco rozdzielić poszczególne części, systemy gry po prostu wysyłają zdarzenia w razie potrzeby, a skrypty misji tylko słuchają wydarzeń i nie martw się, skąd pochodzą. Jeśli nałożysz na to również warunek, misja FSM może współdziałać ze stanem świata (pokaż ten kontakt tylko w stanie misji X), możesz uzyskać dużo mocy z systemu.

koderanger
źródło