Czas ładowania przed grą a czas ładowania gry

9

Rozwijam grę, w której znajduje się losowy labirynt.
Istnieje kilka stworzeń AI, czających się w labiryncie. I chcę, żeby szli jakąś ścieżką zgodnie z kształtem labiryntów.

Teraz mam dwie możliwości, aby to zaimplementować. Pierwszym sposobem (którego użyłem) jest obliczenie kilku poszukiwanych ścieżek po utworzeniu labiryntu.
Drugi polega na obliczeniu ścieżki, którą kiedyś trzeba było obliczyć, gdy stworzenie zacznie ją czaić.

Moim głównym zmartwieniem są czasy ładowania. Jeśli obliczę wiele ścieżek podczas tworzenia labiryntu, czas wstępnego ładowania jest nieco długi, więc pomyślałem o obliczeniu ich w razie potrzeby.
W tej chwili gra nie jest „ciężka”, więc obliczanie ścieżek w połowie gry nie jest zauważalne, ale obawiam się, że stanie się, gdy stanie się bardziej skomplikowane.

Wszelkie sugestie, komentarze, opinie będą pomocne.

Edytować:

Na razie, niech pbędzie liczba wstępnie obliczonych ścieżek, istoty mają szanse 1/pna przyjęcie nowej ścieżki (co oznacza obliczenie ścieżki) zamiast istniejącej.
Stworzenie nie rozpocznie patrolu, dopóki ścieżka nie zostanie w pełni obliczona, więc nie musisz się martwić, że zginie podczas tego procesu.

Opiekun
źródło
8
W tym momencie byłaby to wstępna optymalizacja. Pozostawiłbym tak, jak jest, dopóki nie będzie problemu.
John McDonald,
3
A jeśli chcesz trochę zagrać z @JohnMcDonald, jeśli potrafisz obliczyć te ścieżki w trakcie gry i nie jest to zauważalne, to ile może mieć to wpływ na czas ładowania?
James

Odpowiedzi:

6

BerickCook poprawnie wyraził ten pomysł. Pozostaw obliczenia tam, gdzie są, jeśli teraz działają poprawnie.

Jeśli możesz wykonać obliczenia wcześniej i jesteś pewien, że nie będziesz ich potrzebować w trakcie gry, zrób to wcześniej. W przeciwnym razie zrób to po załadowaniu. Jeśli obliczenia podczas gry są niezauważalne, możesz to zrobić. Jeśli w pewnym momencie złożoność ewoluuje, a obliczenia stają się zbyt ciężkie, zacznij optymalizować.

Ale jedno: jeśli twoje obliczenia są zaimplementowane w celu uruchomienia w połowie gry, zawsze możesz zmusić je do wykonania podczas ładowania.

Istnieje wiele rozwiązań:

  • oblicz / załaduj ścieżki podczas tworzenia / ładowania poziomów
  • użyj drugiego wątku, aby obliczyć ścieżki
  • zoptymalizuj swoje algorytmy
  • użyj systemu przerywanego, jeśli nie masz dostępu do wątków.

Widziałem i wykorzystałem ostatnią opcję w grze na rynku masowym. Po prostu upewnij się, że właściwie zapisałeś wszystkie dane potrzebne do wznowienia obliczeń i regularnie sprawdzaj pozostały czas / operacje podczas obliczeń.

W zależności od przypadku system przerywalny może dostarczyć wstępne i częściowe rozwiązania, które można wykorzystać przed zakończeniem obliczeń.


Edycja : odpowiadanie na @Keeper

„Algorytm przerywalny” był użyteczny tylko ze względu na ograniczenia, które mieliśmy. Zasadniczo doprowadziliśmy do braku wielowątkowości.

W pewnym momencie mieliśmy grę, w której AI musiała obliczyć dużą liczbę ruchów na podstawie wielu słowników. Podczas tych obliczeń wszystkie animacje zostały zatrzymane, ponieważ słowniki zostały rozszerzone o więcej danych, a zestaw danych przechowujący dane został zmieniony i mniej wydajny, gdy gra została przystosowana do gry wieloosobowej (gdzie AI musiała oddziaływać nawet na ruchy gracza). Mamy tylko jeden wątek dostępny dla pętli gry (konieczne jest, aby kod wieloplatformowy musiał działać na wszystkich obsługiwanych platformach). W tym momencie postanowiono przerwać algorytm obliczeniowy, abyśmy mogli go przerwać. Dlatego nie mogliśmy po prostu użyć systemu rekurencyjnego, który istniał, ponieważ zmiennych nie można zapisać. Funkcje zostały zastąpione obiektami, które po prostu zawierały wszystkie niezbędne zmienne i wskaźniki do obiektów nadrzędnych i podrzędnych. Ja nie

  • zapisz status swoich bieżących obliczeń
  • przerwać albo na końcu pętli, albo podczas pętli (gdy obiekt potomny przerywa)
  • wyjdź, gdy skończy się czas
  • wznawia tam, gdzie przestał albo ponownie uruchamiać pętlę przy odpowiednim indeksie, albo wywoływać obiekt potomny znajdujący się aktualnie na szczycie stosu potomnego.
  • wyczyść wszystko, jeśli obliczenia zostaną przerwane
  • dać najlepszy wynik częściowy.

Tylko najdroższe operacje zostały podzielone na osobne obiekty i znalezienie odpowiedniego miejsca, w którym moglibyśmy zatrzymać obliczenia, zajęło trochę czasu, ale ostatecznie działa bardzo dobrze.

Straciliśmy wydajność, ale postrzegana wydajność była znacznie lepsza dla użytkownika, ponieważ animacje działały płynnie na wszystkich platformach, wszystkie platformy mogły wtedy korzystać z większych słowników bez cierpienia na przerywane animacje lub zawieszanie się. Pozwoliło nam to również na uruchomienie wielu instancji równolegle, gdy potrzebowaliśmy ich później.

Oczywiście teraz na iPhonie i iPadzie gra tego nie potrzebuje, idealnie byłoby użyć drugiego wątku. Ale podejrzewam, że kod nadal tam jest.

Kojot
źródło
Dzięki, to brzmi bardzo interesująco. Czy możesz rozwinąć koncepcję „systemu przerywanego” (dlaczego i jak). (googlowanie nie było tak pomocne…). Dodam kilka szczegółów do pytania.
Keeper
@Keeper Mam nadzieję, że odpowiedziałem na twoje pytanie dotyczące części przerywanej. Jest to trudna do zrobienia i nie ma znaczenia w większości nowoczesnych systemów.
Coyote
Chociaż na razie nie zamierzam korzystać z tej metody, otworzyłeś mi oczy na coś nowego. Twoja odpowiedź zasługuje na akceptację.
Keeper
8

Na razie, ponieważ obliczanie ścieżek w trakcie gry jest niezauważalne, jest to idealne podejście. Jeśli / kiedy dojdzie do punktu, w którym gra jest przerywana przez obliczenia, przełącz ją na obliczanie ścieżek przed załadowaniem poziomu.

Dłuższe początkowe czasy ładowania są wybaczalne, ale losowe wahania FPS podczas gry na ogół nie są.

BerickCook
źródło
2

Jedną z możliwości, jeśli potrzebujesz, jest przeniesienie obliczeń do drugiego wątku, ponieważ obecnie prawie każdy komputer ma więcej niż jeden rdzeń procesora.

Podstawowym procesem byłoby:

  • Gdy istota żąda ścieżki, dodaj ją do kolejki bezpiecznych wątków i zasygnalizuj wątek.
  • Stworzenie stoi bezczynnie, czekając, aż wątek wyskoczy z kolejki, przetworzy go i umieści na gotowej liście.
  • Każda ramka sprawdza ukończoną listę z głównego wątku i przypisuje ukończone ścieżki stworzeniom.

Trzeba też uważać na kilka dodatkowych przypadków krawędzi (np. Co jeśli stwór umrze przed przetworzeniem żądania).

Adam
źródło
2
Jeśli nie chcesz wprowadzać wątków, możesz również obliczyć swoją ścieżkę przyrostowo (np. Obliczyć kilka kroków dla każdej klatki).
bummzack