Zurück zum Blog
Tutorial8 Min. Lesezeit

FiveM-Bootsangelsystem: Realistische Jobs auf dem Meer skripten

Erstelle ein komplettes Bootsangelsystem in FiveM. Angelstellen, Fanglogik, Verkaufsketten, Bootsverleih und Top-Skripte für dein Rollenspiel an der Küste.

Agency Scripts

Gründer und leitender Entwickler bei Agency Scripts

Hochseefischen als Gameplay-System

Hochseefischen erweitert die übliche Angelmechanik der meisten FiveM-Server: Spieler fahren aufs offene Meer hinaus, wo sie größere Fischarten fangen, sich durch Gefahren auf dem Meer navigieren und Treibstoff sowie Stauraum ihres Boots im Blick behalten müssen. Während Uferangeln eine passive Aktivität ist, bei der Spieler die Angel auswerfen und warten, ist Hochseefischen eine Expedition, die Vorbereitung, Investitionen und Teamarbeit erfordert. Spieler mieten oder kaufen Boote, besorgen Köder und Angelgerät, fahren zu auf Seekarten markierten Angelgebieten und nutzen Sonargeräte, um Fischschwärme unter der Oberfläche aufzuspüren. Der Fang ist wertvoller als beim Uferangeln, aber auch die Risiken sind höher: Stürme können Boote beschädigen, der Treibstoff kann weit vor der Küste ausgehen und seltene Trophäenfische erfordern lange Drills, die Geduld und Können auf die Probe stellen. Dieses Verhältnis zwischen Risiko und Belohnung sorgt für wirklich spannende Spielmomente, wenn ein Spieler nach einer halben Stunde Fahrt zum richtigen Angelplatz einen riesigen Thunfisch an den Haken bekommt. Gemeinsame Angeltouren mit Freunden schaffen außerdem Erinnerungen, die Spieler immer wieder zurückbringen.

Bootskonfiguration und Flottenverwaltung

Definiere mehrere Bootsklassen, von kleinen Beibooten für das Angeln nahe der Küste bis hin zu großen Charterbooten für Hochseeexpeditionen. Für jedes Boot sollten Eigenschaften konfigurierbar sein, darunter Geschwindigkeit, Tankvolumen, Stauraum für gefangene Fische, Anzahl der Rutenhalter für die gleichzeitig auswerfbaren Angeln und eine Haltbarkeit, die durch Nutzung und Stürme abnimmt. Speichere Bootseigentum in der Datenbank und richte einen Yachthafen ein, an dem Spieler Boote kaufen, aufrüsten und warten lassen können. Bootseigentümer sollten andere Spieler als Crewmitglieder an Bord einladen können, die vom Deck aus angeln. So entsteht ein kooperatives Erlebnis, bei dem der Kapitän navigiert und die Crew mehrere Angeln betreut:

Config.Boats = {
    ['dinghy'] = {
        label = 'Fishing Dinghy',
        model = 'dinghy',
        price = 15000,
        fuelCapacity = 60,
        storageSlots = 10,
        maxWeight = 200,
        rodHolders = 1,
        maxCrew = 2,
        durability = 100,
        speed = 'slow',
        fishingZones = { 'nearshore' },
    },
    ['marquis'] = {
        label = 'Sport Fisher',
        model = 'marquis',
        price = 85000,
        fuelCapacity = 200,
        storageSlots = 30,
        maxWeight = 800,
        rodHolders = 4,
        maxCrew = 6,
        durability = 250,
        speed = 'medium',
        fishingZones = { 'nearshore', 'offshore', 'deep_sea' },
    },
    ['tug'] = {
        label = 'Commercial Trawler',
        model = 'tug',
        price = 250000,
        fuelCapacity = 500,
        storageSlots = 60,
        maxWeight = 3000,
        rodHolders = 6,
        maxCrew = 8,
        durability = 500,
        speed = 'slow',
        fishingZones = { 'nearshore', 'offshore', 'deep_sea', 'abyssal' },
    },
}

Config.FishingZones = {
    ['nearshore'] = {
        areas = {
            { center = vector3(-1850.0, -1250.0, 0.0), radius = 300.0 },
            { center = vector3(-3420.0, 970.0, 0.0), radius = 400.0 },
        },
        fish = {
            { item = 'bass',     weight = { 1, 8 },   chance = 35, price = 15 },
            { item = 'mackerel', weight = { 0.5, 4 },  chance = 40, price = 10 },
            { item = 'snapper',  weight = { 2, 12 },   chance = 20, price = 25 },
            { item = 'grouper',  weight = { 5, 25 },   chance = 5,  price = 40 },
        },
    },
    ['deep_sea'] = {
        areas = {
            { center = vector3(-4200.0, -800.0, 0.0), radius = 600.0 },
            { center = vector3(-3800.0, 2200.0, 0.0), radius = 500.0 },
        },
        fish = {
            { item = 'tuna',      weight = { 20, 120 },  chance = 25, price = 80 },
            { item = 'swordfish', weight = { 30, 200 },  chance = 15, price = 120 },
            { item = 'marlin',    weight = { 50, 350 },  chance = 8,  price = 200 },
            { item = 'shark',     weight = { 80, 500 },  chance = 2,  price = 500 },
        },
    },
}

Das Zonensystem legt fest, welche Fischarten in den einzelnen Gebieten verfügbar sind. Dadurch müssen Spieler sich weiter von der Küste entfernen, um wertvollere Fänge zu machen. Kleine Boote können nur küstennahe Zonen erreichen, während größere Schiffe den Zugang zu küstenfernen und tiefen Seegebieten freischalten, in denen die lukrativsten Fische schwimmen. So entsteht ein natürlicher Fortschritt: Spieler verdienen mit kleineren Fängen Geld und finanzieren damit bessere Boote, die ihnen Zugang zu erstklassigen Angelgebieten bieten.

Sonar- und Fischsuchmechaniken

Füge den Booten eine Sonaranzeige hinzu, die die Fischdichte im umliegenden Wasser anzeigt. Implementiere das Sonar als NUI-Overlay, das erscheint, wenn der Spieler sein Fischsuchgerät über das Bedienfeld des Boots aktiviert. Das Sonar sollte eine kreisförmige Anzeige mit Punkten für Fischschwärme in verschiedenen Tiefen zeigen. Die Anzeige wird alle paar Sekunden mit leichten Positionsänderungen aktualisiert, um die Bewegung der Fische zu simulieren. Die Größe jedes Punkts gibt die Dichte des Schwarms und die mögliche Fangqualität an. Spieler müssen ihr Boot über einem Schwarm positionieren, bevor sie ihre Angeln auswerfen können. So kommt vor dem Angeln selbst ein Navigationselement hinzu. Die Sonardaten sollten serverseitig anhand der tatsächlichen Position des Boots relativ zu den konfigurierten Angelzonen generiert werden. Die Positionen der Schwärme sollten sich zufällig und im Laufe der Zeit verschieben, damit Spieler sich nicht einfach feste Hotspots merken können.

Angel-Minispiel und Kampfmechaniken

Wenn ein Fisch anbeißt, starte ein Angelkampf-Minispiel, dessen Schwierigkeitsgrad je nach Fischart und Gewicht variiert. Dabei muss die Schnurspannung über einen dynamischen Balken kontrolliert werden, der sich entsprechend dem Verhalten des Fischs bewegt. Der Spieler holt die Schnur ein, indem er eine Taste gedrückt hält, muss aber loslassen, wenn der Fisch ruckartig zieht, damit die Schnur nicht reißt. Größere Fische kämpfen härter und länger. Tiefseearten wie Marline und Haie erfordern mehrere Minuten sorgfältige Kontrolle der Schnurspannung. Zeige das geschätzte Fischgewicht, die Silhouette der Fischart und den Fortschritt des Kampfs an, damit auch längere Kämpfe spannend bleiben. Berücksichtige außerdem Umgebungsfaktoren wie Strömungsstärke und Wetterbedingungen, die den Schwierigkeitsgrad beeinflussen. Ruhiges Wetter sollte ideal zum Angeln sein, während Stürme die Herausforderung deutlich erhöhen:

local fishFight = {
    active = false,
    tension = 50,       -- 0-100, snaps at 100
    progress = 0,       -- 0-100, fish landed at 100
    fishStrength = 0,
    fishBehavior = 'steady',
    reeling = false,
}

function StartFishFight(fishData)
    fishFight.active = true
    fishFight.tension = 30
    fishFight.progress = 0
    fishFight.fishStrength = fishData.weight * 0.5

    SendNUIMessage({
        action = 'showFishFight',
        species = fishData.item,
        estimatedWeight = fishData.weight,
    })

    CreateThread(function()
        while fishFight.active do
            -- Fish behavior changes randomly
            local behaviorRoll = math.random(100)
            if behaviorRoll < 15 then
                fishFight.fishBehavior = 'surge'    -- strong pull
            elseif behaviorRoll < 40 then
                fishFight.fishBehavior = 'resist'   -- moderate pull
            else
                fishFight.fishBehavior = 'steady'   -- light pull
            end

            -- Apply fish force
            local force = fishFight.fishStrength * 0.02
            if fishFight.fishBehavior == 'surge' then
                force = force * 3.0
                fishFight.progress = math.max(0, fishFight.progress - 2)
            elseif fishFight.fishBehavior == 'resist' then
                force = force * 1.5
            end

            -- Reeling input
            if IsControlPressed(0, 38) then -- E key
                fishFight.reeling = true
                fishFight.progress = fishFight.progress + 0.8
                fishFight.tension = fishFight.tension + force + 1.5
            else
                fishFight.reeling = false
                fishFight.tension = math.max(0, fishFight.tension - 3)
            end

            -- Check win/lose conditions
            if fishFight.tension >= 100 then
                EndFishFight(false, 'Line snapped!')
                return
            end

            if fishFight.progress >= 100 then
                EndFishFight(true, fishData)
                return
            end

            -- Update HUD
            SendNUIMessage({
                action = 'updateFishFight',
                tension = fishFight.tension,
                progress = fishFight.progress,
                behavior = fishFight.fishBehavior,
            })

            Wait(100)
        end
    end)
end

Wetter- und Meeresbedingungen

Integriere dein Angelsystem in das Wetter des Servers, um dynamische Meeresbedingungen zu schaffen, die das Gameplay beeinflussen. Ruhiges Wetter sorgt mit niedrigen Wellen und maximaler Sonargenauigkeit für ideale Angelbedingungen. Bei Stürmen nehmen die Wellen zu, die Sonarwirkung lässt nach, Boote werden mit der Zeit beschädigt und Fische tauchen tiefer ab, wo sie schwerer zu fangen sind. Implementiere ein Seegangssystem, das abhängig vom aktuellen Wetter allmählich zwischen ruhiger, mäßiger, rauer und stürmischer See wechselt. Zeige bei Stürmen visuelle Effekte an, etwa höhere Wellen mithilfe nativer Wasserstandsanpassungen, Spritzwasserpartikel auf dem Bootsdeck und ein mit der Wellenstärke zunehmendes Kamerawackeln. Stelle Spielern am Yachthafen Wettervorhersagen bereit, damit sie Angeltouren bei günstigen Bedingungen planen können. Füge außerdem ein Sturmwarnsystem hinzu, das Boote auf See bei sich verschlechterndem Wetter alarmiert, damit sie in den Hafen zurückkehren können, bevor die Bedingungen gefährlich werden.

Fischmarkt und Integration in die Wirtschaft

Richte am Yachthafen einen Fischmarkt ein, auf dem Spieler ihren Fang zu Preisen verkaufen können, die sich nach Angebot und Nachfrage richten. Wenn viele Spieler Thunfisch verkaufen, sinkt der Preis für Thunfisch. Wenn eine Weile niemand Schwertfisch verkauft hat, steigt der Preis. Diese dynamische Preisgestaltung motiviert Spieler, ihren Fang zu variieren und weniger beliebte Fischarten ins Visier zu nehmen, wenn der Markt gesättigt ist. Erfasse die insgesamt verkauften Fische pro Art über rollierende Zeiträume und passe die Preise innerhalb festgelegter Mindest- und Höchstgrenzen an. Zeige die aktuellen Marktpreise auf einer Tafel am Yachthafen an, damit Spieler vor dem Auslaufen fundiert entscheiden können, welche Fischarten sie fangen möchten. Für eine erweiterte Integration können Restaurants auf dem Server Großbestellungen für bestimmte Fischarten zu Premiumpreisen aufgeben. So entsteht eine direkte Lieferkette zwischen Spielern, die angeln, und Restaurantbetreibern, von der beide Gameplay-Schleifen profitieren.

Performance und Entity-Verwaltung

Boote und Meeresumgebungen stellen besondere Performance-Herausforderungen dar, da die Wasserdarstellung in GTA V bereits ressourcenintensiv ist und zusätzliche Boots-Entities, Effekte für Fischkämpfe und Sonar-Overlays die Last weiter erhöhen. Erstelle Fisch-Entities nur während aktiver Kämpfe und nur für den Spieler, der gerade kämpft, damit nicht Dutzende Fischobjekte für alle auf dem Server sichtbar sind. Setze Partikeleffekte für Wasserspritzer und Kampfhinweise sparsam ein und deaktiviere sie für weiter entfernte Beobachter durch entfernungsbasierte Darstellung. Verfolge Bootskraftstoff und Lagerbestand serverseitig. Der Client sollte Aktualisierungen nur anfordern, wenn der Spieler das entsprechende UI-Panel öffnet, statt fortlaufend Daten zu synchronisieren. Wenn Spieler ihr Boot am Yachthafen anlegen, entferne die Boot-Entity aus der Spielwelt und speichere ihren Zustand in der Datenbank, einschließlich Kraftstoffstand, Haltbarkeit und gelagerter Fische. So wird verhindert, dass sich die Yachthäfen mit dauerhaft vorhandenen Boots-Entities füllen, die Serverressourcen verbrauchen, obwohl ihre Besitzer offline sind. Teste dein System in Multiplayer-Szenarien, in denen mehrere Boote gleichzeitig in derselben Zone angeln, und stelle sicher, dass Fischschwarmdaten, Sonaranzeigen und Kampf-Instanzen für jeden Spieler korrekt getrennt bleiben.

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.