FiveM-Kraftstoffsysteme: Realistisches Tanken für Fahrzeuge
Ergänze deinen FiveM-Server um funktionierenden Kraftstoff. Tankstellen, Kanister, Elektrofahrzeuge und Top-Scripts für QBCore, ESX und standalone.
Agency Scripts
Gründer und leitender Entwickler bei Agency Scripts
Kraftstoffverbrauchsmechaniken
Ein realistisches Kraftstoffsystem sorgt für mehr Immersion und schafft eine natürliche Möglichkeit, Geld aus dem Wirtschaftskreislauf zu nehmen, wodurch die Serverwirtschaft ausgeglichen wird. Die grundlegende Mechanik erfasst den Kraftstoffstand jedes Fahrzeugs als Fließkommazahl zwischen 0 und 100 und verringert ihn abhängig von Motoraktivität und Fahrverhalten. Speichere den Kraftstoffstand mit Entity-State-Bags, damit Entity(vehicle).state.fuel der Wert für alle Clients bestehen bleibt und Netzwerkbesitzerwechsel übersteht. Berechne den Verbrauch pro Tick anhand der aktuellen Drehzahl des Fahrzeugs, die du über GetVehicleCurrentRpmabrufst, der Drosselklappenstellung aus GetControlNormalund des fahrzeugspezifischen Verbrauchsmultiplikators. Sportwagen und Supersportwagen sollten deutlich mehr Kraftstoff verbrauchen als sparsame Fahrzeuge, während sich LKWs und SUVs im Mittelfeld bewegen. Berücksichtige zusätzlichen Verbrauch bei aggressivem Fahrverhalten wie starkem Beschleunigen, dauerhaft hohen Geschwindigkeiten und Motorbremsen. Wenn der Kraftstoffstand null erreicht, reduziere mit SetVehicleMaxSpeed schrittweise die Höchstgeschwindigkeit des Fahrzeugs, um ein Stottern des Motors zu simulieren, statt ihn sofort abzustellen. So bleiben dem Spieler ein paar entscheidende Sekunden, um sicher anzuhalten.
-- Client-side fuel consumption thread
local fuelConsumptionRate = 0.0
CreateThread(function()
while true do
local ped = PlayerPedId()
local vehicle = GetVehiclePedIsIn(ped, false)
if vehicle ~= 0 and GetPedInVehicleSeat(vehicle, -1) == ped then
local engineOn = GetIsVehicleEngineRunning(vehicle)
if engineOn then
local rpm = GetVehicleCurrentRpm(vehicle)
local speed = GetEntitySpeed(vehicle) * 3.6 -- km/h
local classMultiplier = Config.ClassConsumption[GetVehicleClass(vehicle)] or 1.0
-- Base consumption + RPM factor + speed factor
fuelConsumptionRate = (Config.BaseConsumption
+ (rpm * Config.RpmFactor)
+ (speed * Config.SpeedFactor)
) * classMultiplier
local currentFuel = Entity(vehicle).state.fuel or 100.0
local newFuel = math.max(0.0, currentFuel - fuelConsumptionRate)
Entity(vehicle).state:set('fuel', newFuel, true)
-- Engine stall when empty
if newFuel <= 0 then
SetVehicleUndriveable(vehicle, true)
SetVehicleEngineOn(vehicle, false, true, true)
elseif newFuel <= 5.0 then
-- Sputtering effect
SetVehicleMaxSpeed(vehicle, 30.0 * (newFuel / 5.0))
end
end
end
Wait(1000) -- Update every second
end
end)
Tankstellen-UI und Tanken
Das Tanken sollte sich dank einer gut gestalteten NUI-Oberfläche hochwertig und intuitiv anfühlen. Wenn ein Spieler innerhalb eines festgelegten Radius an einer Zapfsäule parkt, zeige eine Interaktionsaufforderung an. Nach der Interaktion öffnet sich eine Tank-UI, die den aktuellen Kraftstoffstand als Anzeige oder Fortschrittsbalken, das Tankvolumen des Fahrzeugs, den Preis pro Liter der aktuellen Kraftstoffsorte sowie Optionen zum Volltanken oder zum Tanken für einen bestimmten Geldbetrag anzeigt. Die Tankanimation sollte sowohl am Spielercharakter abgespielt werden, der neben dem Fahrzeug steht und mithilfe von TaskPlayAnimeinen Zapfhahn-Prop hält, als auch an der Zapfsäule selbst, wenn du eigene Props verwendest. Der Kraftstoff sollte sich nach und nach in Echtzeit statt sofort auffüllen. Das sorgt für eine kurze Wartezeit, wirkt realistischer und verhindert, dass Spieler während einer Verfolgungsjagd blitzschnell tanken. Zeige die laufenden Kosten während des Tankens in Echtzeit an und ziehe die Zahlung erst ab, wenn der Spieler den Tankvorgang beendet oder der Tank voll ist. Unterstütze an Premium-Tankstellen verschiedene Kraftstoffsorten: normales Benzin zum Standardpreis, Premiumkraftstoff mit einem kleinen Leistungsbonus zu einem höheren Preis sowie Diesel für LKWs und Nutzfahrzeuge, der über separate Zapfsäulen angeboten wird.
Reservekanister und Tanken im Notfall
Wenn jemandem auf der Autobahn der Kraftstoff ausgeht, sollte dein System diese realistische Situation gut handhaben, ohne den Spieler dazu zu zwingen, sein Fahrzeug zurückzulassen. Implementiere einen Reservekanister als Item, das an Tankstellen oder in Baumärkten gekauft und an jeder Zapfsäule befüllt werden kann. Der Reservekanister sollte als benutzbares Inventar-Item funktionieren und in Metadaten den aktuellen Füllstand speichern. Typischerweise fasst er 10-20 Liter. Wenn ein Spieler einen Reservekanister in der Nähe eines leeren Fahrzeugs benutzt, wird eine Gießanimation abgespielt und Kraftstoff aus dem Kanister in den Fahrzeugtank gefüllt. Das Gewicht des Reservekanisters im Inventarsystem sollte sich nach der enthaltenen Kraftstoffmenge richten, sodass ein voller Kanister schwerer ist als ein leerer. Ergänze eine Mechanik, über die Spieler über das Ingame-Telefon einen Pannendienst rufen können. Dieser schickt gegen eine Gebühr einen NPC- oder spielergesteuerten Abschleppwagen mit Kraftstofflieferung. Für mehr Immersion sollten Spieler mithilfe eines Schlauch-Items Kraftstoff aus anderen Fahrzeugen abzapfen können. Dabei wird Kraftstoff zwischen Fahrzeugen umgefüllt, was Zeit kostet und das Risiko birgt, auf frischer Tat ertappt zu werden.
-- Jerry can usage handler
RegisterNetEvent('fuel:useJerryCan')
AddEventHandler('fuel:useJerryCan', function(slot)
local src = source
local ped = GetPlayerPed(src)
local coords = GetEntityCoords(ped)
-- Find nearest vehicle
local nearbyVehicle = GetClosestVehicle(coords, 3.0)
if not nearbyVehicle or nearbyVehicle == 0 then
return notify(src, 'No vehicle nearby.', 'error')
end
-- Get jerry can metadata
local canData = exports.ox_inventory:GetSlot(src, slot)
if not canData or not canData.metadata or not canData.metadata.fuel then
return notify(src, 'Jerry can is empty.', 'error')
end
local canFuel = canData.metadata.fuel
local vehicleFuel = Entity(nearbyVehicle).state.fuel or 0.0
local maxTransfer = math.min(canFuel, 100.0 - vehicleFuel)
if maxTransfer <= 0 then
return notify(src, 'Vehicle tank is already full.', 'error')
end
-- Transfer fuel
Entity(nearbyVehicle).state:set('fuel', vehicleFuel + maxTransfer, true)
-- Update jerry can metadata
local remainingFuel = canFuel - maxTransfer
if remainingFuel <= 0 then
exports.ox_inventory:SetMetadata(src, slot, { fuel = 0, label = 'Empty Jerry Can' })
else
exports.ox_inventory:SetMetadata(src, slot, { fuel = remainingFuel })
end
notify(src, ('Transferred %.1f liters to the vehicle.'):format(maxTransfer), 'success')
end)
Unterstützung für Elektrofahrzeuge
Moderne Roleplay-Server bieten zunehmend Elektrofahrzeuge, die eine eigene Ladeinfrastruktur brauchen. Elektrofahrzeuge sollten kein Benzin verbrauchen, sondern einen Akkuladestand aufbrauchen, der wie eine Tankanzeige funktioniert, sich aber anders schnell verringert. Elektrofahrzeuge sollten pro Kilometer weniger Energie verbrauchen als Benzinfahrzeuge, um ihren Effizienzvorteil in der Realität abzubilden. Das Laden sollte jedoch länger dauern als das Tanken und so für einen anderen Spielfluss sorgen. Platziere Ladestationen an ausgewählten Orten auf der Karte, nicht unbedingt an herkömmlichen Tankstellen, damit sich für Fahrer von Elektrofahrzeugen andere Routen ergeben. Implementiere eine Lade-UI, die den aktuellen Ladestand in Prozent, die geschätzte Zeit bis zum vollständigen Laden und die Kosten pro Kilowattstunde anzeigt. Ergänze an Premium-Ladestationen eine Schnellladeoption, die den Akku in der halben Zeit für den doppelten Preis pro Einheit füllt. Ordne für die Fahrzeugkonfiguration Elektrofahrzeuge anhand ihres Model-Hashes zu und speichere den Fahrzeugtyp in deiner Config. So erkennt das System automatisch, ob ein Fahrzeug Benzin oder Strom benötigt. Unterstütze Hybridfahrzeuge, die beide Energiequellen nutzen können und bei niedrigen Geschwindigkeiten in den Elektromodus und auf der Autobahn in den Benzinmodus wechseln. Dabei verbrauchen sie beide Ressourcen mit geringerer Rate.
Dynamische Kraftstoffpreise
Ein dynamisches Preissystem lässt die Kraftstoffwirtschaft lebendig wirken und schafft interessante wirtschaftliche Entscheidungen für Spieler. Lege die Kraftstoffpreise auf Grundlage eines konfigurierbaren Tarifs fest, der sich abhängig von Angebot und Nachfrage verändert. Erfasse den gesamten an allen Tankstellen gekauften Kraftstoff über rollierende Zeiträume. Bei hohem Verbrauch steigen die Preise allmählich. Sinkt der Verbrauch, fallen die Preise, um mehr Kunden anzulocken. Lege für jede Tankstelle eigene Preise fest. Abgelegene Tankstellen in Blaine County verlangen aufgrund der Transportkosten mehr, während Tankstellen in der Stadt mit niedrigeren Gewinnspannen konkurrieren. Erlaube Spielern, Tankstellen zu besitzen und die Kraftstoffpreise innerhalb eines in der Server-Config festgelegten Mindest- und Höchstbereichs selbst festzulegen. So entsteht echter Preiswettbewerb zwischen Tankstellenbetreibern. Der Tankstellenbesitzer kauft Kraftstoff zum Großhandelspreis bei einem NPC-Lieferanten und verkauft ihn mit Aufschlag zum Einzelhandelspreis. Die Gewinnspanne bildet sein Einkommen. Ergänze saisonale oder eventbasierte Preiserhöhungen, bei denen die Kraftstoffkosten während Serverevents mit viel Fahrzeugverkehr, wie Rennen oder Raubüberfällen, in die Höhe schnellen. Das löst wirtschaftliche Auswirkungen aus, die alle Spieler betreffen, und fördert sparsames Verhalten oder den strategischen Kraftstoffkauf vor erwarteten Preiserhöhungen.
Tankstellen als Unternehmen
Wenn Spieler Tankstellen betreiben können, entsteht ein vollständiger Wirtschaftskreislauf rund um das Kraftstoffsystem. Der Besitzer verwaltet die Bestände, indem er Kraftstofflieferungen bei einem Großhändler bestellt, wartet die Ausstattung und bezahlt Reparaturen und Verbesserungen an den Zapfsäulen und stellt andere Spieler als Tankwarte ein, die einen Stundenlohn erhalten. Implementiere ein Verwaltungsmenü für die Tankstelle, das nur dem Besitzer zugänglich ist und tägliches Verkaufsvolumen, Umsatz, Gewinnspannen, aktuelle Kraftstoffbestände in den unterirdischen Tanks sowie Anwesenheitsdaten der Angestellten anzeigt. Die Tankstelle sollte über einen physischen unterirdischen Tank mit begrenztem Fassungsvermögen verfügen, dessen Inhalt beim Tanken der Kunden abnimmt. Der Besitzer muss Lieferungen per Tanklaster einplanen, deren Ankunft Zeit braucht und im Voraus bezahlt werden muss. Ergänze im Inneren der Tankstelle einen Laden, in dem der Besitzer Dinge des täglichen Bedarfs wie Snacks, Getränke und Grundbedarf anbieten kann. Kunden können diese zusammen mit Kraftstoff kaufen und schaffen so eine zusätzliche Einnahmequelle. Ermögliche Verbesserungen an der Tankstelle, zum Beispiel zusätzliche Zapfsäulen für mehr gleichzeitige Kunden, eine Waschanlage für eine zusätzliche Gebühr oder Ladestationen, um den Markt für Elektrofahrzeuge zu erschließen. Erfasse den Ruf der Tankstelle anhand fairer Preise, Verfügbarkeit und Kundenzufriedenheit. Tankstellen mit besserem Ruf werden auf der Karte hervorgehoben und ziehen mehr Kunden an.
HUD-Integration und Tankanzeige
Die Tankanzeige ist ein dauerhaftes HUD-Element, das Spieler ständig sehen. Sie muss daher übersichtlich und unaufdringlich sein und dennoch die wichtigsten Informationen auf einen Blick vermitteln. Gestalte eine kompakte Kraftstoffanzeige neben dem Tacho oder in einer Bildschirmecke. Sie zeigt den aktuellen Kraftstoffstand als Halbkreis-Anzeige, vertikalen Balken oder einfache Prozentangabe an. Verwende eine Farbcodierung: Grün zeigt einen guten Kraftstoffstand über 50% an, Gelb einen mittleren Stand zwischen 20-50% und Rot warnt vor einem kritischen Stand unter 20%. Wenn der Kraftstoffstand unter 15% fällt, gib in regelmäßigen Abständen einen Warnton aus und lass die Anzeige blinken, damit dem Spieler nicht unerwartet der Kraftstoff ausgeht. Zeige die geschätzte verbleibende Reichweite auf Grundlage des aktuellen Verbrauchs an. Berechne sie, indem du den verbleibenden Kraftstoff durch den durchschnittlichen Verbrauch pro Kilometer der letzten paar Minuten Fahrt teilst. Blende die Tankanzeige komplett aus, wenn der Spieler zu Fuß unterwegs ist, um das HUD übersichtlich zu halten, und lasse sie beim Einsteigen in ein Fahrzeug sanft einblenden. Spieler, die ein minimales HUD bevorzugen, sollten die Tankanzeige vollständig ausblenden und nur dann vorübergehend benachrichtigt werden können, wenn der Kraftstoffstand unter einen konfigurierbaren Schwellenwert fällt. Integriere die Anzeige mit anderen Fahrzeug-HUD-Elementen wie Tacho und Motorgesundheit, damit ein stimmiges Fahrzeug-Cockpit entsteht.
Performance und Synchronisierung
Das Kraftstoffsystem läuft kontinuierlich für jeden Client, der ein Fahrzeug fährt. Deshalb ist die Performance-Optimierung entscheidend. Verwende ein Aktualisierungsintervall von 1000 Millisekunden für den Verbrauch, statt den Code bei jedem Frame auszuführen. Änderungen am Kraftstoffstand erfolgen allmählich, sodass Aktualisierungen pro Sekunde optisch nicht von Aktualisierungen pro Frame zu unterscheiden sind und dabei etwa 60-mal weniger Rechenleistung benötigen. Speichere Kraftstoffwerte in Entity-State-Bags statt in benutzerdefinierten Netzwerk-Events, da State-Bags für häufig wechselnde Werte optimiert sind und nur dann synchronisiert werden, wenn sich der Wert tatsächlich ändert. Wenn du Kraftstoffstände für den Erhalt nach Serverneustarts in der Datenbank speicherst, fasse alle Fahrzeugaktualisierungen in einer einzigen Abfrage zusammen, die alle 60 Sekunden ausgeführt wird, statt bei jeder Änderung des Kraftstoffstands eines Fahrzeugs einzeln zu schreiben. Verwende die Netzwerk-ID des Fahrzeugs als Schlüssel für die Kraftstofferfassung und entferne gespeicherte Kraftstoffdaten von Fahrzeugen, die nicht mehr existieren, um unnötiges Datenbankwachstum zu verhindern. Behandle den Sonderfall, dass ein Fahrzeug während des Tankens einen neuen Netzwerkbesitzer erhält, indem du vor jeder Kraftstoffänderung den Besitz überprüfst und alle Zahlungstransaktionen serverseitig validierst. Richte an Tankstellen mit vielen gleichzeitigen Kunden ein Warteschlangensystem ein, das verhindert, dass zwei Spieler dieselbe Zapfsäule gleichzeitig benutzen. Zeige dabei visuell an, dass die Zapfsäule gerade verwendet wird.