Files
last-hearth/docs/render-distance.md
T
2026-11-03 12:41:09 -05:00

5.8 KiB
Executable File

Full-detail render distance

The managed launcher requests 512 nodes of terrain visibility by default. This applies to both new and existing play worlds, disposable courses, and engine-check/test configs. It is a bounded full-detail terrain preset, not level of detail (LOD). Minecraft Distant Horizons and Sodium are conceptual references for longer horizons and efficient rendering, not Luanti addons or dependencies. This change implements neither their renderer nor their features.

Settings and units

For Luanti 5.18.0, the engine's default viewing_range is 200 nodes (engine maximum 4000), max_block_send_distance is 13 mapblocks, and max_block_generate_distance is 10 mapblocks. A mapblock is 16 nodes per side. Increasing only the client range would leave server-side terrain delivery and generation as bottlenecks, including in single-player's local server.

The launcher writes the following five settings exactly once per config:

Setting Default preset Purpose
viewing_range 512 Client terrain viewing range in nodes
max_block_send_distance 34 Server terrain send limit in mapblocks
max_block_generate_distance 34 Server terrain generation limit in mapblocks
client_mesh_chunk 2 Groups mapblocks into larger client mesh chunks; can reduce draw overhead but increases mesh rebuild granularity
fog_start 0.65 Starts distance fog at 65% of the viewing range; does not replace terrain with cheaper geometry

Both block limits use ceil(distance / 16) + 2, bounded at 66 mapblocks. The two extra blocks provide headroom around the requested range; they are not a promise that every block inside that radius is immediately generated or visible.

Requested nodes Send blocks Generate blocks
128 10 10
512 (default) 34 34
768 50 50
1024 66 66

Environment override and config lifetime

Set HEARTH_VIEW_DISTANCE in the environment inherited by the launcher before starting play, course, or tests. For example, the value 768 requests the 768-node row above; 1024 requests the maximum supported preset. Any integer from 128 through 1024 inclusive is accepted, not just the table entries. Unset the variable to restore 512. Use 128 or 256 as lower-cost fallbacks.

Only canonical unsigned decimal strings are accepted. Empty values, whitespace, leading zeros, signs, fractions, exponent/hex notation, out-of-range values, newlines, and appended config syntax are rejected, not clamped or interpolated. Validation occurs before engine invocation, staging, backups, or world/config writes on launch commands. The shared writer also validates independently before filesystem mutations. Supplying these five managed keys via extra config lines is rejected so they cannot duplicate or override the preset. Package, verify, backup and restore commands do not consume the graphics environment variable.

The config is regenerated for each invocation in the launcher's private session directory under the runtime selected by runtimeHome() / HEARTH_HOME. It is not a persistent user config: normal exit or failure removes the session directory, including its config. Editing that temporary config is not a durable way to tune graphics. Persist the environment override in the launching shell or your own launch environment instead. No personal profile path is hardcoded and no installed engine config is edited. In-game changes to these managed settings are replaced by the preset on the next launch.

World safety and simulation scope

Existing worlds receive the graphics preset without rewriting their saved mapgen, seed, boundary, world identity, or database files. A saved world detected by either its world metadata or map metadata continues to suppress creation-time terrain overrides. New worlds retain the existing creation-time terrain preset. Seeing farther does not expand an old world's saved mapgen boundary or recreate its terrain; terrain beyond that boundary remains unavailable.

No active-block range, object activation range, simulation cadence, entity distance, or gameplay radius is increased. Frustum/occlusion culling is not disabled or otherwise changed. Larger send/generate limits still mean more terrain work: generation, loading, lighting, mesh building, transfer, storage, and memory can all increase even without a larger active simulation radius. Newly generated terrain is ordinary saved world data, not a disposable LOD cache.

Performance and verification limits

The 512-node default requests 2.56 times the engine's default linear viewing range. That does not imply only 2.56 times the cost: visible area, terrain volume, foliage/mesh complexity, hardware, camera direction, and exploration speed all matter. 768 and 1024 are more demanding options, not certified quality tiers. Fog and mesh chunking are pragmatic settings, not measured FPS guarantees.

Node-only tooling tests cover the default, every allowed integer, malformed and injected inputs, 768/1024 config output, unique graphics keys, and new/existing play/course/test config paths with saved mapgen bytes preserved. These tests do not start Luanti, measure GPU/CPU/RAM use, verify visual loading distances, or certify performance. No native engine or asynchronous game launch is needed for this validation.

Before claiming a performance improvement, compare the same world, camera route, resolution, weather and hardware at 128/256/512 and optional 768/1024. Measure client frame-time percentiles, memory, mesh rebuild stalls and generation/loading latency separately for cold exploration and already-generated terrain. Course Lua callback/server-step telemetry is not client FPS or GPU profiling. Lower the override if frame pacing or memory use is unacceptable.