Zurück zum Blog
Guide10 Min. Lesezeit

FiveM Landwirtschaftssystem: Pflanzen, Tiere und Verkaufsketten

Erstelle ein umfangreiches Landwirtschaftssystem für FiveM mit Pflanzen, Nutztieren, Verarbeitung, Verkaufs-NPCs und passenden Scripts für immersives Roleplay.

Agency Scripts

Gründer und leitender Entwickler bei Agency Scripts

Designphilosophie für Farming-Systeme

Ein Landwirtschafts- und Agrarsystem bringt ein völlig anderes Tempo in FiveM-Rollenspielserver und bietet Spielern eine entspannte Alternative zu kriminellen Aktivitäten mit viel Adrenalin und der Strafverfolgung. Die besten Landwirtschaftssysteme schaffen einen sich selbst tragenden Wirtschaftskreislauf: Spieler kaufen Saatgut, pflanzen Feldfrüchte auf ausgewiesenen Feldern an, pflegen sie während echter Wachstumszyklen, ernten die Erzeugnisse und verkaufen sie auf dem Markt mit Gewinn. Die Herausforderung beim Design besteht darin, das System so interessant zu gestalten, dass Spieler regelmäßig zurückkehren, ohne es so zeitaufwendig zu machen, dass es sich wie eine lästige Pflicht anfühlt. Nutze Echtzeit-Wachstumszyklen, die auch dann weiterlaufen, wenn der Spieler offline ist, damit Landwirte beim Einloggen ihre Pflanzen in verschiedenen Wachstumsstadien vorfinden. Das zentrale Datenmodell muss jedes einzelne Pflanzenbeet mit seiner Position, Pflanzenart, aktuellem Wachstumsstadium, Pflanzzeitpunkt, Wasserstand und Qualitätsbewertung erfassen. Speichere all diese Daten serverseitig in einer Datenbank, damit der Zustand der Farm bei Serverneustarts erhalten bleibt und vor Manipulationen durch Clients geschützt ist.

Pflanzen anbauen und Datenbankschema

Das Anpflanzsystem beginnt damit, dass ein Spieler Saatgut aus seinem Inventar auswählt und es auf einer zulässigen Anbaufläche platziert. Definiere Anbauflächen als konfigurierbare polygonale Zonen auf der Karte, in denen das Pflanzen erlaubt ist. So verhinderst du, dass Spieler Feldfrüchte auf Gehwegen oder in Gebäuden anbauen. Jedes Pflanzenbeet sollte abhängig von der Grundstücksgröße nur eine begrenzte Anzahl an Plätzen haben. Spieler können Anbauflächen über einen NPC oder ein Immobilien-System mieten oder kaufen. Wenn ein Spieler einen Samen pflanzt, erstelle einen Datenbankeintrag, der die Pflanze während ihres gesamten Lebenszyklus erfasst. Hier ist ein praktisches Datenbankschema und ein serverseitiger Handler zum Pflanzen:

CREATE TABLE IF NOT EXISTS farm_crops (
    id INT AUTO_INCREMENT PRIMARY KEY,
    owner VARCHAR(50) NOT NULL,
    farm_id VARCHAR(50) NOT NULL,
    crop_type VARCHAR(50) NOT NULL,
    position_x FLOAT NOT NULL,
    position_y FLOAT NOT NULL,
    position_z FLOAT NOT NULL,
    planted_at BIGINT NOT NULL,
    growth_stage INT DEFAULT 0,
    water_level FLOAT DEFAULT 100.0,
    quality FLOAT DEFAULT 1.0,
    is_harvestable TINYINT DEFAULT 0,
    is_dead TINYINT DEFAULT 0,
    last_watered BIGINT DEFAULT 0,
    INDEX idx_owner (owner),
    INDEX idx_farm (farm_id)
);

CREATE TABLE IF NOT EXISTS farm_plots (
    id INT AUTO_INCREMENT PRIMARY KEY,
    farm_id VARCHAR(50) NOT NULL UNIQUE,
    owner VARCHAR(50) DEFAULT NULL,
    max_slots INT DEFAULT 20,
    rent_price INT DEFAULT 500,
    coords_center_x FLOAT NOT NULL,
    coords_center_y FLOAT NOT NULL,
    coords_center_z FLOAT NOT NULL,
    radius FLOAT DEFAULT 30.0
);
RegisterNetEvent('farming:server:plantCrop', function(cropType, position)
    local src = source
    local Player = QBCore.Functions.GetPlayer(src)
    if not Player then return end

    local citizenid = Player.PlayerData.citizenid
    local seedItem = 'seed_' .. cropType

    if not Player.Functions.GetItemByName(seedItem) then
        return TriggerClientEvent('QBCore:Notify', src, 'You need seeds to plant', 'error')
    end

    local farmId = GetFarmAtPosition(position)
    if not farmId then
        return TriggerClientEvent('QBCore:Notify', src, 'You can only plant on farmland', 'error')
    end

    local currentCrops = MySQL.scalar.await(
        'SELECT COUNT(*) FROM farm_crops WHERE farm_id = ? AND is_dead = 0',
        {farmId}
    )
    local maxSlots = MySQL.scalar.await(
        'SELECT max_slots FROM farm_plots WHERE farm_id = ?', {farmId}
    )

    if currentCrops >= maxSlots then
        return TriggerClientEvent('QBCore:Notify', src, 'Farm is full', 'error')
    end

    Player.Functions.RemoveItem(seedItem, 1)

    MySQL.insert(
        'INSERT INTO farm_crops (owner, farm_id, crop_type, position_x, position_y, position_z, planted_at, last_watered) VALUES (?, ?, ?, ?, ?, ?, ?, ?)',
        {citizenid, farmId, cropType, position.x, position.y, position.z, os.time(), os.time()}
    )

    TriggerClientEvent('QBCore:Notify', src, 'Planted ' .. cropType, 'success')
    TriggerClientEvent('farming:client:spawnCropProp', -1, position, cropType, 0)
end)

Jede Pflanzenart sollte unterschiedliche Wachstumsparameter haben, die in einer Konfigurationstabelle definiert sind. Weizen könnte in 30 realen Minuten über 4 Stadien wachsen, während Cannabis oder Trauben mehrere Stunden und 6 Stadien benötigen könnten. So werden geduldige Landwirte mit wertvolleren Erzeugnissen belohnt. Das Wachstumsstadium bestimmt, welches Prop-Modell in der Spielwelt angezeigt wird. Mit der Zeit entwickelt sich die Pflanze von einem kleinen Keimling zu einer ausgewachsenen Pflanze.

Wachstumszyklus-Engine und Bewässerung

Die Wachstumszyklus-Engine ist eine serverseitige Schleife, die regelmäßig alle angebauten Pflanzen prüft und ihre Wachstumsstadien abhängig von der verstrichenen Zeit und Bedingungen wie dem Wasserstand fortschreibt. Führe sie als zeitgesteuerten Server-Thread aus, der alle paar Minuten läuft und anhand der Wachstumsdauer der Pflanzenart und der Zeit seit dem Pflanzen berechnet, ob die Pflanze in das nächste Stadium wechseln sollte. Der Wasserstand ist die zentrale Spielmechanik, die Spieler bei der Stange hält: Pflanzen verbrauchen mit der Zeit Wasser. Sinkt der Wasserstand auf null, pausiert das Wachstum und die Qualität der Pflanze nimmt ab. Spieler müssen zu ihrer Farm zurückkehren und eine Gießkanne oder ein Bewässerungssystem nutzen, um den Wasserstand wieder aufzufüllen. Hier ist die serverseitige Wachstums-Engine:

local CropConfig = {
    wheat = {
        stages = 4,
        growthTime = 1800,    -- 30 min total, ~7.5 min per stage
        waterConsumption = 5, -- per cycle
        baseYield = 5,
        sellPrice = 50
    },
    corn = {
        stages = 5,
        growthTime = 3600,
        waterConsumption = 7,
        baseYield = 4,
        sellPrice = 80
    },
    tomato = {
        stages = 4,
        growthTime = 2400,
        waterConsumption = 8,
        baseYield = 6,
        sellPrice = 65
    },
    grape = {
        stages = 6,
        growthTime = 7200,
        waterConsumption = 4,
        baseYield = 8,
        sellPrice = 120
    }
}

CreateThread(function()
    while true do
        Wait(60000 * 5) -- Run every 5 minutes

        local crops = MySQL.query.await(
            'SELECT * FROM farm_crops WHERE is_dead = 0 AND is_harvestable = 0'
        )

        for _, crop in ipairs(crops or {}) do
            local config = CropConfig[crop.crop_type]
            if not config then goto continue end

            local elapsed = os.time() - crop.planted_at
            local stageTime = config.growthTime / config.stages
            local expectedStage = math.min(math.floor(elapsed / stageTime), config.stages)

            -- Degrade water
            local newWater = math.max(0, crop.water_level - config.waterConsumption)
            local newQuality = crop.quality

            -- Quality degrades without water
            if newWater <= 0 then
                newQuality = math.max(0.3, crop.quality - 0.05)
                expectedStage = crop.growth_stage -- Pause growth
            end

            local isHarvestable = expectedStage >= config.stages and newWater > 0

            if expectedStage ~= crop.growth_stage or newWater ~= crop.water_level then
                MySQL.update(
                    'UPDATE farm_crops SET growth_stage = ?, water_level = ?, quality = ?, is_harvestable = ? WHERE id = ?',
                    {expectedStage, newWater, newQuality, isHarvestable and 1 or 0, crop.id}
                )

                if expectedStage ~= crop.growth_stage then
                    TriggerClientEvent('farming:client:updateCropStage', -1,
                        crop.id, expectedStage, crop.crop_type,
                        vector3(crop.position_x, crop.position_y, crop.position_z))
                end
            end

            :continue:
        end
    end
end)

Die Bewässerung sollte interaktiv und nicht mühsam sein. Gib dem Spieler eine Gießkanne als Item, die bei Verwendung in der Nähe von Pflanzen eine Animation auslöst. Bewässere mehrere Pflanzen in der Nähe mit einer Aktion, anstatt sie einzeln gießen zu müssen. Führe für größere Farmen ein Upgrade für ein Bewässerungssystem ein, das alle Pflanzen auf dem Grundstück regelmäßig automatisch bewässert. Das reduziert die manuelle Arbeit, erfordert aber eine Anfangsinvestition in Materialien. Zeige den Wasserstand und den Wachstumsfortschritt jeder Pflanze über eine kleine Anzeige über dem Prop an, wenn der Spieler sie ansieht. Verwende dafür 3D-Text oder eine Einblendung des Zielsystems.

Ernte und Qualität der Erzeugnisse

Die Ernte ist der Höhepunkt, der den gesamten Landwirtschaftskreislauf befriedigend macht. Wenn eine Pflanze ihr letztes Wachstumsstadium erreicht hat und ausreichend bewässert wurde, kann sie geerntet werden. Der Spieler interagiert mit der Pflanze, führt eine Ernteanimation aus und erhält Erzeugnisse in sein Inventar. Menge und Qualität der Erzeugnisse hängen davon ab, wie gut der Spieler die Pflanze während ihres Wachstums gepflegt hat: Regelmäßiges Bewässern bringt hochwertigere Items ein, die sich teurer verkaufen lassen. Vernachlässigte Pflanzen liefern weniger Items von geringerer Qualität. Implementiere einen Qualitätsmultiplikator, der sowohl die Erntemenge als auch den Verkaufspreis beeinflusst und so einen starken Anreiz für sorgfältige Landwirtschaft schafft. Entferne die Pflanze nach der Ernte aus der Datenbank und lösche das Prop aus der Spielwelt. Dadurch wird der Beetplatz wieder zum Anpflanzen frei. Erwäge eine Kompostierungsmechanik, bei der Ernten von geringer Qualität in Dünger umgewandelt werden können, der die Qualität künftiger Pflanzen verbessert. So entsteht ein abfallfreier Kreislauf, der fortlaufende Landwirtschaft belohnt.

Nutztierhaltung

Tiere bereichern die Landwirtschaft um eine weitere Dimension und schaffen zusätzliche Einnahmequellen. Implementiere kaufbare Tiere wie Hühner, Kühe und Schafe, die in ausgewiesenen Tiergehegen auf der Anbaufläche platziert werden. Jede Tierart hat ihren eigenen Produktionszyklus: Hühner legen alle paar Stunden Eier, Kühe geben täglich Milch und Schafe können regelmäßig zur Wollgewinnung geschoren werden. Tiere müssen mit Erzeugnissen aus dem Inventar des Spielers gefüttert werden. Dadurch ist das Pflanzensystem direkt mit dem Tiersystem verbunden und es entsteht ein geschlossener Wirtschaftskreislauf. Hier ist ein Konfigurations- und Fütterungssystem für Nutztiere:

Config.Animals = {
    chicken = {
        model = 'a_c_hen',
        purchasePrice = 500,
        feedItem = 'wheat',
        feedInterval = 3600,       -- needs feeding every hour
        productionItem = 'eggs',
        productionAmount = 3,
        productionInterval = 7200, -- produces every 2 hours
        maxPerFarm = 10
    },
    cow = {
        model = 'a_c_cow',
        purchasePrice = 3000,
        feedItem = 'corn',
        feedInterval = 5400,
        productionItem = 'milk',
        productionAmount = 2,
        productionInterval = 14400,
        maxPerFarm = 5
    },
    sheep = {
        model = 'a_c_sheep',
        purchasePrice = 1500,
        feedItem = 'wheat',
        feedInterval = 4800,
        productionItem = 'wool',
        productionAmount = 1,
        productionInterval = 21600,
        maxPerFarm = 8
    }
}

RegisterNetEvent('farming:server:feedAnimal', function(animalId)
    local src = source
    local Player = QBCore.Functions.GetPlayer(src)
    if not Player then return end

    local animal = MySQL.query.await(
        'SELECT * FROM farm_animals WHERE id = ? AND owner = ?',
        {animalId, Player.PlayerData.citizenid}
    )

    if not animal or not animal[1] then return end
    animal = animal[1]

    local config = Config.Animals[animal.animal_type]
    if not Player.Functions.GetItemByName(config.feedItem) then
        return TriggerClientEvent('QBCore:Notify', src, 'Need ' .. config.feedItem .. ' to feed', 'error')
    end

    Player.Functions.RemoveItem(config.feedItem, 1)

    MySQL.update(
        'UPDATE farm_animals SET last_fed = ?, hunger = 100 WHERE id = ?',
        {os.time(), animalId}
    )

    TriggerClientEvent('QBCore:Notify', src, 'Animal fed successfully', 'success')
end)

Tiere, die nicht rechtzeitig gefüttert werden, werden unglücklich und produzieren weniger. Werden sie zu lange nicht gefüttert, stellen sie die Produktion vollständig ein. Zeige den Status eines Tieres über eine Zielinteraktion an, die Hunger, Zufriedenheit und die Zeit bis zur nächsten Produktion anzeigt. So entsteht für Landwirte eine tägliche Routine, die sie auch zwischen den Wachstumszyklen ihrer Pflanzen auf dem Server hält.

Marktsystem und Verkauf von Erzeugnissen

Das Marktsystem verbindet Landwirte mit der größeren Serverwirtschaft. Erstelle Standorte mit NPC-Händlern auf Bauernmärkten, in Lebensmittelgeschäften und Restaurants auf der Karte, bei denen Spieler ihre Erzeugnisse verkaufen können. Implementiere ein dynamisches Preissystem, bei dem die Preise je nach Angebot und Nachfrage schwanken: Wenn viele Landwirte Weizen anbauen, sinkt der Weizenpreis und schafft einen Anreiz für vielfältigere Kulturen. Erfasse das gesamte Verkaufsvolumen jeder Pflanzenart über gleitende Zeitfenster und passe die Preise entsprechend an. Premium-Erzeugnisse aus hochwertigen Pflanzen erzielen einen Aufschlag auf den Grundpreis und belohnen sorgfältige Landwirtschaft. Erwäge eine Option für den Handel zwischen Spielern, bei der Landwirte an ausgewiesenen Orten Marktstände aufstellen und direkt an andere Spieler zu selbst festgelegten Preisen verkaufen können. Dadurch entstehen spontane Rollenspielinteraktionen zwischen Landwirten und Käufern. Unternehmerische Spieler können außerdem davon profitieren, günstig im Großhandel gekaufte Erzeugnisse in stark frequentierten Gegenden mit Einzelhandelsaufschlag weiterzuverkaufen.

Wettereinflüsse auf die Landwirtschaft

Die Einbindung des Wetters bringt Unvorhersehbarkeit und Strategie in die Landwirtschaft. Binde das Wettersystem deines Servers ein, um das Pflanzenwachstum und den Wasserverbrauch zu beeinflussen. Regen bewässert alle Pflanzen im Freien auf natürliche Weise und verringert bei nassem Wetter den Bedarf an manuellem Gießen. Extreme Hitze erhöht den Wasserverbrauch und zwingt Landwirte bei heißem Wetter zu häufigerer Bewässerung. Stürme können Pflanzen beschädigen, ihre Qualität verringern oder sogar nicht geerntete Erzeugnisse zerstören, die zu lange stehen gelassen wurden. Frostperioden im Winter können bestimmte Pflanzenarten vollständig abtöten. Landwirte müssen daher frostbeständige Sorten wählen oder in Gewächshäuser investieren, die Pflanzen vor Wettereinflüssen schützen. Implementiere eine Wettervorhersage, die über eine In-Game-Handy-App oder eine TV-Übertragung zugänglich ist. So können Landwirte ihren Pflanzplan an die bevorstehenden Bedingungen anpassen und die Landwirtschaft erhält eine strategische Planungsebene, die über simple Mechaniken nach dem Motto „klicken und warten“ hinausgeht.

Farm-Upgrades und Fortschritt

Ein Fortschrittssystem gibt Landwirten langfristige Ziele und belohnt regelmäßiges Spielen. Beginne mit einem kleinen Grundstück, auf dem nur wenige Pflanzen Platz haben, und ermögliche ihnen dann, durch Landwirtschafts-XP oder direkten Kauf Erweiterungen freizuschalten. Jede Upgrade-Stufe schaltet neue Möglichkeiten frei: automatische Sprinkleranlagen, die das Bewässern übernehmen, größere Tiergehege für mehr Nutztiere, eine Scheune zur Lagerung überschüssiger Erzeugnisse, Verarbeitungsstationen, die Rohwaren in höherwertige Waren wie Mehl aus Weizen oder Wein aus Trauben verwandeln, und einen Traktor, der das Pflanzen und Ernten auf großen Flächen beschleunigt. Erfasse Landwirtschafts-XP getrennt vom übrigen Serverfortschritt, um eine eigene Landwirtschaftsfertigkeit zu schaffen. Höhere Stufen verbessern die Erntequalität und verkürzen die Wachstumszeiten. Das Verarbeitungssystem ist besonders wichtig für die Wirtschaft, denn es fügt zwischen rohen Erzeugnissen und fertigen Waren Schritte hinzu, die den Wert steigern. So entstehen Möglichkeiten für Rollenspiel entlang der Lieferkette: Landwirte verkaufen Rohstoffe an Bäckereien, Weingüter oder Restaurants im Besitz von Spielern, die sie zu Endprodukten für Verbraucher verarbeiten.

Bereit loszulegen?

Hol dir die Scripts in unserem Shop, oder komm auf den Discord für Support, Updates und einen Blick auf das, was kommt.