Closed ACBob closed 3 years ago
Each client has a 'chunkIndex' which is a 1D array up to RenderDistance³, every server update we increment that and send the chunk at that position.\ I prototyped smth like that but it was fucky and was generating chunks at, I shit you not, Chunk Position 9 Quintillion. Or, 144 quintillion world coords. Obviously something wrong with the weird disconnect from Vectors and WorldPos.
Not sure how expensive it is to send a new chunk for each player every frame, but we can worry about that later!
I'd removed chunk pos entirely, now chunks just have a generic vector.
This works fine and I've got some kind of infinite world setup going, but it leads to some issues in that we start at -2,-2,-2 chunk pos relative to the player, so chunks don't load by the time you get to them - a solution would be to spiral out from the player's chunk pos, making sure that the chunks nearest to the player have the highest priority. This'll be a difficult change.
I've figured out a potential way to load the chunks satisfactorily.\ Spiral!
psuedo-code (could be much better, loosely translated python turtle code)
for (CNetworkPlayer *cl : m_players)
{
if (cl->m_iHorizLoad >= /* horz. dist */ || cl->m_iLoadOppurtunity > m_iTick)
continue;
if (cl->m_iHorizLoadIDX % 3== 0)
{
cl->m_vLoadDir = cl->m_vLoadDir.Rotate(2, 90);
cl->m_iHorizLoad ++;
}
/* Load chunk at position, centred vertically before going up and then down */
cl->m_vLoadPosition = m_vLoadPosition + cl_m_vLoadDir;
}
I ended up with a loading algorithm along the lines of
for ( CNetworkPlayer *c : m_players )
{
// Update chunk pos
// Unfortunate name
CVector cP = ( c->m_pEntity->m_vPosition / CVector( CHUNKSIZE_X, CHUNKSIZE_Y, CHUNKSIZE_Z ) ).Floor();
if ( cP != c->m_vChunkPos )
{
c->m_iLoadedChunkIDX = 0;
c->m_iNextChunkLoadTick = m_iCurrentTick;
c->m_iLoadedChunkLength = 0;
c->m_iLoadedChunkTarget = 0;
}
c->m_vChunkPos = cP;
if ( c->m_iNextChunkLoadTick < m_iCurrentTick )
c->m_iNextChunkLoadTick = m_iCurrentTick + 1;
else
continue;
if (c->m_iLoadedChunkIDX > (c->m_iChunkLoadSizeHorz))
continue;
if (c->m_iLoadedChunkLength >= c->m_iLoadedChunkTarget)
{
if (c->m_iLoadedChunkIDX % 3 == 0)
{
c->m_iLoadedChunkTarget ++;
}
c->m_iChunkDir ++;
if (c->m_iChunkDir >= UP)
c->m_iChunkDir = NORTH;
c->m_iLoadedChunkLength = 0;
}
c->m_vChunkLoadPos = c->m_vChunkLoadPos + DirectionVector[c->m_iChunkDir];
CVector p = c->m_vChunkLoadPos + c->m_vChunkPos;
protocol::SendServerChunkData( c->m_pPeer, &m_world, p );
con_info("%i, %i, %i, %i, %.0f, %.0f, %.0f",
c->m_iLoadedChunkIDX,
c->m_iChunkDir,
c->m_iLoadedChunkLength,
c->m_iLoadedChunkTarget,
c->m_vChunkLoadPos.x,
c->m_vChunkLoadPos.y,
c->m_vChunkLoadPos.z
);
c->m_iLoadedChunkLength ++;
c->m_iLoadedChunkIDX ++;
}
But I couldn't get it to spiral out properly....
Technically resolved, chunk loading just needs to be revised.
Each player up to their render distance (and up to the server's forced render distance) will load chunks around them from the server
Requires #6 ideally so we can see some cool shit and not an empty plane of grass