Optymalizacja skryptów FiveM: obniż resmon, zachowaj płynne FPS
Zoptymalizuj skrypty FiveM pod kątem wysokiego FPS i niskiego resmonu. Pętle, wielowątkowość, NUI, zdarzenia i sprawdzone triki z profilera stosowane przez czołowe serwery nastawione na wydajność.
Agency Scripts
Założyciel i główny deweloper w Agency Scripts
Zrozumienie resmon i wydajności skryptów
Ten resmon polecenie w FiveM wyświetla wskaźniki wydajności zasobów w czasie rzeczywistym, pokazując, ile milisekund każdy skrypt zużywa na tick serwera. Dobrze zoptymalizowany skrypt powinien przez większość czasu pokazywać w resmon 0.00ms, skacząc na krótko tylko podczas aktywnego przetwarzania zdarzeń. Skrypty stale wykazujące wysokie wartości w resmon obniżają wydajność serwera, zwiększają desynchronizację graczy i mogą powodować uciążliwe lagi serwera, które odstraszają społeczność. Regularne profilowanie skryptów to pierwszy krok do utrzymania płynnego serwera.
Zarządzanie wątkami i czasy oczekiwania
Największym zabójcą wydajności w skryptach FiveM jest nieprawidłowe zarządzanie wątkami. Używanie Citizen.Wait(0) wewnątrz pętli oznacza, że Twój kod wykonuje się w każdej pojedynczej klatce, czyli około 60 razy na sekundę. Większość zadań nie wymaga takiej częstotliwości. Zwiększ czasy oczekiwania do Wait(500) lub Wait(1000) do sprawdzeń, które muszą być uruchamiane tylko okresowo, takich jak wykrywanie bliskości markerów czy sprawdzanie stref. W przypadku systemów opartych na odległości zastosuj podejście warstwowe, w którym sprawdzasz w dłuższych odstępach czasu, gdy gracz jest daleko od punktów zainteresowania, i w krótszych odstępach, gdy znajduje się w pobliżu.
Wyłączanie niepotrzebnych wątków
Zamiast uruchamiać wątki w sposób ciągły, rozważ ich aktywację tylko wtedy, gdy są potrzebne. Używaj eventów lub zmian stanu, aby uruchamiać i zatrzymywać pętle przetwarzania. Na przykład skrypt wędkowania nie musi uruchamiać pętli zarzucania wędki, gdy gracz nie znajduje się w pobliżu wody. Śledź zmienną stanu aktywności i opuść wątek za pomocą return gdy funkcja nie jest używana. Ten wzorzec może zredukować zużycie skryptu ze stałych 0.50ms do 0.00ms w okresach bezczynności, co stanowi różnicę między skryptem, który się skaluje, a takim, który przeciąża twój serwer.
Cachowanie i unikanie zbędnych wywołań
Natywne wywołania funkcji w FiveM wiążą się z narzutem wydajnościowym, zwłaszcza gdy są wywoływane wielokrotnie w ciasnych pętlach. Zapisuj w pamięci podręcznej wyniki wywołań takich jak GetEntityCoords, GetPlayerPed, oraz GetPlayerServerId na początku iteracji pętli, zamiast wywoływać je wielokrotnie w tym samym cyklu. Przechowuj dane statyczne, takie jak wartości konfiguracyjne, pozycje markerów i współrzędne blipów, w zmiennych lokalnych podczas ładowania skryptu. Ta prosta technika może radykalnie skrócić czas wykonywania skryptu i jest jedną z najbardziej efektywnych optymalizacji, jakie możesz wprowadzić.
Optymalizacje matematyczne
Obliczanie odległości to jedna z najczęstszych operacji w skryptach FiveM. Zastąp standardowe #(coords1 - coords2) sprawdzanie odległości za pomocą porównań kwadratów odległości, gdy potrzebujesz tylko odległości względnej. Ponieważ obliczanie pierwiastka kwadratowego jest kosztowne, porównywanie kwadratów odległości z kwadratami wartości progowych daje ten sam rezultat bez kosztownej operacji matematycznej. Dodatkowo unikaj wywoływania GetDistanceBetweenCoords native, gdy możesz obliczyć odległość w Lua, ponieważ wywołania natywne wiążą się z dodatkowym narzutem w porównaniu z czystymi operacjami Lua.
Zarządzanie encjami i blipami
Tworzenie bytów, blipów i markerów generuje obciążenie zarówno renderowania, jak i sieci. Usuwaj blipy i byty, gdy nie są już potrzebne, zamiast pozostawiać je w świecie gry. Używaj DrawMarker tylko wtedy, gdy gracz znajduje się w odległości renderowania, a nie globalnie na całej mapie. W przypadku skryptów zarządzających wieloma encjami wdróż spatial partitioning, aby przetwarzać tylko pobliskie obiekty. Rozważ użycie systemów streamingu, które tworzą i niszczą encje na podstawie bliskości gracza, zamiast ładować wszystko na raz podczas startu zasobu.