← Voltar à documentação

Documentação do servidor

QuantumHy

Ativo

Hytale • Version 0.4.0

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.7.

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


Visão geral

O QuantumHy é um mod de FPS server-side para Hytale 0.7. 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 para reduzir o raio de visão em chunks e o raio de stream de entidades. Cada jogador pode ativar ou desativar a otimização para si sem alterar os outros.

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.4.0.jar na aba Files da CurseForge
  2. Coloque o JAR na pasta mods/ do servidor, ou no Windows: %AppData%\Hytale\UserData\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 optimize on
/q optimize off
/q help

Aliases: /quantumhy, /qhy. Um jogador comum vê apenas seu próprio modo e última decisão em /q status. Admins e console veem o diagnóstico completo. /q optimize on|off altera apenas o jogador que executa e salva a escolha pelo UUID.


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, com cache recente do mesmo chunk, e enquanto já estiver no mínimo com expand travado. O cache de um jogador parado expira após 15 segundos.
  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 e global. O padrão 1.0 mantém o LOD do engine. Valores acima de 1.0 são um override explícito do admin, e só nesse caso a pressão de MSPT aplica pressureLodMultiplier.


Configuração

Arquivos de runtime: QuantumHy.json e PlayerPreferences.json na pasta de dados do plugin, criados no primeiro boot. Instalações novas recebem configVersion 8.

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).
adaptiveTerrainViewEnabledtrueAdapta o raio de visão do terreno durante o jogo normal.
emergencyTerrainTrimEnabledtruePermite redução temporária do terreno após pressão visual sustentada.
clientRenderCapEnabledtrueLimita a distância de desenho e a névoa do cliente ao raio cortado. Exige reinício.
clientStrainEnabledtrueAlivia o raio e o envio de chunks pra um cliente que fica pra trás. Exige reinício.
clientStrainFrameLagLowMs25Atraso do loop principal do cliente (ms) onde a sobrecarga começa a contar (uns 40 FPS).
clientStrainFrameLagHighMs60Atraso tratado como sobrecarga total (uns 16 FPS).
clientStrainQueueLow64Fila de pacotes do cliente onde a sobrecarga começa a contar.
clientStrainQueueHigh512Fila de pacotes tratada como sobrecarga total.
effectBudgetEnabledtrueOrçamento de partículas e sons 3D distantes por jogador. Exige reinício.
effectBudgetPerSecond120Efeitos distantes que cada jogador pode receber por segundo.
effectProtectRadius16Efeitos dentro desse número de blocos nunca são descartados.
effectSoftRadius48Depois de gastar metade do orçamento, efeitos além disso caem primeiro.
effectMaxDistance0Corte fixo em blocos pra efeitos posicionais. 0 = só o orçamento.
distantUpdateThrottleEnabledfalseEnvia updates de posição de entidades distantes com menos frequência. A posição mais recente sempre chega. Exige reinício.
distantUpdateNearBlocks32Entidades mais perto que isso recebem todo update.
distantUpdateFarBlocks64Entidades além disso recebem 1 a cada 4 updates.
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.
chunkLoadLowChunks2800Sections loaded+loading em ou abaixo disso: sem shrink por chunk-load. Também é onde a visão assenta quando está calmo (por volta de view 10 no 0.7).
chunkLoadHighChunks5900Nesse número de sections ou acima: shrink por chunk-load no máximo (por volta de view 14).
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).
entityLodAggressiveness1.0Override global explícito de LOD. 1.0 mantém 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.
holdSpawnOnLoadingChunksfalsePausa spawn ambiental durante backlog pesado de sections. Controle global do admin.
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).
streamCatchUpEnabledtrueEleva temporariamente os limites após viagem rápida enquanto o MSPT está saudável.
streamCatchUpIntervalMs250Intervalo do controlador leve de streaming.
streamCatchUpPerSecond256Limite saudável de catch-up em sections por segundo.
streamCatchUpPerTick12Limite saudável de catch-up em sections por tick.
streamCatchUpHoldMs1500Tempo mínimo de catch-up após movimento rápido.
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.15Multiplicador de pressão usado apenas com LOD global explícito acima de 1.0.
pressureVerticalTrimBlocks8Sob pressão, subtrai de maxEntityVerticalDistance.
pressureWorldLeversfalseSob pressão, pausa spawn de NPC e tick de bloco (restaurado na saída).
pressureTrimClientEffectsfalseSob pressão, corta bloom/sunshaft (adiado se o last tick for hitch).
pressureEffectScale0.5Multiplicador das intensidades de efeito enquanto cortadas.
pressureItemMergefalseSob pressão, junta itens dropados de mais longe pra pilhas virarem menos entidades. Exige reinício.
pressureItemMergeRadius4.0Raio de merge em blocos enquanto isso está ativo (padrão da engine é 2).
leanCoreMemoryAwaretrueCom o LeanCore, reduz o raio enquanto o tier de heap dele está TIGHT ou CRITICAL. Só leitura.

Permissões

PermissãoQuem
durkz.quantumhy.adminAvisos de update e /q status completo. 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.
  • Escolha pessoal: use /q optimize off para restaurar e parar as alavancas por jogador para você. Use /q optimize on para reativar.
  • 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.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
  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