Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Infinite world #25

Merged
merged 24 commits into from
Jan 22, 2020
Merged

Infinite world #25

merged 24 commits into from
Jan 22, 2020

Conversation

Unarelith
Copy link
Owner

@Unarelith Unarelith commented Jan 15, 2020

The world is currently limited to its compile-time defined size using WORLD_WIDTH, WORLD_HEIGHT and WORLD_DEPTH.

This PR will attempt to make the world completely infinite (see #24), by removing these constants and everything related to it.

Checklist:

  • Get rid of the constants
  • Send spawn area on client connection
  • Wait for all the neighbours to be loaded before generating a chunk mesh
  • Wait for all the neighbours to be loaded before propagating light into a chunk
  • Fix tree generation
  • While server is sending spawn area, block placing is buggy and workbench/furnace doesn't work
  • When another player joins the server, no data is sent to him, fix this
  • Load chunks dynamically depending on player position
  • Fix lag spikes when too many chunks are sent at once
  • Fix furnace crash
  • Fix block blinking
  • Fix last lighting issues
  • Unload chunks when they're too far from the player
  • Review code

@Unarelith
Copy link
Owner Author

Unarelith commented Jan 15, 2020

This first commit got rid of the constants, and fixed everything related to them.

The issue I have now, is related to this:

float ud = 1000.0;
s32 ux = 0;
s32 uy = 0;
s32 uz = 0;
std::vector<std::pair<ClientChunk*, gk::Transform>> chunks;
for(auto &it : m_chunks) {
states.transform = glm::translate(glm::mat4(1.0f),
glm::vec3(it.second->x() * CHUNK_WIDTH,
it.second->y() * CHUNK_HEIGHT,
it.second->z() * CHUNK_DEPTH));
// Is the chunk close enough?
glm::vec4 center = target.getView()->getViewTransform().getMatrix()
* states.transform.getMatrix()
* glm::vec4(CHUNK_WIDTH / 2, CHUNK_HEIGHT / 2, CHUNK_DEPTH / 2, 1);
if(glm::length(center) > (Config::renderDistance + 1) * CHUNK_WIDTH) {
continue;
}
// Is this chunk on the screen?
center = target.getView()->getTransform().getMatrix() * center;
float d = glm::length(center);
center.x /= center.w;
center.y /= center.w;
// If it is behind the camera, don't bother drawing it
if(center.z < -CHUNK_HEIGHT / 2) {
continue;
}
// If it is outside the screen, don't bother drawing it
if(fabsf(center.x) > 1 + fabsf(CHUNK_HEIGHT * 2 / center.w)
|| fabsf(center.y) > 1 + fabsf(CHUNK_HEIGHT * 2 / center.w)) {
continue;
}
// If this chunk is not initialized, skip it
if(!it.second->isInitialized()) {
// But if it is the closest to the camera, mark it for initialization
if(d < ud) {
ud = d;
ux = it.second->x();
uy = it.second->y();
uz = it.second->z();
}
continue;
}
chunks.emplace_back(it.second.get(), states.transform);
}
ClientChunk *chunk = getChunk(ux, uy, uz);
if(ud <= 1000 && (!chunk || !chunk->hasBeenRequested())) {
auto it = m_chunks.emplace(gk::Vector3i(ux, uy, uz), new ClientChunk(ux, uy, uz, m_texture));
it.first->second->setHasBeenRequested(true);
m_client->sendChunkRequest(ux, uy, uz);
DEBUG("Chunk requested at", ux, uy, uz);
}

Because I don't have the chunks vector anymore to be able to get ud, ux, uy, and uz.
I'll think about it more, I'm sure it can be fixed using another method.

@Unarelith
Copy link
Owner Author

Unarelith commented Jan 16, 2020

It is currently working, but:

  1. Too many chunks are sent at once, so it slows down the client for a while
  2. Each loaded chunk will have to update its neighbours, so again, it slows down the mesh building
  3. Light has many issues
  4. Player collisions and block placing are not working

Possible improvements:

  1. No idea yet
  2. Delay chunk building until all surrounding chunks are loaded
  3. Delay light generation/sending until all surrounding chunks are loaded (and probably split chunk data and light data into two packets)
  4. This should be an easy fix, I must have messed up something with the changes I made in ClientWorld

When these problems will be fixed, I'll still need to load/unload chunks accordingly to player position, and to test multiplayer in order to check that everything is fine.

@Unarelith
Copy link
Owner Author

Other issues:

  • Tree generation is messed up if the tree is generated between two chunks
  • Blocks blink when they're placed, and can sometimes disappear

@Unarelith
Copy link
Owner Author

Almost working!

@Unarelith
Copy link
Owner Author

Ready!

@Unarelith Unarelith merged commit 7017ccd into master Jan 22, 2020
@Unarelith Unarelith deleted the infinite_world branch January 22, 2020 00:22
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

1 participant