Servidores de Jogos

Timers no Pawn: como usar sem derrubar o desempenho

Timers no Pawn: como usar sem derrubar o desempenho

Timers executam uma função depois de um intervalo, uma vez ou repetidamente. São indispensáveis (salário, fome, relógio, anúncios), mas timers mal usados estão entre as causas mais comuns de lag em servidores open.mp.

SetTimer e SetTimerEx

forward AtualizarRelogio();
public AtualizarRelogio()
{
    // roda para o servidor inteiro
    return 1;
}

// em OnGameModeInit
SetTimer("AtualizarRelogio", 60000, true); // a cada 60 s, repetindo

Para passar parâmetros, como o playerid, use SetTimerEx:

forward LiberarJogador(playerid);
public LiberarJogador(playerid)
{
    TogglePlayerControllable(playerid, true);
    return 1;
}

SetTimerEx("LiberarJogador", 3000, false, "i", playerid);

A função chamada precisa ser public e ter forward.

Um timer global em vez de 500 timers por jogador

Um erro clássico é criar um timer repetitivo para cada jogador. Com 300 jogadores online, são 300 timers disparando o tempo todo.

Na maioria dos casos, um timer global que percorre os jogadores resolve com menos custo:

forward TickJogadores();
public TickJogadores()
{
    for (new i = 0, j = GetPlayerPoolSize(); i <= j; i++)
    {
        if (!IsPlayerConnected(i)) continue;
        // fome, sede, tempo online...
    }
    return 1;
}

SetTimer("TickJogadores", 1000, true);

Escolha o intervalo certo

  • Salário e pagamentos: minutos;
  • Fome e sede: dezenas de segundos;
  • Velocímetro e HUD: centenas de milissegundos, só quando necessário;
  • Anti-cheat: depende da checagem, mas evite rodar tudo a cada 100 ms.

Quanto menor o intervalo, maior o custo. Pergunte-se se o jogador realmente percebe a diferença.

Mate os timers que não usa mais

Guarde o ID e use KillTimer:

new TimerVelocimetro[MAX_PLAYERS] = {-1, ...};

// ao entrar no veículo
TimerVelocimetro[playerid] = SetTimerEx("AtualizarVelocimetro", 250, true, "i", playerid);

// ao sair do veículo ou desconectar
if (TimerVelocimetro[playerid] != -1)
{
    KillTimer(TimerVelocimetro[playerid]);
    TimerVelocimetro[playerid] = -1;
}

Timers "órfãos" de jogadores que já saíram continuam rodando e podem agir sobre outro jogador que recebeu o mesmo ID. Esse é um bug difícil de rastrear.

Timers x OnPlayerUpdate

OnPlayerUpdate é chamado muitas vezes por segundo para cada jogador. Mover lógica para lá "porque é mais rápido" costuma piorar o desempenho. Prefira timers com intervalos razoáveis.

Alternativas

Bibliotecas como o YSI oferecem timers declarativos (task e ptask) que deixam o código mais limpo. O princípio é o mesmo: poucos timers e intervalos sensatos.

Hospede seu servidor com a VittHost

Nos planos OPENMP-BR da VittHost, você acompanha o uso de CPU do servidor pelo painel Pterodactyl e percebe rápido quando um timer pesa demais. Servidores no Brasil, proteção DDoS, MySQL incluso, compatibilidade total com scripts SA-MP e teste grátis de 3 dias.

Compartilhar:

Pronto para hospedar seu próximo projeto?

VPS com painel pré-instalado em 1 clique. Ativação imediata.

Ver planos VPS