Unicellular – Manager-Driven ECS
Codebase Breakdown • Unity • Custom ECS • Simulation
Overview
A 2D life simulation where colourful unicells roam, fight, and evolve. The project uses a manager-driven ECS-style architecture in Unity to keep systems modular and scalable.
Architecture
Gameplay is coordinated by specialised managers handling entities, economy, camera and UI.
Data Model
Persistent statistics for each unicell are stored in a simple serialisable class.
Field | Type | Description |
---|---|---|
Species | string | Identifier for the unicell species |
Damage | float | Base attack damage |
MaxHealth | float | Maximum health value |
Level | int | Current evolution level |
XP | float | Accumulated experience points |
XP_Threshold | int | XP required for next level |
BaseScale | Vector2 | Default sprite scale |
Key APIs / Contracts
Entity Manager
public void SpawnUnicells(UnicellSpecies species, int amount);
Economy Manager
public void IncrementUnicellPopulation(string unicellType);
Representative Code Snippets
Spawning species-specific cells – loops through count and initialises each with the correct prefab.
Show code
@EntityManager.cs lines 1422-1468
public void SpawnUnicells(UnicellSpecies species, int Amount)
{
for (int x = 0; x < Amount; x++)
{
switch (species)
{
case UnicellSpecies.Blue:
initialUnicell = Instantiate(blueUnicellPrefab).GetComponent<Unicell>();
initialUnicell.transform.parent = BlueUnicellsGameObject.transform;
Initialise(initialUnicell, Unicell.UnicellSpecies.Blue);
break;
case UnicellSpecies.Pink:
initialUnicell = Instantiate(pinkUnicellPrefab).GetComponent<Unicell>();
initialUnicell.transform.parent = PinkUnicellsGameObject.transform;
Initialise(initialUnicell, Unicell.UnicellSpecies.Pink);
break;
case UnicellSpecies.Yellow:
initialUnicell = Instantiate(yellowUnicellPrefab).GetComponent<Unicell>();
initialUnicell.transform.parent = YellowUnicellsGameObject.transform;
Initialise(initialUnicell, Unicell.UnicellSpecies.Yellow);
break;
case UnicellSpecies.Green:
initialUnicell = Instantiate(greenUnicellPrefab).GetComponent<Unicell>();
initialUnicell.transform.parent = GreenUnicellsGameObject.transform;
Initialise(initialUnicell, Unicell.UnicellSpecies.Green);
break;
case UnicellSpecies.Purple:
initialUnicell = Instantiate(purpleUnicellPrefab).GetComponent<Unicell>();
initialUnicell.transform.parent = PurpleUnicellsGameObject.transform;
Initialise(initialUnicell, Unicell.UnicellSpecies.Purple);
break;
case UnicellSpecies.Red:
initialUnicell = Instantiate(redUnicellPrefab).GetComponent<Unicell>();
initialUnicell.transform.parent = RedUnicellsGameObject.transform;
Initialise(initialUnicell, Unicell.UnicellSpecies.Red);
break;
case UnicellSpecies.Orange:
initialUnicell = Instantiate(orangeUnicellPrefab).GetComponent<Unicell>();
initialUnicell.transform.parent = OrangeUnicellsGameObject.transform;
Initialise(initialUnicell, Unicell.UnicellSpecies.Orange);
break;
}
initialUnicell.transform.position = new Vector2((Random.value * Amount * 10) - (Amount / 2f), (Random.value * Amount * 10) - (Amount / 2f));
initialUnicell.CurrentState = UnicellState.Idle;
RegisterUnicell(initialUnicell);
}
}
View on GitHub (lines 1422–1468)
Adjusting target populations – ensures economy goals drive spawning needs.
Show code
@EconomyManager.cs lines 901-930
public void IncrementUnicellPopulation(string UnicellType)
{
switch (UnicellType)
{
case "Blue":
TargetBlueUnicellPopulation++;
break;
case "Pink":
TargetPinkUnicellPopulation++;
break;
case "Yellow":
TargetYellowUnicellPopulation++;
break;
case "Green":
TargetGreenUnicellPopulation++;
break;
case "Purple":
TargetPurpleUnicellPopulation++;
break;
case "Red":
TargetRedUnicellPopulation++;
break;
case "Orange":
TargetOrangeUnicellPopulation++;
break;
default:
Debug.LogError("EconomyManager IncrementUnicellPopulation() - Unknown UnicellType for target population incrementation");
break;
}
}
Performance Notes
Initial profiling focuses on entity spawning and per-frame manager updates; further optimisation is ongoing.
All profiling was recorded in-editor on a Ryzen 7 7800X3D. Demo clips on the main portfolio page show:
- 1000 Unicells sustaining 144+ fps.
- 6000 Unicells maintaining roughly 100 fps.
Testing & Validation
Functionality is verified through manual playtesting; automated unit tests are not yet available.
Manual playtests were carried out with multiple people. One tester discovered a bug where 64-bit long
values were truncated to 32-bit int
s; explicit conversions have been added to prevent this from recurring. Automated unit tests are not yet available.