Dokumentation

Dokumentation Yoga minigame

Das Yoga-Minigame aus dem Story-Modus, aus der Mission gelöst und zu einer Roleplay-Aktivität gemacht, die jeder starten kann. Beide Marker ausrichten, die Pose halten, während der Körper sie einnimmt, dann mit den Triggern ein- und ausatmen. Drei Abläufe, vierzehn Posen, die echten Animationen und die echten Atemgeräusche. Und ein Score, auf den deine eigenen Scripts reagieren können.

  • ESX
  • QBCore
  • Qbox
  • vRP
  • Standalone
01

Installation

  1. Resource ablegen

    Hol dir das Script aus deinem Tebex-Konto, kopier den Ordner avenida_yoga/ in dein resources-Verzeichnis und trag ensure avenida_yoga in deine Serverconfig ein.

  2. Sprache und Abläufe setzen

    Config.Locale nimmt jeden der fünfzehn Codes aus locales/. Config.EnabledMoves entscheidet, welche Abläufe Spieler starten dürfen, und Config.DefaultMove legt den fest, der ohne Angabe genommen wird.

  3. Deine Spots setzen

    Die beiden Koordinaten in Config.Spots sind Beispiele, ersetz sie durch deine eigenen. Jeder Eintrag nimmt eine Ausrichtung, einen Ablauf und einen Blip, den du abschalten kannst. Eine leere Liste deaktiviert die Funktion samt Thread.

  4. Notifications auf deinen Stack umbiegen

    Config.Notif steht auf auto und erkennt ox_lib, okokNotify, QBCore oder ESX in dieser Reihenfolge. Erzwing ein Ziel, wenn du mehrere fährst, oder nimm den custom-Zweig in bridges/notif.lua für dein eigenes System.

  5. Belohnung anhängen, oder auch nicht

    Die Aktivität läuft von Haus aus, ohne eine Zeile von dir. Wenn sie etwas auszahlen soll, hör auf avenida_yoga:server:sessionCompleted und lies den Score. Das ist der einzige Integrationspunkt.

02

Konfiguration

Aus einer Einheit eine Belohnung machen

Ein Event, einmal am Ende gefeuert. Der Score ist schon berechnet: 1 für einen beendeten Ablauf, bei einem Abbruch auf 0,4 gedeckelt, minus 8 Prozent pro verpatzter Pose. Was er auszahlt, entscheidest du.

lua
AddEventHandler('avenida_yoga:server:sessionCompleted', function(src, data)
    -- data.move       'warrior' | 'triangle' | 'sunsalutation'
    -- data.completed  true when the routine went to the end
    -- data.posesBest  poses held
    -- data.poses      poses in the routine
    -- data.fails      poses dropped
    -- data.score      0.0 to 1.0

    if not data.completed then return end

    -- your own reward: stress, stamina, a skill, a payout
    local reward = math.floor(250 * data.score)
end)
03

Exports

Server

  • StartYoga
    exports['avenida_yoga']:StartYoga(src, moveKey?) --> boolean

    Startet eine Einheit für einen Spieler aus deinem Servercode, mit dem genannten Ablauf oder mit dem Standard. Gibt false zurück, wenn der Ablauf unbekannt ist oder der Spieler schon in einer Einheit steckt, ein Job oder ein Prop kann also reagieren, statt blind zu feuern.

  • IsDoingYoga
    exports['avenida_yoga']:IsDoingYoga(src) --> boolean

    True, solange der Spieler eine laufende Einheit hat. Abgelaufene zählen nicht mit. Praktisch, um eine Job-Aktion, einen Teleport oder einen Shop zu blockieren, während das Minigame die Controls belegt.

Client

  • StartYoga
    exports['avenida_yoga']:StartYoga(moveKey?) --> boolean

    Fragt aus deinem Clientcode eine Einheit beim Server an. Die Anfrage läuft trotzdem über die Server-Registry, das ist also kein Weg am Schutz des Servers vorbei.

  • IsDoingYoga
    exports['avenida_yoga']:IsDoingYoga() --> boolean

    True, solange der lokale Spieler in einer Einheit ist. Das Gegenstück zum Server-Export, für alles, was im selben Frame reagieren muss.

04

Rezepte

Einen Yoga-Spot auf deine Map setzen

Ein Spot braucht Koordinaten und eine Ausrichtung. Alles andere ist optional: welchen Ablauf er startet, ob er einen Blip bekommt und ob die Matte überhaupt gespawnt wird. Für Abwechslung setzt du move auf random, für eine Auswahl auf menu.

lua
-- config/config.lua
Config.Spots = {
    {
        coords  = vector3(-1204.02, -1566.28, 3.63),
        heading = 125.0,
        move    = 'menu',
        blip    = { sprite = 311, colour = 2, scale = 0.7 },
    },
}

Yoga aus einem Job oder einem Prop starten

Ein Wellness-Job, ein Gefängnishof, eine Entzugs-Aktivität: Gib deinem Spieler die Einheit ohne Command. Lies den Rückgabewert, er sagt dir, ob der Spieler überhaupt starten konnte.

lua
local started = exports['avenida_yoga']:StartYoga(src, 'sunsalutation')

if not started then
    -- unknown routine, or the player is already in a session
    return
end

Die Einheit nachsichtig oder gnadenlos machen

Die ganze Schwierigkeit steckt in vier Zahlen. Erhöh die Versuche und die Fehler für einen Server voller Gelegenheitsspieler, senk sie, wenn es näher am Grundspiel liegen soll. Das Atem-Timeout verhindert, dass jemand einfach den Trigger gedrückt hält.

lua
-- config/config.lua
Config.BreathingAttempts = 3      -- missed cycles before a pose fails
Config.MaxFails          = 5      -- failed poses before the session stops
Config.HoldBreathFailMs  = 15000  -- holding the breath longer fails the pose
Config.MouseGain         = 3.0    -- marker sensitivity on mouse and keyboard

Erst einen Ablauf ausliefern, den Rest später

Nur die in der Config gelisteten Abläufe lassen sich starten, per Command, per Export oder per Spot. Ein Server kann mit dem Krieger starten und die längeren als Event freischalten, ohne sonst irgendetwas anzufassen.

lua
-- config/config.lua
Config.EnabledMoves = { 'warrior' }
Config.DefaultMove  = 'warrior'
05

Fragen

Brauche ich ein Framework?

Nein. Die Aktivität liest nie Geld, Items, Jobs oder Identität, es gibt also nichts, was ein Framework liefern könnte. Dieselbe Datei läuft auf ESX, QBCore, Qbox, vRP, ox_core oder einem nackten Server, ohne dass du eine einzige Bridge konfigurierst. Das Einzige, was hier überhaupt ein Framework berührt, ist die Notification-Zeile, eine offene Datei mit sechs Zweigen.

Brauche ich ox_lib?

Nein, und hier lässt es sich genau sagen: Genutzt wird ox_lib für genau eine Sache, die Ablauf-Auswahl auf einem Spot mit menu. Ohne ox_lib startet dieser Spot stattdessen den Standard-Ablauf. Config.UseOxLib schaltet außerdem das Laden der Assets zwischen ox_lib-Helfern und den nativen Aufrufen um, und im Auslieferungszustand ist es aus, die Resource läuft also standardmäßig auf Natives.

Gibt es eine Datenbank?

Keine, und auch keine SQL-Datei. Der Server hält die laufenden Einheiten im Speicher, eine pro Spieler, mit einem Timeout, der eine abgebrochene aufräumt. Wir schreiben nirgendwo etwas. Willst du eine Historie pro Spieler, ist genau dafür das Abschluss-Event da: Du speicherst, was dich interessiert, in deinem eigenen Schema.

Kann ein modifizierter Client eine perfekte Einheit vortäuschen?

Nein. Die Einheit öffnet der Server, und das Ergebnis wird begrenzt, bevor es dein Event erreicht: Gehaltene Posen können den Ablauf nicht überschreiten, Fehler nicht dreißig, das Fertig-Flag ist ein strikter Vergleich und der Score wird serverseitig aus diesen begrenzten Werten neu berechnet. Das Schlimmste, was ein modifizierter Client kann, ist, eine Einheit zu melden, die er wirklich geöffnet hat.

Was passiert, wenn ein Spieler eine Pose fallen lässt?

Der Körper steht wieder auf. Die Resource liest die exakte Animation, die der Ped gerade abspielt, und wählt die passende Aufsteh-Animation aus den zwölf, die das Spiel mitbringt, wobei vier davon eine eigene Variante für eine früh abgebrochene Pose haben. Die Pose zählt als verpatzt, und nach fünf verpatzten Posen stoppt die Einheit von selbst.

Können Spieler überall Yoga machen oder nur an einem Spot?

Beides. Der Command funktioniert überall, solange dein Spieler zu Fuß ist, und die Spots sind eine optionale Schicht obendrauf, für die Orte, die du mit Matte und Blip ausschildern willst. Lass Config.Spots leer, und es bleiben nur der Command und die Exports, der Spot-Thread startet dann gar nicht erst.

Funktioniert es am Controller?

Ja, und gebaut haben wir es zuerst für ihn, wie im Grundspiel. Zwei Sticks führen die Marker, die Schultertrigger tragen das Atmen, dazu ein Rumble, solange beide Marker auf dem Ziel sitzen. Mit Maus und Tastatur läuft dieselbe Einheit über WASD und die Maus, und die Anzeigen wechseln von selbst, je nachdem, was der Spieler zuletzt benutzt hat.

Was kostet es, wenn niemand Yoga macht?

0.00ms. Die Schleife einer Einheit existiert nur, solange eine läuft, und der Spot-Thread schläft, solange kein Spieler in der Nähe ist. Ohne einen einzigen deklarierten Spot startet dieser Thread überhaupt nicht.

Warenkorb
Spirit RP
Discord