← Back to documentation

Server documentation

QuantumHy

In Development

Hytale • Version 0.2.1

Install, config keys, how the adaptive chunk and entity radius work, global LOD culling, and LeanCore coexistence for QuantumHy.

Install, configuration, and runtime behavior for QuantumHy.


Overview

QuantumHy is a server-side FPS mod for Hytale. The client is native and cannot be modded, but the server decides how much each client has to render, so QuantumHy trims that on a per-player basis. Every few seconds it samples the entity density around each player, smooths it, and uses it to shrink two things: the client chunk view radius and the per-player entity stream radius. A global entity LOD setting drops small and distant entities sooner on top of that. In the open everything returns to the player’s own ceiling; QuantumHy never inflates a view past what the player asked for. It helps only where it is installed, never on a remote server you merely join.


Installation

  1. Download QuantumHy-0.2.1.jar from the CurseForge Files tab
  2. Place the JAR in your server’s mods/ folder (or %AppData%\Hytale\UserData\Mods\ on Windows)
  3. Start the server. Config is generated as QuantumHy.json in the plugin data folder
  4. Watch the server log for the setup line and the per-pass decisions (see Verifying it works)

How it works

Every pass (default 5s) QuantumHy does the per-player work on the owning world’s thread:

  1. Sample density. It counts the entities in the chunks around the player (a square of densityScanChunkRadius chunks each way) and divides by the number of loaded chunks scanned, giving entities per chunk. A normal world idles around 1 to 1.5 per chunk.
  2. Smooth it. The per-chunk value is fed through an exponential moving average (densitySmoothing), so a player moving through a brief crowd does not get their view yanked around.
  3. Turn it into a shrink factor. At or below densityLowPerChunk the factor is 0 (no shrink). At or above densityHighPerChunk it is 1 (full shrink). In between it scales linearly.
  4. Apply it to two levers. The same factor scales the chunk view radius (down toward minClientViewRadius) and, when adaptEntityRadius is on, the entity stream radius in blocks (down toward minEntityViewBlocks). The entity lever is the big win in mob-heavy areas, since it controls how far the server streams entities regardless of chunks.

Both levers ramp back up in the open. While a player is still streaming chunks (just joined, sprinting), shrink is held so the client is not told to drop chunks it is busy loading. Because writing the view radius also lowers what the live value reports, QuantumHy remembers the highest value it ever saw per player and ramps back toward that, so the view recovers correctly.

entityLodAggressiveness is separate: it is a single server-wide multiplier on the engine’s entity LOD cull, applied once at startup and restored on shutdown. Higher values drop small and distant entities sooner for everyone.


Configuration

Runtime file: QuantumHy.json in the plugin data folder, created on first run.

KeyDefaultWhat it does
enabledtrueMaster switch. When false, QuantumHy never touches any view radius.
verboseLogtrueLog every pass with each player’s density and view decision.
tickIntervalSeconds5How often it re-checks each player.
initialDelaySeconds20Wait this long after start before the first pass.
targetClientViewRadius0Hard cap in chunks. 0 means no cap, just adapt to density.
minClientViewRadius6Never pull anyone below this chunk radius.
maxClientViewRadius32Ceiling for the hard cap (the player’s own view radius still wins).
densityScanChunkRadius4How many chunks each way to count entities in.
densityLowPerChunk2.0Entities per chunk at or below this: full radius.
densityHighPerChunk8.0Entities per chunk at or above this: pulled to the minimum.
densitySmoothing0.4Weight of the newest sample in the EMA, in (0, 1]. Lower is smoother; 1.0 is off.
adaptEntityRadiustrueAlso shrink the per-player entity stream radius, not just chunks.
minEntityViewBlocks48Lower bound for the entity radius, in blocks (16 blocks = 1 chunk).
entityLodAggressiveness1.5Global entity LOD cull. 1.0 is the engine default; higher drops small/distant entities sooner.
minViewRadiusDelta2Minimum change (chunks) before an update is sent, to avoid churn.
respectStreamingGracetrueHold cuts while a player is still streaming chunks.
streamingBacklogThreshold8How many loading chunks counts as “still streaming”.
leanCoreTakeovertrueIf LeanCore is installed, take the view radius over from it.
yieldToLeanCoreViewRadiusfalseThe opposite: leave the client view radius entirely to LeanCore.

Running it with LeanCore

QuantumHy and LeanCore can both write the client view radius, and only one should. By default QuantumHy takes it: on startup it detects LeanCore and turns off LeanCore’s view-radius governance (viewRadiusGovernanceEnabled, liteViewRadiusEnabled, motionViewRadiusBoostEnabled), then drives the view radius itself. LeanCore keeps simulation radius, chunk throughput, and memory. No config change is needed on either side. LeanCore is an optional dependency: when it is absent, QuantumHy just runs standalone.

  • leanCoreTakeover: false leaves LeanCore alone. Both may then fight over the view radius.
  • yieldToLeanCoreViewRadius: true makes QuantumHy stay out of the client view radius entirely and lets LeanCore keep it.

  • Solo or your own server: leave the defaults. You only lose view distance when it is actually crowded.
  • Want FPS everywhere: set targetClientViewRadius to 12 to 16 to cap view distance even in the open.
  • Mob farms / heavy events: keep adaptEntityRadius: true; this is what holds frames when hundreds of entities are on screen.
  • Once you trust it, set verboseLog: false to quiet the log.

Verifying it works

  1. Start the server and look for the setup line: QuantumHy 0.2.1 setup. config: verboseLog=true tickInterval=5s ... densityLow=1.0/ch densityHigh=4.0/ch baseline=10% ... entityLod=2.00x ...
  2. Then the runtime start line: QuantumHy runtime started (interval=5s, hardCap=0, min=6, max=32, scan=4, entityRadius=true).
  3. If LeanCore is present: LeanCore detected: took over the client view radius (governance turned off). Otherwise: LeanCore not detected after 3 checks: QuantumHy owns the client view radius standalone.
  4. With verboseLog=true, each pass logs one line per player. Reading it: Durkz_z 312/81ch 3.9/ch~2.7 cl 14->13 ent 448->404 [density] means 312 entities across 81 chunks (3.9 per chunk, smoothed to 2.7), chunk view radius going 14 to 13, entity radius going 448 to 404 blocks, reason density.
  5. In the open the reason reads [open] and both values hold at the ceiling; in a crowd they fall, with [density-min] once they hit the floor.

License

MIT License