From 062207e696cfbe382157ece4746e104977b7e2cd Mon Sep 17 00:00:00 2001 From: sfan5 Date: Sat, 1 Mar 2025 00:16:18 +0100 Subject: [PATCH] Enforce minimum client_mapblock_limit depending on view range --- builtin/settingtypes.txt | 4 +++- src/client/client.cpp | 39 +++++++++++++++++++++++++++++++-------- src/client/client.h | 7 +------ 3 files changed, 35 insertions(+), 15 deletions(-) diff --git a/builtin/settingtypes.txt b/builtin/settingtypes.txt index 11aac1d66..2fad0cdef 100644 --- a/builtin/settingtypes.txt +++ b/builtin/settingtypes.txt @@ -1998,7 +1998,9 @@ max_out_chat_queue_size (Maximum size of the outgoing chat queue) int 20 -1 3276 client_unload_unused_data_timeout (Mapblock unload timeout) float 600.0 0.0 # Maximum number of mapblocks for client to be kept in memory. -# Set to -1 for unlimited amount. +# Note that there is an internal dynamic minimum number of blocks that +# won't be deleted, depending on the current view range. +# Set to -1 for no limit. client_mapblock_limit (Mapblock limit) int 7500 -1 2147483647 # Maximum number of blocks that are simultaneously sent per client. diff --git a/src/client/client.cpp b/src/client/client.cpp index 48dc61984..3c7716cbd 100644 --- a/src/client/client.cpp +++ b/src/client/client.cpp @@ -446,20 +446,43 @@ void Client::step(float dtime) /* Run Map's timers and unload unused data */ - const float map_timer_and_unload_dtime = 5.25; + constexpr float map_timer_and_unload_dtime = 5.25f; + constexpr s32 mapblock_limit_enforce_distance = 200; if(m_map_timer_and_unload_interval.step(dtime, map_timer_and_unload_dtime)) { std::vector deleted_blocks; + + // Determine actual block limit to use + const s32 configured_limit = g_settings->getS32("client_mapblock_limit"); + s32 mapblock_limit; + if (configured_limit < 0) { + mapblock_limit = -1; + } else { + s32 view_range = g_settings->getS16("viewing_range"); + // Up to a certain limit we want to guarantee that the client can keep + // a full 360° view loaded in memory without blocks vanishing behind + // the players back. + // We use a sphere volume to approximate this. In practice far less + // blocks will be needed due to occlusion/culling. + float blocks_range = ceilf(std::min(mapblock_limit_enforce_distance, view_range) + / (float) MAP_BLOCKSIZE); + mapblock_limit = (4.f/3.f) * M_PI * powf(blocks_range, 3); + assert(mapblock_limit > 0); + mapblock_limit = std::max(mapblock_limit, configured_limit); + if (mapblock_limit > std::max(configured_limit, m_mapblock_limit_logged)) { + infostream << "Client: using block limit of " << mapblock_limit + << " rather than configured " << configured_limit + << " due to view range." << std::endl; + m_mapblock_limit_logged = mapblock_limit; + } + } + m_env.getMap().timerUpdate(map_timer_and_unload_dtime, std::max(g_settings->getFloat("client_unload_unused_data_timeout"), 0.0f), - g_settings->getS32("client_mapblock_limit"), - &deleted_blocks); + mapblock_limit, &deleted_blocks); - /* - Send info to server - NOTE: This loop is intentionally iterated the way it is. - */ + // Send info to server - std::vector::iterator i = deleted_blocks.begin(); + auto i = deleted_blocks.begin(); std::vector sendlist; for(;;) { if(sendlist.size() == 255 || i == deleted_blocks.end()) { diff --git a/src/client/client.h b/src/client/client.h index ce753ebdf..237dd93b6 100644 --- a/src/client/client.h +++ b/src/client/client.h @@ -486,23 +486,18 @@ private: u8 m_server_ser_ver; // Used version of the protocol with server - // Values smaller than 25 only mean they are smaller than 25, - // and aren't accurate. We simply just don't know, because - // the server didn't send the version back then. // If 0, server init hasn't been received yet. u16 m_proto_ver = 0; bool m_update_wielded_item = false; Inventory *m_inventory_from_server = nullptr; float m_inventory_from_server_age = 0.0f; + s32 m_mapblock_limit_logged = 0; PacketCounter m_packetcounter; // Block mesh animation parameters float m_animation_time = 0.0f; int m_crack_level = -1; v3s16 m_crack_pos; - // 0 <= m_daynight_i < DAYNIGHT_CACHE_COUNT - //s32 m_daynight_i; - //u32 m_daynight_ratio; std::queue m_out_chat_queue; u32 m_last_chat_message_sent; float m_chat_message_allowance = 5.0f;