>
Guia 2026-05-13

Sistema de Comboios e Transporte Público em FiveM

OntelMonke

OntelMonke

Developer & Criador de Conteúdo na Agency Scripts

Transporte Público como Infraestrutura de Servidores

Um sistema de trem e transporte público transforma seu servidor FiveM de uma cidade centrada no carro em uma área metropolitana viva com transporte de massa funcional. Os comboios que circulam em horários regulares ao longo da rede ferroviária existente da GTA, os autocarros que seguem rotas pelas ruas da cidade e as estações de metro que proporcionam viagens rápidas entre distritos contribuem para um mundo que parece genuinamente vivo. O transporte público beneficia todos os jogadores do servidor, independentemente de riqueza ou emprego. Novos jogadores que não podem comprar um carro podem pegar o ônibus para chegar aos locais de trabalho. Jogadores experientes usam o metrô durante o pico de tráfego para evitar estradas congestionadas. Os jogadores criminosos usam o trânsito para se movimentar pela cidade sem um veículo pessoal rastreável. O sistema de transporte também cria oportunidades de trabalho únicas para motoristas de ônibus, maquinistas de trem e funcionários de autoridades de trânsito operados por jogadores, que mantêm horários, cobram tarifas e gerenciam incidentes na rede. Do ponto de vista técnico, trens e ônibus que circulam em rotas consistentes povoam o mundo com entidades móveis que fazem a cidade parecer ocupada sem exigir contagem adicional de jogadores.

Rota do trem e configuração de programação

GTA V possui uma rede ferroviária integrada que circunda o mapa, e seu sistema de trem deve aproveitar esses trilhos existentes para máxima compatibilidade. Defina rotas de trem como sequências de paradas de estações ao longo dos trilhos com horários de chegada e partida calculados a partir da velocidade média do trem entre as estações. Cada estação precisa de uma zona de plataforma onde os jogadores embarcam e saem, um ponto de interação com a máquina de bilhetes e painéis de exibição mostrando as próximas chegadas. Configure vários serviços de trem que funcionam simultaneamente em diferentes segmentos da rede, com horários que se repetem em um ciclo configurável que corresponde à progressão dia-noite do seu servidor:

Config.TrainSystem = {
    ticketPrice = 50,
    speedMultiplier = 1.0,
    despawnDistance = 500.0,
    announceArrival = true,
    announceDeparture = true,
}

Config.TrainRoutes = {
    ['metro_line_1'] = {
        label = 'Metro Line 1 - City Loop',
        model = 'metrotrain',
        carriages = 3,
        frequency = 300,  -- seconds between departures
        stations = {
            {
                name = 'Los Santos Central',
                coords = vector3(268.09, -1204.28, 38.90),
                platform = vector3(264.55, -1200.12, 38.90),
                stopDuration = 20,
                announceText = 'Now arriving at Los Santos Central Station',
            },
            {
                name = 'Strawberry',
                coords = vector3(36.81, -1393.78, 29.36),
                platform = vector3(40.22, -1389.45, 29.36),
                stopDuration = 15,
                announceText = 'Now arriving at Strawberry Station',
            },
            {
                name = 'Del Perro',
                coords = vector3(-1359.88, -474.17, 15.02),
                platform = vector3(-1355.44, -470.89, 15.02),
                stopDuration = 15,
                announceText = 'Now arriving at Del Perro Station',
            },
            {
                name = 'Rockford Hills',
                coords = vector3(-512.47, -680.33, 33.42),
                platform = vector3(-508.12, -676.88, 33.42),
                stopDuration = 15,
                announceText = 'Now arriving at Rockford Hills Station',
            },
            {
                name = 'Burton',
                coords = vector3(-283.66, -324.78, 10.07),
                platform = vector3(-279.33, -321.44, 10.07),
                stopDuration = 15,
                announceText = 'Now arriving at Burton Station',
            },
        },
    },
}

Config.BusRoutes = {
    ['route_1'] = {
        label = 'Route 1 - Downtown Express',
        model = 'bus',
        frequency = 180,
        stops = {
            { name = 'Legion Square', coords = vector3(208.24, -935.88, 30.69),
              stopDuration = 12 },
            { name = 'Pillbox Hospital', coords = vector3(311.44, -592.33, 43.29),
              stopDuration = 12 },
            { name = 'Alta Street', coords = vector3(-226.87, -381.44, 30.05),
              stopDuration = 12 },
            { name = 'Vinewood Blvd', coords = vector3(302.33, 193.67, 104.38),
              stopDuration = 12 },
        },
    },
}

O valor frequency determina a frequência com que um novo trem parte da primeira estação da rota. Vários trens podem operar na mesma rota simultaneamente, espaçados pelo intervalo de frequência. O stopDuration em cada estação dá aos jogadores tempo suficiente para embarcar ou sair, com um anúncio de áudio tocando quando o trem chega e um aviso de partida alguns segundos antes de partir.

Treinar geração e movimento de entidades

Gerar e controlar trens no FiveM requer funções nativas específicas que diferem do manuseio normal de veículos. Use CreateMissionTrain para gerar trens na rede ferroviária, o que os coloca automaticamente nos trilhos mais próximos e controla os trilhos seguindo a física. Controle a velocidade do trem com SetTrainSpeed e SetTrainCruiseSpeed e pare os trens nas estações reduzindo a velocidade gradualmente à medida que eles se aproximam das coordenadas da plataforma. O trem deve parar precisamente na posição da plataforma para que as portas se alinhem com as zonas de embarque, o que requer cálculos cuidadosos de redução de velocidade com base na distância até a próxima estação:

local activeTrains = {}

function SpawnTrain(routeId)
    local route = Config.TrainRoutes[routeId]
    if not route then return end

    local firstStation = route.stations[1]
    local variation = 24  -- metro train variation

    -- Create the mission train
    local train = CreateMissionTrain(variation, firstStation.coords.x,
        firstStation.coords.y, firstStation.coords.z, true)

    if not DoesEntityExist(train) then
        print('[Transit] Failed to spawn train for route: ' .. routeId)
        return
    end

    SetTrainSpeed(train, 0.0)
    SetTrainCruiseSpeed(train, 0.0)
    SetEntityAsMissionEntity(train, true, true)

    -- Store train state
    activeTrains[routeId] = {
        entity = train,
        route = route,
        currentStation = 1,
        state = 'stopped',  -- stopped, departing, moving, arriving
        stateTimer = GetGameTimer(),
        passengers = {},
    }

    return train
end

-- Train movement controller
CreateThread(function()
    while true do
        for routeId, trainData in pairs(activeTrains) do
            local train = trainData.entity
            if not DoesEntityExist(train) then
                activeTrains[routeId] = nil
                goto continue
            end

            local station = trainData.route.stations[trainData.currentStation]
            local elapsed = GetGameTimer() - trainData.stateTimer

            if trainData.state == 'stopped' then
                if elapsed >= (station.stopDuration * 1000) then
                    -- Depart from station
                    trainData.state = 'departing'
                    trainData.stateTimer = GetGameTimer()
                    AnnounceToPassengers(trainData, 'Doors closing. Next stop: '
                        .. GetNextStationName(trainData))
                end

            elseif trainData.state == 'departing' then
                local speed = math.min(15.0, elapsed * 0.005)
                SetTrainCruiseSpeed(train, speed)
                SetTrainSpeed(train, speed)
                if speed >= 15.0 then
                    trainData.state = 'moving'
                end

            elseif trainData.state == 'moving' then
                local nextIdx = trainData.currentStation + 1
                if nextIdx > #trainData.route.stations then
                    nextIdx = 1
                end
                local nextStation = trainData.route.stations[nextIdx]
                local trainCoords = GetEntityCoords(train)
                local dist = #(trainCoords - nextStation.coords)

                if dist < 200.0 then
                    trainData.state = 'arriving'
                    trainData.stateTimer = GetGameTimer()
                    AnnounceToPassengers(trainData, nextStation.announceText)
                end

            elseif trainData.state == 'arriving' then
                local nextIdx = trainData.currentStation + 1
                if nextIdx > #trainData.route.stations then
                    nextIdx = 1
                end
                local nextStation = trainData.route.stations[nextIdx]
                local trainCoords = GetEntityCoords(train)
                local dist = #(trainCoords - nextStation.coords)

                -- Gradually slow down
                local speed = math.max(0.0, dist * 0.08)
                SetTrainCruiseSpeed(train, speed)
                SetTrainSpeed(train, speed)

                if dist < 3.0 then
                    SetTrainSpeed(train, 0.0)
                    SetTrainCruiseSpeed(train, 0.0)
                    trainData.currentStation = nextIdx
                    trainData.state = 'stopped'
                    trainData.stateTimer = GetGameTimer()
                end
            end

            ::continue::
        end
        Wait(100)
    end
end)

Embarque e emissão de passagens de passageiros

Quando um trem para em uma estação, exibe avisos de interação para jogadores próximos, permitindo-lhes embarcar. Verifique se o jogador possui um bilhete ou passe de transporte válido antes de permitir sua entrada. Os ingressos podem ser adquiridos nas máquinas de bilhetes em cada estação usando uma interface NUI simples que mostra as rotas e preços disponíveis. Uma vez embarcado, teletransporte o jogador para o interior do vagão do trem e defina sua posição em relação à entidade do trem para que ele se mova com ela. Os interiores de trem integrados do GTA funcionam para implementações básicas, mas os interiores personalizados usando objetos ou instâncias anexados proporcionam uma experiência melhor com assentos, áreas de pé e janelas que mostram o cenário que passa. Acompanhe em qual estação cada passageiro embarcou para que o sistema possa calcular as diferenças de tarifas para preços baseados na distância. Exiba o nome da próxima estação e o tempo estimado de chegada dentro do vagão por meio de um elemento de texto 3D ou display NUI anexado que é atualizado conforme o trem avança ao longo de sua rota.

Sistema de ônibus e drivers NPC

Os ônibus complementam a rede ferroviária cobrindo áreas que a ferrovia não alcança. Gere ônibus dirigidos por NPCs que seguem rotas predefinidas pelas ruas da cidade, parando em pontos de ônibus marcados para pegar e deixar os jogadores. O motorista NPC usa o sistema de tarefas do GTA para navegar entre as paradas usando TaskVehicleDriveToCoordLongrange com sinalizadores de direção apropriados para obedecer às leis de trânsito e parar em locais designados. Em cada parada, o ônibus espera por um período configurado enquanto os jogadores embarcam ou saem, então o motorista NPC continua para a próxima parada. Exiba informações da rota nos pontos de ônibus mostrando o número da rota, destino e tempo estimado de espera até a chegada do próximo ônibus. Para uma variante operada por jogadores, permita que jogadores com o cargo de autoridade de trânsito dirijam ônibus manualmente, ganhando pagamento por passageiro transportado e bônus por manter o cumprimento do cronograma.

Mapa de trânsito e IU da estação

Crie um mapa de transporte público que os jogadores possam acessar em seus telefones, quiosques de estação ou displays de pontos de ônibus. O mapa deve mostrar todas as rotas ativas codificadas por cores por linha, localizações de estações com indicadores de intercâmbio onde várias linhas se conectam e posições de trens em tempo real atualizadas a cada poucos segundos. A IU da estação nos quiosques deve exibir a hora atual, as próximas chegadas de cada linha que atende aquela estação, quaisquer interrupções ou atrasos no serviço e uma interface de compra de passagens. Implemente o mapa de trânsito como uma sobreposição NUI que renderiza a rede ferroviária de forma esquemática em vez de geográfica, semelhante aos mapas metropolitanos do mundo real que priorizam a clareza em vez da precisão geográfica. Adicione indicadores em tempo real mostrando a posição atual de cada trem como um ponto móvel ao longo de sua rota, dando aos jogadores feedback imediato sobre quanto tempo eles precisam esperar pelo próximo serviço.

Sistema tarifário e passes de trânsito

Implemente um sistema de tarifas escalonadas com bilhetes de viagem única, passes diários e assinaturas mensais. Os bilhetes únicos custam a tarifa básica e expiram após uma viagem. Os passes diários permitem viagens ilimitadas por vinte e quatro horas de jogo a um preço fixo que se torna econômico após três ou quatro viagens. Os passes mensais fornecem o melhor valor por viagem para passageiros regulares e são armazenados como um item no inventário do jogador com um carimbo de data e hora de expiração. Valide as tarifas nos portões de entrada das estações usando interações de destino nas catracas e nos ônibus por meio da interação do motorista no embarque. Para preços baseados na distância, calcule a tarifa na saída do passageiro com base no número de estações percorridas. Jogadores sem ingressos válidos que forem pegos durante inspeções aleatórias pela equipe da autoridade de trânsito receberão multas, adicionando jogabilidade de fiscalização para o trabalho da autoridade de trânsito.

Desempenho e sincronização

Trens e ônibus são entidades grandes que devem ser sincronizadas entre todos os clientes, tornando-os recursos sensíveis ao desempenho que exigem otimização cuidadosa. Use o gerenciamento de estado do lado do servidor para controlar as posições dos trens e transmitir atualizações aos clientes, permitindo que cada cliente renderize a entidade do trem localmente com base nas coordenadas recebidas. Despawn treina entidades para jogadores que estão longe de qualquer estação ou linha ferroviária para reduzir a sobrecarga de renderização, e só as gera quando um jogador entra nas proximidades da rede ferroviária. Os motoristas NPC de ônibus só devem receber tarefas ativas quando os jogadores estão próximos, com ônibus distantes usando interpolação de posição simplificada em vez de localização de caminho completa por IA. Limite o número total de entidades simultâneas de trem e barramento no servidor para evitar a degradação do desempenho durante horários de pico. Alterne os horários de partida em diferentes rotas para que vários veículos não apareçam simultaneamente. Limpe todas as entidades de trânsito na reinicialização do recurso e implemente uma lógica de recuperação que recalcula as posições dos trens com base no horário quando o recurso é iniciado, para que os trens apareçam nos locais corretos imediatamente, em vez de começarem sempre na primeira estaçã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.