FiveM resmon ms élevé : comment trouver et corriger les scripts lents
Une ressource affiche un ms élevé dans resmon ? Comment lire resmon 1, pourquoi les boucles Wait(0) coûtent autant, et comment dormir loin, mettre en cache le ped et utiliser les points et zones ox_lib.
Vous ouvrez le moniteur de ressources et un script affiche ceci :
my_script 0.35 msUn script au repos devrait être près de zéro. Un script qui mange un tiers d'une milliseconde, ou bien plus, sur chaque image rend votre jeu saccadé, et les joueurs avec des ordinateurs plus faibles le ressentent en premier. Ce guide montre comment voir quelle ressource est le problème et les changements qui le réduisent.
Ouvrir le moniteur de ressources
Dans la console F8 du jeu, tapez :
resmon 1Une superposition affiche chaque ressource client avec son temps CPU (ms) par image et sa mémoire. Tapez resmon 0 pour le fermer. Vérifiez ces choses :
- Restez immobile, dans un endroit calme, et lisez la liste. Les nombres qui comptent sont ceux qui restent élevés quand vous ne faites rien.
- Regardez qui est au top. Une ressource qui monte seulement près de son propre marqueur ou boutique est normal. Une qui est élevée partout ne l'est pas.
- Regardez pendant quelques secondes. Un pic unique quand un script démarre est inoffensif ; une valeur constante est le problème.
Le ms est le temps sur le client. Les performances du serveur sont un sujet séparé : consultez avertissement de scintillement du thread serveur.
Cause 1 : une boucle avec Wait(0)
La raison la plus courante d'une valeur élevée est une boucle qui s'exécute chaque image, tout le temps :
CreateThread(function()
while true do
Wait(0)
local ped = PlayerPedId()
local coords = GetEntityCoords(ped)
local dist = #(coords - vec3(215.0, -810.0, 30.7))
if dist < 3.0 then
DrawText3D(215.0, -810.0, 30.7, 'Press E')
end
end
end)Cela exécute les natives 60 fois par seconde, même quand le joueur est de l'autre côté de la carte. La plupart du temps la réponse est "rien à faire", et ce coût est gaspillé.
Correction 1 : dormir quand vous êtes loin
Laissez la boucle dormir plus longtemps quand rien n'est proche, et exécutez seulement chaque image quand le joueur est près :
CreateThread(function()
local target = vec3(215.0, -810.0, 30.7)
while true do
local sleep = 1000
local coords = GetEntityCoords(PlayerPedId())
local dist = #(coords - target)
if dist < 10.0 then
sleep = 0
if dist < 3.0 then
DrawText3D(target.x, target.y, target.z, 'Press E')
end
elseif dist < 50.0 then
sleep = 250
end
Wait(sleep)
end
end)La boucle vérifie une fois par seconde quand vous êtes loin, ce qui coûte presque rien, et s'exécute chaque image uniquement dans la zone de 10 mètres où elle se dessine. Utilisez #(a - b) avec des valeurs vec3 pour la distance : c'est plus rapide que la native GetDistanceBetweenCoords plus ancienne.
Correction 2 : mettre en cache les valeurs que vous réutilisez
Appeler une native à chaque image pour obtenir une valeur qui change rarement est un gaspillage. PlayerPedId() est le classique. Enregistrez-le une fois et rafraîchissez-le seulement quand cela peut changer :
local ped = PlayerPedId()
CreateThread(function()
while true do
Wait(500)
ped = PlayerPedId()
end
end)Si vous utilisez ox_lib, il le fait pour vous. cache.ped est tenu à jour, et cache.vehicle et cache.serverId fonctionnent de la même façon :
local coords = GetEntityCoords(cache.ped)lib.onCache vous permet de réagir quand une valeur en cache change, sans vérifier dans une boucle.
Correction 3 : arrêter d'appeler les natives chaque image
Vérifiez le corps de la boucle et demandez pour chaque ligne : est-ce que cela doit vraiment s'exécuter chaque image ? Déplacez ce qui ne le fait pas.
- Dessin (texte, marqueurs, sprites) doit s'exécuter chaque image, mais seulement pendant qu'il est visible.
- Lire les données (travail, argent, inventaire) ne le fait pas : lisez-le sur un événement, et gardez-le dans une variable.
- Chercher (
GetClosestVehicle,GetGamePool, boucles sur tous les joueurs) est coûteux. Exécutez-le une fois par seconde ou deux, pas chaque image. - Ne créez pas de choses dans une boucle : créer des blips, des entrées de texte ou des tables chaque image remplit la mémoire et fait travailler le collecteur de déchets.
-- run once per second
local closest = nil
CreateThread(function()
while true do
closest = GetClosestVehicle(GetEntityCoords(cache.ped), 5.0, 0, 70)
Wait(1000)
end
end)Correction 4 : utiliser les points et zones ox_lib à la place des boucles
La plupart des boucles "suis-je près de ce point" ne sont pas nécessaires. ox_lib peut faire le travail de distance pour vous, et n'exécute votre code que quand cela compte.
Un point appelle une fonction quand vous entrez ou quittez un rayon, et une chaque image uniquement pendant que vous êtes à l'intérieur :
local point = lib.points.new({
coords = vec3(215.0, -810.0, 30.7),
distance = 10.0,
})
function point:onEnter()
print('entered')
end
function point:onExit()
print('left')
end
function point:nearby()
DrawText3D(self.coords.x, self.coords.y, self.coords.z, 'Press E')
if self.currentDistance < 2.0 and IsControlJustReleased(0, 38) then
print('used')
end
endLes zones font la même chose pour les formes comme une sphère, une boîte ou un polygone :
local zone = lib.zones.sphere({
coords = vec3(215.0, -810.0, 30.7),
radius = 3.0,
onEnter = function() print('in') end,
onExit = function() print('out') end,
})Pour l'interaction avec les entités et les spots, une ressource cible (ox_target, par exemple) remplace la boucle "appuyez sur E" de la même façon. Vérifiez la documentation ox_lib pour les options exactes de chacun.
Vérifiez le résultat
Exécutez resmon 1 à nouveau. Un script corrigé devrait s'asseoir près de 0,00 ms quand vous restez loin de ses spots, et augmenter seulement quand vous êtes près d'eux. S'il est toujours élevé, cherchez une deuxième boucle dans la même ressource : un Wait(0) n'est souvent pas le seul.
Attention : n'utilisez pas une boucle de sommeil longue qui gère une pression de touche ou un dessin. Si vous dormez 500 ms et que le joueur appuie sur la touche, le script la ratera. Dormez seulement quand vous savez que rien ne se passe, et descendez à
Wait(0)quand quelque chose l'est.
Liste de contrôle
| Symptôme | Correction |
|---|---|
| Ms élevé quand inactif | Trouvez la boucle while true do Wait(0) et ajoutez une mise en veille basée sur la distance |
PlayerPedId() dans chaque image |
Mettez-le en cache, ou utilisez cache.ped d'ox_lib |
| Vérifications de distance dans une boucle | Remplacez avec lib.points.new ou lib.zones |
| Recherche d'entités chaque image | Exécutez-la une fois par seconde et gardez le résultat |
| Lecture des données du joueur dans une boucle | Lisez-la sur l'événement du framework et enregistrez-la |
| Pressions de touches manquées après l'ajout d'une mise en veille | Utilisez Wait(0) uniquement pendant que le joueur est près |
Réponses rapides
Quelle est une bonne valeur resmon pour un script ?
Un script qui est au repos devrait s'asseoir autour de 0,00 à 0,01 ms. Tout ce qui reste bien au-dessus cela quand vous ne l'utilisez pas a une boucle qui fonctionne trop fort.
Qu'est-ce que Wait(0) fait et pourquoi c'est coûteux ?
Wait(0) exécute la boucle une fois par image. À 60 images par seconde, cela représente 60 exécutions par seconde, et chaque native que vous appelez est appelée 60 fois par seconde.
Ai-je besoin d'ox_lib pour corriger le ms élevé ?
Non. Les corrections fonctionnent en Lua simple. ox_lib seulement les rend plus courts, avec cache.ped, lib.points et lib.zones.
Des scripts sans ce problème
CCTV Security CamerasDes caméras à placer, une tablette multi-vues en direct et des photos imprimées comme preuves.Voir le script →
Advanced BoostingDu boosting de véhicules piloté par tablette : contrats de classe D à S+, crews et file d’attente en direct.Voir le script →
Arcade MachinesSept jeux d’arcade jouables dans de vraies bornes, avec classements et paris.Voir le script →