Gå til indhold

Skeleton-gennemgang

Dette afsnit beskriver den grundlæggende struktur i en LightScript-integration og behandler vigtige tekniske krav, virkelige eksempler, navnekonventioner og effektivitetstips. Det guider dig igennem update-løkken, målernes adfærd, logikken bag effektudløsning og fremhæver almindelige faldgruber. Uanset om du debugger, bygger fra bunden eller vedligeholder andres kode – denne vejledning fremhæver klarhed, stabilitet og ydeevne som kernestandarder for kvalitetsintegrationer.

Dette afsnit giver et hurtigt overblik over opsætning af et LightScript fra et vedligeholdelsesperspektiv med fokus på, hvor problemer typisk opstår, og hvordan fejl opdages og rettes. Vi gennemgår kort en ideel LightScript-struktur, behandler fejlfinding og afslutter med en FAQ.

Det grundlæggende skeleton kræver en <head>, <body> og <script>. Alle måler- og brugerkontroldeklarationer hører hjemme i <head>. Alle canvas-deklarationer hører hjemme i <body>. Alt andet bør placeres i <script>-afsnittet.

<head> er en af de mest kritiske og komplekse dele af et LightScript. En fejlagtig brugerkontrol eller en fejlagtig måler her kan forårsage nedbrudssløjfer eller deaktivere sig selv og alle efterfølgende deklarerede målere.

Når du opretter målere, skal du sikre:

  • Perfekt syntaks (for at undgå nedbrud og defekte målere)
  • Ingen duplikerede målernavne (duplikater overskrives)
  • Ingen målere der går ud over skærmbegrænsningerne (forårsager nedbrud og fejl)
  • Ingen manglende eller overflødige indstillinger i målere (fører til nedbrud)
  • Alle målere indeholder opløsningsjusteringer (sikrer konsistent adfærd)

Hvad angår opløsninger er de mest almindelige billedformater:

  • 16:9 (3840x2160, 2560x1440, 1920x1080, 1600x900, 1366x768, 1360x768, 1280x720)
  • 16:10 (2560x1600, 1920x1200, 1680x1050, 1440x900, 1280x800)
  • 21:9 (5120x2160, 3440x1440)

Som standard bruges opløsningen 2560x1440.

Alle LightScripts skal understøtte billedformaterne 16:9, 16:10 og 21:9. Selvom 4:3 ikke udgør en væsentlig del af brugergruppen, bør det overvejes for fremtidig kompatibilitet.

Her er et eksempel på strukturen af en måler med flere opløsningsindstillinger:

Standardpositionen og -størrelsen for målere gælder for alle andre opløsninger inden for samme billedformat. Hvis målerne for eksempel oprindeligt er tilpasset til 1600x900, bør de fungere korrekt på alle andre 16:9-opløsninger. Der er dog undtagelser. Fortnite har flere forskellige målerpositioner selv inden for samme billedformat, og nogle billedformater kan selv være vildledende. For eksempel er 1366x768, en globalt udbredt opløsning, ofte opført som 16:9, men er ikke et ægte 16:9-forhold – hvilket ikke er usædvanligt. Tilsvarende gælder det for ultrabred skærm-formater som 21:9, der sjældent svarer til deres nominelle dimensioner. I erfaringen som integrationsudjvikler er der endnu ikke stødt på en eksakt 21:9-opløsning, selvom de benævnes sådan. Derfor skal hver ultrabreed skærm-opløsning oprettes, testes og konfigureres individuelt.

Alle justeringer skal placeres mellem de åbne <meta>- og lukkende </meta>-tags; ellers virker de ikke. Hvis standardmåleren er baseret på 16:9 og fungerer konsistent på tværs af disse opløsninger, behøver du ikke tilføje justeringer for andre 16:9-opløsninger. Du skal dog tilføje poster for hver opløsning i andre billedformater (som 16:10 og 21:9), selv hvis forholdet er konsistent.

Endelig kræver alle målere undtagen OCR-målere et HSL-område til udløsning. Disse områder kan kompliceres af følgende faktorer:

  • Gennemsigtige UI-elementer
  • Farvegradienter i farveområder
  • Billedforvrængningseffekter
  • Åbning af menuer i spillet
  • UI-tilpasninger pr. opløsning
  • Controller- vs. tastaturbrug
  • Videooptagelser der kan introducere kompressionsbetingede pixelfejl

Grundlæggende vejledning om HSL og normaliserede koordinater behandles i udviklerdokumentationen og gentages ikke her. Test af disse målere diskuteres i afsnittet “Identifikation af problemer”, men det er vigtigt at understrege: Den testindsats der kræves for at verificere alle målere perfekt beregnes som (antal målere) × (antal opløsningsjusteringer) × (antal siltilstande) × (antal spillbare karakterer) × (varighed af et gennemsnitligt spil). Dette kan nemt summere til timevis af verifikation pr. spil, særligt når øvelsestilstande eller andre løsninger ikke er tilgængelige.

HOLD MÅLERE EFFEKTIVE – vores standard er perfektion.

<body>-tagget er stedet, hvor selve canvas-elementet deklareres. Det bør altid se mere eller mindre ud som følgende eksempel. Den faktiske canvas-id kan ændres, men sørg for at den hentes korrekt i scriptet.

Spar dig selv lidt tid og kopiér dette eksempel.

Fire ting skal ske i dette tag ved enhver integration:

  • Canvas hentes og bruges til at oprette 2D-konteksten.
  • Den første update-løkke sætter målerværdier og kalder derefter sig selv igen ubegrænset for at opretholde dem.
  • Update-løkken holder brugerkontrollernes variabler opdaterede.
  • Målere udfører deres callback-funktioner, når de er stabile.

Det grundlæggende kodeskeleton er allerede sat op. Næste trin er at gennemgå udførselsløkken, der udløser effekter fra start til slut.

  1. Videospillets UI viser information i form af farvede barer, knapper, tekstfelter osv. SignalRGB opfanger disse data adskillige gange i sekundet, men den faktiske opfangningshastighed afhænger stærkt af kodens effektivitet. Bemærk: En enkelt løkke eller en udeklareret variabel kan afbryde hele scriptet og endda forårsage at SignalRGB crasher. Endnu værre: Det er nemt at skrive kode der teknisk set fungerer, men er så ineffektiv at den kun opfanger information ved 1–2 FPS.
  2. Hver måler deklareret i <head> skal være så lille og effektiv som mulig for at reducere overhead. Foretag beregninger tidligt og hyppigt; en måler der optager 25% af skærmen er aldrig effektiv. For OCR-målere bør du opfange individuelle bogstaver frem for hele ord. For livs- og manapoint-barer bør du kun overvåge de væsentlige segmenter. HOLD MÅLERE SÅ SMÅ SOM MULIGT.
  3. Målere opfanger information der opdateres med hver løkke.
  4. Tidligere blev Meter-klassedefinitionen behandlet, som gemmer målerdata og udløser en callback, når informationsarrayet bliver stabilt. Deklarér alle Meter-instanser i en blok i begyndelsen af scriptet. De kan organiseres eller sorteres alfabetisk; de bør blot ikke spredes over tusindvis af linjer. På et tidspunkt vil du skulle justere stabilitetsværdier, og det er spild af tid at skulle huske, hvor de er placeret.
  5. Inden for update-funktionen modtager disse målere i hver løkke værdier fra skærmlæsningslogikken. Deres interne logik evaluerer stabiliteten og udløser, når de er stabile, den tilknyttede callback-funktion.
  6. Disse callback-funktioner bør deklareres i scriptet, men uden for update-funktionen. Heri kontrolleres tilstanden af Meter-værdierne (value, decreased, increased, diff), og ud fra disse bestemmes om en effektanimation skal afspilles. Denne strukturering af koden – i stedet for at lægge alt direkte i update-løkken – gør det muligt at bygge skalerbare integrationer.

Nu hvor den overordnede idé er på plads, gennemgår vi hurtigt et virkeligt eksempel på en løkke.

  • Spillet League of Legends spilles, og tilgængelige færdigheder omgives af et lyst gult fremhæv.
  • I hver løkke opfanger den specifikke færdighedsmåler denne farve som værdien “1”, fordi den fuldt ud opfylder målerens HSL-område.
  • Denne “1” sendes til den Meter-instans der er tilknyttet skærmlæsemåleren og indsættes i den pågældende Meters informationsarray.
  • Når alle værdier i dette array er “1”, anses det som stabilt og aktiverer den tilknyttede effekt-callback-funktion. Denne callback-funktion ville også aktiveres, hvis alle værdier var “0” eller “.1”; Meter-klassen bekymrer sig kun om stabilitet. Et vigtigt punkt er at callback-funktionen ikke aktiveres kontinuerligt, hvis Meter-klassen konstant er stabil ved den samme værdi – kun stabilitet med en NY værdi aktiverer callbacken.
  • Når callback-funktionen udføres, foretages nogle betingede kontroller – i dette tilfælde er det nok at kontrollere, om Meter.value er “0”, hvilket betyder at en færdighed er blevet brugt.
  • Da Meter-værdien er “1”, fejler denne kontrol og færdighedseffekten afspilles ikke.
  • Nogle sekunder senere aktiveres færdigheden, og det gule fremhæv omkring knappen forsvinder.
  • Den nye målerværdi er 0, som sendes til dens Meter-klasse.
  • Når stabilitet er opnået, aktiverer callbacken betingelsen og færdighedseffekten afspilles. Latensen afhænger udelukkende af Meter-arrayets længde, der fastsættes ved deklarationen. Større længde betyder mere latens og færre falske udløsninger; test derfor indtil du finder en god balance.

Skærmlæsemålere bør have enkle, klare og beskrivende navne, der altid starter med et lille bogstav. At kalde en livsstangsmåler “healthBar” er fremragende. At kalde to målere “healthBarRed” og “healthBarGreen”, når de sporer forskellige farver i samme område, er også fint. Men at kalde en lille måler der kun vises under en heltens ultimative færdighed for “hrO21_yes” skaber kun smerte og lidelse for enhver der skal reparere koden. At finde ud af hvad en dårligt navngivet, lille måler sporer kan bogstaveligt talt tage en time med at stirre på individuelle pixels – så undgå den fejl.

Meter-klasse-instanser bør skrives med stort begyndelsesbogstav og slutte med ordet Meter. Eksempler som “Q_Meter”, “TookDamageMeter” og “TowerDestroyedMeter” er alle fine. Disse bør klart kunne skelnes fra de målere der er deklareret i <head>-afsnittet.

Effektfunktioner bør også navngives så enkelt og beskrivende som muligt. Nogle spil har hundredvis af disse funktioner; andre har færre end ti. Hvis flere helte har unikke færdigheder, indsæt heltens navn som præfiks, som “SonaQ”, “ChamberE” eller “AshUlt”. I League of Legends er der for eksempel funktioner som “DragonEffect”, “TowerEffect” og “Q_Effects”, der indeholder flere betingelser og bruges af flere målere. Denne type navngivning hjælper derfor også med at optimere for skalerbarhed.

Stav ord korrekt. Slå stavemåden op hvis du er i tvivl. Navne skal være klare og læsbare, uanset hvem der arbejder på koden eller hvor meget tid der er gået. At sortere navne alfabetisk hjælper med hurtig søgning, særligt når dette afsnit redigeres hyppigt. Selvom dette niveau af organisation ikke er nødvendigt for kodens udførelse, gør det en stor forskel for vedligeholdelsesudviklere.