I’ve been trying to write a chunk loading system for a game I’m making in Godot. For that I want to use threads to load multiple chunks at once.
<code>int threadsToUtilise = 7;
Thread[] threads; // array to store threads
ArrayMesh[] threadResults; // array to save meshes returned by WorldLoader.GetChunk();
Vector3I[] chunkIDsLoading; // array to save position (Vector3I) of the chunk thread[i] is loading; serves to later position the mesh at the right position
// the arrays are initialised with a size of threadsToUtilise (7)
List<Vector3I> chunksToLoad = new(); // List to store positions of all chunks that still need to be loaded in
public override void _Process(double delta) // method runs every frame
{
for (var i = 0; i < threadsToUtilize; i++)
{
if (threads[i] == null){
if (chunksToLoad.Count == 0) break;
threads[i] = new Thread(() => { threadResults[i] = WorldLoader.GetChunk(chunksToLoad[0], false); });
threads[i].Start();
chunkIDsLoading[i] = chunksToLoad[0];
chunksToLoad.RemoveAt(0);
}
else if (!threads[i].IsAlive) {
if (threadResults[i] != null) {
// implement some stuff
}
threads[i] = null;
threadResults[i] = null;
chunkIDsLoading[i] = Vector3I.Zero;
}
}
}
</code>
<code>int threadsToUtilise = 7;
Thread[] threads; // array to store threads
ArrayMesh[] threadResults; // array to save meshes returned by WorldLoader.GetChunk();
Vector3I[] chunkIDsLoading; // array to save position (Vector3I) of the chunk thread[i] is loading; serves to later position the mesh at the right position
// the arrays are initialised with a size of threadsToUtilise (7)
List<Vector3I> chunksToLoad = new(); // List to store positions of all chunks that still need to be loaded in
public override void _Process(double delta) // method runs every frame
{
for (var i = 0; i < threadsToUtilize; i++)
{
if (threads[i] == null){
if (chunksToLoad.Count == 0) break;
threads[i] = new Thread(() => { threadResults[i] = WorldLoader.GetChunk(chunksToLoad[0], false); });
threads[i].Start();
chunkIDsLoading[i] = chunksToLoad[0];
chunksToLoad.RemoveAt(0);
}
else if (!threads[i].IsAlive) {
if (threadResults[i] != null) {
// implement some stuff
}
threads[i] = null;
threadResults[i] = null;
chunkIDsLoading[i] = Vector3I.Zero;
}
}
}
</code>
int threadsToUtilise = 7;
Thread[] threads; // array to store threads
ArrayMesh[] threadResults; // array to save meshes returned by WorldLoader.GetChunk();
Vector3I[] chunkIDsLoading; // array to save position (Vector3I) of the chunk thread[i] is loading; serves to later position the mesh at the right position
// the arrays are initialised with a size of threadsToUtilise (7)
List<Vector3I> chunksToLoad = new(); // List to store positions of all chunks that still need to be loaded in
public override void _Process(double delta) // method runs every frame
{
for (var i = 0; i < threadsToUtilize; i++)
{
if (threads[i] == null){
if (chunksToLoad.Count == 0) break;
threads[i] = new Thread(() => { threadResults[i] = WorldLoader.GetChunk(chunksToLoad[0], false); });
threads[i].Start();
chunkIDsLoading[i] = chunksToLoad[0];
chunksToLoad.RemoveAt(0);
}
else if (!threads[i].IsAlive) {
if (threadResults[i] != null) {
// implement some stuff
}
threads[i] = null;
threadResults[i] = null;
chunkIDsLoading[i] = Vector3I.Zero;
}
}
}
Generally I wanted to load a chunk and as soon as the mesh is created, implement it. It more or less works but there are two main problems:
- Sometimes, very randomly, get an error: Index was outside the bounds of the array.
This happens in the line, where the thread is created and threadResults[i] = WorldLoader.GetChunk… is assigned. But that shouldn’t be the case, because the arrays are created with the size of threadsToUtilise and the loop is depending on it, too. - Sometimes the chunks are placed correctly, another time they are offset from the position they are supposed to be in (about 1 or 2 chunkpositions too early/late). The method creating the meshes works fine, I did test that one.
New contributor
RandomFussel is a new contributor to this site. Take care in asking for clarification, commenting, and answering.
Check out our Code of Conduct.
0