Como o CLEO funciona no GTA San Andreas
O CLEO é uma biblioteca de script que roda como DLL injetada no executável do jogo. Quando você coloca o arquivo .asi na pasta raiz, o motor carrega um interpretador Lua customizado que executa comandos de jogo em tempo real. Nada mágico, apenas memória endereçada e chamadas de função. O formato dos scripts é .cs. Cada linha é uma operação com operandos definidos. Se você já viu isso funcionando, provavelmente notou que os arquivos são basicamente texto legível aberto no Bloco de Notas. O compilador do CLEO traduz isso para bytecode que o interpretador executa frame a frame.
gta sa mod cleo: instalação e configuração básica
Você precisa de duas coisas: o ASI Loader (SAMPFUNCS ou dinput8 hook) e o plugin CLEO. Ambos entram na pasta raiz do jogo junto com os scripts .cs que você quer rodar. A ordem de carregamento não costuma dar problema sério, mas se um script não estiver funcionando, tente mover o CLEO para antes do SAMPFUNCS na chain de load. Isso resolveu um problema meu onde marcadores de missões customizadas não apareciam porque o SAMPFUNCS estava sobrescrevendo o handler de draw sprite. Depois de colocar os arquivos, o jogo deve carregar uma logagem na pasta\CLEO\cleo.log se tiver o debug habilitado. Sem log, é provável que o ASI Loader nem tenha carregado. Verifique isso antes de qualquer coisa. Leva dois minutos e evita cinquenta.
O compilador oficial vem no pacote do CLEO. Ele tem menu de contexto no botão direito do Windows: "Compile com CLEO". O script é traduzido para .cs otimizado na mesma pasta. Arquivos sem compilar não rodam — o interpretador só aceita bytecode, nunca texto puro.
Comandos mais usados e estrutura prática
Os comandos seguem a convenção 0@variavel = comando arg0 arg1. Variáveis locais começam com 0@ até 9@, e variáveis globais com @variavel_nome. O sistema suporta arrays também, então 0@meu_array[0] funciona perfeitamente. O comando mais citado é $PLAYER_ACTOR. Ele retorna o ponteiro do jogador ativo. Se o jogador estiver dentro de um carro, ele retorna o veículo, não o ped. Isso causa confusão porque muitos tutoriais tratam isso como se fosse sempre um ped. Na prática, você precisa verificar o tipo com CHECK_EXTRA_CAR_CONTAINS before any ped-specific operation.
Para criar missões customizadas, o fluxo padrão é: ativar um marcador com 0167, detectar ativação com 016A, executar lógica e finalizar com 016C ou 016B. Marcadores suportam raio esférico, caixa, cone e zona interna a veículo. Zona de veículo é especialmente útil para missões que precisam detectar quando o jogador entra num carro específico sem que o motor do jogo reclame. Um detalhe que quase ninguém menciona: o comando 00BF (WAIT) não pausa o thread principal do jogo. Ele pausa apenas aquele thread CLEO. Isso significa que você pode ter múltiplos threads rodando simultaneamente, cada um com seu próprio ciclo de espera. Use isso a seu favor para criar sistemas reativos sem travar a física do jogo.
👉 Clique no botão abaixo para saber mais sobre o assunto!
Problema comum e solução que eu encontrei na prática
Uma vez eu estava criando um script que modificava a radiação do jogador (wanted level) dinamicamente enquanto o jogador estava dirigindo. O problema era que o wanted level reseta para zero assim que o jogador sai do veículo em uma zona segura. Eu tentei usar 01D5 para setar a radiação, mas ela sempre caía de volta para zero em poucos segundos. A solução foi usar o comando 0AA5 para chamar funções nativas do jogo diretamente via ponteiro de script. Especificamente, eu apontava para a função que controla o timer de redução de radiação e bloqueava o decremento. O resultado foi um script de cerca de 40 linhas que manteve a radiação estável por tempo indefinido enquanto o jogador permanecesse no veículo. O tempo de desenvolvimento foi aproximadamente 3 horas de teste, porque a documentação das funções nativas disponíveis é praticamente inexistente.
O que o CLEO não consegue fazer bem
Performance é o limitante mais óbvio. Cada thread CLEO roda dentro do loop principal do jogo. Se um script tem um loop apertado sem WAIT suficiente, o FPS cai. Já vi scripts mal escritos que baixavam o desempenho de 60fps para 25fps em áreas densas. A regra prática é colocar um WAIT de pelo menos 100ms dentro de qualquer loop que verifique condições repetidamente. O CLEO também não consegue modificar arquivos de mapa ou geometria do jogo. Ele opera apenas em variáveis de jogo, entidades ativas e estados. Se você precisa mudar a geometria de uma rua, precisa de outro modificador — DFF, TXD ou até mesmo edição direta do arquivo .ide. CLEO só lida com comportamento, não com conteúdo.
Compatibilidade com multijogador é outro ponto fraco. Scripts CLEO rodam localmente e não são sincronizados via rede. Em servidores SAMP or CR-MP, eles podem funcionar na interface singleplayer mas não terão efeito em sessão multiplayer. Isso é óbvio, mas muitos iniciantes tentam usar CLEO para criar recursos multiplayer e perdem horas entendendo por que nada acontece nos outros clientes. Se o objetivo é modificar texturas, modelos ou geometria, ferramentas como 3D Fix Manager, Silent's patch ou editores de TXD/DFF são mais adequados. CLEO complemente isso, mas não substitui.
Onde encontrar scripts e o compilador
O pacote original do CLEO para San Andreas ainda está disponível no repositório oficial do projeto Cleo-IV. A versão mais recente suporta DirectX 9 e funciona com a patched version 1.0 US do jogo. Para a Steam ou Rockstar Social Club, é necessário aplicar o patch 1.0 US primeiro ou usar a versão compatible do CLEO-IV que já vem corrigida. Scripts de comunidade podem ser encontrados em fóruns como GTAGeneric e ModDB. A qualidade varia muito — alguns arquivos vêm pré-compilados, outros exigem que você compile com o compilador oficial. Sempre verifique se o script foi feito para a versão correta do CLEO. Um script CLEO 3 não roda no CLEO 4 sem adaptação, e vice-versa.
O compilador suporta includes personalizados, macros e bibliotecas de comandos adicionais. Se você for escrever scripts com frequência, vale a pena criar um include próprio com funções que você usa sempre. Isso economiza tempo e evita repetir blocos de código idênticos em múltiplos projetos.