Basic universe management, generation and simulation flow

This commit is contained in:
Aslan 2026-01-26 10:19:40 -05:00
parent 4c078dbede
commit 78fceeb95e
29 changed files with 664 additions and 29 deletions

View file

@ -1,12 +1,148 @@
using System.Threading;
using System.Threading.Tasks;
using Godot;
public partial class GameManager : Node
{
public override void _Ready()
{
PackedScene shipPrefab = ResourceLoader.Load<PackedScene>("res://prefabs/vessel.tscn");
Node3D shipInstance = shipPrefab.Instantiate<Node3D>();
[Export] Player player;
GetTree().CurrentScene.CallDeferred("add_child", shipInstance);
}
[Export] double closeTickInterval = 1;
[Export] double farTickInterval = 10;
[Export] int maxFarThreads = 16;
public static GameManager Singleton { get; private set; }
public IGenerator Generator { get; private set; }
public Universe GameUniverse { get; private set; }
public Sector CurrentSector { get; private set; }
private double closeTickTimer = 0;
private double farTickTimer = 0;
public override void _Ready()
{
Singleton = this;
Generator = new TestGenerator();
Generator.GenerateUniverse((universe) =>
{
GameUniverse = universe;
CurrentSector = universe.Sectors[1, 1, 1];
});
}
public override void _Process(double delta)
{
closeTickTimer += delta;
farTickTimer += delta;
if (closeTickTimer >= closeTickInterval)
{
SimulateClose(closeTickTimer);
closeTickTimer = 0;
}
if (farTickTimer >= farTickInterval)
{
SimulateFar(farTickTimer);
farTickTimer = 0;
}
}
private void SimulateClose(double delta)
{
Vector3I currentCoordinates = CurrentSector.Coordinates;
Sector[,,] sectors = GameUniverse.Sectors;
int sizeX = sectors.GetLength(0);
int sizeY = sectors.GetLength(1);
int sizeZ = sectors.GetLength(2);
int startX = Mathf.Clamp(currentCoordinates.X - 1, 0, sizeX);
int startY = Mathf.Clamp(currentCoordinates.Y - 1, 0, sizeY);
int startZ = Mathf.Clamp(currentCoordinates.Z - 1, 0, sizeZ);
int endX = Mathf.Clamp(currentCoordinates.X + 1, 0, sizeX);
int endY = Mathf.Clamp(currentCoordinates.Y + 1, 0, sizeY);
int endZ = Mathf.Clamp(currentCoordinates.Z + 1, 0, sizeZ);
for (int x = startX; x <= endX; x++)
{
for (int y = startY; y <= endY; y++)
{
for (int z = startZ; z <= endZ; z++)
{
int taskX = x;
int taskY = y;
int taskZ = z;
Task.Run(() =>
{
sectors[taskX, taskY, taskZ].Simulate(delta);
});
}
}
}
}
private void SimulateFar(double delta)
{
Sector[,,] sectors = GameUniverse.Sectors;
int sizeX = sectors.GetLength(0);
int countX = Mathf.Clamp(sizeX / maxFarThreads, 1, int.MaxValue);
for (int x = 0; x < sizeX; x += countX)
{
double taskDelta = delta;
int taskStartX = x;
int taskCountX = countX;
_ = SimulateFarThreaded(taskDelta, taskStartX, taskCountX);
}
}
private async Task SimulateFarThreaded(double delta, int startX, int countX)
{
Vector3I currentCoordinates = CurrentSector.Coordinates;
Sector[,,] sectors = GameUniverse.Sectors;
int sizeX = sectors.GetLength(0);
int sizeY = sectors.GetLength(1);
int sizeZ = sectors.GetLength(2);
int startSkipX = Mathf.Clamp(currentCoordinates.X - 1, 0, sizeX);
int startSkipY = Mathf.Clamp(currentCoordinates.Y - 1, 0, sizeY);
int startSkipZ = Mathf.Clamp(currentCoordinates.Z - 1, 0, sizeZ);
int endSkipX = Mathf.Clamp(currentCoordinates.X + 1, 0, sizeX);
int endSkipY = Mathf.Clamp(currentCoordinates.Y + 1, 0, sizeY);
int endSkipZ = Mathf.Clamp(currentCoordinates.Z + 1, 0, sizeZ);
int endX = Mathf.Clamp(startX + countX, 0, sizeX);
for (int x = startX; x < endX; x++)
{
for (int y = 0; y < sizeY; y++)
{
for (int z = 0; z < sizeZ; z++)
{
if (Helpers.IsBetweenInclusive(x, startSkipX, endSkipX))
{
if (Helpers.IsBetweenInclusive(y, startSkipY, endSkipY))
{
if (Helpers.IsBetweenInclusive(z, startSkipZ, endSkipZ))
{
continue;
}
}
}
sectors[x, y, z].Simulate(delta);
}
}
}
}
}