Documentación del servidor
QuantumHy
ActivoHytale • Version 0.4.0
Instalación, claves de config, radio adaptativo de chunks y entidades, freeze de expand, gobernador de presión y convivencia con LeanCore en Hytale 0.7.
Instalación, configuración y comportamiento en tiempo de ejecución de QuantumHy.
Resumen
QuantumHy es un mod de FPS del lado del servidor para Hytale 0.7. El cliente es nativo y no se puede modificar, pero el servidor decide cuánto tiene que renderizar cada cliente, así que QuantumHy lo recorta por jugador. Cada pocos segundos muestrea la densidad de entidades alrededor de cada jugador, la suaviza y la usa para reducir el radio de visión en chunks y el radio de stream de entidades. Cada jugador puede activar o desactivar la optimización para sí mismo sin cambiar a los demás.
Nunca infla la visión más allá de lo que el jugador pidió. El radio no vuelve en el instante en que la densidad parece abierta: el expand se congela hasta que la carga esté calmada, el disco de density esté al menos a medio cargar, el jugador no esté volando y el mundo no esté bajo presión MSPT. Solo ayuda donde está instalado, nunca en un servidor remoto al que solo te conectas.
Instalación
- Descarga QuantumHy-0.4.0.jar desde la pestaña Files de CurseForge
- Coloca el JAR en la carpeta mods/ del servidor, o en Windows:
%AppData%\Hytale\UserData\Mods - Inicia el servidor. La config se genera como QuantumHy.json en la carpeta de datos del plugin
- Observa el registro del servidor por la línea de setup (ver Comprobando que funciona)
Comandos
/q status
/q optimize on
/q optimize off
/q help
Aliases: /quantumhy, /qhy. Un jugador común solo ve su modo y última decisión en /q status. Los admins y la consola ven el diagnóstico completo. /q optimize on|off solo cambia al jugador que lo ejecuta y guarda la elección por UUID.
Cómo funciona
En cada pasada (5s por defecto) QuantumHy hace el trabajo por jugador en el hilo del mundo dueño:
- Muestrea la densidad (a veces se omite). Cuenta entidades en un disco de
densityScanChunkRadiuschunks (dx²+dz² ≤ r²). El barrido de 49 columnas se omite en la primera pasada, en vuelo (2+ chunks/pasada), en streaming, con caché reciente del mismo chunk, y mientras ya está en el mínimo con expand congelado. La caché de un jugador quieto caduca tras 15 segundos. - La suaviza. Una muestra válida pasa por una media móvil exponencial (
densitySmoothing). - La convierte en un factor de reducción. La densidad usa smoothstep entre
densityLowPerChunkydensityHighPerChunk. Se combina con shrink por chunk-load (sections cargadas + cargando) y un suelo baseline. El factor combinado solo aumenta el shrink hasta que el expand está permitido (ratchet). - Rampa dos palancas. La visión en chunks se mueve como máximo +1 / −2 por pasada (−4 bajo presión). El radio de entidades usa el mismo factor; en shrink completo (
[min]) baja aminEntityViewBlocksen una escritura. Las escrituras paran después deworldPassBudgetMso durante streaming.
El expand solo se permite tras expandHysteresisPasses pasadas calmadas, disco de density ≥ 50% cargado, sin streaming, sin desplazamiento rápido y sin presión MSPT.
entityLodAggressiveness es aparte y global. El valor 1.0 mantiene el LOD del motor. Los valores superiores a 1.0 son un override explícito del admin, y solo entonces la presión MSPT aplica pressureLodMultiplier.
Configuración
Archivos de runtime: QuantumHy.json y PlayerPreferences.json en la carpeta de datos del plugin, creados en el primer arranque. Las instalaciones nuevas reciben configVersion 8.
| Clave | Por defecto | Qué hace |
|---|---|---|
enabled | true | Interruptor maestro. Cuando es false, QuantumHy nunca toca ningún radio de visión. |
verboseLog | false | Registra cada pasada con la densidad y la decisión de visión de cada jugador. Off en instalaciones nuevas. |
checkForUpdates | true | Al arrancar, lee la página de QuantumHy y avisa a operadores o durkz.quantumhy.admin si hay un JAR más nuevo. |
tickIntervalSeconds | 5 | Cada cuánto revisa a cada jugador. |
initialDelaySeconds | 20 | Espera este tiempo tras el arranque antes de la primera pasada. |
targetClientViewRadius | 0 | Tope fijo en chunks. 0 significa sin tope, solo adapta por densidad. |
minClientViewRadius | 6 | Nunca baja a nadie por debajo de este radio en chunks. |
maxClientViewRadius | 32 | Tope para el límite fijo (el propio radio de visión del jugador sigue ganando). |
adaptiveTerrainViewEnabled | true | Adapta el radio de visión del terreno durante el juego normal. |
emergencyTerrainTrimEnabled | true | Permite un recorte temporal del terreno tras presión visual sostenida. |
clientRenderCapEnabled | true | Limita la distancia de dibujado y la niebla del cliente al radio recortado. Requiere reinicio. |
clientStrainEnabled | true | Alivia el radio y el envío de chunks para un cliente que se queda atrás. Requiere reinicio. |
clientStrainFrameLagLowMs | 25 | Retraso del bucle principal del cliente (ms) donde la saturación empieza a contar (unos 40 FPS). |
clientStrainFrameLagHighMs | 60 | Retraso tratado como saturación total (unos 16 FPS). |
clientStrainQueueLow | 64 | Cola de paquetes del cliente donde la saturación empieza a contar. |
clientStrainQueueHigh | 512 | Cola de paquetes tratada como saturación total. |
effectBudgetEnabled | true | Presupuesto de partículas y sonidos 3D lejanos por jugador. Requiere reinicio. |
effectBudgetPerSecond | 120 | Efectos lejanos que cada jugador puede recibir por segundo. |
effectProtectRadius | 16 | Los efectos dentro de estos bloques nunca se descartan. |
effectSoftRadius | 48 | Gastada la mitad del presupuesto, los efectos más allá de esto caen primero. |
effectMaxDistance | 0 | Corte fijo en bloques para efectos posicionales. 0 = solo presupuesto. |
distantUpdateThrottleEnabled | false | Envía updates de posición de entidades lejanas con menos frecuencia. La posición más reciente siempre llega. Requiere reinicio. |
distantUpdateNearBlocks | 32 | Las entidades más cerca que esto reciben todos los updates. |
distantUpdateFarBlocks | 64 | Las entidades más allá de esto reciben 1 de cada 4 updates. |
densityScanChunkRadius | 4 | Cuántos chunks a cada lado contar entidades. |
densityLowPerChunk | 1.0 | Entidades ponderadas por chunk en o por debajo de esto: sin shrink por densidad. |
densityHighPerChunk | 4.0 | Entidades ponderadas por chunk en o por encima de esto: bajado al mínimo. |
densityRingWeighting | true | Los chunks centrales cuentan al 100%, los anillos exteriores menos. |
densityRingEdgeWeight | 0.55 | Peso en el anillo del borde (1.0 = conteo plano). |
baselineShrinkFraction | 0.10 | Shrink mínimo incluso con densidad “abierta” (0 = off). |
chunkLoadShrinkEnabled | true | Shrink extra por el recuento de sections cargadas + en streaming. |
chunkLoadLowChunks | 2800 | Sections loaded+loading en o por debajo de esto: sin shrink por chunk-load. También es donde se asienta la visión en calma (alrededor de view 10 en 0.7). |
chunkLoadHighChunks | 5900 | En este recuento de sections o por encima: shrink por chunk-load al máximo (alrededor de view 14). |
densitySmoothing | 0.4 | Peso de la muestra más nueva en la EMA, en (0, 1]. 1.0 lo desactiva. |
adaptEntityRadius | true | También reduce el radio de stream de entidades por jugador, no solo los chunks. |
minEntityViewBlocks | 48 | Límite inferior del radio de entidades, en bloques (16 bloques = 1 chunk). |
entityLodAggressiveness | 1.0 | Override global explícito de LOD. 1.0 mantiene el valor del motor. |
maxEntityVerticalDistance | 32 | Descarta entidades demasiado lejos arriba/abajo del jugador. 0 = off. |
maxVisibleEntitiesPerPlayer | 80 | Tope de entidades streameadas por jugador en multitudes. 0 = off. |
holdSpawnOnLoadingChunks | false | Pausa el spawn ambiental durante un backlog pesado de sections. Control global del admin. |
minViewRadiusDelta | 2 | Cambio mínimo (chunks) antes de enviar una actualización. Los expands +1 siguen aplicándose. |
maxExpandChunksPerPass | 1 | Máximo de chunks que el radio de visión sube en una pasada. |
maxShrinkChunksPerPass | 2 | Máximo que baja en una pasada (duplicado bajo presión). |
maxExpandEntityBlocksPerPass | 16 | Máximo de bloques que el radio de entidades sube en una pasada. |
expandHysteresisPasses | 2 | Pasadas calmadas exigidas antes de permitir expand. |
worldPassBudgetMs | 8 | Presupuesto de reloj para escrituras de radio en el hilo del mundo. 0 lo desactiva. |
pressureExitRequiresLastTick | true | Pressure solo sale cuando el promedio de 10s y el último tick están calmados. |
respectStreamingGrace | true | Retiene recortes mientras el jugador todavía transmite sections. |
streamingBacklogThreshold | 80 | Cuántas sections cargando cuentan como “todavía transmitiendo”. |
smoothChunkStreaming | true | Limita la velocidad a la que llegan sections a cada cliente gestionado. |
maxChunksPerSecond | 128 | Tope de sections por segundo. 0 mantiene el valor del motor. |
maxChunksPerTick | 8 | Tope de sections por tick (el motor usa 40 en 0.6). |
streamCatchUpEnabled | true | Eleva temporalmente los límites tras un viaje rápido mientras el MSPT está sano. |
streamCatchUpIntervalMs | 250 | Intervalo del controlador ligero de streaming. |
streamCatchUpPerSecond | 256 | Límite sano de catch-up en sections por segundo. |
streamCatchUpPerTick | 12 | Límite sano de catch-up en sections por tick. |
streamCatchUpHoldMs | 1500 | Tiempo mínimo de catch-up tras movimiento rápido. |
leanCoreTakeover | true | Si LeanCore está instalado, le toma el radio de visión. |
yieldToLeanCoreViewRadius | false | Deja el radio de visión del cliente enteramente a LeanCore. |
pressureGovernorEnabled | true | Aprieta las palancas de render cuando el MSPT del mundo se mantiene alto. |
pressureMsptEnter | 48 | Promedio de 10s de MSPT en este valor o por encima entra en pressure. |
pressureMsptExit | 43 | MSPT en este valor o por debajo sale de pressure. |
pressureSustainSeconds | 4 | Cuánto debe mantenerse alto el MSPT antes de apretar. |
pressureCooldownSeconds | 15 | Cuánto debe mantenerse bajo el MSPT antes de restaurar. |
pressureDensityMultiplier | 1.45 | Bajo presión, los umbrales de densidad se aprietan por este factor. |
pressureChunkRateMultiplier | 0.75 | Bajo presión, multiplica los topes de streaming de chunks. |
pressureLodMultiplier | 1.15 | Multiplicador de presión usado solo con LOD global explícito superior a 1.0. |
pressureVerticalTrimBlocks | 8 | Bajo presión, resta de maxEntityVerticalDistance. |
pressureWorldLevers | false | Bajo presión, pausa spawn de NPC y tick de bloques (se restaura al salir). |
pressureTrimClientEffects | false | Bajo presión, recorta bloom/sunshaft (se aplaza si el último tick es un hitch). |
pressureEffectScale | 0.5 | Multiplicador de las intensidades de efecto mientras están recortadas. |
pressureItemMerge | false | Bajo presión, junta ítems soltados desde más lejos para que los montones sean menos entidades. Requiere reinicio. |
pressureItemMergeRadius | 4.0 | Radio de merge en bloques mientras eso está activo (por defecto del motor es 2). |
leanCoreMemoryAware | true | Con LeanCore, reduce el radio mientras su tier de heap está en TIGHT o CRITICAL. Solo lectura. |
Permisos
| Permiso | Quién |
|---|---|
durkz.quantumhy.admin | Avisos de update y /q status completo. Los operadores del servidor lo heredan a través de *. |
Usándolo con LeanCore
QuantumHy y LeanCore pueden ambos ajustar el radio de visión del cliente, y solo uno debe hacerlo. Por defecto QuantumHy lo toma: al arrancar detecta LeanCore y apaga la gobernanza de radio de visión de LeanCore (viewRadiusGovernanceEnabled, liteViewRadiusEnabled, motionViewRadiusBoostEnabled), y luego pasa a controlar el radio él mismo. LeanCore conserva el radio de simulación, el throughput de chunks y la memoria. No hace falta ningún cambio de config en ninguno de los dos lados. LeanCore es una dependencia opcional: cuando no está presente, QuantumHy se ejecuta por su cuenta.
leanCoreTakeover: falsedeja a LeanCore en paz. Entonces ambos pueden pelear por el radio de visión.yieldToLeanCoreViewRadius: truehace que QuantumHy se quede fuera del radio de visión del cliente por completo y deja que LeanCore lo conserve.
Recomendado
- En solitario o tu propio servidor: deja los valores por defecto. Solo pierdes distancia de visión cuando hay aglomeración real o el mundo está hitching.
- Quieres FPS en todas partes: pon
targetClientViewRadiusentre 12 y 16 para limitar la distancia de visión incluso en campo abierto. - Granjas de mobs / eventos pesados: mantén
adaptEntityRadius: true; es lo que sostiene los frames cuando hay cientos de entidades en pantalla. - Elección personal: usa
/q optimize offpara restaurar y detener las palancas por jugador para ti. Usa/q optimize onpara reactivarlas. - Activa
verboseLogsolo para diagnosticar; por defecto está off. - Deja
checkForUpdatesactivo salvo que no quieras el aviso de JAR nuevo para operadores.
Comprobando que funciona
- Inicia el servidor y busca la línea de setup:
QuantumHy 0.4.0 setup. config: verboseLog=false tickInterval=5s ... densityLow=1.0/ch densityHigh=4.0/ch baseline=10% ... entityLod=1.00x ... expand=1 shrink=2 ... budget=8ms - Luego la línea de inicio del runtime:
QuantumHy runtime started (interval=5s, hardCap=0, min=6, max=32, scan=4, entityRadius=true). - Si LeanCore está presente:
LeanCore detected: took over the client view radius (governance turned off).Si no:LeanCore not detected after 3 checks: QuantumHy owns the client view radius standalone. - Con
verboseLog=true, cada pasada registra una línea por jugador. Leyéndola:Durkz_z 32/49ch 0.7/ch~0.5 cl 6=6 ent 48=48 [hold]significa 32 entidades en 49 chunks, visión en chunks retenida en 6, radio de entidades en 48 bloques, expand congelado (hold). Otros motivos comunes:[min],[pressure],[baseline],[chunk-load],[density]. - El radio no salta 6→13 en una pasada. Bajo presión o volando deberías ver
[pressure]o[hold], no6->7 [baseline].
Licencia
Licencia MIT