From ba2546e096c93e13fc0abfcf0e0447eb1721960f Mon Sep 17 00:00:00 2001 From: MihailRis Date: Fri, 27 Feb 2026 20:34:23 +0300 Subject: [PATCH 1/8] fix 'attempt to compare string with number' in audio.input.fetch --- res/modules/internal/bytearray.lua | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/res/modules/internal/bytearray.lua b/res/modules/internal/bytearray.lua index f64bfddb6..c7c756f1c 100644 --- a/res/modules/internal/bytearray.lua +++ b/res/modules/internal/bytearray.lua @@ -261,7 +261,8 @@ local function create_FFIview_class(name, typename, typesize) return function() i = i + 1 if i <= self.bytes.size / typesize then - return i, self.ptr[i - 1] + local ptr = FFI.cast(ptrtype, self.bytes.bytes) + return i, ptr[i - 1] end end end From d7316f27f02c8dbf7f472371107e535388a9d459 Mon Sep 17 00:00:00 2001 From: MihailRis Date: Fri, 27 Feb 2026 22:36:22 +0300 Subject: [PATCH 2/8] fix blocks random tick pattern --- src/logic/BlocksController.cpp | 38 ++++++++++++++++++++++++++-------- src/logic/BlocksController.hpp | 4 +--- 2 files changed, 30 insertions(+), 12 deletions(-) diff --git a/src/logic/BlocksController.cpp b/src/logic/BlocksController.cpp index 1e3ad2441..2de34442f 100644 --- a/src/logic/BlocksController.cpp +++ b/src/logic/BlocksController.cpp @@ -16,6 +16,11 @@ #include "world/World.hpp" #include "objects/Player.hpp" #include "objects/Players.hpp" +#include "util/random.hpp" + +#include + +static inline constexpr int CHUNK_RANDOM_TICK_SEGMENTS = 4; BlocksController::BlocksController(const Level& level, Lighting* lighting) : level(level), @@ -143,20 +148,36 @@ void BlocksController::onBlocksTick(int tickid, int parts) { } void BlocksController::randomTick( - const Chunk& chunk, int segments, const ContentIndices* indices + const Chunk& chunk, const ContentIndices* indices ) { + const int segments = CHUNK_RANDOM_TICK_SEGMENTS; const int segheight = CHUNK_H / segments; + static std::array randomPattern; + static bool randomPatternInitialized = false; + if (!randomPatternInitialized) { + randomPatternInitialized = true; + for (int i = 0; i < randomPattern.size(); i++) { + randomPattern[i] = i; + } + auto randomDevice = std::random_device{}; + auto randomEngine = + util::seeded_random_engine(randomDevice); + std::shuffle(randomPattern.begin(), randomPattern.end(), randomEngine); + } + for (int s = 0; s < segments; s++) { - for (int i = 0; i < 4; i++) { + int repetions = 4; + for (int i = 0; i < repetions; i++) { int segmentY = s * segheight; - if (segmentY > chunk.top) { + if (segmentY > chunk.top) { break; } - int bx = random.rand() % CHUNK_W; - int by = random.rand() % segheight + segmentY; - int bz = random.rand() % CHUNK_D; - const voxel& vox = chunk.voxels[vox_index(bx, by, bz)]; + size_t index = randomPattern[(s * repetions + i + randomTickId) % randomPattern.size()]; + int bx = index % CHUNK_W; + int bz = (index / CHUNK_W) % CHUNK_D; + int by = (index / (CHUNK_W * CHUNK_D)) + segmentY; + const voxel& vox = chunk.voxels[index + segmentY * CHUNK_W * CHUNK_D]; auto& block = indices->blocks.require(vox.id); if (block.rt.funcsset.randupdate) { scripting::random_update_block( @@ -177,7 +198,6 @@ void BlocksController::randomTick(int tickid, int parts, uint padding) { const auto& chunks = *player->chunks; int width = chunks.getWidth(); int height = chunks.getHeight(); - int segments = 4; for (uint z = padding; z < height - padding; z++) { for (uint x = padding; x < width - padding; x++) { @@ -193,7 +213,7 @@ void BlocksController::randomTick(int tickid, int parts, uint padding) { continue; } chunk->lastRandomTickId = randomTickId; - randomTick(*chunk, segments, indices); + randomTick(*chunk, indices); } } } diff --git a/src/logic/BlocksController.hpp b/src/logic/BlocksController.hpp index ed6ebca5b..35461f349 100644 --- a/src/logic/BlocksController.hpp +++ b/src/logic/BlocksController.hpp @@ -47,9 +47,7 @@ public: ); void update(float delta, uint padding); - void randomTick( - const Chunk& chunk, int segments, const ContentIndices* indices - ); + void randomTick(const Chunk& chunk, const ContentIndices* indices); void randomTick(int tickid, int parts, uint padding); void onBlocksTick(int tickid, int parts); int64_t createBlockInventory(int x, int y, int z); From a550c765ef95ef86db0ed7ed9f59ab729f8f2dc0 Mon Sep 17 00:00:00 2001 From: MihailRis Date: Fri, 27 Feb 2026 23:31:14 +0300 Subject: [PATCH 3/8] cleanup --- src/logic/BlocksController.hpp | 2 -- 1 file changed, 2 deletions(-) diff --git a/src/logic/BlocksController.hpp b/src/logic/BlocksController.hpp index 35461f349..afd3f59f4 100644 --- a/src/logic/BlocksController.hpp +++ b/src/logic/BlocksController.hpp @@ -3,7 +3,6 @@ #include #include -#include "maths/fastmaths.hpp" #include "typedefs.hpp" #include "util/Clock.hpp" #include "voxels/voxel.hpp" @@ -31,7 +30,6 @@ class BlocksController { util::Clock randTickClock; util::Clock blocksTickClock; util::Clock worldTickClock; - FastRandom random {}; std::vector blockInteractionCallbacks; uint64_t randomTickId = 0; public: From 6c15407530b146441dd4402ec8a1c1064430e7a5 Mon Sep 17 00:00:00 2001 From: MihailRis Date: Sat, 28 Feb 2026 00:02:11 +0300 Subject: [PATCH 4/8] stabilise buggy alFilterf --- src/audio/AL/ALAudio.cpp | 110 +++++++++++++++--------------- src/graphics/render/Decorator.cpp | 41 ++++++----- src/graphics/render/Decorator.hpp | 2 + 3 files changed, 79 insertions(+), 74 deletions(-) diff --git a/src/audio/AL/ALAudio.cpp b/src/audio/AL/ALAudio.cpp index d05ccce58..527fc7c71 100644 --- a/src/audio/AL/ALAudio.cpp +++ b/src/audio/AL/ALAudio.cpp @@ -47,6 +47,7 @@ static LPALDELETEEFFECTS alDeleteEffects = nullptr; static LPALISEFFECT alIsEffect = nullptr; static LPALEFFECTI alEffecti = nullptr; static LPALEFFECTF alEffectf = nullptr; +static LPALGETEFFECTF alGetEffectf = nullptr; static LPALGENFILTERS alGenFilters = nullptr; static LPALDELETEFILTERS alDeleteFilters = nullptr; static LPALISFILTER alIsFilter = nullptr; @@ -562,6 +563,7 @@ static bool request_efx_ext_functions() { && get_proc_address("alIsEffect", alIsEffect) && get_proc_address("alEffecti", alEffecti) && get_proc_address("alEffectf", alEffectf) + && get_proc_address("alGetEffectf", alGetEffectf) && get_proc_address("alGenFilters", alGenFilters) && get_proc_address("alDeleteFilters", alDeleteFilters) && get_proc_address("alIsFilter", alIsFilter) @@ -799,77 +801,73 @@ void ALAudio::setAcoustics(Acoustics acoustics) { alAuxiliaryEffectSloti(effectSlots[0], AL_EFFECTSLOT_EFFECT, 0); return; } + + auto setEffectValue = [](int effect, ALenum param, float value, float min, float max) { + const float smoothFactor = 0.5f; + value = glm::clamp(value, min, max); + float prevValue = 0.0f; + alGetEffectf(effect, param, &prevValue); + AL_CHECK(alEffectf( + effect, + param, + glm::clamp( + prevValue * (1.0f - smoothFactor) + value * smoothFactor, + min, + max + ) + )); + }; + int reverbEffect = effects[REVERB_EFFECT]; - AL_CHECK(alEffectf( + setEffectValue( reverbEffect, AL_REVERB_GAIN, - glm::clamp(glm::min(acoustics.reverbGain, 0.8f) * + acoustics.reverbGain * (1.0f - glm::min(1.0f, acoustics.reverbAbsorption)), - AL_REVERB_MIN_GAIN, - AL_REVERB_MAX_GAIN) - )); - AL_CHECK(alEffectf( + AL_REVERB_MIN_GAIN, + AL_REVERB_MAX_GAIN + ); + setEffectValue( reverbEffect, AL_REVERB_REFLECTIONS_DELAY, - glm::clamp( - acoustics.reverbReflectionsDelay, - AL_REVERB_MIN_REFLECTIONS_DELAY, - AL_REVERB_MAX_REFLECTIONS_DELAY - ) - )); - AL_CHECK(alEffectf( + acoustics.reverbReflectionsDelay, + AL_REVERB_MIN_REFLECTIONS_DELAY, + AL_REVERB_MAX_REFLECTIONS_DELAY + ); + setEffectValue( reverbEffect, AL_REVERB_LATE_REVERB_DELAY, - glm::clamp( - acoustics.reverbLateReflectionsDelay, - AL_REVERB_MIN_LATE_REVERB_DELAY, - AL_REVERB_MAX_LATE_REVERB_DELAY - ) - )); - AL_CHECK(alEffectf( + acoustics.reverbLateReflectionsDelay, + AL_REVERB_MIN_LATE_REVERB_DELAY, + AL_REVERB_MAX_LATE_REVERB_DELAY + ); + setEffectValue( reverbEffect, AL_REVERB_DECAY_TIME, - glm::clamp( - acoustics.reverbDecayTime, - AL_REVERB_MIN_DECAY_TIME, - AL_REVERB_MAX_DECAY_TIME - ) - )); - AL_CHECK(alEffectf( + acoustics.reverbDecayTime, + AL_REVERB_MIN_DECAY_TIME, + AL_REVERB_MAX_DECAY_TIME + ); + setEffectValue( reverbEffect, AL_REVERB_ROOM_ROLLOFF_FACTOR, - glm::clamp( - acoustics.reverbRoomRolloff, - AL_REVERB_MIN_ROOM_ROLLOFF_FACTOR, - AL_REVERB_MAX_ROOM_ROLLOFF_FACTOR - ) - )); - AL_CHECK(alEffectf( + acoustics.reverbRoomRolloff, + AL_REVERB_MIN_ROOM_ROLLOFF_FACTOR, + AL_REVERB_MAX_ROOM_ROLLOFF_FACTOR + ); + setEffectValue( reverbEffect, AL_REVERB_REFLECTIONS_GAIN, - glm::clamp( - glm::pow(acoustics.reverbGain, 2.0f), - AL_REVERB_MIN_REFLECTIONS_GAIN, - AL_REVERB_MAX_REFLECTIONS_GAIN - ) - )); - AL_CHECK(alEffectf( + glm::pow(acoustics.reverbGain, 2.0f), + AL_REVERB_MIN_REFLECTIONS_GAIN, + AL_REVERB_MAX_REFLECTIONS_GAIN + ); + setEffectValue( reverbEffect, AL_REVERB_LATE_REVERB_GAIN, - glm::clamp( - glm::pow(acoustics.reverbGain, 2.0f), - AL_REVERB_MIN_LATE_REVERB_GAIN, - AL_REVERB_MAX_LATE_REVERB_GAIN - ) - )); - AL_CHECK(alEffectf( - reverbEffect, - AL_REVERB_DECAY_HFRATIO, - glm::clamp( - 1.0f - acoustics.reverbAbsorption, - AL_REVERB_MIN_DECAY_HFRATIO, - AL_REVERB_MAX_DECAY_HFRATIO - ) - )); + glm::pow(acoustics.reverbGain, 2.0f), + AL_REVERB_MIN_LATE_REVERB_GAIN, + AL_REVERB_MAX_LATE_REVERB_GAIN + ); alAuxiliaryEffectSloti(effectSlots[0], AL_EFFECTSLOT_EFFECT, reverbEffect); } diff --git a/src/graphics/render/Decorator.cpp b/src/graphics/render/Decorator.cpp index 0b1bcaddb..80291194e 100644 --- a/src/graphics/render/Decorator.cpp +++ b/src/graphics/render/Decorator.cpp @@ -1,29 +1,30 @@ #include "Decorator.hpp" -#include "ParticlesRenderer.hpp" -#include "WorldRenderer.hpp" -#include "TextsRenderer.hpp" -#include "TextNote.hpp" -#include "assets/Assets.hpp" #include "assets/assets_util.hpp" +#include "assets/Assets.hpp" +#include "audio/audio.hpp" #include "content/Content.hpp" -#include "voxels/Chunks.hpp" -#include "voxels/Chunk.hpp" -#include "voxels/Block.hpp" -#include "world/Level.hpp" -#include "window/Camera.hpp" -#include "objects/Player.hpp" -#include "objects/Players.hpp" -#include "objects/Entities.hpp" -#include "objects/Entity.hpp" -#include "logic/LevelController.hpp" -#include "util/stringutil.hpp" +#include "debug/Logger.hpp" #include "engine/Engine.hpp" #include "engine/EnginePaths.hpp" #include "io/io.hpp" -#include "audio/audio.hpp" +#include "logic/LevelController.hpp" #include "maths/util.hpp" -#include "debug/Logger.hpp" +#include "objects/Entities.hpp" +#include "objects/Entity.hpp" +#include "objects/Player.hpp" +#include "objects/Players.hpp" +#include "ParticlesRenderer.hpp" +#include "settings.hpp" +#include "TextNote.hpp" +#include "TextsRenderer.hpp" +#include "util/stringutil.hpp" +#include "voxels/Block.hpp" +#include "voxels/Chunk.hpp" +#include "voxels/Chunks.hpp" +#include "window/Camera.hpp" +#include "world/Level.hpp" +#include "WorldRenderer.hpp" namespace fs = std::filesystem; @@ -48,6 +49,7 @@ Decorator::Decorator( ) : level(*controller.getLevel()), assets(assets), + settings(engine.getSettings()), player(player), renderer(renderer) { controller.getBlocksController()->listenBlockInteraction( @@ -90,6 +92,9 @@ void Decorator::addParticles(const Block& def, const glm::ivec3& pos) { } void Decorator::updateAcoustics(const Camera& camera) { + if (!settings.audio.acousticEffects.get()) { + return; + } audio::Acoustics acoustics {}; util::PseudoRandom random(34621U); diff --git a/src/graphics/render/Decorator.hpp b/src/graphics/render/Decorator.hpp index 4fe52c50a..cb89dfc37 100644 --- a/src/graphics/render/Decorator.hpp +++ b/src/graphics/render/Decorator.hpp @@ -20,10 +20,12 @@ class LevelController; class WorldRenderer; struct Weather; struct WeatherPreset; +struct EngineSettings; class Decorator { const Level& level; const Assets& assets; + const EngineSettings& settings; Player& player; WorldRenderer& renderer; std::unordered_map blockEmitters; From fc04284b34d5dfc8afd008933b61644dda6b73c6 Mon Sep 17 00:00:00 2001 From: MihailRis Date: Sat, 28 Feb 2026 03:01:37 +0300 Subject: [PATCH 5/8] fix fatal exception caused by empty skeleton model texture name --- src/graphics/render/ModelBatch.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/graphics/render/ModelBatch.cpp b/src/graphics/render/ModelBatch.cpp index cefe94ac1..35e891aff 100644 --- a/src/graphics/render/ModelBatch.cpp +++ b/src/graphics/render/ModelBatch.cpp @@ -135,7 +135,7 @@ void ModelBatch::setLightsOffset(const glm::vec3& offset) { void ModelBatch::setTexture(const std::string& name, const texture_names_map* varTextures) { - if (varTextures && name.at(0) == '$') { + if (varTextures && !name.empty() && name.at(0) == '$') { const auto& found = varTextures->find(name); if (found == varTextures->end()) { return batch->setTexture(nullptr); From 8c72e3ab4bbd1dbdf3c36601b01b94e22c93e342 Mon Sep 17 00:00:00 2001 From: MihailRis Date: Sun, 1 Mar 2026 14:57:32 +0300 Subject: [PATCH 6/8] add 'obj' format support to assets.parse_model --- src/logic/scripting/lua/libs/libassets.cpp | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) diff --git a/src/logic/scripting/lua/libs/libassets.cpp b/src/logic/scripting/lua/libs/libassets.cpp index fa0b51cdb..a9691038e 100644 --- a/src/logic/scripting/lua/libs/libassets.cpp +++ b/src/logic/scripting/lua/libs/libassets.cpp @@ -1,16 +1,17 @@ #include "api_lua.hpp" +#include "../usertypes/lua_type_canvas.hpp" #include "assets/Assets.hpp" #include "assets/AssetsLoader.hpp" +#include "coders/obj.hpp" #include "coders/png.hpp" #include "coders/vcm.hpp" #include "debug/Logger.hpp" #include "engine/Engine.hpp" #include "graphics/commons/Model.hpp" -#include "graphics/core/Texture.hpp" #include "graphics/core/Atlas.hpp" +#include "graphics/core/Texture.hpp" #include "util/Buffer.hpp" -#include "../usertypes/lua_type_canvas.hpp" using namespace scripting; @@ -76,6 +77,11 @@ static int l_parse_model(lua::State* L) { skeletonName = lua::require_string(L, 4); } + if (format == "obj") { + assets.store(obj::parse(name, string), name); + return 0; + } + if (format != "xml" && format != "vcm") { throw std::runtime_error( "unknown format " + util::quote(std::string(format)) From bd1ce0fa481e783adbba368b222b36d28458f54f Mon Sep 17 00:00:00 2001 From: MihailRis Date: Sun, 1 Mar 2026 18:13:53 +0300 Subject: [PATCH 7/8] add doc/en/vcm.md --- doc/en/main-page.md | 1 + doc/en/vcm.md | 101 ++++++++++++++++++++++++++++++++++++++++++++ doc/ru/main-page.md | 2 +- 3 files changed, 103 insertions(+), 1 deletion(-) create mode 100644 doc/en/vcm.md diff --git a/doc/en/main-page.md b/doc/en/main-page.md index 57a5b25d8..5bb2d8f2d 100644 --- a/doc/en/main-page.md +++ b/doc/en/main-page.md @@ -21,5 +21,6 @@ Documentation for 0.31. - [Rigging](rigging.md) - [Scripting](scripting.md) - [Text styles](text-styles.md) +- [VCM models format](vcm.md) - [World generator engine](world-generator.md) - [XML UI building](xml-ui-layouts.md) diff --git a/doc/en/vcm.md b/doc/en/vcm.md new file mode 100644 index 000000000..d384bb7d4 --- /dev/null +++ b/doc/en/vcm.md @@ -0,0 +1,101 @@ +# VCM + +A text format for describing 3D models, replacing the deprecated `model-primitives` property. + +Syntax: + +``` +@primitive attribute (value1, value2,...) attribute2 "value3" { + @inner_primitive ... +} +``` + +Same structure in XML: + +```xml + + + +``` + +Unlike XML, the root can contain multiple elements. + +Currently, there are three types of primitives: `tri`, `box`, `rect` and `part` (describes a part of a primitive, such as the side of a cube). + +> [!NOTE] +> By default, texture coordinates are determined by the dimensions of the primitives. +> For sizes greater than 1.0, the result is undefined and may change in future updates. +> Use `region` or `region-scale` for manual adjustments. + +## Primitives + +### `tri` Properties + +This primitive describes a triangle. + +- `a` - Point A. Example: `a (0,0,0)` +- `b` - Point B. Example: `b (1,0,0)` +- `c` - Point C. Example: `c (1,1,0)` +- `uv` - Normalized texture coordinates of the points (6 numbers, 2 per point). Example: `uv (0,0,1,0,1)` +- `texture` - The texture to display. Default: `$0`. Example: `texture "blocks:sand"` +- `region` - UV region within the selected texture, defined by the positions of opposite corners of a square of normalized texture coordinates. Example: `region (0,0,1,1)` +- `region-scale` - multiplier vector for the UV region. Example: `region-scale (0.5,1)` +- `shading` - determines whether shading is enabled on the primitive. Example: `shading off` + +By default, texture coordinates are not affected by shape or size, unlike other primitives. + +### `rect` Properties + +This primitive describes a parallelogram using the right and up vectors. + +- `from` - the origin of the primitive. Example: `from (0,0.5,0.125)` +- `right` - the X vector, which also determines the width of the primitive. Example: `right (1,0,0)` +- `up` - the Y vector, which also determines the primitive's height. Example: `up (0,1,0)` +- `texture` - the texture to display. Default: `$0`. Example: `texture "blocks:sand"` +- `region` - the UV region within the selected texture, defined by the positions of opposite corners. Example: `region (0,0,1,1)` +- `region-scale` - the multiplier vector for the automatically selected UV region. Example: `region-scale (0.5,1)` +- `shading` - determines whether shading is enabled on the primitive. Example: `shading off` +- `flip` - flips the UV region horizontally or vertically. Example: `flip v` + +### `box` Properties + +This primitive describes a rectangular parallelepiped. + +- `from` - the primitive's origin. Example: `from (0,0,0)` +- `to` - the point opposite the origin. Example: `to (1,1,1)` +- `origin` - the point relative to which the rotation will be applied. Default: the center of the primitive. Example: `origin (0.5,0.5,0.5)` +- `rotate` - rotation around the (x,y,z) axes in degrees, or a quaternion (x,y,z,w). Example: `rotate (45,0,0)` or `rotate (0.3826834, 0, 0, 0.9238795)` +- `texture` - the default texture to display for all sides. +- `shading` determines whether shading is enabled on the primitive. Example: `shading off` +- `delete` deletes sides by name (top, bottom, east, west, north, south) + +### `part` properties (nested in `box`) + +This primitive describes the properties of the sides of a rectangular parallelepiped with the specified tags (top/bottom/north/south/east/west). + +- `tags` - determines which side the properties will be applied to. Example: `tags (top,bottom)` +- `texture` - the texture to display. Default: `$side_index`. +- `region` - the UV region within the selected texture, defined by the positions of opposite corners. Example: `region (0,0,1,1)` +- `region-scale` is a multiplier vector for the automatically selected UV region. Example: `region-scale (0.5,1)` + +## Skeleton + +VCM can describe the [skeleton](rigging.md) of a model. The `@bone` element is used for this. + +There are two types of bones: +- unnamed - used only for transformations on inner primitives and not included in the final skeleton. +- named - will be included in the final skeleton. The name is specified via the `name` attribute. + +The main bone (`root`) is created automatically for the entire model. +If bones are explicitly specified, the model will be divided into several parts named as `model_name.bone_name`. +Since the model is an asset and has no prefix, the loaded skeleton receives the model name, also without a prefix. +The loaded skeleton can be used in the [entity](entity-properties.md#skeleton-name) via the `skeleton-name` property. + +In the `pack/preload.json` list, if `"squash": true` is specified, the vcm will be loaded as a single model, without a skeleton. + +### `bone` Properties + +- `name` - The bone name. If omitted, the bone will be "dissolved" and will not be included in the final skeleton, but transformations will be applied. +- `move` - Moves nested elements. +- `scale` - Scales nested elements. Applied before moving. +- `rotate` - Rotates nested elements around the (x, y, z) axes in degrees, or as a quaternion (x, y, z, w). Example: `rotate (45,0,0)` or `rotate (0.3826834, 0, 0, 0.9238795)` diff --git a/doc/ru/main-page.md b/doc/ru/main-page.md index c1773d5d1..517dcdfad 100644 --- a/doc/ru/main-page.md +++ b/doc/ru/main-page.md @@ -22,5 +22,5 @@ - [Свойства сущностей](entity-properties.md) - [Скриптинг](scripting.md) - [Стили текста](text-styles.md) -- [Частицы](particles.md) - [Формат моделей VCM](vcm.md) +- [Частицы](particles.md) From 9eb85bd2dd3efa4eb21388ee75464b92b1ebe1be Mon Sep 17 00:00:00 2001 From: MihailRis Date: Sun, 1 Mar 2026 20:57:41 +0300 Subject: [PATCH 8/8] fix: ChunksRenderer mostly ignores background workers --- src/graphics/render/ChunksRenderer.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/graphics/render/ChunksRenderer.cpp b/src/graphics/render/ChunksRenderer.cpp index 8498091c9..57603d63e 100644 --- a/src/graphics/render/ChunksRenderer.cpp +++ b/src/graphics/render/ChunksRenderer.cpp @@ -203,7 +203,7 @@ const Mesh* ChunksRenderer::retrieveChunk( ); auto mesh = getOrRender( chunk, - distance < CHUNK_W * 1.5f * 10.0f, + distance < CHUNK_W * 1.5f, distance > CHUNK_W * settings.chunks.loadDistance.get() * 0.5 ); if (mesh == nullptr) {