Estrutura Base
Esta secção descreve a estrutura fundamental de uma integração LightScript, cobrindo requisitos técnicos essenciais, exemplos do mundo real, convenções de nomenclatura e dicas de eficiência. Percorre o loop de atualização, o comportamento dos medidores, a lógica de acionamento de efeitos e destaca armadilhas comuns. Seja a depurar, a construir do zero ou a manter o código de outra pessoa, este guia enfatiza clareza, estabilidade e desempenho como os padrões fundamentais de integrações de alta qualidade.
Layout Básico
Seção intitulada “Layout Básico”Esta secção oferece uma visão geral rápida de como configurar um LightScript do ponto de vista de manutenção, com foco em onde os problemas costumam ocorrer e como identificar e corrigir bugs. Começaremos com uma breve apresentação de uma estrutura ideal de LightScript para familiarizá-lo com o código, depois abordaremos a resolução de problemas e terminaremos com um FAQ.
A estrutura básica requer um <head>, um <body> e um <script>. Todas as declarações de medidores e controlos de utilizador vão dentro do <head>. Todas as declarações de canvas pertencem ao <body>. Todo o resto deve ser colocado na secção <script>.
O <head> é uma das partes mais críticas e complexas de qualquer LightScript. Um controlo de utilizador ou medidor defeituoso aqui pode causar loops de falha ou desativar-se juntamente com quaisquer medidores declarados depois dele.
Ao criar medidores, precisa de garantir:
- Sintaxe perfeita (para evitar falhas e medidores quebrados)
- Sem nomes de medidores duplicados (duplicados são sobrescritos)
- Nenhum medidor a ultrapassar os limites do ecrã (causa falhas e erros)
- Sem opções em falta ou extras nos medidores (leva a falhas)
- Todos os medidores incluem ajustes de resolução (garante comportamento consistente)
Em relação às resoluções, as proporções de ecrã mais comuns são:
- 16:9 (3840x2160, 2560x1440, 1920x1080, 1600x900, 1366x768, 1360x768, 1280x720)
- 16:10 (2560x1600, 1920x1200, 1680x1050, 1440x900, 1280x800)
- 21:9 (5120x2160, 3440x1440)
Por predefinição, usamos a resolução 2560x1440.
Todos os LightScripts devem suportar as proporções 16:9, 16:10 e 21:9. Embora 4:3 não represente uma parcela significativa da nossa base de utilizadores, ainda deve ser considerada para compatibilidade futura.
Aqui está um exemplo da estrutura de um medidor com múltiplas configurações de resolução:

A localização e o tamanho padrão dos seus medidores aplicam-se a todas as outras resoluções dentro da mesma proporção. Por exemplo, se ajustou originalmente os seus medidores para funcionar com 1600x900, esse medidor deve funcionar corretamente em todas as outras resoluções 16:9. No entanto, há exceções. Fortnite tem múltiplas posições de medição diferentes mesmo dentro da mesma proporção, e algumas proporções em si podem ser enganosas. Por exemplo, 1366x768, uma resolução comum em todo o mundo, é frequentemente listada como 16:9 mas não é realmente uma proporção verdadeira de 16:9, o que não é incomum. Da mesma forma, proporções ultrawide como 21:9 raramente correspondem às suas dimensões nominais. Na minha experiência como programador de integração, nunca encontrei uma resolução exata de 21:9 apesar de serem rotuladas como tal. Por isso, cada resolução ultrawide precisa de ser criada, testada e configurada individualmente.
Todos os ajustes devem ser colocados entre as tags de abertura <meta> e fechamento </meta>; caso contrário, não funcionarão. Se o seu medidor padrão é baseado em 16:9 e se comporta de forma consistente nessas resoluções, não é necessário adicionar ajustes para outras resoluções 16:9. Porém, é obrigatório adicionar entradas para cada resolução noutras proporções (como 16:10 e 21:9), mesmo que a proporção seja consistente.
Por fim, todo medidor, exceto os OCR, requer um intervalo HSL para acionar. Estes intervalos podem ser complicados por fatores como:
- Elementos de UI transparentes
- Gradientes em áreas de cor
- Efeitos de distorção de ecrã
- Abertura de menus no jogo
- Ajustes de UI por resolução
- Uso de comando vs. teclado
- Gravação de vídeo, que pode introduzir erros de píxel relacionados à compressão
Instruções básicas sobre HSL e coordenadas normalizadas são abordadas nos nossos documentos para programadores e não serão repetidas aqui. Os testes destes medidores serão discutidos na secção “Identificando Problemas”, mas é importante enfatizar: a quantidade de testes necessária para verificar todos os medidores perfeitamente é calculada como (número de medidores) × (número de ajustes de resolução) × (número de modos de jogo) × (número de personagens jogáveis) × (duração de uma partida média). Isto pode facilmente somar horas de verificação por jogo, especialmente se modos de prática ou outras alternativas não estiverem disponíveis.
MANTENHA OS SEUS MEDIDORES EFICIENTES, o nosso padrão é a perfeição.
A tag <body> é onde o elemento canvas é declarado. Deve sempre parecer mais ou menos com o exemplo seguinte. O id real do canvas pode ser alterado se quiser, mas certifique-se de o obter corretamente no script.

<script>
Seção intitulada “<script>”Quatro coisas devem acontecer dentro desta tag em cada integração:
- O canvas é obtido e usado para criar o contexto 2D.
- O loop de atualização inicial define os valores dos medidores e volta a chamar-se indefinidamente para os manter atualizados.
- O loop de atualização mantém as variáveis de controlo do utilizador atualizadas.
- Os medidores executam as suas funções de callback quando estão estáveis.
Procedimento Geral
Seção intitulada “Procedimento Geral”Já configuramos a estrutura básica do código. O próximo passo é percorrer o loop de execução que aciona efeitos do início ao fim.
- A interface do videojogo exibe informações na forma de barras coloridas, botões, caixas de texto, etc. O SignalRGB captura esses dados várias vezes por segundo, mas a taxa de captura real depende muito da eficiência do seu código. Para ser claro, um único loop ou variável não declarada pode quebrar todo o seu script, e até mesmo bloquear o SignalRGB. Pior ainda, é fácil escrever código que tecnicamente funciona, mas é tão ineficiente que captura informações a apenas 1-2 FPS.
- Cada medidor declarado no <head> deve ser o menor e mais eficiente possível para reduzir o overhead. Faça os seus cálculos cedo e com frequência; um medidor que ocupa 25% do ecrã nunca é eficiente. Com medidores OCR, capture letras individuais em vez de palavras inteiras. Para barras de vida e mana, monitorize apenas os segmentos essenciais. MANTENHA OS SEUS MEDIDORES O MENOR POSSÍVEL.
- Os medidores capturam informações que se atualizam a cada loop.
- Anteriormente, abordámos a definição da classe Meter, que armazena dados de medidores e aciona um callback quando o array de informações se torna estável. No topo do seu script, declare todos os Meters num bloco. Pode organizá-los ou alfabetizá-los; apenas não os espalhe por milhares de linhas. Eventualmente precisará de ajustar os valores de estabilidade, e é uma perda de tempo tentar lembrar onde os colocou.
- Dentro da função update, estes medidores receberão valores da lógica de leitura de ecrã a cada loop. A sua lógica interna avalia a estabilidade e, quando estável, aciona a função de callback associada.
- Estas funções de callback devem ser declaradas no seu script mas fora da função update. Dentro delas, verifique o estado dos valores do seu Meter (value, decreased, increased, diff) e use-os para determinar se deve reproduzir uma animação de efeito. Estruturar o seu código desta forma, em vez de colocar tudo diretamente dentro do loop de atualização, permite-nos construir integrações escaláveis.
Exemplo do Mundo Real
Seção intitulada “Exemplo do Mundo Real”Agora que tem a ideia geral, vou percorrer rapidamente um exemplo de loop do mundo real.
- Estou a jogar League of Legends, que envolve as habilidades disponíveis com um destaque amarelo brilhante.
- A cada loop, o medidor de habilidade específico capta essa cor como um valor de “1” porque passa completamente pelo intervalo HSL do medidor.
- Esse “1” é passado para a instância Meter associada ao medidor de leitura de ecrã e inserido no array de informações desse Meter.
- Se todos os valores nesse array forem “1”, é considerado estável e ativará a função de callback de efeito associada. Esta função de callback também seria ativada se todos os valores fossem “0”, ou “.1”, por exemplo; tudo o que o Meter verifica é a estabilidade. Uma observação importante aqui é que a função de callback não será continuamente ativada se o Meter estiver constantemente estável no mesmo valor — apenas a estabilidade com um NOVO valor ativará o callback.
- Uma vez que a função de callback é executada, chegamos a algumas verificações condicionais — neste caso, tudo o que precisamos de fazer é verificar se o Meter.value é “0”, indicando que uma habilidade foi usada.
- Como o valor do Meter é “1”, falhamos nessa verificação e não reproduziremos o efeito de habilidade.
- Alguns segundos depois, ativo a habilidade e o destaque amarelo em redor do botão desaparece.
- O novo valor do medidor é 0, que é passado para a sua classe Meter.
- Uma vez que a estabilidade é alcançada, o callback é ativado e a nossa condição é satisfeita, reproduzindo o efeito de habilidade. A latência depende inteiramente do comprimento do array do Meter, que define na declaração. Mais comprimento significa mais latência e menos acionamentos falsos, portanto teste até encontrar um bom equilíbrio.
Convenções de Nomenclatura
Seção intitulada “Convenções de Nomenclatura”Os medidores de leitura de ecrã devem ter nomes simples, claros e descritivos, sempre começando com uma letra minúscula. Nomear um medidor de barra de vida como “healthBar” é excelente. Nomear dois medidores “healthBarRed” e “healthBarGreen” quando rastreiam cores diferentes na mesma área também é ótimo. Mas nomear um medidor pequeno que só aparece durante o efeito de ultimate de um herói como “hrO21_yes” só vai trazer dor e sofrimento para qualquer outra pessoa que tente corrigir o seu código. Descobrir o que um medidor mal nomeado e minúsculo está a rastrear pode literalmente levar uma hora a olhar para píxeis individuais se tiver azar, portanto não faça isto.
As instâncias da classe Meter devem começar com maiúscula e terminar com a palavra Meter. Exemplos como “Q_Meter”, “TookDamageMeter” e “TowerDestroyedMeter” são todos perfeitamente adequados. Devem ser claramente distinguíveis dos medidores declarados na secção <head>.
As funções de efeito também devem ser nomeadas de forma o mais simples e descritiva possível. Alguns jogos têm centenas destas funções; outros podem ter menos de dez. Se múltiplos heróis têm habilidades únicas, inclua o nome do herói como prefixo, como “SonaQ”, “ChamberE” ou “AshUlt”. Em League of Legends, por exemplo, existem funções como “DragonEffect”, “TowerEffect” e “Q_Effects”, que contêm múltiplos condicionais e são usadas por vários medidores. Por isso, este tipo de nomenclatura também ajuda a otimizar para escala.
Não escreva palavras erradas. Se não tiver a certeza de como escrever algo, pesquise. Os nomes devem ser claros e legíveis, independentemente de quem está a trabalhar no código ou quanto tempo passou. Organizar os nomes por ordem alfabética ajuda na pesquisa rápida, especialmente se for editar esta secção com frequência. Embora este nível de organização não seja necessário para o código funcionar, faz uma grande diferença para os nossos programadores de manutenção.