Streaming PCG data

Hi!

I am working on procedurall generation of maps. I already have quite good results and now I want to add support for multiplayer. Let me describe first how more or less my PCG algorithm works:

  • my world is splitted into terrain chunks and foliage chunks
  • I have an actor component that is responsible for tracking which chunks should be shown for given player
  • I have separate component responsible for managing the chunks data
  • Finally I have actors that consumes generated HeightGrid and produces voxelized mesh from heightmap

The number of bytes per terrain chunk I need to transfer is around ~1kB. With view range set to around 300 [m] I need to transfer around 12000 chunks, that is ~12MB.

I want server to have full controll over the heightgrid. I tried two approaches

  • RPCs → on client I have actor component tracking what chunks to show & requesting data from server. Its replicated counterpart finds proper actor on server, asks it for data and sends it via another RPC. This looks like:

Client_ReceiveChunkData_Implementation(int x, int y, int z, FChunkRawData ChunkData)
{
GroundChunkID iD { .X = x, .Y = y, .Z = z };
AddChunk(iD, ChunkData);
}

Server_RequestChunk_Implementation(int x, int y)
{
auto world = GetWorld();
if (world == nullptr) {
return;
}
auto* gameMode = world->GetAuthGameMode();
if (!gameMode) {
return;
}

auto terrainManager = gameMode->GetTerrainManager();
if (!terrainManager) {
    return;
}

const auto chunks = terrainManager->GetChunksToSpawnInLocation(GroundChunkID2D { .X = x, .Y = y, .Z = 0 });
for (auto& chunk : chunks) {
    auto rawData = terrainManager->GetChunkRawData(chunk);
    Client_ReceiveChunkData(x, y, 0, rawData);
}

}

but this causes error:
LogNet: Warning: Closing connection. Can’t send function ‘Client_ReceiveChunkData’ on ‘ChunksOrchestrator’: Reliable buffer overflow. FieldCache->FieldNetIndex: 2 Max 4. Ch MaxPacket: 1024.

I do not know whether I am doing something wrong, but I can not get over this issue. I tried throttling (queue chunks data, send every ~10ms) but this still seems slow.

I tried also second approach - variable replication.

I replicate my ground chunks actors heightgrids (in compressed format). This seems to work, but its quite slow. When player loads into game I’d like for him to be able to see the map in approximately same time it takes for the server to generate it, but its not that fast. Also with this approach I do not know how to implement the mechanism of waiting for all chunks to load, before spawning in player. Right now my player just spawns in while the chunks are loading (so he drops off map).

Do you have any suggestions?