Saltar al contenido
En esta página

Documentación / Operar el servidor

Encontrar qué da lag

Cuando el servidor da tirones o los jugadores pierden FPS, fivedock perf nombra los recursos que hay detrás, hasta el archivo y la línea. Lee el profiler que trae FXServer, así que en el servidor no cambia nada.

Deja que el agente use el profiler

FXServer solo deja que un recurso arranque el profiler si server.cfg lo permite. El bloque que da el panel al conectar un servidor ya trae estas líneas. En un servidor que conectaste antes, añádelas y reinicia el recurso fivedock:

server.cfg
add_ace resource.fivedock command.profiler allow
add_ace resource.fivedock command.record allow
add_ace resource.fivedock command.saveJSON allow

fivedock_check en la consola del servidor dice si el profiler está permitido. Sin estas líneas, el reporte igual cuenta comandos y mide FPS, y te dice qué líneas faltan.

Mide el servidor

Ejecútalo mientras el servidor tiene lag, desde una máquina que le hace backup (fivedock servers add). El agente graba 10 segundos, o de 3 a 20 con --seconds, cuenta los comandos de cada recurso, mide el juego de cada jugador y lee los scripts de cliente y las páginas de UI que descargan los jugadores. --json imprime el mismo reporte para scripts.

shell
fivedock perf my-city
fivedock perf my-city --seconds 20

Lee el reporte

Un reporte de un servidor al que un trabajo de basurero traba cada pocos segundos, y cuyo pack de emotes registra un comando por emote:

fivedock perf my-city
my-city  profiled 10 s · 214 players online
  server thread  late by 3.8 ms on average, 212 ms at worst in the last minute

Server  198 ticks, the slowest took 212 ms
  resource          total   per tick  worst tick
  jobs_garbage   1,236 ms     6.2 ms      205 ms
  hud              412 ms     2.1 ms      6.3 ms
  oxmysql           96 ms     0.5 ms       14 ms
  emotes            12 ms     0.1 ms      0.4 ms

Where exactly  the threads, events and exports that took longest
  jobs_garbage     611 ms  thread · server/main.lua:88-131 · 3× · worst 203 ms
  jobs_garbage     598 ms  thread · server/main.lua:12-40 · 198× · worst 6.1 ms
  hud              380 ms  event hud:sync · server.lua:52-77 · 1,420× · worst 4.2 ms
  oxmysql           88 ms  export · dist/build.js:310 · 402× · worst 14 ms

Commands  on the server, and in the game of 3 sampled players
  resource     server  players
  emotes            –    2,034
  admin_menu       61       12
  hud               9        4
  total           248    2,310
  A command per emote or item adds up fast. Check whether that resource needs them all.

Players  207 of 214 answered · 5 players in the pause menu or loading, left out
  FPS          24 for the slowest tenth · 47 median · 71 for the fastest tenth
  1% low       19 median · 64 players had a frame over 50 ms
  around them  980 objects · 310 peds · 180 vehicles (median)
  slowest
    Player 112   13 fps  1% low 4 · 9 frames over 50 ms · 4,210 objects  at 1693, 3245
    Player 17    16 fps  1% low 6 · 7 frames over 50 ms · 3,980 objects · a UI open  at 1702, 3251

Where exactly, in players’ games  the client functions that cost most, in the game they cost most
  hud              3.8 ms  thread · client/status.lua:14 · 9 players
  jobs_garbage     2.4 ms  thread · client/bags.lua:52 · 4 players
  phone            0.9 ms  NUI getMessages · client/nui.lua:88 · 2 players
  hud              0.6 ms  event hud:updateStatus · client/main.lua:120 · 12 players
  Measured in 31 traced resources, per frame.

Entities scripts made  in a player’s own game, the most any one of them had
  jobs_garbage  2,940 objects
  hud           12 objects
  A script that spawns props or peds and never deletes them slows every frame after.

Client loops that never sleep  each runs on every frame, in every player’s game
  hud         2  client/status.lua:14 · client/minimap.lua:41
  A while true do whose only Wait is Wait(0), or a setTick. resmon 1 in F8 shows what each costs.

UI pages  each loads in every player’s game on join and stays loaded
  phone      41.8 MiB  video ui/wallpapers/live.mp4 · endless animation ×4 ui/assets/index.css:1 · backdrop blur ×6 ui/assets/index.css:1
  hud         0.6 MiB  endless animation html/hud.css:212
  An endless animation, a backdrop blur or a video makes the game’s browser repaint every frame while it shows.

Streamed to every player  the heaviest packs, from the last asset scan
  [cars]       2.4 GiB · 23 texture dictionaries over 16 MiB
  sandy_mlo  479.7 MiB · 2 texture dictionaries over 16 MiB
  fivedock optimize <folder> shows what shrinking them saves, and --apply does it.

  Escrowed, so their client code could not be read: vehicle_shop

Exact cost per client resource  only a player’s own profiler can see it
  Ask Player 112 to type these two lines in F8:
    profiler record 500
    profiler saveJSON lag.json
  It saves into FiveM Application Data › citizen. fivedock perf --file lag.json reads it.

Stalls the agent caught  each one recorded for 10 s after it happened
  21:04  212 ms stall  then jobs_garbage took 203 ms in one tick
         jobs_garbage · server/main.lua:88-131

FPS drops the agent caught  players below 40 fps and well under their usual, newest first
  21:12  Player 112   58 → 14 fps  jobs_garbage
         jobs_garbage spawned 1,800 objects in the minute before
  20:51  Player 17    71 → 22 fps
         driving at 170 km/h, so the game streams fast
  20:30  Player 64    66 → 19 fps  phone
         phone started in the minute before · a UI had focus · the phone UI has a video and an endless animation
Server
Los recursos que más tiempo de script usaron durante la grabación. per tick es lo que cuestan de media por frame del servidor, worst tick su frame más lento. Por encima de 50 ms, los jugadores lo notan como un tirón.
Where exactly
Ese tiempo repartido en hilos, handlers de eventos y exports, con el archivo, las líneas, cuántas veces corrió cada uno y su ejecución más lenta. Un hilo que corre cada tick y cuesta milisegundos cada vez suele esperar demasiado poco entre vueltas.
Commands
Los comandos de cada recurso, en el servidor y en el juego de tres jugadores. Un recurso con cientos suele registrar un comando por emote o por ítem.
Players
Los FPS de la décima parte más lenta de los jugadores, la mediana y la décima parte más rápida, su 1% low (los FPS de sus fotogramas más lentos) y cuántos tuvieron un fotograma de más de 50 ms, lo que tienen alrededor, y los cinco jugadores más lentos con dónde están. Los jugadores en el menú de pausa o que aún están cargando no cuentan. Si los lentos están en el mismo sitio, mira qué se streamea ahí.
Where exactly, in players’ games
En los recursos con el perfilador de cliente, las funciones que más cuestan por fotograma, en el juego donde más cuestan, con el archivo, la línea y en cuántos juegos aparecieron. Sin el perfilador, el reporte dice cómo añadirlo.
Entities scripts made
Props, peds y vehículos que los scripts de cliente de un recurso crearon en el juego de un jugador, lo máximo que tuvo cualquiera de ellos. Cientos de un solo recurso suelen significar que los genera y nunca los borra.
Client loops that never sleep
Bucles de cliente que despiertan en cada fotograma y nunca pueden dormir: un while true do cuya única espera es Wait(0), o un setTick. Se dejan fuera los bucles que salen, que a veces esperan más o que solo corren en debug. resmon 1 en la consola F8 de un jugador muestra cuánto cuesta cada uno.
UI pages
La página de UI de cada recurso se carga en el juego de cada jugador al entrar y se queda cargada. El reporte nombra las pesadas y lo que hace que el navegador del juego vuelva a pintar mientras se muestran: animaciones CSS infinitas, desenfoque de fondo (backdrop blur) y video, con el archivo y la línea, además de imágenes de más de 1 MiB y páginas que cargan desde otro sitio.
Streamed to every player
Los paquetes streameados más pesados y sus diccionarios de texturas de más de 16 MiB, del último escaneo de assets del agente. fivedock optimize reduce esas texturas.
Stalls the agent caught
Los tirones que el agente grabó por su cuenta, el más reciente primero.
FPS drops the agent caught
Las caídas que registró la vigilancia de FPS, de la más reciente a la más antigua, cada una con lo que cambió en el juego de ese jugador. Con la vigilancia desactivada, el reporte dice cómo activarla.

Tirones que graba por su cuenta

Cuando el hilo del servidor se para 150 ms o más, el agente graba por su cuenta los 10 segundos siguientes, como mucho una vez cada 15 minutos, y guarda los tres últimos hasta que el recurso se reinicia. Si el tirón no volvió mientras grababa, el reporte lo dice en vez de culpar a lo que estuviera corriendo.

Las caídas de FPS que registra solo

Con estas líneas, el agente vigila los FPS de cada jugador. Su juego lee el contador de fotogramas una vez por segundo, así que vigilar no cuesta nada en ningún fotograma. Cuando un jugador baja del mínimo y muy por debajo de sus FPS habituales durante cinco segundos, el agente registra un aviso player.low_fps en la Black Box: hasta cuánto, desde cuánto y qué cambió en su juego justo antes. Puede ser un recurso que generó props o peds, uno que acababa de arrancar, una UI con el foco o ir tan rápido que el streaming no da abasto. Un jugador se registra como mucho una vez cada diez minutos.

server.cfg
set fivedock_fps_watch 1
set fivedock_fps_floor 40

fivedock_fps_floor es el mínimo, 40 FPS si no lo cambias. Activar o desactivar la vigilancia en la consola surte efecto en 30 segundos, sin reiniciar. Filtra la Black Box por player.low_fps para ver todas las caídas; fivedock perf lista las diez últimas.

Ver la función de cliente detrás de los FPS de cada jugador

FiveM guarda los tiempos de cada recurso dentro del juego, fuera del alcance de los scripts. fivedock trace mete un pequeño perfilador en cada recurso que se puede leer: una línea al principio de su manifiesto y un fivedock_trace.lua al lado. No hace nada hasta que fivedock perf o la vigilancia de FPS se lo piden; entonces mide durante unos segundos cada hilo, manejador de eventos, callback de NUI y comando de ese recurso. Los recursos con escrow, protegidos con Skalp u ofuscados no se tocan, y la lista dice por qué.

shell
fivedock trace C:\FXServer\server-data\resources
fivedock trace C:\FXServer\server-data\resources --apply

Reinicia el servidor para que los jugadores lo carguen. Desde entonces, el reporte y cada aviso player.low_fps nombran el recurso, el archivo, la línea y cuántos milisegundos por fotograma costó. En Windows, la app de escritorio hace lo mismo en Herramientas, Perfilador de cliente. Para quitarlo, con cada manifiesto devuelto byte a byte:

shell
fivedock trace C:\FXServer\server-data\resources --remove --apply

Los FPS de un jugador

Lo que un script cuesta en el juego de un jugador solo lo ve ese juego. Cuando un jugador tiene pocos FPS, pídele que lo grabe en F8 y te mande el archivo:

F8
profiler record 500
profiler saveJSON lag.json

fivedock perf --file lo lee igual que una grabación del servidor:

shell
fivedock perf --file lag.json

Para la medición, los jugadores reciben unas pocas líneas con el agente. Cuando lo pides, su juego cuenta fotogramas durante tres segundos, anota si está en pausa, cargando o con una UI abierta, cuenta los props, peds y vehículos a su alrededor junto con el recurso que creó cada uno, lista los comandos registrados y recoge lo que midió el perfilador de cliente donde lo añadiste. No lee nada más ni envía nada por su cuenta, salvo que actives la vigilancia de FPS.

Lo que no ve

  • Un tirón que vuelve con menos frecuencia de lo que dura una grabación. Ejecuta fivedock perf --seconds 20 cuando toque, o deja que el agente lo atrape.
  • El tiempo fuera de los scripts: la red, el servidor de base de datos o el streaming del propio juego. Un script que se bloquea esperando a la base sí aparece, como tiempo propio.
  • El tiempo dentro de un recurso sin el perfilador de cliente: con escrow, protegido con Skalp, ofuscado o escrito en JavaScript o C#. La grabación de F8 de un jugador los sigue mostrando.
  • Lo que el código hace solo a veces. El reporte juzga los bucles y las páginas de UI leyendo los archivos, no midiéndolos, así que un bucle que pesa solo de vez en cuando no aparece, y el código de los recursos con escrow no se puede leer. El reporte nombra esos recursos.