Parent : [[INDEX-FIVEM]]
FiveM - Asset Streaming Hub : cache strings CFX et registration dynamique
Problème
Pour streamer des assets (modèles, textures, sons) dans FiveM, il faut les enregistrer via CFX runtime. Gérer manuellement des centaines de fichiers dans fxmanifest.lua est fastidieux et source d'erreurs.
Solution
Scan récursif du dossier stream/ via Node.js, génération de cache strings CFX avec RegisterResourceAsset, transmission au client pour RegisterStreamingFileFromCache.
// server.js
const fs = require('fs');
const path = require('path');
function walk(dir) {
return fs.readdirSync(dir, { withFileTypes: true })
.flatMap((file) => file.isDirectory()
? walk(path.join(dir, file.name))
: path.join(dir, file.name)
);
}
const files = walk('./stream');
const cacheStrings = {};
for (const file of files) {
const relativePath = file.replace(/\\/g, '/');
const cacheString = RegisterResourceAsset(GetCurrentResourceName(), relativePath);
cacheStrings[relativePath] = cacheString;
}
// Envoi au client
RegisterNetEvent('vertex-hub:loadAssets');
onNet('vertex-hub:loadAssets', () => {
emitNet('vertex-hub:receiveAssets', source, cacheStrings);
});
// client.js
RegisterNetEvent('vertex-hub:receiveAssets');
onNet('vertex-hub:receiveAssets', (cacheStrings) => {
for (const [fileName, cacheString] of Object.entries(cacheStrings)) {
RegisterStreamingFileFromCache(GetCurrentResourceName(), fileName, cacheString);
}
});
Pourquoi
- Automatise la registration de centaines d'assets sans les lister manuellement
- Les cache strings sont uniques et persistent entre redémarrages
- Le client reçoit la map complète au chargement
Quand l'utiliser
- Resources avec beaucoup d'assets streamés (vêtements, véhicules, mapping)
- Hubs de streaming centralisés pour plusieurs resources
Quand NE PAS l'utiliser
- Resources avec < 10 assets (overkill)
- Si les assets sont déjà déclarés dans
fxmanifest.luaavecfiles { 'stream/**/*' }
Exemples
Correct
// Registration différée par batch pour éviter le lag au spawn
const BATCH_SIZE = 50;
RegisterNetEvent('vertex-hub:receiveAssets');
onNet('vertex-hub:receiveAssets', (cacheStrings) => {
const entries = Object.entries(cacheStrings);
let index = 0;
function processBatch() {
const batch = entries.slice(index, index + BATCH_SIZE);
for (const [fileName, cacheString] of batch) {
RegisterStreamingFileFromCache(GetCurrentResourceName(), fileName, cacheString);
}
index += BATCH_SIZE;
if (index < entries.length) {
setTimeout(processBatch, 100);
}
}
processBatch();
});
Incorrect
// Pas de cache string → le client ne peut pas streamer
for (const file of files) {
// RegisterResourceAsset manquant
RegisterStreamingFileFromCache('myresource', file, null); // Échoue
}
Références
- vertex-hub/server.js
- vertex-hub/client.js
- CFX Docs : RegisterResourceAsset / RegisterStreamingFileFromCache