Tworzę grę MMO i właśnie doszedłem do momentu, w którym muszę wdrożyć osiągnięcia ... Jak to zrobić? Najprostszą rzeczą do zrobienia byłoby uruchomienie tego raz na 100 ms:
for a in achievements
for p in players
if a.meetsRequirements(p) then p.completeAchievement(a)
Ale to tylko powoduje jeszcze więcej komplikacji. Na przykład, jak sprawdzić, czy osiągnięcie zostało rzeczywiście ukończone? Czy gracze mają na sobie niestandardowe właściwości tylko dla konkretnego osiągnięcia? Robiłem coś takiego z zadaniami, ponieważ są one głównie „zbierz 100 drewna”, więc aktywne zadania u gracza to sprawdzają. Ponadto musi być lepszy moment, aby to sprawdzić, co moim zdaniem spowalnia okresowo mój serwer.
Odpowiedzi:
To, co robisz, zależy od charakteru osiągnięcia. O ile wszystkie twoje osiągnięcia nie pasują do prostego wzorca (zbierz X liczby Y), będziesz musiał je do pewnego stopnia w specjalnym przypadku.
Korzystając z systemu komunikacji opartego na komunikatach, można zapewnić haczyki, które umiejscawiają kodowanie specjalnych przypadków. Możesz mieć określone działania wysyłające wiadomości do słuchaczy, którzy się zarejestrują. Następnie Twój kod / skrypt osiągnięć może po prostu zarejestrować się u odpowiednich słuchaczy i wykonać wszystko, co jest konieczne do odpalenia osiągnięcia.
Będziesz mieć wiadomości o typowych wydarzeniach, których oczekujesz od osiągnięć. Rzeczy takie jak „gracz zdobył przedmiot X” lub „jednostka Y zabiła jednostkę Z”. W ten sposób możesz śledzić np. Liczbę Z, które zabił gracz.
To chyba najlepsze, co możesz zrobić dla systemu osiągnięć. Centralizuje kod tak bardzo, jak to możliwe, i nakłada na słuchaczy ciężar rzeczywistego wykrywania osiągnięć.
Należy również zauważyć, że w przypadku scentralizowanych systemów osiągnięć (X-Box Live, osiągnięcia Steam) postęp w kierunku osiągnięć jest zwykle zapisywany na serwerze. Tak więc w przypadku osiągnięć akumulacji („wykonaj zadanie XY wiele razy”) skrypt osiągnięć wykrywa tylko, kiedy X zostało wykonane, i zlicza liczbę serwerów. W przypadku innych osiągnięć („wykonaj zadanie X”) osiągnięcie serwera jest binarne: albo to zrobiłeś, albo nie.
źródło
W zależności od charakteru twoich osiągnięć możesz również wprowadzić pewnego rodzaju „osiągnięcia znaczników”.
Jeśli masz na przykład 3 kolejne osiągnięcia:
Drewno 1 - Zbierz 100 drewna
Drewno 2 - Zbierz 500 drewna
Drewno 3 - Zbierz 1 tys. Drewna
W takim przypadku warto zarejestrować zdarzenie OnChange dla pierwszego osiągnięcia, dopóki gracz go nie ukończy. Po zakończeniu możesz zarejestrować kolejny obiekt osiągnięcia.
To oczywiście wymaga zaprojektowania (lub obliczenia) drzewa zależności osiągnięć.
źródło