Ga naar inhoud

Skeletwalkthrough

Deze sectie beschrijft de fundamentele structuur van een LightScript-integratie, met aandacht voor belangrijke technische vereisten, praktijkvoorbeelden, naamgevingsconventies en efficiëntietips. Het behandelt de updatelus, metergedrag, effectactiveringslogica en belicht veelvoorkomende valkuilen. Of u nu debugt, van nul af aan bouwt of de code van iemand anders onderhoudt, deze gids benadrukt duidelijkheid, stabiliteit en prestaties als de kernnormen van hoogwaardige integraties.

Deze sectie geeft een snel overzicht van het opzetten van een LightScript vanuit een onderhoudsperspectief, met de nadruk op waar problemen doorgaans optreden en hoe u bugs kunt herkennen en verhelpen. We beginnen met een korte walkthrough van een ideale LightScript-structuur om u vertrouwd te maken met de code, behandelen dan probleemoplossing en eindigen met een FAQ.

Het basisskelet vereist een <head>, <body> en <script>. Alle meters en gebruikersbesturingsdeclaraties gaan in de <head>. Alle canvas-declaraties horen in de <body>. Al het andere moet in de sectie <script> worden geplaatst.

De <head> is een van de meest kritische en complexe onderdelen van elke LightScript. Een defect gebruikersbesturingselement of meter hier kan crashlussen veroorzaken of zichzelf en alle meters die daarna zijn gedeclareerd uitschakelen.

Bij het aanmaken van meters moet u zorgen voor:

  • Perfecte syntaxis (om crashes en defecte meters te voorkomen)
  • Geen dubbele meternamen (duplicaten worden overschreven)
  • Geen meters die buiten de schermgrenzen reiken (veroorzaakt crashes en fouten)
  • Geen ontbrekende of extra opties in meters (leidt tot crashes)
  • Alle meters bevatten resolutie-aanpassingen (zorgt voor consistent gedrag)

Wat resoluties betreft, zijn de meest voorkomende beeldverhoudingen:

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

Standaard gebruiken we de resolutie 2560x1440.

Alle LightScripts moeten 16:9, 16:10 en 21:9-beeldverhoudingen ondersteunen. Hoewel 4:3 geen significant deel van onze gebruikersbasis vertegenwoordigt, moet het toch worden overwogen voor toekomstige compatibiliteit.

Hier is een voorbeeld van de structuur voor een meter met meerdere resolutie-instellingen:

De standaardlocatie en -grootte van uw meters zijn van toepassing op alle andere resoluties binnen dezelfde beeldverhouding. Als u uw meters oorspronkelijk aanpast voor 1600x900, zou die meter correct moeten werken voor alle andere 16:9-resoluties. Er zijn echter uitzonderingen. Fortnite heeft meerdere verschillende meteringposities zelfs binnen dezelfde beeldverhouding, en sommige beeldverhoudingen zelf kunnen misleidend zijn. Zo is 1366x768, een veel voorkomende resolutie wereldwijd, vaak vermeld als 16:9 maar is het geen echte 16:9-verhouding, wat niet ongewoon is. Evenzo komen ultrawide-verhoudingen zoals 21:9 zelden overeen met hun nominale afmetingen. In mijn ervaring als integratieontlwikkelaar heb ik nooit een exacte 21:9-resolutie tegengekomen ondanks dat ze zo worden aangeduid. Daarom moet elke ultrawide-resolutie afzonderlijk worden aangemaakt, getest en geconfigureerd.

Alle aanpassingen moeten worden geplaatst tussen de openende <meta> en sluitende </meta>-tags; anders werken ze niet. Als uw standaardmeter is gebaseerd op 16:9 en consistent werkt voor die resoluties, hoeft u geen aanpassingen toe te voegen voor andere 16:9-resoluties. U moet echter vermeldingen toevoegen voor elke resolutie in andere beeldverhoudingen (zoals 16:10 en 21:9), zelfs als de verhouding consistent is.

Tot slot vereist elke meter behalve onze OCR-meters een HSL-bereik om te activeren. Deze bereiken kunnen worden bemoeilijkt door factoren zoals:

  • Transparante UI-elementen
  • Verlopen in kleurgebieden
  • Schermvervormingseffecten
  • Openingen van in-game menu’s
  • UI-aanpassingen per resolutie
  • Controller- versus toetsenbordgebruik
  • Video-opname, die compressiegerelateerde pixelfouten kan introduceren

Basisinstructies over HSL en genormaliseerde coördinaten worden behandeld in onze ontwikkelaarsdocs en worden hier niet herhaald. Het testen van deze meters wordt besproken in de sectie “Problemen identificeren”, maar het is belangrijk dit te benadrukken: de hoeveelheid tests die nodig is om alle meters perfect te verifiëren, wordt berekend als (aantal meters) × (aantal resolutie-aanpassingen) × (aantal spelmodi) × (aantal speelbare personages) × (duur van een gemiddeld spel). Dit kan gemakkelijk oplopen tot uren verificatie per spel, vooral als er geen oefenmodi of andere oplossingen beschikbaar zijn.

HOUD UW METERS EFFICIËNT, onze standaard is perfectie.

De <body>-tag is waar het daadwerkelijke canvas-element wordt gedeclareerd. Het zou er altijd min of meer als volgt uit moeten zien. De daadwerkelijke canvas-id kan worden gewijzigd als u wilt, maar zorg ervoor dat u deze correct ophaalt in het script.

Bespaar uzelf wat tijd en kopieer en plak dit.

Vier dingen moeten plaatsvinden binnen deze tag in elke integratie:

  • Het canvas wordt opgehaald en gebruikt om onze 2D-context te maken.
  • De initiële updatelus stelt meterwaarden in en roept zichzelf vervolgens onbepaald tijd opnieuw aan om ze te handhaven.
  • De updatelus houdt gebruikersbesturingsvariabelen bijgewerkt.
  • Meters voeren hun callbackfuncties uit wanneer ze stabiel zijn.

We hebben al het basiscodeskeleton opgezet. De volgende stap is het doorlopen van de uitvoeringslus die effecten van begin tot eind activeert.

  1. De videogame-UI toont informatie in de vorm van gekleurde balken, knoppen, tekstvakken, enz. SignalRGB legt deze gegevens meerdere keren per seconde vast, maar de werkelijke vastleggingssnelheid hangt sterk af van de efficiëntie van uw code. Om duidelijk te zijn: één lus of niet-gedeclareerde variabele kan uw volledige script breken en zelfs SignalRGB laten crashen. Erger nog, het is gemakkelijk om code te schrijven die technisch werkt, maar zo inefficiënt is dat het informatie vastlegt met slechts 1-2 FPS.
  2. Elke meter gedeclareerd in de <head> moet zo klein en efficiënt mogelijk zijn om overheadkosten te verminderen. Doe uw berekeningen vroeg en vaak; een meter die 25% van het scherm inneemt is nooit efficiënt. Met OCR-meters legt u individuele letters vast in plaats van hele woorden. Voor gezondheids- en manabalken bewaakt u alleen de essentiële segmenten. HOUD UW METERS ZO KLEIN MOGELIJK.
  3. Meters leggen informatie vast die bij elke lus wordt vernieuwd.
  4. Eerder bespraken we de definitie van de Meter-klasse, die metergegevens opslaat en een callback activeert wanneer de info-array stabiel wordt. Declareer bovenaan uw script alle Meters in één blok. U kunt ze organiseren of alfabetiseren; maar begraaf ze niet verspreid over duizenden regels. U zult uiteindelijk stabiliteitswaarden moeten bijstellen, en het kost onnodig tijd om te onthouden waar u ze heeft geplaatst.
  5. Binnen de updatefunctie ontvangen deze meters elke lus waarden van schermleeslogica. Hun interne logica evalueert stabiliteit en activeert, wanneer stabiel, hun bijbehorende callbackfunctie.
  6. Deze callbackfuncties moeten worden gedeclareerd in uw script maar buiten de updatefunctie. Controleer daarbinnen de toestand van uw Meter-waarden (value, decreased, increased, diff) en gebruik die om te bepalen of u een effectanimatie moet afspelen. Door uw code op deze manier te structureren in plaats van alles direct in de updatelus te plaatsen, kunnen we schaalbare integraties bouwen.

Nu u het algemene idee heeft, loop ik snel door een praktijkvoorbeeld.

  • Ik speel het spel League of Legends, dat beschikbare vaardigheden omringt met een heldere gele markering.
  • Elke lus pikt de specifieke vaardigheidsmeter deze kleur op als een waarde van “1” omdat het het HSL-bereik van de meter volledig doorstaat.
  • Dit “1” wordt doorgegeven aan de Meter-instantie gekoppeld aan de schermleesmeter en ingevoegd in de info-array van die Meter.
  • Als elke waarde in die array een “1” is, wordt het als stabiel beschouwd en wordt de bijgevoegde effectcallbackfunctie geactiveerd. Deze callbackfunctie zou ook worden geactiveerd als elke waarde een “0” was, of “.1” bijvoorbeeld; de Meter geeft alleen om stabiliteit. Een belangrijke opmerking hierbij is dat de callbackfunctie niet continu wordt geactiveerd als de Meter constant stabiel is op dezelfde waarde — alleen stabiliteit met een NIEUWE waarde activeert de callback.
  • Zodra de callbackfunctie wordt uitgevoerd, komen we bij enkele conditionele controles — in dit geval hoeven we alleen te controleren of de Meter.value “0” is, wat aangeeft dat een vaardigheid is gebruikt.
  • Omdat de Meter-waarde “1” is, slagen we niet voor deze controle en spelen we het vaardigheideffect niet af.
  • Enkele seconden later activeer ik de vaardigheid en verdwijnt de gele markering rondom de knop.
  • De nieuwe meterwaarde is 0, die wordt doorgegeven aan zijn Meter-klasse.
  • Zodra stabiliteit is bereikt, activeert de callback en wordt onze conditie doorstaan, waardoor het vaardigheideffect wordt afgespeeld. Latentie hangt volledig af van de lengte van de Meter-array, die u instelt bij de declaratie. Meer lengte betekent meer latentie en minder valse activeringen, dus zorg dat u test totdat u een goede balans heeft gevonden.

Schermleesmeters moeten eenvoudige, duidelijke en beschrijvende namen hebben, altijd beginnen met een kleine letter. Een gezondheidsbalksmeter “healthBar” noemen is uitstekend. Twee meters “healthBarRed” en “healthBarGreen” noemen wanneer ze verschillende kleuren in hetzelfde gebied volgen, is ook prima. Maar een kleine meter die alleen verschijnt tijdens het ultieme effect van één held iets noemen als “hrO21_yes” brengt alleen pijn en ellende voor iedereen die uw code probeert te repareren. Uitzoeken wat een slecht genoemde, kleine meter volgt kan letterlijk een uur van het staren naar individuele pixels kosten als u pech heeft, doe dit dus niet.

Meter-klasse-instanties moeten met een hoofdletter beginnen en eindigen met het woord Meter. Voorbeelden zoals “Q_Meter”, “TookDamageMeter” en “TowerDestroyedMeter” zijn allemaal prima. Ze moeten duidelijk onderscheidbaar zijn van meters gedeclareerd in de <head>-sectie.

Effectfuncties moeten ook zo eenvoudig en beschrijvend mogelijk worden benoemd. Sommige spellen hebben honderden van deze functies; andere hebben er misschien minder dan tien. Als meerdere helden unieke vaardigheden hebben, gebruik dan de naam van de held als voorvoegsel, zoals “SonaQ”, “ChamberE” of “AshUlt”. In League of Legends zijn er bijvoorbeeld functies zoals “DragonEffect”, “TowerEffect” en “Q_Effects”, die meerdere conditionals bevatten en door meerdere meters worden gebruikt. Dit soort naamgeving helpt dus ook bij het optimaliseren voor schaal.

Spel geen woorden fout. Als u niet zeker weet hoe iets gespeld wordt, zoek het op. Namen moeten duidelijk en leesbaar zijn, ongeacht wie aan de code werkt of hoeveel tijd er is verstreken. Namen alfabetisch ordenen helpt bij snel opzoeken, vooral als u die sectie vaak zult bewerken. Hoewel dit niveau van organisatie niet vereist is voor het uitvoeren van de code, maakt het een groot verschil voor onze onderhoudsontwikkelaars.