← Back to mod overview

Release notes

LeanCore Changelog

Active

Hytale • Latest version 1.7.0

Changelog version 1.7.0 1.6.1 → 1.7.0 • June 23, 2026

Added

  • Content-aware zone dormancy: LeanCore now samples built-content density per zone (chests, benches, and other block entities) and biases dormancy timers and eviction order toward keeping content-rich zones loaded longer, even when idle. On by default
  • Hot/simulation radius governance: under heap pressure LeanCore can trim the server-side ticking radius, separate from client view radius so there is no view pop-in, cutting simulation cost on top of the existing view-radius trims. On by default, with the same grace window as the view-radius governor
  • Per-chunk unload truth: engine chunk eviction is now counted exactly on the world thread instead of inferred from net loaded-chunk deltas, so the learning signal for “this unload stuck” is far cleaner. On by default

Changed

  • Per-world reads (hot zones, chunk-set diff, content scan) are batched into a single world-thread dispatch per tick, reducing dispatch overhead
  • Hot-radius changes are now logged, so the ticking-radius governor reports its target the way the view-radius governor already does
  • Learning persistence schema bumped to v9 (adds a per-zone content score); older v7 and v8 snapshots are read and upgraded automatically

Fixed

  • Zone reuse stats are now immutable for safe cross-thread reads, false-cut counters are atomic, and the per-world chunk-set tracker no longer retains snapshots for worlds that went away
  • Dormancy aging no longer advances its clock when a per-world fan-out only partially completes under load, so idle zones still cool on time
  • Runtime shutdown is guarded against double execution, so a restart cannot run the save and teardown path twice
  • World-thread tasks that throw are now logged instead of being silently swallowed
  • Content-rich zones now persist even before they reach the normal visit threshold

Notes

  • New LeanCore.json keys are added on first run: per-chunk unload truth, content model, and hot-radius governance default to on. Set them to false to keep 1.6.x behavior
  • Existing LeanCore.json and learning.state.gz are kept and upgraded in place; no manual migration
Changelog version 1.6.1 1.6.0 → 1.6.1 • June 20, 2026

Changed

  • Internal cleanup: removed dead code (unused snapshot type, unused dormancy/profile helpers, legacy persistence writers). No behavior change

Fixed

  • Thread safety: heap-spread sampling, regional entity pressure, engine unload polling, chunk saturation, dormancy player positions, and solo motion now reuse the position sampled on the world thread or run inside a world-thread dispatch, instead of reading player transforms or chunk stores off the world thread
  • Dispatch timeouts respected: a timed-out world task no longer advances policy state or over-reports unloaded chunks; the action just retries next tick
  • Admin tools work with the HUD off: /leancore heatmap and /leancore zone pin|unpin|pins no longer require hudFeatureEnabled, so admins can use them with the HUD disabled (the default)

Notes

  • No config, command, or API changes since 1.6.0; existing LeanCore.json and learning.state.gz are kept as-is
  • Drop-in upgrade from 1.6.0; still requires Hytale server >=0.5.6
Changelog version 1.6.0 1.5.0 → 1.6.0 • June 20, 2026

Added

  • Player motion model (motionModelEnabled, on by default): per-player velocity and confidence with a predicted position over a short horizon
  • Predictive zone retention: chunk unload is biased away from where players are heading; zones inside a player’s current or predicted view are never eviction candidates (protected cone)
  • Reuse-distance + survival model (zoneReuseModelEnabled, on by default): learns which zones get revisited and scales dormancy thresholds per zone; persisted with prune/TTL
  • Always-on diagnostics (diagnosticLogEnabled, on by default): startup/shutdown summaries and [diag] decision logs for every profile, so the server log alone explains what the mod did and why
  • Cinematic view boost (motionViewRadiusBoostEnabled, opt-in / off by default): smoothly raises view distance for fast movers
  • Learning snapshot schema v8: adds player motion features and zone reuse stats; reads v7 snapshots

Changed

  • Dormancy unload ranking measures distance to a zone’s nearest chunk (AABB edge), not the zone center, for more accurate eviction
  • Learning persistence runs on a dedicated single-writer thread, separate from the runtime tick
  • Fresh LeanCore.json ships 1.6.0 defaults: motion model and reuse model on; cinematic boost off

Fixed

  • Multi-world safety: per-world fan-out merges only on success and respects a per-tick budget; world-thread affinity corrected so one world never ages or unloads another’s zones
  • Race-free persistence: single-writer flush with unique temp files; thread-safe motion features and activity classifier; symmetric codec read/write caps
  • Chunk streaming smoothness: cinematic view boost stays off by default because rewriting the client view radius every tick churns chunk loading and stutters on the current engine

Removed

  • LeanCoreAPI public surface (now internal only)

Notes

  • Requires Hytale server >=0.5.6
  • Solo/LITE defaults stay smooth: the motion and reuse models do not change view radius or chunk rate on their own; the cinematic boost is opt-in
  • Residual chunk-load stutter on fast movement is engine-side (pre-load hooks) and outside the mod’s reach
Changelog version 1.5.0 1.4.1 → 1.5.0 • June 15, 2026

Added

  • LITE memory governor on solo embedded (liteMemoryGovernorEnabled, default on): view scaling, zone demotion, and unload sweeps without governEnabled
  • Adaptive view-radius in LITE (liteViewRadiusEnabled): COMFORT stays at 100% until chunk or heap pressure; gentle cuts in WATCH; aggressive only in TIGHT/CRITICAL
  • AFK chunk unload in LITE (liteUnloadEnabled): reclaims distant dormant/frozen zones when idle; probe gate still applies; no unloadEnabled required on solo
  • LITE learning (liteLearningEnabled, default on): demand model + gzip persistence on solo; no policy bandit or holdout in LITE
  • Lite config keys: liteViewPressureThreshold, liteViewComfortCapScale, liteViewWatchScale, liteViewTightScale, liteViewCriticalScale, liteMinClientViewRadius, liteViewRadiusLoginGraceSeconds, liteUnloadIdleSeconds, liteUnloadMaxChunksPerSweep
  • Dual pressure signals in LITE: JVM heap tier plus chunk saturation (loaded / view budget)
  • /leancore savings: lite governor block (preset, tier, lite flags, zone/chunk counters)
  • /leancore status: lite govern/view/learning/unload flags and lite unload gate line
  • /leancore learn: LITE footer clarifies demand-only learning on solo

Changed

  • Solo profile LITE now runs a full lite governor tick on the world thread (not dormancy sampling only)
  • Fresh LeanCore.json ships 1.5.0 defaults (lite*Enabled=true, STANDARD/FULL paths still off until you enable them)
  • Learning persistence interval defaults remain conservative for STANDARD/FULL; LITE flushes on its own path when liteLearningEnabled is on

Fixed

  • World-thread dispatch scoped per world (GovernorWorldContext); inline dispatch only when the target world matches
  • LITE governor tick runs entirely inside world.execute
  • Learning load hardening: invalid learning.state.gz quarantined; codec validation on read
  • LeanCore.json sanitization: invalid JSON quarantined, atomic save, caps on view/unload tuning keys

Notes

  • LITE unload still needs /leancore probe when unloadProbeGateEnabled is true (default)
  • LITE unload sweeps only run when heap tier is WATCH or worse and distant zones are dormant; COMFORT + low spread is normal with zero unload counts
  • STANDARD/FULL behavior unchanged: governEnabled, learningEnabled, unloadEnabled as before
  • Set embeddedStandardProfile: true only for dev dogfood of STANDARD on solo
Changelog version 1.4.1 1.4.0 → 1.4.1 • June 14, 2026

Added

  • Unload probe gate (unloadProbeGateEnabled, default on): policy chunk unload stays blocked until /leancore probe passes; gate line on /leancore status; probePassedAtMs saved to LeanCore.json
  • gcHint session metrics in /leancore savings when gcHintEnabled is on (hint count and last hint age)

Changed

  • /leancore status shows solo LITE diagnostics (adaptive tick, govern/learning/unload flags, unload gate line)
  • /leancore probe persists pass timestamp on success and confirms when the unload gate opens
  • /leancore learn reports learning flush status (flushErr, last flush time); v7 load/flush IO errors log to server

Fixed

  • Governor defers unload, view-radius, and regional pressure when the primary world is missing (heap sampling and learning updates continue)

Notes

  • Chunk unload on STANDARD/FULL still needs governEnabled + unloadEnabled + successful probe when the gate is enabled
  • Set unloadProbeGateEnabled: false only if you intentionally override the safety gate
  • View-radius on embedded solo unchanged: requires dedicatedServerMode: true
Changelog version 1.4.0 1.3.0 → 1.4.0 • June 10, 2026

Added

  • Learning snapshot v7 (learning.state.gz): gzip binary format; migrates legacy text learning.state on first flush

  • Profile pruning: learningMaxPersistedPlayers (default 512) and learningPlayerTtlDays (default 90)

  • embeddedStandardProfile: solo embedded STANDARD (15s) without dedicatedServerMode / FULL 5s tick

  • World dispatch layer: WorldDispatch, GovernorWorldContext, RuntimeGuard for Hytale TickingThread semantics

  • gcHintEnabled: optional experimental LITE idle GC hint (off by default)

Changed

  • Daemon LeanCore-runtime scheduler; shutdown hooks on ShutdownEvent

  • Governor ticks: coalesced world.execute (one pending tick; scheduler no longer blocks up to 5s)

  • Policy apply + chunk unload run inline when world.isInThread()

  • HUD overlays removed on shutdown; webhook HTTP client uses daemon executor

Fixed

  • Zombie java.exe after closing embedded Hytale with dedicated-style config (nested world.execute + blocking wait stranded tasks on the world queue; TickingThread kept JVM alive after Shutdown completed!)

  • View-radius on embedded solo still requires dedicatedServerMode: true (by design)

Notes

  • Enable unloadEnabled only after /leancore probe baseline
Changelog version 1.3.0 1.2.2 → 1.3.0 • June 9, 2026

Added

  • /leancore savings: session JVM heap peak, baseline, delta, governor state, and cumulative zone/chunk actions with measured vs estimated labels
  • DedicatedBootstrap: one-time preset on first dedicated boot (governEnabled, viewRadiusGovernanceEnabled, learningEnabled; unloadEnabled stays off)
  • 10-minute view-radius grace after dedicated runtime start

Changed

  • ZoneDormancyMap: incremental refresh without full map rebuild; stale zone prune
  • OnlineLinearDemandModel: per-update weight decay (0.9995) for playstyle changes
  • chunkUnloadEventTracking: engine unload counts via world-thread polling (no ECS ChunkUnloadEvent listener)
  • STANDARD/FULL governor tick dispatched on the world thread

Fixed

  • Crash on profile FULL / dedicated preset (Assert not in thread in engine chunk unload) from off-thread ChunkStore access and unsafe unload event registration
  • Regional pressure probe (S4) no longer reads ChunkStore from the scheduler thread

Notes

  • /leancore savings is JVM heap only — not OS/VPS RSS
  • Set dedicatedBootstrapEnabled: false to skip the auto-preset
  • CurseForge build must include post-53c801f thread-safety commits on main
Changelog version 1.2.2 1.2.1 → 1.2.2 • June 8, 2026

Added

  • Policy blacklist persistence in learning.state schema v5 (rollback bans survive restart when learningEnabled is on)
  • /leancore learn reports learning=v5 and active blacklist count

Changed

  • LeanCore.json read/write uses UTF-8 encoding
  • Governor blacklist state owned by LearningStore via PolicyBlacklistTracker

Fixed

  • FIGHTER stuck after exploring — explore activity pulses, zone discovery records EXPLORE, combat EMA decays when moving or switching roles

Notes

  • Blacklist persistence requires learningEnabled: true
  • v4 learning.state upgrades automatically; blacklist is empty until the next policy rollback
Changelog version 1.2.1 1.1.1 → 1.2.1 • June 8, 2026

First public 1.2.x release (includes Activity Sense from 1.2.0 plus 1.2.1 fixes). No separate 1.2.0 file on CurseForge.

Added

  • Activity Sense (ML): online multiclass softmax classifier trained from live ECS events

  • Block/tool context classifier: item id, gather type, and block group label breaks/places (MINE, CHOP, FARM, BUILD)

  • New playstyle labels: MINER, LUMBERJACK, FARMER alongside existing behaviors

  • Per-activity EMA features: mine, wood, farm, build, craft, combat rolling windows

  • Combat signal listener: FIGHTER only from damage events, not generic block breaks

  • Craft signal: CraftRecipeEvent.Pre feeds craft activity

  • Demand feature schema v2 (demandDim=11) with activity-specific EMAs

  • /leancore learn player: activity EMAs and activityModel=SOFTMAX status

  • Block break/place classify cache and per-item gather-type cache

  • Recent activity window for fast MINER / LUMBERJACK / BUILDER switches

  • Dirty flush for learning.state when learning is enabled

  • Unit tests for activity classifier, posterior, and role switching

Changed

  • Behavior posterior uses ML softmax as primary path; EMA fallback before warm-up

  • learning.state schema v4: persists activity classifier + per-player activity EMAs (migrates from v3)

  • /leancore learn reports featureSchema=v2 when demand model is active

  • Activity EMA half-life 20s with cross-inhibition on role change

  • ML training throttled; LITE profile skips chunk probe on dormancy refresh

  • Hatchet and Hytale wood blocks classified before pickaxe heuristics

Fixed

  • Mining with pickaxe no longer tagged as FIGHTER

  • Slow role change after switching from mining to chopping (e.g. Hatchet)

  • EMA decay on solo LITE during block events

  • Stutter from per-break classify + ML train on ECS thread

Notes

  • Activity ML runs in-process on the server JVM (no client mod)

  • Heuristic teacher bootstraps softmax until updates >= 8

  • Primary KPI: server JVM heap, not client FPS

  • Upgrade from 1.1.1 directly to 1.2.1

Changelog version 1.2.0 1.1.0 → 1.2.0 • June 8, 2026

Added

  • Activity Sense (ML): online multiclass softmax classifier trained from live ECS events

  • Block/tool context classifier: item id, gather type, and block group label breaks/places (MINE, CHOP, FARM, BUILD)

  • New playstyle labels: MINER, LUMBERJACK, FARMER alongside existing behaviors

  • Per-activity EMA features: mine, wood, farm, build, craft, combat rolling windows

  • Combat signal listener: FIGHTER only from damage events, not generic block breaks

  • Craft signal: CraftRecipeEvent.Pre feeds craft activity

  • Demand feature schema v2 (demandDim=11) with activity-specific EMAs

  • /leancore learn player: activity EMAs and activityModel=SOFTMAX status

  • Unit tests for block classifier, activity model, and behavior posterior

Changed

  • Behavior posterior uses ML softmax as primary path; EMA fallback before warm-up

  • learning.state schema v4: persists activity classifier + per-player activity EMAs

  • /leancore learn reports featureSchema=v2 when demand model is active

Fixed

  • Mining with pickaxe no longer tagged as FIGHTER — breaks weighted by tool/block context

Notes

  • Activity ML runs in-process on the server JVM (no client mod)

  • Heuristic teacher bootstraps softmax until updates >= 8

  • Primary KPI remains server JVM heap, not client FPS

Changelog version 1.1.0 1.0.0 → 1.1.0 • June 8, 2026

Added

  • Scaled runtime profiles on embedded hosts: LITE (solo), STANDARD (friends), FULL (dedicated)

  • localHostMode AUTO (default): light dormancy tick on solo; scales when friends join

  • Regional entity probe (S4): zone-level entity counts via EntityChunk in /leancore probe

  • ChunkUnloadEvent tracking (opt-in): policy sweep vs engine unload counters in /leancore learn

  • OnlineLinearDemandModel: learned retention demand blended with activity features (feature schema v1)

  • LeanCoreAPI: query memory tier, pin/unpin zones, player snapshots for other mods

  • Holdout cohort (10%): bandit learns from treatment players; holdout players skip view-radius cuts

  • Unit tests for runtime profiles, activation policy, feature normalization, and demand model

Changed

  • Runtime uses HytaleServer.SCHEDULED_EXECUTOR with 30s initial delay on local worlds

  • Safer defaults: governEnabled=false, viewRadiusGovernanceEnabled=false, HUD/learning off by default

  • View-radius governance disabled on embedded solo even when governor is enabled

  • Policy applier only applies view-radius when policy actually changes (throttled)

  • /leancore status shows active runtime profile (LITE / STANDARD / FULL)

  • /leancore learn shows featureSchema=v1, demand model status, and unload attribution

Fixed

  • Embedded local worlds no longer stutter from a heavy 5s background tick + HUD + learning loop

  • Chunk-unload event tracking off by default (avoids engine thread assert on some worlds)

Notes

  • Primary KPI remains server JVM heap, not client FPS or GPU

  • Solo: keep localHostMode: AUTO. Dedicated: dedicatedServerMode: true then tune governor

Changelog version 1.0.0 0.5.0-SNAPSHOT → 1.0.0 • June 7, 2026

Added

  • First stable public release (1.0.0)
  • Memory governor with COMFORT → CRITICAL tiers, rollback, and contextual policy learning
  • Spatial dormancy map (HOT / WARM / DORMANT / FROZEN) and chunk unload sweeps
  • Per-player retention demand from live activity features
  • Server-calibrated heap quantiles and learning.state persistence (schema v3)
  • Admin HUD (/leancore hud on|off|status) — opt-in, group and permission gated
  • Zone heatmap (/leancore heatmap [limit])
  • Zone pin overrides (/leancore zone pin|unpin|pins)
  • Optional CRITICAL webhook (criticalWebhookUrl, generic JSON)
  • Bundled server asset pack for HUD UI

Notes

  • Primary KPI is server JVM heap, not client FPS