From 4631bbe6d697463c20ae80c03bf0dcae3ea4cb59 Mon Sep 17 00:00:00 2001 From: zhenyan121 <3367366583@qq.com> Date: Thu, 25 Jun 2026 21:57:55 +0800 Subject: [PATCH] feat(gameplay): optimize chunk request with player chunk tracking Add `update_player_chunk()` method to `ClientPlayer` that triggers a chunk request when the player moves more than 2 chunks away from the last recorded chunk. Introduce an atomic `m_requesting_chunk` flag in `ClientWorld` to prevent concurrent requests. Rename `m_player_chunk_pos` to `m_last_chunk_pos` for clarity. --- include/Cubed/gameplay/client_player.hpp | 3 ++- include/Cubed/gameplay/client_world.hpp | 4 ++-- src/gameplay/client_player.cpp | 16 ++++++++++++++++ src/gameplay/client_world.cpp | 7 +++++-- src/gameplay/network_client.cpp | 3 ++- 5 files changed, 27 insertions(+), 6 deletions(-) diff --git a/include/Cubed/gameplay/client_player.hpp b/include/Cubed/gameplay/client_player.hpp index b7ae386..5bfce48 100644 --- a/include/Cubed/gameplay/client_player.hpp +++ b/include/Cubed/gameplay/client_player.hpp @@ -86,7 +86,7 @@ private: // player is tow block tall, the pos is the lower pos glm::vec3 m_player_pos{0.0f, 255.0f, 0.0f}; - ChunkPos m_player_chunk_pos{0, 0}; + ChunkPos m_last_chunk_pos{0, 0}; glm::vec3 m_front{0, 0, -1}; glm::vec3 m_right{0, 0, 0}; @@ -112,5 +112,6 @@ private: void update_x_move(glm::vec3& player_pos); void update_y_move(glm::vec3& player_pos); void update_z_move(glm::vec3& player_pos); + void update_player_chunk(); }; } // namespace Cubed diff --git a/include/Cubed/gameplay/client_world.hpp b/include/Cubed/gameplay/client_world.hpp index 9cfce46..6ff0111 100644 --- a/include/Cubed/gameplay/client_world.hpp +++ b/include/Cubed/gameplay/client_world.hpp @@ -40,7 +40,7 @@ public: void stop_client_thread(); void hot_reload(); - + void request_chunk(); std::vector& planes(); std::vector& render_snapshots(); glm::vec3 sunlight_dir() const; @@ -76,6 +76,7 @@ private: std::atomic m_rendering_distance{24}; std::atomic m_game_ticks{0}; std::atomic m_day_tick{6000}; + std::atomic m_requesting_chunk{false}; std::shared_ptr m_client; void client_run(std::stop_token token); @@ -83,7 +84,6 @@ private: void report_player_pos(); - void request_chunk(); void set_block(const glm::ivec3& pos, unsigned id); }; } // namespace Cubed diff --git a/src/gameplay/client_player.cpp b/src/gameplay/client_player.cpp index 2aa0ebf..0118174 100644 --- a/src/gameplay/client_player.cpp +++ b/src/gameplay/client_player.cpp @@ -390,6 +390,7 @@ void ClientPlayer::update_move(float delta_time) { std::lock_guard lock(m_player_pos_mutex); m_player_pos = player_pos; } + update_player_chunk(); } void ClientPlayer::update_x_move(glm::vec3& player_pos) { @@ -498,6 +499,21 @@ void ClientPlayer::update_z_move(glm::vec3& player_pos) { } } +void ClientPlayer::update_player_chunk() { + float x, z; + { + std::shared_lock lock(m_player_pos_mutex); + x = m_player_pos.x; + z = m_player_pos.z; + } + ChunkPos chunk_pos = get_chunk_pos(x, z); + float dist = distance2(chunk_pos, m_last_chunk_pos); + if (dist > 2) { + m_world.request_chunk(); + m_last_chunk_pos = chunk_pos; + } +} + void ClientPlayer::update_scroll(double yoffset) { if (m_game_mode == SPECTATOR) { if (yoffset > 0) { diff --git a/src/gameplay/client_world.cpp b/src/gameplay/client_world.cpp index 9f40bef..28a6eef 100644 --- a/src/gameplay/client_world.cpp +++ b/src/gameplay/client_world.cpp @@ -197,7 +197,6 @@ void ClientWorld::init(std::string_view player_name, m_client = client; // timer register_timer("player_pos", 2, [this]() { report_player_pos(); }); - // register_timer("chunk_request", 20, [this]() { request_chunk(); }); LoginReq req; req.set_name(m_player.get_name()); while (!client->is_connected()) { @@ -261,6 +260,10 @@ void ClientWorld::report_player_pos() { } void ClientWorld::request_chunk() { + if (m_requesting_chunk.exchange(true)) { + Logger::warn("It is requesting new chunk!"); + return; + } ChunkPosSet required_chunks; glm::vec3 player_pos = m_player.get_player_pos(); @@ -310,6 +313,7 @@ void ClientWorld::request_chunk() { p->set_z(pos.z); m_client->send(make_packet(req)); } + m_requesting_chunk = false; } void ClientWorld::receive_chunk(const ChunkDataRsp& data) { @@ -318,7 +322,6 @@ void ClientWorld::receive_chunk(const ChunkDataRsp& data) { { std::lock_guard lock(m_pending_queue_mutex); m_pending_queue.emplace_back(std::move(chunk)); - Logger::info("ClientWorld Add a new pending chunk"); } } diff --git a/src/gameplay/network_client.cpp b/src/gameplay/network_client.cpp index 68febaa..1445a54 100644 --- a/src/gameplay/network_client.cpp +++ b/src/gameplay/network_client.cpp @@ -80,7 +80,8 @@ asio::awaitable NetworkClient::read_loop() { } break; case to_num(PacketEnum::CHUNK_DATA_RSP): { ChunkDataRsp rsp; - Logger::info("Client: Receive Chunk Data rsp"); + Logger::info("Client: Receive Chunk Data rsp, size {}mb", + body_data.size() / 1024.0f / 1024); if (rsp.ParseFromArray(body_data.data(), body_data.size())) { m_world.receive_chunk(rsp); }