← Back to documentation

Server documentation

QuantumHy

Active

Hytale • Version 0.2.3

Instalação, chaves de config, raio adaptativo de chunks e entidades, freeze de expand, governor de pressão e coexistência com o LeanCore no Hytale 0.6.

Instalação, configuração e comportamento em runtime do QuantumHy.


Visão geral

O QuantumHy é um mod de FPS server-side para Hytale 0.6. O cliente é nativo e não dá pra modar, mas o servidor decide o quanto cada cliente precisa desenhar, então o QuantumHy corta isso por jogador. A cada poucos segundos ele amostra a densidade de entidades ao redor de cada jogador, suaviza e usa isso pra reduzir duas coisas: o raio de visão em chunks do cliente e o raio de stream de entidades por jogador. Um ajuste global de LOD de entidades descarta entidades pequenas e distantes mais cedo por cima disso.

Ele nunca infla a visão além do que o jogador pediu. O raio não volta no instante em que a densidade parece aberta: o expand fica congelado até a carga estar calma, o disco de density estar pelo menos metade carregado, o jogador não estar voando e o mundo não estar sob pressão de MSPT. Só ajuda onde está instalado, nunca num servidor remoto que você só entra.


Instalação

  1. Baixe QuantumHy-0.2.3.jar na aba Files da CurseForge
  2. Coloque o JAR na pasta mods/ do servidor, ou no solo Windows: %AppData%\Hytale\data\release\Mods
  3. Inicie o servidor. A config é gerada como QuantumHy.json na pasta de dados do plugin
  4. Acompanhe o log do servidor pela linha de setup (veja Conferindo se está funcionando)

Comandos

/q status
/q help

Aliases: /quantumhy, /qhy. /q status é diagnóstico só leitura. Não há /q perf público.


Como funciona

A cada passada (5s por padrão) o QuantumHy faz o trabalho por jogador na thread do mundo dono:

  1. Amostra a densidade (às vezes pula). Conta entidades num disco de densityScanChunkRadius chunks (dx²+dz² ≤ r²). A varredura de 49 colunas é pulada na primeira passada, em voo (2+ chunks/passada), em streaming, no cache do mesmo chunk, e enquanto já estiver no mínimo com expand travado.
  2. Suaviza. Uma amostra válida passa por uma média móvel exponencial (densitySmoothing).
  3. Vira um fator de redução. A densidade usa smoothstep entre densityLowPerChunk e densityHighPerChunk. Isso combina com shrink por chunk-load (sections carregadas + carregando) e um piso baseline. O fator combinado só aumenta o shrink até o expand ser permitido (ratchet).
  4. Rampa duas alavancas. Visão em chunks move no máximo +1 / −2 por passada (−4 sob pressão). O raio de entidades usa o mesmo fator; em shrink cheio ([min]) vai a minEntityViewBlocks num write. Escritas param depois de worldPassBudgetMs ou durante streaming.

O expand só é permitido depois de expandHysteresisPasses passadas calmas, disco de density ≥ 50% carregado, sem streaming, sem deslocamento rápido e sem pressão MSPT.

O entityLodAggressiveness é separado: multiplicador único no servidor no cull de LOD do engine, aplicado no boot e restaurado no shutdown.


Configuração

Arquivo de runtime: QuantumHy.json na pasta de dados do plugin, criado no primeiro boot. Install nova recebe configVersion 5.

ChavePadrãoO que faz
enabledtrueInterruptor mestre. Quando false, o QuantumHy nunca toca em raio de visão nenhum.
verboseLogfalseLoga cada passada com a densidade e a decisão de visão de cada jogador. Off em install nova.
checkForUpdatestrueNo boot, lê a página do QuantumHy e avisa operadores ou durkz.quantumhy.admin se um JAR mais novo estiver listado.
tickIntervalSeconds5De quanto em quanto tempo ele recheca cada jogador.
initialDelaySeconds20Espera esse tempo após o start antes da primeira passada.
targetClientViewRadius0Teto fixo em chunks. 0 significa sem teto, só adapta pela densidade.
minClientViewRadius6Nunca puxa ninguém abaixo desse raio em chunks.
maxClientViewRadius32Teto pro limite fixo (o próprio raio de visão do jogador ainda vence).
densityScanChunkRadius4Quantos chunks pra cada lado contar entidades.
densityLowPerChunk1.0Entidades ponderadas por chunk em ou abaixo disso: sem shrink por densidade.
densityHighPerChunk4.0Entidades ponderadas por chunk em ou acima disso: puxado pro mínimo.
densityRingWeightingtrueChunks centrais contam cheio, anéis externos menos.
densityRingEdgeWeight0.55Peso no anel da borda (1.0 = contagem plana).
baselineShrinkFraction0.10Shrink mínimo mesmo com densidade “aberta” (0 = off).
chunkLoadShrinkEnabledtrueShrink extra pela contagem de sections carregadas + em streaming.
chunkLoadLowChunks700Sections loaded+loading em ou abaixo disso: sem shrink por chunk-load.
chunkLoadHighChunks1550Nesse número de sections ou acima: shrink por chunk-load no máximo.
densitySmoothing0.4Peso da amostra mais nova na EMA, em (0, 1]. 1.0 desliga.
adaptEntityRadiustrueTambém reduz o raio de stream de entidades por jogador, não só os chunks.
minEntityViewBlocks48Limite inferior do raio de entidades, em blocos (16 blocos = 1 chunk).
entityLodAggressiveness2.0Cull global de LOD de entidades. 1.0 é o padrão do engine.
maxEntityVerticalDistance32Descarta entidades longe demais acima/abaixo do jogador. 0 = off.
maxVisibleEntitiesPerPlayer80Teto de entidades streamadas por jogador em multidões. 0 = off.
holdSpawnOnLoadingChunkstruePausa spawn ambiental enquanto algum jogador tem backlog de sections.
minViewRadiusDelta2Mudança mínima (chunks) antes de mandar uma atualização. Expands +1 ainda aplicam.
maxExpandChunksPerPass1Máximo de chunks que o raio de visão sobe numa passada.
maxShrinkChunksPerPass2Máximo que desce numa passada (dobrado sob pressão).
maxExpandEntityBlocksPerPass16Máximo de blocos que o raio de entidades sobe numa passada.
expandHysteresisPasses2Passadas calmas exigidas antes de permitir expand.
worldPassBudgetMs8Budget de relógio para writes de raio na world thread. 0 desliga.
pressureExitRequiresLastTicktruePressure só sai quando a média de 10s e o last tick estão calmos.
respectStreamingGracetrueSegura cortes enquanto o jogador ainda está transmitindo sections.
streamingBacklogThreshold80Quantas sections carregando contam como “ainda transmitindo”.
smoothChunkStreamingtrueLimita a velocidade com que sections chegam a cada cliente gerenciado.
maxChunksPerSecond128Teto de sections por segundo. 0 mantém o padrão do engine.
maxChunksPerTick8Teto de sections por tick (padrão do engine é 40 no 0.6).
leanCoreTakeovertrueSe o LeanCore estiver instalado, assume o raio de visão dele.
yieldToLeanCoreViewRadiusfalseDeixa o raio de visão do cliente inteiramente pro LeanCore.
pressureGovernorEnabledtrueAperta as alavancas de render quando o MSPT do mundo fica alto.
pressureMsptEnter48Média de 10s de MSPT nesse valor ou acima entra em pressure.
pressureMsptExit43MSPT nesse valor ou abaixo sai de pressure.
pressureSustainSeconds4Quanto tempo o MSPT precisa ficar alto antes de apertar.
pressureCooldownSeconds15Quanto tempo o MSPT precisa ficar baixo antes de restaurar.
pressureDensityMultiplier1.45Sob pressão, os limiares de densidade apertam por esse fator.
pressureChunkRateMultiplier0.75Sob pressão, multiplica os tetos de streaming de chunks.
pressureLodMultiplier1.15Sob pressão, cull extra de LOD de entidades.
pressureVerticalTrimBlocks8Sob pressão, subtrai de maxEntityVerticalDistance.
pressureWorldLeversfalseSob pressão, pausa spawn de NPC e tick de bloco (restaurado na saída).
pressureTrimClientEffectstrueSob pressão, corta bloom/sunshaft (adiado se o last tick for hitch).
pressureEffectScale0.5Multiplicador das intensidades de efeito enquanto cortadas.

Permissões

PermissãoQuem
durkz.quantumhy.adminAvisos de update in-game. Operadores do servidor herdam isso via *.

Rodando com o LeanCore

O QuantumHy e o LeanCore podem ambos ajustar o raio de visão do cliente, e só um deve. Por padrão o QuantumHy assume: no boot ele detecta o LeanCore e desliga a governança de raio de visão do LeanCore (viewRadiusGovernanceEnabled, liteViewRadiusEnabled, motionViewRadiusBoostEnabled), e então passa a controlar o raio ele mesmo. O LeanCore continua com o raio de simulação, o throughput de chunks e a memória. Nenhuma mudança de config é necessária dos dois lados. O LeanCore é uma dependência opcional: quando ele não está presente, o QuantumHy roda sozinho.

  • leanCoreTakeover: false deixa o LeanCore em paz. Aí os dois podem brigar pelo raio de visão.
  • yieldToLeanCoreViewRadius: true faz o QuantumHy ficar fora do raio de visão do cliente por completo e deixa o LeanCore manter.

Recomendado

  • Solo ou seu próprio servidor: deixe os padrões. Você só perde distância de visão quando está realmente cheio ou o mundo está hitchando.
  • Quer FPS em todo lugar: defina targetClientViewRadius entre 12 e 16 pra limitar a distância de visão até em área aberta.
  • Farms de mob / eventos pesados: mantenha adaptEntityRadius: true; é o que segura os frames quando tem centenas de entidades na tela.
  • Ligue verboseLog só pra diagnosticar; o padrão é off.
  • Deixe checkForUpdates ligado a menos que você não queira o aviso de JAR novo para operadores.

Conferindo se está funcionando

  1. Inicie o servidor e procure a linha de setup: QuantumHy 0.2.3 setup. config: verboseLog=false tickInterval=5s ... densityLow=1.0/ch densityHigh=4.0/ch baseline=10% ... entityLod=2.00x ... expand=1 shrink=2 ... budget=8ms
  2. Depois a linha de início do runtime: QuantumHy runtime started (interval=5s, hardCap=0, min=6, max=32, scan=4, entityRadius=true).
  3. Se o LeanCore estiver presente: LeanCore detected: took over the client view radius (governance turned off). Caso contrário: LeanCore not detected after 3 checks: QuantumHy owns the client view radius standalone.
  4. Com verboseLog=true, cada passada loga uma linha por jogador. Lendo: Durkz_z 32/49ch 0.7/ch~0.5 cl 6=6 ent 48=48 [hold] significa 32 entidades em 49 chunks, visão em chunks presa em 6, raio de entidades em 48 blocos, expand congelado (hold). Outros motivos comuns: [min], [pressure], [baseline], [chunk-load], [density].
  5. O raio não salta 6→13 numa passada. Sob pressão ou voando você deve ver [pressure] ou [hold], não 6->7 [baseline].

Licença

Licença MIT