Przewodnik po szkielecie
Ta sekcja opisuje podstawową strukturę integracji LightScript, zwracając uwagę na kluczowe wymagania techniczne, praktyczne przykłady, konwencje nazewnictwa i wskazówki dotyczące wydajności. Omawia pętlę aktualizacji, zachowanie mierników, logikę aktywowania efektów i podkreśla typowe pułapki. Niezależnie od tego, czy debugujesz, budujesz od zera, czy utrzymujesz czyjś kod, ten przewodnik podkreśla przejrzystość, stabilność i wydajność jako podstawowe standardy wysokiej jakości integracji.
Podstawowy układ
Dział zatytułowany „Podstawowy układ”Ta sekcja zawiera szybki przegląd konfigurowania LightScript z perspektywy utrzymania, koncentrując się na tym, gdzie zazwyczaj pojawiają się problemy i jak rozpoznawać i naprawiać błędy. Zaczynamy od krótkiego przewodnika po idealnej strukturze LightScript, aby zapoznać cię z kodem, następnie omawiamy rozwiązywanie problemów i kończymy na FAQ.
Podstawowy szkielet wymaga <head>, <body> i <script>. Wszystkie deklaracje mierników i kontrolek użytkownika trafiają do <head>. Wszystkie deklaracje canvas należą do <body>. Wszystko inne musi być umieszczone w sekcji <script>.
<head> jest jedną z najbardziej krytycznych i złożonych części każdego LightScript. Wadliwa kontrolka użytkownika lub miernik tutaj może powodować pętle awarii lub wyłączyć siebie i wszystkie mierniki zadeklarowane po nim.
Podczas tworzenia mierników upewnij się, że:
- Składnia jest doskonała (aby zapobiec awariom i uszkodzonym miernikom)
- Brak zduplikowanych nazw mierników (duplikaty są nadpisywane)
- Brak mierników wykraczających poza granice ekranu (powoduje awarie i błędy)
- Brak brakujących lub dodatkowych opcji w miernikach (prowadzi do awarii)
- Wszystkie mierniki zawierają dostosowania rozdzielczości (zapewnia spójne zachowanie)
Jeśli chodzi o rozdzielczości, najpopularniejsze proporcje to:
- 16:9 (3840x2160, 2560x1440, 1920x1080, 1600x900, 1366x768, 1360x768, 1280x720)
- 16:10 (2560x1600, 1920x1200, 1680x1050, 1440x900, 1280x800)
- 21:9 (5120x2160, 3440x1440)
Domyślnie używamy rozdzielczości 2560x1440.
Wszystkie LightScripts muszą obsługiwać proporcje 16:9, 16:10 i 21:9. Chociaż 4:3 nie stanowi znacznej części naszej bazy użytkowników, powinno być brane pod uwagę ze względu na przyszłą kompatybilność.
Oto przykład struktury dla miernika z wieloma ustawieniami rozdzielczości:

Domyślna lokalizacja i rozmiar twoich mierników mają zastosowanie do wszystkich innych rozdzielczości w ramach tej samej proporcji. Jeśli początkowo dostosujesz swoje mierniki dla 1600x900, miernik ten powinien poprawnie działać dla wszystkich innych rozdzielczości 16:9. Istnieją jednak wyjątki. Fortnite ma wiele różnych pozycji miernikowania nawet w ramach tej samej proporcji, a niektóre same proporcje mogą być mylące. Na przykład 1366x768, powszechna rozdzielczość na całym świecie, jest często wymieniana jako 16:9, ale nie jest prawdziwą proporcją 16:9, co nie jest rzadkością. Podobnie proporcje ultrawide, takie jak 21:9, rzadko zgadzają się z ich nominalnymi wymiarami. W mojej doświadczeniu jako dewelopera integracji, nigdy nie spotkałem dokładnej rozdzielczości 21:9, mimo że są tak opisywane. Dlatego każda rozdzielczość ultrawide musi być tworzona, testowana i konfigurowana osobno.
Wszystkie dostosowania muszą być umieszczone między otwierającym tagiem <meta> a zamykającym </meta>; w przeciwnym razie nie będą działać. Jeśli twój domyślny miernik jest oparty na 16:9 i działa konsekwentnie dla tych rozdzielczości, nie musisz dodawać dostosowań dla innych rozdzielczości 16:9. Jednak musisz dodać wpisy dla każdej rozdzielczości w innych proporcjach (jak 16:10 i 21:9), nawet jeśli proporcja jest spójna.
Na koniec każdy miernik poza naszymi miernikami OCR wymaga zakresu HSL do aktywacji. Te zakresy mogą być utrudnione przez czynniki takie jak:
- Przezroczyste elementy UI
- Gradienty w obszarach kolorów
- Efekty zniekształcenia ekranu
- Otwieranie menu w grze
- Dostosowania UI na rozdzielczość
- Kontroler kontra klawiatura
- Nagrywanie wideo, które może wprowadzać błędy pikseli związane z kompresją
Podstawowe instrukcje dotyczące HSL i znormalizowanych współrzędnych są omówione w naszych dokumentach deweloperskich i nie są tutaj powtarzane. Testowanie tych mierników jest omawiane w sekcji “Identyfikowanie problemów”, ale ważne jest podkreślenie: ilość testów potrzebnych do idealnej weryfikacji wszystkich mierników jest obliczana jako (liczba mierników) × (liczba dostosowań rozdzielczości) × (liczba trybów gry) × (liczba grywalnych postaci) × (czas trwania przeciętnej gry). Może to łatwo przekroczyć godziny weryfikacji na grę, szczególnie jeśli nie są dostępne tryby treningowe ani inne rozwiązania.
DBAJ O WYDAJNOŚĆ MIERNIKÓW, naszym standardem jest doskonałość.
Tag <body> jest miejscem, gdzie deklarowany jest rzeczywisty element canvas. Powinien zawsze wyglądać mniej więcej tak. Rzeczywiste id canvas można zmienić, jeśli chcesz, ale upewnij się, że poprawnie go pobierasz w skrypcie.

<script>
Dział zatytułowany „<script>”Cztery rzeczy muszą się wydarzyć w tym tagu w każdej integracji:
- Canvas jest pobierany i używany do tworzenia naszego kontekstu 2D.
- Początkowa pętla aktualizacji ustawia wartości mierników, a następnie wywołuje siebie nieskończenie, aby je utrzymać.
- Pętla aktualizacji utrzymuje zaktualizowane zmienne kontrolki użytkownika.
- Mierniki wykonują swoje funkcje callback, gdy są stabilne.
Ogólna procedura
Dział zatytułowany „Ogólna procedura”Mamy już podstawowy szkielet kodu. Następnym krokiem jest przejście przez pętlę wykonywania aktywującą efekty od początku do końca.
- UI gry wideo wyświetla informacje w postaci kolorowych pasków, przycisków, pól tekstowych itp. SignalRGB przechwytuje te dane wiele razy na sekundę, ale rzeczywista szybkość przechwytywania zależy w dużej mierze od wydajności twojego kodu. Aby być precyzyjnym: jedna pętla lub niezadeklarowana zmienna może zepsuć cały twój skrypt i nawet spowodować awarię SignalRGB. Co gorsza, łatwo jest napisać kod, który technicznie działa, ale jest tak nieefektywny, że przechwytuje informacje tylko z 1-2 FPS.
- Każdy miernik zadeklarowany w <head> powinien być jak najmniejszy i najwydajniejszy, aby zmniejszyć koszty ogólne. Rób obliczenia wcześnie i często; miernik zajmujący 25% ekranu nigdy nie jest wydajny. W przypadku mierników OCR przechwytuj pojedyncze litery zamiast całych słów. W przypadku pasków zdrowia i many monitoruj tylko niezbędne segmenty. DBAJ O TO, ABY TWOJE MIERNIKI BYŁY JAK NAJMNIEJSZE.
- Mierniki przechwytują informacje, które są odświeżane przy każdej pętli.
- Wcześniej omawialiśmy definicję klasy Meter, która przechowuje dane miernika i aktywuje callback, gdy tablica informacji staje się stabilna. Na górze swojego skryptu deklaruj wszystkie Metery w jednym bloku. Możesz je organizować lub alfabetyzować; ale nie zakopuj ich rozrzuconych po tysiącach linii. Ostatecznie będziesz musiał dostosowywać wartości stabilności i niepotrzebnie traci się czas na pamiętanie, gdzie je umieściłeś.
- Wewnątrz funkcji aktualizacji te mierniki otrzymują przy każdej pętli wartości z logiki odczytu ekranu. Ich wewnętrzna logika ocenia stabilność i aktywuje, gdy jest stabilna, przypisaną funkcję callback.
- Te funkcje callback muszą być zadeklarowane w twoim skrypcie, ale poza funkcją aktualizacji. Sprawdź w nich stan wartości Meter (value, decreased, increased, diff) i użyj ich do określenia, czy powinieneś odtwarzać animację efektu. Strukturowanie kodu w ten sposób, zamiast umieszczania wszystkiego bezpośrednio w pętli aktualizacji, pozwala nam budować skalowalne integracje.
Praktyczny przykład
Dział zatytułowany „Praktyczny przykład”Teraz, gdy znasz ogólny pomysł, szybko przejdę przez praktyczny przykład.
- Gram w grę League of Legends, która otacza dostępne umiejętności jasnym żółtym podświetleniem.
- Przy każdej pętli konkretny miernik umiejętności pobiera ten kolor jako wartość “1”, ponieważ w pełni przechodzi zakres HSL miernika.
- To “1” jest przekazywane do instancji Meter powiązanej z miernikiem odczytu ekranu i wstawiane do tablicy informacyjnej tej Meter.
- Gdy każda wartość w tej tablicy jest “1”, jest uważana za stabilną i aktywowana jest dołączona funkcja callback efektu. Ta funkcja callback byłaby również aktywowana, gdyby każda wartość wynosiła “0”, lub “.1” na przykład; Meter dba tylko o stabilność. Ważna uwaga tutaj: funkcja callback nie jest aktywowana ciągle, jeśli Meter jest stale stabilna na tej samej wartości — tylko stabilność z NOWĄ wartością aktywuje callback.
- Po wykonaniu funkcji callback docieramy do kilku sprawdzeń warunkowych — w tym przypadku musimy tylko sprawdzić, czy Meter.value wynosi “0”, co wskazuje, że umiejętność została użyta.
- Ponieważ wartość Meter wynosi “1”, nie przechodzimy tego sprawdzenia i nie odtwarzamy efektu umiejętności.
- Kilka sekund później aktywuję umiejętność i żółte podświetlenie wokół przycisku znika.
- Nowa wartość miernika wynosi 0, która jest przekazywana do jego klasy Meter.
- Gdy zostanie osiągnięta stabilność, callback aktywuje się i nasz warunek jest spełniony, powodując odtworzenie efektu umiejętności. Opóźnienie zależy całkowicie od długości tablicy Meter, którą ustawiasz przy deklaracji. Większa długość oznacza większe opóźnienie i mniej fałszywych aktywacji, więc testuj, aż znajdziesz dobrą równowagę.
Konwencje nazewnictwa
Dział zatytułowany „Konwencje nazewnictwa”Mierniki odczytu ekranu powinny mieć proste, jasne i opisowe nazwy, zawsze zaczynając od małej litery. Nazwanie miernika paska zdrowia “healthBar” jest doskonałe. Nazwanie dwóch mierników “healthBarRed” i “healthBarGreen”, gdy śledzą różne kolory w tym samym obszarze, jest również w porządku. Ale nazwanie małego miernika, który pojawia się tylko podczas efektu ultimate jednego bohatera, czymś takim jak “hrO21_yes” przynosi jedynie ból i nieszczęście wszystkim, którzy próbują naprawić twój kod. Ustalenie, co śledzi źle nazwany, mały miernik, może kosztować dosłownie godzinę wpatrywania się w pojedyncze piksele, jeśli masz pecha, więc nie rób tego.
Instancje klasy Meter powinny zaczynać się od wielkiej litery i kończyć słowem Meter. Przykłady takie jak “Q_Meter”, “TookDamageMeter” i “TowerDestroyedMeter” są wszystkie w porządku. Powinny być wyraźnie odróżnialne od mierników zadeklarowanych w sekcji <head>.
Funkcje efektów również powinny być nazwane jak najprościej i jak najbardziej opisowo. Niektóre gry mają setki tych funkcji; inne mogą mieć ich mniej niż dziesięć. Jeśli wielu bohaterów ma unikalne umiejętności, użyj nazwy bohatera jako prefiksu, jak “SonaQ”, “ChamberE” lub “AshUlt”. Na przykład w League of Legends są funkcje takie jak “DragonEffect”, “TowerEffect” i “Q_Effects”, które zawierają wiele warunków i są używane przez wiele mierników. Taki rodzaj nazewnictwa pomaga również w optymalizacji pod kątem skali.
Nie pisz słów z błędami. Jeśli nie jesteś pewien, jak coś się pisze, sprawdź to. Nazwy muszą być jasne i czytelne, niezależnie od tego, kto pracuje nad kodem i ile czasu minęło. Alfabetyczne porządkowanie nazw pomaga przy szybkim wyszukiwaniu, szczególnie jeśli często będziesz edytować tę sekcję. Chociaż ten poziom organizacji nie jest wymagany do uruchomienia kodu, ma ogromne znaczenie dla naszych deweloperów utrzymania.