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

102 lines
5.8 KiB
Markdown
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.