>
Tutorial 2026-03-24

Criar um Sistema de Corridas de Rua para FiveM

OntelMonke

OntelMonke

Admin & Developer na Agency Scripts

Projetando o Sistema de Criação de Corrida

Um sistema atraente de corrida de rua começa dando aos jogadores o poder de criar e gerenciar suas próprias rotas de corrida. Em vez de depender apenas de pistas predefinidas, os melhores scripts de corrida permitem que os organizadores coloquem pontos de controle dinamicamente, dirigindo ao longo de uma rota e marcando posições. Armazene cada corrida como uma estrutura de dados contendo um identificador exclusivo, o ID do jogador do criador, um nome, a lista ordenada de coordenadas de pontos de verificação com ângulos de rumo e metadados como distância e tempo estimado de volta. O processo de criação deve ser intuitivo: o jogador entra no modo editor de corrida, dirige até cada posição de checkpoint, confirma a colocação pressionando uma tecla e termina retornando à linha de partida. Salve corridas concluídas em seu banco de dados para que elas persistam durante as reinicializações do servidor e possam ser compartilhadas com a comunidade. Implemente um sistema de revisão onde os administradores possam aprovar rotas criadas pelos jogadores antes que elas apareçam na lista pública de corridas, evitando sofrimento devido a designs de pistas impossíveis ou injustos.

Sistema de Checkpoint e Lógica de Corrida

Os pontos de verificação são a mecânica central que valida o progresso da corrida e evita atalhos. Cada ponto de verificação deve ser definido como uma zona 3D com raio configurável, normalmente entre 8 e 15 metros, dependendo da largura da estrada. Use as funções nativas de desenho de marcadores do GTA para exibir pontos de controle visualmente, com o ponto de controle atual destacado em uma cor brilhante e o próximo mostrado como uma visualização transparente. Acompanhe o progresso de cada piloto através de uma lista de pontos de verificação indexados, avançando-os somente quando eles entrarem na próxima zona correta de pontos de verificação em sequência. Implemente medidas anti-cheat monitorando o tempo entre os pontos de controle e sinalizando ou desqualificando os pilotos que completam segmentos com uma rapidez impossível, o que indica teletransporte ou speed hacking.

-- Client-side checkpoint detection
local currentCheckpoint = 1
local raceCheckpoints = {} -- populated when race starts

CreateThread(function()
    while isRacing do
        local playerCoords = GetEntityCoords(PlayerPedId())
        local checkpoint = raceCheckpoints[currentCheckpoint]

        if checkpoint then
            local dist = #(playerCoords - checkpoint.coords)

            -- Draw current checkpoint marker
            DrawMarker(1, checkpoint.coords.x, checkpoint.coords.y,
                checkpoint.coords.z - 1.0, 0, 0, 0, 0, 0, 0,
                checkpoint.radius * 2, checkpoint.radius * 2, 2.0,
                45, 212, 191, 120, false, true, 2, false, nil, nil, false)

            if dist < checkpoint.radius then
                PlaySoundFrontend(-1, 'CHECKPOINT_NORMAL', 'HUD_MINI_GAME_SOUNDSET', true)
                currentCheckpoint = currentCheckpoint + 1

                if currentCheckpoint > #raceCheckpoints then
                    -- Race finished
                    local finishTime = GetGameTimer() - raceStartTime
                    TriggerServerEvent('racing:finished', raceId, finishTime)
                    isRacing = false
                else
                    -- Notify server of checkpoint progress
                    TriggerServerEvent('racing:checkpoint', raceId, currentCheckpoint)
                end
            end
        end
        Wait(50)
    end
end)

Tabela de classificação e sistema de classificação

As tabelas de classificação impulsionam a competição e fazem com que os jogadores voltem para melhorar seus tempos. Armazene os resultados da corrida em uma tabela de banco de dados que registra o identificador do jogador, o ID da corrida, o tempo de conclusão em milissegundos, o modelo do veículo usado, a data e se a corrida foi um recorde pessoal. Exiba tabelas de classificação por meio de uma interface NUI que mostra os melhores tempos de cada pista, filtráveis ​​por classe de veículo para que os jogadores possam comparar de forma justa em categorias como esportivo, super, muscular ou compacto. Implemente um sistema de classificação sazonal que seja redefinido periodicamente para manter a competição atualizada, ao mesmo tempo em que mantém um quadro de recordes históricos para o direito de se gabar. Calcule uma classificação de corrida no estilo ELO com base no desempenho frente a frente em corridas multijogador, dando aos pilotos habilidosos uma classificação visível que aumenta quando eles derrotam oponentes com classificações mais altas e diminui quando perdem para adversários com classificações mais baixas. Exiba esta classificação na UI da corrida e use-a para matchmaking opcional ao organizar corridas aleatórias.

Sistema de apostas e prêmios

Um sistema de apostas adiciona apostas financeiras às corridas e integra o cenário das corridas com a economia mais ampla do seu servidor. Permita que os organizadores da corrida estabeleçam uma taxa de inscrição que todos os participantes deverão pagar, com o prêmio total distribuído entre os primeiros colocados de acordo com uma divisão configurável, como 70-20-10 para o primeiro, segundo e terceiro colocados. Implemente um sistema de apostas para espectadores onde os jogadores que não participam de corridas possam apostar no resultado, escolhendo um piloto para apostar com seu dinheiro. Use a lógica do lado do servidor exclusivamente para todas as transações financeiras para evitar a exploração. Adicione uma redução da casa de 5 a 10% em todas as apostas para funcionar como um sumidouro de dinheiro para sua economia. Para eventos organizados maiores, permita que os administradores adicionem prêmios de bônus financiados pelo tesouro do servidor. Acompanhe as estatísticas de apostas por jogador para detectar e evitar padrões de manipulação de resultados, como um piloto perdendo corridas consistentemente onde grandes apostas são feitas contra ele.

-- Server-side betting handler
local raceBets = {}

RegisterNetEvent('racing:placeBet')
AddEventHandler('racing:placeBet', function(raceId, targetRacerId, amount)
    local src = source
    if not activeRaces[raceId] then return end
    if activeRaces[raceId].state ~= 'lobby' then
        return notify(src, 'Betting is closed once the race starts.', 'error')
    end

    -- Validate the target racer is in this race
    local racerFound = false
    for _, racer in ipairs(activeRaces[raceId].participants) do
        if racer.src == targetRacerId then racerFound = true break end
    end
    if not racerFound then return end

    -- Check and deduct funds
    local playerMoney = GetPlayerMoney(src)
    if playerMoney < amount or amount < Config.MinBet then
        return notify(src, 'Insufficient funds or below minimum bet.', 'error')
    end

    RemoveMoney(src, amount)

    if not raceBets[raceId] then raceBets[raceId] = {} end
    table.insert(raceBets[raceId], {
        bettor = src,
        target = targetRacerId,
        amount = amount,
    })

    notify(src, ('Bet $%s on %s'):format(amount, GetPlayerName(targetRacerId)), 'success')
end)

Construindo a UI da corrida com NUI

A UI de corrida precisa transmitir informações críticas em tempo real, sem sobrecarregar a tela ou distrair o motorista. Projete um HUD mínimo que mostre a posição atual entre os pilotos, o número da volta, se aplicável, um cronômetro dividido comparando a corrida atual com o recorde pessoal ou o histórico da pista e uma sobreposição de minimapa destacando a direção do próximo ponto de verificação. Use um velocímetro que corresponda ao tema da corrida, mostrando a velocidade em mph ou km/h com base na preferência do jogador. A tela do lobby antes de uma corrida deve exibir todos os participantes registrados com seus veículos, o nome da pista e a distância, o detalhamento do prêmio e uma contagem regressiva. Crie a UI com HTML, CSS e JavaScript usando o sistema NUI e comunique atualizações de estado de corrida da Lua do lado do cliente para o quadro NUI via SendNUIMessage. Mantenha a resposta da IU limitando as atualizações de posição para 4 a 5 vezes por segundo, em vez de cada quadro, o que reduz significativamente a sobrecarga da NUI sem qualquer impacto visível nas informações exibidas. Considere adicionar uma tela de resultados pós-corrida com estatísticas detalhadas, como velocidade máxima alcançada, velocidade média e comparação de tempo por segmento de ponto de verificação.

Categorias de corrida e classes de veículos

Organize as corridas em categorias distintas para garantir competição justa e variedade. Defina classes de veículos com base em métricas de desempenho, como velocidade máxima, aceleração e classificações de manuseio extraídas dos dados de manuseio nativos do jogo. Crie restrições de classe para raças específicas para que um jogador do Dominador não possa entrar em uma corrida restrita a compactos e vice-versa. Além da classe de veículo, oferece diferentes formatos de corrida: sprints ponto a ponto que vão de A a B pela cidade, corridas de circuito com múltiplas voltas em torno de um loop, corridas de arrancada em estradas retas com início de tempo de reação e competições de drift pontuadas por ângulo, velocidade e proximidade de pontos de corte. Cada formato requer uma lógica ligeiramente diferente para pontuação e detecção de conclusão. A pontuação de desvio, em particular, precisa de um algoritmo personalizado que avalie o ângulo de escorregamento do veículo em relação ao seu vetor de velocidade, a velocidade mantida durante o desvio e multiplicadores de bônus para encadear desvios consecutivos sem perder o controle. Permita que os organizadores da corrida alternem opções como mecânica de recuperação, passagem de outros pilotos para evitar colisões dolorosas e configurações de clima ou hora do dia para a atmosfera.

Integração policial e corridas ilegais

As corridas de rua deveriam ser uma atividade ilegal que cria interações orgânicas com as autoridades. Quando uma corrida começa, gere reclamações de ruído dos NPCs na área que aparecem no sistema de despacho policial após um atraso configurável, dando aos pilotos uma vantagem inicial, mas garantindo que corridas mais longas atraiam a atenção. Os policiais que responderem podem tentar interromper a corrida implantando faixas de espinhos, montando bloqueios de estradas ou perseguindo pilotos individuais. Se um piloto for pego pela polícia, ele enfrentará multas, apreensão do veículo e, potencialmente, pena de prisão, acrescentando consequências reais que tornam o cenário da corrida perigoso e emocionante. Implemente um sistema de níveis de procurado especificamente para corridas que aumente com a repetição de ofensas, para que os corredores de rua crônicos atraiam respostas policiais mais agressivas ao longo do tempo. Permitir que a polícia use câmeras de vigilância em locais de corrida conhecidos para construir casos contra os organizadores, criando uma camada investigativa que recompensa o trabalho paciente da polícia com prisões maiores que derrubam equipes inteiras de corrida em vez de pilotos individuais.

Otimização de desempenho para corridas

Os sistemas de corrida exigem um desempenho suave, pois mesmo um pequeno atraso pode arruinar a experiência competitiva. Minimize a comunicação servidor-cliente durante corridas ativas gerenciando a detecção de pontos de verificação e o rastreamento de posição no lado do cliente, enviando atualizações ao servidor somente quando um ponto de verificação for alcançado ou a corrida terminar. Use pacotes de estado de entidade para transmissão de posição em vez de eventos de rede personalizados, pois os pacotes de estado são otimizados para atualizações frequentes e lidam com a largura de banda com mais eficiência. Para a renderização do ponto de verificação, desenhe apenas marcadores para o ponto de verificação atual e o próximo, em vez de todos os pontos de verificação simultaneamente, e use a lógica LOD (Nível de detalhe) para reduzir a complexidade do marcador em distâncias maiores. Agrupe suas solicitações de dados de corrida buscando tabelas de classificação e listas de corrida em operações em lote, em vez de consultas individuais, e armazene em cache os resultados do lado do cliente com um TTL curto para reduzir a carga do banco de dados durante os horários de pico das corridas. Teste seu sistema com o número máximo esperado de pilotos simultâneos, normalmente de 8 a 16 por corrida, para garantir que a sincronização de posição e a validação do ponto de verificação sejam dimensionadas corretamente, sem quedas de quadros ou problemas de dessincronização.

Partilhar este artigo

Pronto para melhorar o teu servidor?

Explora os nossos scripts FiveM premium na loja Agency Scripts ou junta-te à nossa comunidade no Discord para suporte e atualizações.