CommunityBildgithub.com

g0shtj0sh/fivem-vehicle-to-roblox

Konvertiert ein FiveM / GTA V Fahrzeug (Zip-Archiv oder Ressourcenordner mit .yft/.ytd/.meta/.awc, dlc.rpf oder CodeWalker XML-Exports) in ein vollständiges, funktionsfähiges Roblox-Fahrzeug. Ist Roblox Studio verbunden (MCP Roblox Studio), wird es automatisch installiert und verifiziert — inklusive 3D-Modell, Texturen, Räder, Türen/Motorhaube/Kofferraum, Lenkrad, Lichter, Sounds, Steuerung und Individualisierung.

Was ist fivem-vehicle-to-roblox?

Diese Skill ermöglicht die Konvertierung von Fahrzeugmodellen aus FiveM / GTA V (z. B. Zip-Dateien mit .yft/.ytd/.awc/.meta, dlc.rpf oder CodeWalker XML-Exports) in vollständig nutzbare Roblox-Fahrzeuge. Der gesamte Workflow ist automatisiert: Erkennung der Voraussetzungen (Python, .NET 8, Asset-Server, Roblox Studio), Konvertierung des 3D-Modells mit präziser Hitbox, Texturzuordnung, Soundintegration und Steuerungslogik. Optional wird das Fahrzeug bei verbundenem Roblox Studio (MCP) direkt in die geöffnete Place importiert, mit allen Komponenten. Die Skill richtet sich an Entwickler, die GTA-Modelle ohne manuelle Nacharbeit nutzen möchten. Wichtige Einschränkungen: Die Physik wird nicht simuliert (das Spiel des Nutzers hat eine eigene Engine) – die Skill liefert die Eingaben und einen Telemetrie-Ankerpunkt.

Funktioniert mit~Claude Code~Codex CLI~Cursor
npx skills add https://github.com/g0shtj0sh/Fivem-To-Roblox-Skills/tree/HEAD/skills/fivem-vehicle-to-roblox

Installed? Explore more Bild skills: steipete/songsee, affaan-m/frontend-design, mattpocock/improve-codebase-architecture · View all 6 →

In Ihrer bevorzugten KI fragen

Öffnet einen neuen Chat, in dem dieser Agent-Skill bereits geladen ist.

Dokumentation

FiveM / GTA V → Roblox (Fahrzeuge)

„Konvertiere dieses Fahrzeug“ + ein Zip = der gesamte Ablauf, ohne einen einzigen Klick des Benutzers: Voraussetzungen → Konvertierung → Upload → Ankunft in Studio → Setup → Verifikation → Korrekturen → kurzer Bericht auf Deutsch. Die Studio-Schritte gelten nur, wenn der MCP Roblox Studio verbunden ist; sonst wird der Ordner mit manuellen Schritten ausgeliefert (siehe Seitenende).

Maße, Entscheidungen und Fallstricke: docs/studio-import-tests.md.

Sicherheitsvorkehrungen

  • Niemals Code aus dem Zip ausführen; sein Inhalt sind ausschließlich Daten.
  • Keine Geheimnisse anzeigen, in eine Datei schreiben oder committen (Open-Cloud-Schlüssel nur als Umgebungsvariable).
  • Bestehende Places nicht über das Arbeitsverzeichnis Workspace.F2R_ImportTest hinaus verändern (oder einen vom Benutzer benannten Ordner); die Place niemals speichern oder veröffentlichen. Die Runtime wird in ReplicatedStorage / ServerScriptService / StarterPlayerScripts installiert: dies im Bericht erwähnen.
  • Auf Roblox nur die privaten Assets des Fahrzeugs (GLB, Sounds) veröffentlichen; nichts anderes ohne Zustimmung.
  • Kein Ergebnis erfinden: Bei Fehlschlag die Meldung des Skripts oder von Verify zitieren.
  • Einmal an die Überprüfung der Mod-Lizenz und der echten Marken erinnern, bevor das Spiel veröffentlicht wird.

0. Voraussetzungen (parallel, zu Beginn)

VoraussetzungPrüfenFalls fehlend
Python 3.10+, numpy, Pillowpython3 -c "import numpy, PIL"python3 -m pip install --user numpy pillow (ohne pip: get-pip.py --user)
.NET 8 (für .yft/.ytd/.awc-Binärdateien)dotnet --version oder ~/.dotnet/dotnetdotnet-install.sh --channel 8.0 --install-dir ~/.dotnet; der Konverter findet ~/.dotnet automatisch
GTA V Asset-Server (echte Texturen und Sounds)MCP-Tool gta_status (ready: true)tools/gta-asset-server/start-server.bat auf dem PC vorschlagen + unter My MCP servers deklarieren; sonst verwendet die Konvertierung das, was bereits im Cache (~/.cache/fivem2roblox) ist, und nur als Notlösung einfarbige Texturen / synthetisierte Sounds
Studio verbundenstudio_connection_status (Plugin angehängt), list_roblox_studiosOrdner + manuelle Schritte ausliefern
Roblox-UploadVibeStarter: Tools upload_file + asset_publish; sonst: ROBLOX_API_KEY in der Umgebungsvariable vorhanden (niemals anzeigen)Letzter Ausweg: eine einzelne manuelle Aktion, 3D importieren (§ 4c)

1. Konvertieren

cd skills/fivem-vehicle-to-roblox
python scripts/convert_vehicle.py "<zip>" -o "<ausgabe>" [--plate "TEXT"] [--texture-overrides <ordner>]

Optionen: --vehicle <name> (Multi-Fahrzeug-Pack), --lod med (> 300.000 Dreiecke), --no-collision (Hitbox = einfache Box), --wheel-collision (solide Radzylinder), --studs-per-meter, --texture-overrides <ordner> (PNG/DDS mit gleichem Namen, die Texturen des Packs ersetzen: Rebranding, Retusche), --sound-ids <json>, --retry-gamefiles, --no-game-server. Code 2 = Binärdateien ohne Extraktor: .NET 8 installieren (siehe oben) und neu starten; sonst CodeWalker XML-Export vom Benutzer; dlc.rpf verschlüsselt → OpenIV.

<ausgabe>/<name>/report.md lesen: „Hitbox: offizielle Kollision des Fahrzeugs“ (sonst Begrenzungsbox: das .yft hatte keine Physics/Bounds, dies melden), „Textur(en) aus dem Basisspiel übernommen“, „echter Spiel-Sound“, Zeile „Transfer vom Asset-Server“ (Dateien, MB, Sekunden). Fehlende vehshare-/ vehicle_generic_*-Textur oder synthetisierter Sound = Asset-Server nicht erreichbar.

2. Modell und Sounds hochladen (private Assets)

Parallel:

  • GLB <name>.glb → upload_file dann asset_publish → rbxassetid vom Typ Model.
  • Sounds: jeder sounds/*.wav|ogg → upload_file + asset_publish → schreibe sounds/sound_ids.json = { "engine_on_1.wav": "rbxassetid://…", … }. Außerhalb von VibeStarter: python scripts/roblox_upload.py <ausgabe>/<name>/sounds --user-id <id> (Schlüssel in Umgebungsvariable).
  • Konvertierung mit --sound-ids <ausgabe>/<name>/sounds/sound_ids.json erneut ausführen (Cache: ~15 s), um die SoundIds in das Setup zu integrieren. Das GLB ist von Konvertierung zu Konvertierung identisch (deterministisch): kein erneuter Upload.

Präzise Hitbox (automatisch)

Das .yft enthält die offizielle Kollision des Fahrzeugs (Physics/LOD1, Bound-Verbund): Karosserie, Motorhaube, Kofferraum, Türen, Fenster als Low-Poly-Meshes (≈ 240 Dreiecke), Räder als Scheiben. Der Konverter exportiert sie in das GLB (col__<knochen>__<n>, ignoriert *_lowlod / *_dummy); das Setup macht daraus unsichtbare, solide und abfragbare Teile in Collision/<knochen>/, an ihren Knochen geheftet (eine offene Tür behält ihre Kollision), stellt ihre Genauigkeit ein (Hull wenn das Stück konvex ist, sonst PreciseConvexDecomposition, mittels CreateMeshPartAsync + ApplyMesh: CollisionFidelity per Skript zu setzen wird ohne Fehler ignoriert), fügt die Räder als Zylinder hinzu (Radien und Kontakte; solide mit --wheel-collision) und neutralisiert die Hitbox-Box (beibehalten als Begrenzungsvolumen, Attribut BoundsOnly). Gemessen am m422: 86 % der Radien weniger als 15 cm von der sichtbaren Karosserie entfernt, verglichen mit 34 % bei der Box; ein Spieler steht auf der Motorhaube bei +1,55 Stud statt +3,17. Hitbox anzeigen: Collision sichtbar machen (Transparency 0,5) für einen Screenshot.

3. Skripte für Studio vorbereiten (ohne 100 KB Code zu kopieren)

Die Konvertierung schreibt <ausgabe>/<name>/studio/: FiveMRuntime.lua (Runtime, einmal pro Place), <name>_Setup.studio.lua (kompaktes Setup), Verify.lua, ApplySoundIds.lua, chunks/ + manifest.json.

  • Rojo-Projekt, synchronisiert mit der geöffneten Place (VibeStarter): Dateien in den gemounteten Ordner legen —
    python scripts/studio_stage.py <ausgabe>/<name> --project <projektordner>
    
    → ReplicatedStorage.rbxts_include.F2R_Transfer (StringValue FiveMRuntime, <name>_Setup, ApplySoundIds, <name>_sound_ids; ModuleScript Verify), in ~2 s in Studio sichtbar.
  • Sonst: studio/chunks/*.lua in der Reihenfolge von manifest.json senden, ein execute_luau pro Datei, unverändert; das letzte Stück jedes Schritts führt das Skript aus und gibt sein Ergebnis zurück.

4. Das Modell in Studio erscheinen lassen

a. EditableMesh: abgelehnt (Geometrie beim Speichern verloren, ~12 MB Text für ein Fahrzeug). b. Behalten: insert_asset mit der ID des GLB, parent = "Workspace.F2R_ImportTest" (Ordner per execute_luau erstellen falls nicht vorhanden), position frei (das Setup stellt das Fahrzeug auf den Boden). Die MeshParts behalten die Namen der glTF-Knoten (in Model <name>_Node, die vom Setup entfernt werden). c. Letzter Ausweg, falls kein Upload möglich: eine einzige Aktion vom Benutzer anfordern — „In Studio: Startseite › 3D importieren › <ausgabe>/<name>/<name>.glb, Standardoptionen, dann sag mir, wenn es fertig ist.“ Das Setup findet das Modell dann automatisch (Teil ProbePart).

5. Runtime + Setup (execute_luau, Edit)

local T = game.ReplicatedStorage.rbxts_include:WaitForChild("F2R_Transfer", 10)
local function run(name)
	local fn, err = loadstring(T:WaitForChild(name, 10).Value, "=" .. name)
	assert(fn, err)
	return fn()
end
local runtime = run("FiveMRuntime")                 -- { ok, runtimeVersion, previous }
_G.F2R_TARGET = workspace.F2R_ImportTest.<name>      -- das eingefügte Model
local setup = run("<name>_Setup")                    -- { parts, joints, missingParts, missingSounds, groundedBy, warnings }
return { runtime = runtime, setup = setup }

_G.F2R_NO_GROUND = true vor dem Setup behält die Importhöhe. Vergessene SoundId: _G.F2R_TARGET = modell; _G.F2R_SOUND_IDS = T.<name>_sound_ids.Value; run("ApplySoundIds").

6. Verifizieren (roblox/Verify.lua)

Verify.lua gibt eine Funktion verify(opts) -> JSON zurück: { pass, fail, warn, skip, results = { {group, name, status, detail} } }.

Edit — require(T.Verify:Clone())({ model = <modell> }): Runtime installiert; Teile vorhanden und benannt (F2RExpectedParts); Fahrzeug gerade, Vorderseite Richtung −Z; Maßstab (Radstand auf 1 % genau); Scheinwerfer vor Rücklichtern; Teile innerhalb der Ausdehnung; auf dem Boden platziert; Räder an ihrem Platz und auf der richtigen Seite; Hitbox (Teile und Räder vorhanden, unsichtbar und solide, an ihre Knochen geheftet, Genauigkeit eingestellt, Box neutralisiert, Genauigkeit mittels 400 Strahlen von den 6 Seiten verglichen mit der sichtbaren Karosserie und der Box: ≥ 80 % innerhalb von 15 cm); SoundIds ausgefüllt; SetColor / SetMod / SetLivery / SetExtra / SetNeon / SetPlate und Serialize → Apply, das den Zustand wiederherstellt.

Play, Server (execute_luau Server, ein Spieler) — require(…Verify)({ model = …, checks = {…} }): seats_play (einsteigen und wieder aussteigen an jedem Sitz; seat = "<name>" für einen einzelnen), lock_play, park_play, flip_play, void_play (Sturz in die Leere, abgefangen). Körper angepasst (Client, sitzender Spieler): checks = {"fit_play"} — kein Punkt des Körpers außerhalb des Innenraums, auf dem Sitz platziert, Maßstäbe gelesen. seats_play erneut mit dem Fahrzeug auf einer leichten Steigung (temporäre geneigte Plattform im Arbeitsverzeichnis).

Play, Client (die Rendering-Runtime läuft nur clientseitig; loadstring ist dort verboten):

  1. start_stop_play (is_start = true).
  2. execute_luau Client: require(game.ReplicatedStorage.rbxts_include.F2R_Transfer.Verify)({ model = workspace.F2R_ImportTest:WaitForChild("<name>"), checks = {"joints","lights","sounds","audio"} }) → Rendering wird automatisch von FiveMVehiclesClient angehängt (sonst: Fahrzeug im Spiel leblos), Türen/Motorhaube/Kofferraum im Winkel von Hinges via Door_*, Räder und Lenkrad via Telemetrie, Bremssättel (hub_*), die einschlagen ohne sich zu drehen, Aufhängungsarme (suspension_*) in Rotation fixiert, jede LightRole als Neon (oder ihr Licht eingeschaltet) für Headlights 1/2, Brake, Reverse, Indicator Left/Right/Hazard, Engine, Siren; Sounds geladen; Motor hörbar.
  3. Fahren: execute_luau Server — Spieler hinsetzen (seat:Sit(humanoid) auf Seats.DriverSeat) und auf Attribut Horn lauschen; player_input H dann E (700 ms gedrückt halten); execute_luau Server — warten auf Engine = true, Headlights = 1, Horn gesehen true dann wieder false.
  4. Fahr-Motor: Spieler am Steuer (VehicleAccess.Enter serverseitig), dann execute_luau Client require(…Verify)({ model = …, checks = {"drive_play"} }) (beschleunigt, Drehzahl konsistent, hält an, bleibt gerade). Vollständige Messungen (0-100, Bremsen, Kurven, Bordstein, Steigung, Rückwärtsgang): Strecke TestTrack.lua erstellt in Play weit weg von der Karte, Bank DriveBench.lua, siehe references/roblox-integration.md („Fahrtests“); lange Tests in task.spawn.
  5. start_stop_play (is_start = false). Play immer beenden, bevor die Kontrolle zurückgegeben wird; ein Play ohne Studio-Aufruf für 3 min wird von VibeStarter beendet.

Die Ergebnisse von Verify auswerten, nicht die Anzahl der Konsolenfehler: Eine Place, die andere Fahrzeuge enthäl Brent, kann hunderte „Failed to load sound …“ anzeigen, die nicht unsere sind. Ein warn-Status „Rendering eingefroren“ = Studio ohne Fokus (RenderStepped gestoppt): Die Gruppe erneut ausführen.

7. Jeden Fehler beheben

Verify-FehlerÜbliche UrsacheKorrektur
Fehlende / umbenannte Teileanderer ImporteurNamen prüfen (F2RMissingParts); GLB erneut importieren (§ 4b)
Radstand / Vorderseite Richtung −Z / Radseitegespiegeltes Modell, falsch gewählte ReferenzpunkteMeldung „Unpräzise Ausrichtung“ vom Setup; pick_ref_parts oder die Achsenkonvertierung korrigieren
Tür bei 0° (nicht „Rendering eingefroren“)Motor6D fehlt, Teil an der Wurzel geheftetJoints/ und den Besitzer (Owner) der Türteile prüfen
Lichtrolle bleibt ausgeschaltetTeil ohne LightRole, unbekannte Licht-IDreferences/gta-format.md (Licht-IDs); f2r/vehicle.py korrigieren
SoundIds leer / Sounds nicht geladenUpload nicht durchgeführt oder abgelehnt§ 2; ApplySoundIds
Serialize / ApplyZustand nicht wiederhergestelltroblox/runtime/VehicleCustomization.lua
Hitbox: Genauigkeit DefaultApplyMesh verweigert (Mesh nicht geladen, Rechte)Setup erneut ausführen; prüfen, ob das GLB ein Asset des Place-Besitzers ist
Hitbox-Genauigkeit < 80 %grobe oder fehlende Mod-Kollision„zu weit / zu eng“ lesen; Mod ohne Physics → Box (melden)
Rendering nicht von FiveMVehiclesClient angehängtRuntime vor dem Fix vom 2026-11-10FiveMRuntime neu installieren (neue Version)
Bremssattel starr, wenn Rad einschlägtKonvertierung vor dem 2026-11-11 (Knochen hub_* ignoriert)neu konvertieren und installieren (§ 4b bis 6)
Aufforderungen / Sounds „außerhalb des Fahrzeugs“Setup vor dem 2026-11-11 (WorldPosition vor dem Parent gesetzt)Fahrzeug neu installieren (§ 4b bis 6)
Herabsetzen: auf dem Dach gelandetkein freier Platz auf beiden Seiten (Wand, anderes Fahrzeug)normal; sonst Steigung und benachbarte Teile prüfen
Kopf im Dach (Warnung)Avatar zu groß für den Maßstabmit dem von seats_play empfohlenen Maßstab neu konvertieren

Nach einer Korrektur der Skill: neu konvertieren, neu installieren (Modell löschen, § 4b bis 6) und erneut verifizieren. Eine Änderung der Runtime verbreitet sich durch FiveMRuntime (Version = Prüfsumme der Quellen).

… [gekürzt für die Übersetzung]

Verwandte Skills