Dzięki wsparciu Luau dla generacji kodu natywnego, skrypty po stronie serwera w twojej grze mogą być kompilowane bezpośrednio do instrukcji kodu maszynowego, które wykonują procesory, zamiast regularnego bajtowego kodu, na którym działa maszyna wirtualna Luau. Ta funkcja może być używana do poprawy szybkości wykonania niektórych skryptów na serwerze, w szczególności tych, które mają dużo obliczeń numerycznych bez używania zbyt wielu ciężkich wywołań biblioteki Luau lub API Roblox.
Włącz generację kodu natywnego
Aby włączyć generację kodu natywnego dla Script, dodaj komentarz --!native na górze:¹
--!native
print("Witaj z kodu natywnego!")To włącza generację kodu natywnego dla wszystkich funkcji w skrypcie oraz dla zasięgu najwyższego poziomu, jeśli uznaje się to za opłacalne. Nie są wymagane żadne dodatkowe zmiany; zachowanie skryptów wykonujących natywnie jest dokładnie takie samo jak wcześniej, a tylko wydajność jest inna. Wszystkie funkcje języka Luau i wszystkie API Roblox pozostają wspierane.
Alternatywnie, możesz włączyć generację kodu natywnego dla pojedynczej funkcji, dodając atrybut @native:
@native
local function f(x)
return (x + 1)
endNajlepsze praktyki
Poniższe wskazówki pomogą ci w pełni skorzystać z generacji kodu natywnego:
Najlepiej włączyć tę funkcję w skryptach, które wykonują dużo obliczeń bezpośrednio w Luau. Jeśli masz dużo operacji matematycznych na tabelach, a zwłaszcza typach buffer, skrypt może być dobrym kandydatem.
Zaleca się mierzenie czasu, jaki zajmuje skrypt lub funkcja z generacją natywną i bez niej, aby ocenić, kiedy najlepiej jej używać. Narzędzie Profiler skryptów może mierzyć wydajność funkcji, aby podejmować świadome decyzje.
Może być kuszące umieścić komentarz --!native w każdym skrypcie, na wypadek gdyby niektóre z nich działały szybciej, ale generacja kodu natywnego ma pewne wady:
- Wymagana jest czas kompilacji kodu, co może zwiększyć czas uruchamiania serwerów.
- Dodatkowa pamięć jest zajmowana na przechowywanie natywnie skompilowanego kodu.
- Istnieje limit na całkowitą dozwoloną ilość natywnie skompilowanego kodu w grze.
Te problemy można rozwiązać przez rozsądne użycie atrybutu @native.
Kod do unikania
Chociaż wszystkie funkcje będą działać tak samo z włączoną lub wyłączoną generacją kodu natywnego, niektóre z nich nie będą działać natywnie i mogą powodować de‑optymalizację lub powrót do interpretowanego wykonania. Należą do nich:
- Użycie różnych wbudowanych funkcji Luau, takich jak math.asin() z argumentami nienumerycznymi.
- Przekazywanie niewłaściwie typowanych parametrów do typowanych funkcji, na przykład wywołanie foo(true), gdy foo jest zadeklarowane jako function foo(arg: string). Pamiętaj, aby zawsze używać poprawnych adnotacji typów.
Podczas korzystania z Profilera skryptów możesz porównać czas wykonania zwykłej wersji funkcji z tą skompilowaną natywnie. Jeśli funkcja wewnątrz skryptu --!native lub oznaczona jako @native nie wydaje się działać natywnie, jeden lub więcej czynników z powyższej listy może wywoływać de‑optymalizację.
Używaj adnotacji typów
Generacja kodu natywnego stara się wywnioskować najbardziej prawdopodobny typ dla danego zmiennej, aby zoptymalizować ścieżki kodu. Na przykład zakłada się, że a + b jest wykonywane na liczbach, lub że tabela jest dostępna w t.X. Biorąc pod uwagę przeciążanie operatorów, jednak a i b mogą być tabelami lub typami Vector3, lub t może być typem danych Roblox.
Chociaż generacja kodu natywnego będzie wspierać dowolny typ, błędne przewidywania mogą wywołać niepotrzebne kontrole, co skutkuje wolniejszym wykonaniem kodu.
Aby rozwiązać niektóre powszechne problemy, adnotacje typów Luau na argumentach funkcji są sprawdzane, ale szczególnie zaleca się adnotowanie argumentów Vector3:
--!native
-- "v" jest zakładane jako tabela; funkcja działa wolniej z powodu kontroli tabeli
local function sumComponentsSlow(v)
return v.X + v.Y + v.Z
end
-- "v" jest zadeklarowane jako Vector3; generowany jest kod specjalizowany dla wektorów
local function sumComponentsFast(v: Vector3)
return v.X + v.Y + v.Z
endNarzędzia Studio
Poniższe narzędzia Studio są wspierane dla skryptów --!native i funkcji @native.
Debugowanie
Ogólne debugowanie skryptów jest wspierane, ale widoki dla lokalnych/upvalue mogą być niekompletne i brakować zmiennych z ramek stosów wywołań, które są wykonywane natywnie.
Należy również zauważyć, że podczas debugowania kodu wybranego do kompilacji natywnej, umieszczanie punktów przerwania wyłączy natywne wykonanie dla tych funkcji.
Profiler skryptów
W Profilerze skryptów funkcje wykonujące natywnie wyświetlają <native> obok nich:

Jeśli funkcja oznaczona jako @native lub znajdująca się w skrypcie --!native nie pokazuje adnotacji <native>, ta funkcja może nie być wykonywana natywnie z powodu umiejscowienia punktów przerwania, użycia niedozwolonego kodu lub niedopasowanych adnotacji typów.
Stos Luau
W profilerze stosu Luau pamięć zajmowana przez natywne funkcje wyświetla się jako elementy [native] w wykresie.

Analiza rozmiaru
Każdy natywnie skompilowany skrypt zużywa pamięć. Gdy rozmiar skompilowanego kodu osiągnie zdefiniowany limit, generacja kodu natywnego zatrzymuje się, a pozostały kod jest wykonywany nienatywnie. Dlatego ważne jest, aby starannie wybierać skrypty do natywnej kompilacji.
Aby monitorować rozmiar kodu natywnego poszczególnych funkcji i skryptów:
- Upewnij się, że jesteś w widoku Serwera za pomocą przycisku przełączania klient/serwer.
- Wywołaj debug.dumpcodesize() z Paska poleceń.
W oknie Wyjście zobaczysz całkowitą liczbę skryptów i funkcji, które zostały natywnie skompilowane do momentu wywołania, pamięć zajmowaną przez ich natywny kod oraz limit rozmiaru kodu natywnego. Po podsumowaniu zobaczysz tabelę dla każdego natywnie skompilowanego skryptu w porządku malejącym według rozmiaru kodu.

Dla każdego skryptu wyjście wyświetla liczbę skompilowanych funkcji oraz zużycie pamięci kodu natywnego. Każda funkcja jest następnie wymieniana w porządku malejącym według rozmiaru kodu natywnego, a funkcje anonimowe są pokazane jako [anonymous], a całe skrypty jako [top level]. W ostatniej kolumnie procent obliczany jest w odniesieniu do limitu rozmiaru kodu natywnego. Należy pamiętać, że rozmiar kodu natywnego funkcji jest raportowany dokładnie, ale zużycie pamięci dla skryptów jest zaokrąglane do najbliższego rozmiaru strony.
Limity i rozwiązywanie problemów
Kompilacja kodu do instrukcji dla konkretnego CPU wymaga dodatkowej pamięci. Dodatkowo, optymalizacje dla złożonych funkcji mogą zająć zbyt dużo czasu. Przekroczenie wewnętrznego limitu zgłosi błąd w oknie Wyjście Studio, w tym:
Funkcja 'f' w linii 20 przekroczyła limit pojedynczego bloku kodu
Ten błąd oznacza, że pojedynczy blok kodu wewnątrz funkcji użył więcej niż 64K instrukcji. Można tego uniknąć, upraszczając funkcję lub dzieląc ją na mniejsze funkcje.
Funkcja 'f' w linii 20 przekroczyła limit bloku kodu funkcji
Ten błąd oznacza, że pojedyncza funkcja zawiera więcej niż 32K wewnętrznych bloków kodu. Wewnętrzne bloki kodu nie dokładnie odpowiadają blokom przepływu sterowania w twoim skrypcie, ale ten błąd można uniknąć, upraszczając przepływ sterowania w funkcji lub dzieląc ją na mniejsze funkcje.
Funkcja 'f' w linii 200 przekroczyła całkowity limit instrukcji modułu
Ten błąd oznacza, że funkcja osiągnęła limit 1 miliona instrukcji dla całego skryptu. W niektórych przypadkach zgłoszona funkcja sama może mieć dużo instrukcji, lub limit mógł zostać osiągnięty przez funkcje wcześniejsze w skrypcie. Aby uniknąć tego problemu, zaleca się przeniesienie szczególnie dużych funkcji do osobnego nienatywnego skryptu lub użycie @native w innych funkcjach. Możesz także spróbować oznaczyć ten osobny skrypt jako --!native, ale 1 milion instrukcji zajmuje dużo pamięci i możesz przekroczyć limit pamięci.
Funkcja 'f' w linii 20 napotkała wewnętrzny błąd obniżania (lub)
Błąd wewnętrzny: Generacja kodu natywnego nie powiodła się (obniżanie assemblera)
Czasami funkcja zawiera złożone fragmenty kodu, których kompilator kodu natywnego obecnie nie może obsłużyć. Aby uniknąć tego błędu, sprawdź złożone wyrażenia w kodzie i podziel je lub uprość, ale rozważ także otwarcie zgłoszenia błędu z przykładem kodu, który nie powiódł się z tego powodu.
Osiągnięto limit alokacji pamięci dla generacji kodu natywnego
Ten błąd oznacza, że osiągnięto ogólny limit pamięci dla danych kodu natywnego. Aby tego uniknąć, spróbuj usunąć --!native z bardziej pamięciochłonnych skryptów, co pozwoli na zmieszczenie większej liczby mniejszych skryptów w limicie. Alternatywnie, przenieś duże lub rzadko wywoływane funkcje do osobnego nienatywnego modułu.