FiveM resmon ms alto: come trovare e correggere gli script lenti
Una risorsa mostra ms alto in resmon? Come leggere resmon 1, perché i loop Wait(0) costano così tanto, e come dormire quando lontano, cachea il ped e usa punti e zone ox_lib.
Apri il monitor delle risorse e uno script mostra questo:
my_script 0.35 msUno script inattivo dovrebbe essere vicino a zero. Uno script che mangia un terzo di un millisecondo, o molto di più, su ogni frame fa stutter il tuo gioco, e i giocatori con computer più deboli lo sentono per primi. Questa guida mostra come vedere quale risorsa è il problema e i cambiamenti che lo riducono.
Apri il monitor delle risorse
Nella console F8 del gioco, digita:
resmon 1Un overlay mostra ogni risorsa client con il suo tempo CPU (ms) per frame e la sua memoria. Digita resmon 0 per chiuderlo. Controlla queste cose:
- Stai fermo, in un posto tranquillo, e leggi l'elenco. I numeri che contano sono quelli che rimangono alti quando non fai nulla.
- Guarda chi è in cima. Una risorsa che sale solo vicino al suo marker o negozio è normale. Una che è alta ovunque non lo è.
- Guardala per alcuni secondi. Un singolo picco quando uno script inizia è innocuo; un valore costante è il problema.
Il ms è il tempo sul client. Le prestazioni del server sono un argomento separato: vedi avvertimento server thread hitch.
Causa 1: un loop con Wait(0)
La ragione più comune per un valore alto è un loop che gira ogni frame, tutto il tempo:
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)Questo esegue i nativi 60 volte al secondo, anche quando il giocatore è dall'altra parte della mappa. La maggior parte del tempo la risposta è « nulla da fare », e quel costo è sprecato.
Soluzione 1: dormi quando sei lontano
Lascia che il loop dorma più a lungo quando nulla è vicino, e gira solo ogni frame quando il giocatore è vicino:
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)Il loop controlla una volta al secondo quando sei lontano, che costa quasi nulla, e gira ogni frame solo dentro l'area di 10 metri dove disegna. Usa #(a - b) con valori vec3 per la distanza: è più veloce del nativo più vecchio GetDistanceBetweenCoords.
Soluzione 2: cachea i valori che riusi
Chiamare un nativo ogni frame per ottenere un valore che raramente cambia è uno spreco. PlayerPedId() è il classico. Immagazzinalo una volta e aggiornalo solo quando può cambiare:
local ped = PlayerPedId()
CreateThread(function()
while true do
Wait(500)
ped = PlayerPedId()
end
end)Se usi ox_lib, lo fa per te. cache.ped è mantenuto aggiornato, e cache.vehicle e cache.serverId funzionano allo stesso modo:
local coords = GetEntityCoords(cache.ped)lib.onCache ti permette di reagire quando un valore cacheato cambia, senza controllare in un loop.
Soluzione 3: smetti di chiamare nativi ogni frame
Controlla il corpo del loop e chiediti per ogni riga: davvero ha bisogno di girare ogni frame? Muovi fuori quello che non lo fa.
- Disegno (testo, marker, sprite) ha bisogno di girare ogni frame, ma solo mentre è visibile.
- Lettura dati (job, soldi, inventario) non lo fa: leggilo su un evento, e tienilo in una variabile.
- Ricerca (
GetClosestVehicle,GetGamePool, loop su tutti i giocatori) è costosa. Eseguila una volta ogni secondo o due, non ogni frame. - Non creare cose in un loop: creare blip, voci di testo o tabelle ogni frame riempie la memoria e fa lavorare il garbage collector.
-- 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)Soluzione 4: usa punti e zone ox_lib invece di loop
La maggior parte dei loop « sono vicino a questo spot » non sono necessari. ox_lib può fare il lavoro di distanza per te, e esegue il tuo codice solo quando conta.
Un punto chiama una funzione quando entri o esci da un raggio, e uno ogni frame solo mentre sei dentro:
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
endLe zone fanno lo stesso per forme come una sfera, una scatola o un poligono:
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,
})Per l'interazione con entità e spot, una risorsa target (ox_target, per esempio) sostituisce il loop « premi E » nello stesso modo. Controlla la documentazione di ox_lib per le opzioni esatte di ognuno.
Controlla il risultato
Esegui resmon 1 di nuovo. Uno script corretto dovrebbe stare vicino a 0.00 ms quando stai lontano dai suoi spot, e salire solo quando sei vicino loro. Se è ancora alto, cerca un secondo loop nella stessa risorsa: un Wait(0) spesso non è l'unico.
Attenzione: non impostare un sonno lungo in un loop che gestisce una pressione di tasto o un disegno. Se dormi 500 ms e il giocatore preme il tasto, lo script lo perderà. Dormi solo quando sai che nulla sta succedendo, e scendi a
Wait(0)quando qualcosa lo fa.
Checklist
| Sintomo | Soluzione |
|---|---|
| Ms alto quando inattivo | Trova il loop while true do Wait(0) e aggiungi un sonno basato sulla distanza |
PlayerPedId() in ogni frame |
Cachea, o usa cache.ped da ox_lib |
| Controlli di distanza in un loop | Sostituisci con lib.points.new o lib.zones |
| Ricerca di entità ogni frame | Eseguila una volta al secondo e tieni il risultato |
| Lettura dati del giocatore in un loop | Leggilo sull'evento del framework e immagazzinalo |
| Pressioni di tasto perse dopo aver aggiunto un sonno | Usa Wait(0) solo mentre il giocatore è vicino |
Risposte rapide
Qual è un buon valore resmon per uno script?
Uno script che è inattivo dovrebbe stare intorno a 0.00 a 0.01 ms. Qualsiasi cosa che rimane ben sopra quello quando non la stai usando ha un loop che funziona troppo forte.
Cosa fa Wait(0) e perché è costoso?
Wait(0) esegue il loop una volta ogni frame. A 60 frame al secondo sono 60 esecuzioni al secondo, e qualsiasi nativo che chiami in esso è chiamato 60 volte al secondo.
Ho bisogno di ox_lib per correggere ms alto?
No. Le correzioni funzionano in Lua semplice. ox_lib solo le rende più corte, con cache.ped, lib.points e lib.zones.
Script senza questo problema
CCTV Security CamerasTelecamere posizionabili, un tablet multi-vista in diretta e foto stampate come prove.Vedi script →
Advanced BoostingBoosting di veicoli dal tablet: contratti dalla classe D alla S+, crew e coda in tempo reale.Vedi script →
Arcade MachinesSette giochi arcade giocabili in cabinati veri, con classifiche e scommesse.Vedi script →