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.
This commit is contained in:
2026-06-25 21:57:55 +08:00
parent db10d30dc2
commit 4631bbe6d6
5 changed files with 27 additions and 6 deletions

View File

@@ -86,7 +86,7 @@ private:
// player is tow block tall, the pos is the lower pos // player is tow block tall, the pos is the lower pos
glm::vec3 m_player_pos{0.0f, 255.0f, 0.0f}; 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_front{0, 0, -1};
glm::vec3 m_right{0, 0, 0}; glm::vec3 m_right{0, 0, 0};
@@ -112,5 +112,6 @@ private:
void update_x_move(glm::vec3& player_pos); void update_x_move(glm::vec3& player_pos);
void update_y_move(glm::vec3& player_pos); void update_y_move(glm::vec3& player_pos);
void update_z_move(glm::vec3& player_pos); void update_z_move(glm::vec3& player_pos);
void update_player_chunk();
}; };
} // namespace Cubed } // namespace Cubed

View File

@@ -40,7 +40,7 @@ public:
void stop_client_thread(); void stop_client_thread();
void hot_reload(); void hot_reload();
void request_chunk();
std::vector<glm::vec4>& planes(); std::vector<glm::vec4>& planes();
std::vector<ChunkRenderSnapshot>& render_snapshots(); std::vector<ChunkRenderSnapshot>& render_snapshots();
glm::vec3 sunlight_dir() const; glm::vec3 sunlight_dir() const;
@@ -76,6 +76,7 @@ private:
std::atomic<int> m_rendering_distance{24}; std::atomic<int> m_rendering_distance{24};
std::atomic<TickType> m_game_ticks{0}; std::atomic<TickType> m_game_ticks{0};
std::atomic<TickType> m_day_tick{6000}; std::atomic<TickType> m_day_tick{6000};
std::atomic<bool> m_requesting_chunk{false};
std::shared_ptr<NetworkClient> m_client; std::shared_ptr<NetworkClient> m_client;
void client_run(std::stop_token token); void client_run(std::stop_token token);
@@ -83,7 +84,6 @@ private:
void report_player_pos(); void report_player_pos();
void request_chunk();
void set_block(const glm::ivec3& pos, unsigned id); void set_block(const glm::ivec3& pos, unsigned id);
}; };
} // namespace Cubed } // namespace Cubed

View File

@@ -390,6 +390,7 @@ void ClientPlayer::update_move(float delta_time) {
std::lock_guard lock(m_player_pos_mutex); std::lock_guard lock(m_player_pos_mutex);
m_player_pos = player_pos; m_player_pos = player_pos;
} }
update_player_chunk();
} }
void ClientPlayer::update_x_move(glm::vec3& player_pos) { 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) { void ClientPlayer::update_scroll(double yoffset) {
if (m_game_mode == SPECTATOR) { if (m_game_mode == SPECTATOR) {
if (yoffset > 0) { if (yoffset > 0) {

View File

@@ -197,7 +197,6 @@ void ClientWorld::init(std::string_view player_name,
m_client = client; m_client = client;
// timer // timer
register_timer("player_pos", 2, [this]() { report_player_pos(); }); register_timer("player_pos", 2, [this]() { report_player_pos(); });
// register_timer("chunk_request", 20, [this]() { request_chunk(); });
LoginReq req; LoginReq req;
req.set_name(m_player.get_name()); req.set_name(m_player.get_name());
while (!client->is_connected()) { while (!client->is_connected()) {
@@ -261,6 +260,10 @@ void ClientWorld::report_player_pos() {
} }
void ClientWorld::request_chunk() { void ClientWorld::request_chunk() {
if (m_requesting_chunk.exchange(true)) {
Logger::warn("It is requesting new chunk!");
return;
}
ChunkPosSet required_chunks; ChunkPosSet required_chunks;
glm::vec3 player_pos = m_player.get_player_pos(); glm::vec3 player_pos = m_player.get_player_pos();
@@ -310,6 +313,7 @@ void ClientWorld::request_chunk() {
p->set_z(pos.z); p->set_z(pos.z);
m_client->send(make_packet(req)); m_client->send(make_packet(req));
} }
m_requesting_chunk = false;
} }
void ClientWorld::receive_chunk(const ChunkDataRsp& data) { 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); std::lock_guard lock(m_pending_queue_mutex);
m_pending_queue.emplace_back(std::move(chunk)); m_pending_queue.emplace_back(std::move(chunk));
Logger::info("ClientWorld Add a new pending chunk");
} }
} }

View File

@@ -80,7 +80,8 @@ asio::awaitable<void> NetworkClient::read_loop() {
} break; } break;
case to_num(PacketEnum::CHUNK_DATA_RSP): { case to_num(PacketEnum::CHUNK_DATA_RSP): {
ChunkDataRsp 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())) { if (rsp.ParseFromArray(body_data.data(), body_data.size())) {
m_world.receive_chunk(rsp); m_world.receive_chunk(rsp);
} }