Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
31 commits
Select commit Hold shift + click to select a range
30a9996
Exclude nucleus from specialisation calculation
Accidental-Explorer Mar 13, 2026
f36185d
Switched to using hex counts instead of organelle number to normalize…
Accidental-Explorer Mar 13, 2026
54ff465
Removed the minimum size for specialisation
Accidental-Explorer Mar 13, 2026
0a005a0
Corrected usage of the nucleus check.
Accidental-Explorer Mar 16, 2026
49dbad2
Moved assignments of the nucleusDefinition to field in classes.
Accidental-Explorer Mar 16, 2026
f5cd750
Format
Accidental-Explorer Mar 16, 2026
65318e7
Removed assignement of nucelus definition from class in two cases
Accidental-Explorer Mar 16, 2026
5a9949b
Merge remote-tracking branch 'origin/changed-specialisation-calculati…
Accidental-Explorer Mar 17, 2026
199bf6e
Removed assignment of nucleus definition from class in two cases
Accidental-Explorer Mar 16, 2026
4ede9c1
Merge remote-tracking branch 'origin/changed-specialisation-calculati…
Accidental-Explorer Mar 17, 2026
2c22f7f
Merge branch 'master' into changed-specialisation-calculation
Accidental-Explorer Mar 17, 2026
7323510
Made cell specialisation bonus apply to positive effects on environme…
Accidental-Explorer Mar 18, 2026
10f8464
Merge branch 'master' into changed-specialisation-calculation
Accidental-Explorer Mar 18, 2026
434b9ec
post-merge adaptation.
Accidental-Explorer Mar 18, 2026
cd02bd6
Merge branch 'changed-specialisation-calculation' into expanded-cell-…
Accidental-Explorer Mar 18, 2026
f3178ff
WIP cell specialisation effect on storage capacity.
Accidental-Explorer Mar 19, 2026
7850aa4
Resolved ambiguity
Accidental-Explorer Mar 19, 2026
e272d8b
Applied cell specialization bonus to flagellum speed
Accidental-Explorer Mar 20, 2026
00bc5be
WIP add cell specialization Bonus to rotation speed from cilia
Accidental-Explorer Mar 20, 2026
9c91a69
Tried to correctly prepare for multicellular adjacency in one location.
Accidental-Explorer Mar 20, 2026
392deed
Store cell specialization bonus in new entity component, and use that…
Accidental-Explorer Mar 23, 2026
2f1a333
Line too long
Accidental-Explorer Mar 23, 2026
e457a7a
Format fix?
Accidental-Explorer Mar 23, 2026
c23ba30
Apply cell specialization bonus to digestion speed and efficiency fro…
Accidental-Explorer Mar 23, 2026
0a49ffa
remove forgotten TODO
Accidental-Explorer Mar 24, 2026
8995a5f
Ensure that flagella are also affected by cell specialization bonus i…
Accidental-Explorer Mar 24, 2026
be4c9cb
Apply cell specialization bonus to pulling cilia force and range. Als…
Accidental-Explorer Mar 24, 2026
37205a8
Merge remote-tracking branch 'origin/expanded-cell-specialization-eff…
Accidental-Explorer Mar 25, 2026
9f78133
Format fix.
Accidental-Explorer Mar 25, 2026
4e62d5b
Make cell specialization bonus affect slimejet emission amount, movem…
Accidental-Explorer Mar 25, 2026
78db62d
Fixed forgotten step in slime jets.
Accidental-Explorer Mar 25, 2026
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
42 changes: 31 additions & 11 deletions src/auto-evo/simulation/SimulationCache.cs
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,9 @@ public class SimulationCache
private readonly CompoundDefinition oxytoxy = SimulationParameters.GetCompound(Compound.Oxytoxy);
private readonly CompoundDefinition mucilage = SimulationParameters.GetCompound(Compound.Mucilage);

private readonly OrganelleDefinition nucleusDefinition =
SimulationParameters.Instance.GetOrganelleType("nucleus");

private readonly WorldGenerationSettings worldSettings;

#if USE_HASHED_SCORE_KEYS
Expand Down Expand Up @@ -141,7 +144,8 @@ public EnergyBalanceInfoSimple GetEnergyBalanceForSpecies(MicrobeSpecies species
var cached = new EnergyBalanceInfoSimple();

// Assume here that the species specialization factor may not be up to date, so recalculate here
var specialization = MicrobeInternalCalculations.CalculateSpecializationBonus(species.Organelles, workMemory1);
var specialization = MicrobeInternalCalculations.CalculateSpecializationBonus(species.Organelles, workMemory1,
nucleusDefinition);

// Auto-evo uses the average values of compound during the course of a simulated day
ProcessSystem.ComputeEnergyBalanceSimple(species.Organelles, biomeConditions,
Expand Down Expand Up @@ -169,8 +173,14 @@ public float GetSpeedForSpecies(MicrobeSpecies species)
return speed;
}

var cached = MicrobeInternalCalculations.CalculateSpeed(species.Organelles.Organelles, species.MembraneType,
species.MembraneRigidity, species.IsBacteria, true);
var organelles = species.Organelles;

var specialization = MicrobeInternalCalculations.CalculateSpecializationBonus(organelles,
new Dictionary<OrganelleDefinition, int>(),
nucleusDefinition);

var cached = MicrobeInternalCalculations.CalculateSpeed(organelles.Organelles, species.MembraneType,
species.MembraneRigidity, species.IsBacteria, specialization, true);

cachedBaseSpeeds.Add(key, cached);
return cached;
Expand Down Expand Up @@ -202,7 +212,13 @@ public float GetRotationSpeedForSpecies(MicrobeSpecies species)
// prey species by multiple predators might benefit ever so slightly, but it seems kind of unlikely).
// A more useful thing would be to cache this directly in the species when calculating other movement cached
// properties.
return MicrobeInternalCalculations.CalculateRotationSpeed(species.Organelles.Organelles);
var organelles = species.Organelles;

var specialization = MicrobeInternalCalculations.CalculateSpecializationBonus(organelles,
new Dictionary<OrganelleDefinition, int>(),
nucleusDefinition);

return MicrobeInternalCalculations.CalculateRotationSpeed(organelles.Organelles, specialization);
}

public float GetCompoundConversionScoreForSpecies(CompoundDefinition fromCompound, CompoundDefinition toCompound,
Expand Down Expand Up @@ -390,9 +406,13 @@ public float GetPredationScore(Species predatorSpecies, Species preySpecies, Bio
}
}

// This will likely be used at several points to mimic the effect the specialization bonus has on organelles
var specializationBonus = MicrobeInternalCalculations.CalculateSpecializationBonus(
predator.Organelles.Organelles, workMemory1, nucleusDefinition);

var predatorHexSize = GetBaseHexSizeForSpecies(predator);
var preyHexSize = GetBaseHexSizeForSpecies(prey);
var enzymesScore = GetEnzymesScore(predator, prey.MembraneType.DissolverEnzyme);
var enzymesScore = GetEnzymesScore(predator, prey.MembraneType.DissolverEnzyme, specializationBonus);
var canDigestPrey = predatorHexSize / preyHexSize > Constants.ENGULF_SIZE_RATIO_REQ && canEngulf &&
enzymesScore > 0.0f;

Expand Down Expand Up @@ -447,13 +467,13 @@ public float GetPredationScore(Species predatorSpecies, Species preySpecies, Bio

var toxicity = predatorToolScores.AverageToxicity;
var macrolideScore = predatorToolScores.MacrolideScore;
var predatorSlimeJetScore = predatorToolScores.SlimeJetScore;
var pullingCiliaModifier = predatorToolScores.PullingCiliaModifier;
var predatorSlimeJetScore = predatorToolScores.SlimeJetScore * specializationBonus;
var pullingCiliaModifier = predatorToolScores.PullingCiliaModifier * specializationBonus;
var strongPullingCiliaModifier = pullingCiliaModifier * pullingCiliaModifier;
var predatorToxinResistance = predator.MembraneType.ToxinResistance;
var predatorPhysicalResistance = predator.MembraneType.PhysicalResistance;

var preySlimeJetScore = preyToolScores.SlimeJetScore;
var preySlimeJetScore = preyToolScores.SlimeJetScore * specializationBonus;
var preyMucocystsScore = preyToolScores.MucocystsScore;
var preyPilusScore = preyToolScores.PilusScore;
var preyInjectisomeScore = preyToolScores.InjectisomeScore;
Expand Down Expand Up @@ -1222,7 +1242,7 @@ public PredationToolsRawScores GetPredationToolsRawScores(MicrobeSpecies microbe
return predationToolsRawScores;
}

public float GetEnzymesScore(MicrobeSpecies predator, string dissolverEnzyme)
public float GetEnzymesScore(MicrobeSpecies predator, string dissolverEnzyme, float specializationBonus)
{
// This is not cached as it is not useful at the present time (as this is only called from places that cache
// stuff)
Expand Down Expand Up @@ -1263,9 +1283,9 @@ public float GetEnzymesScore(MicrobeSpecies predator, string dissolverEnzyme)

// If not digestible, mark that as a 0 score
if (!isMembraneDigestible)
enzymesScore = 0;
return 0;

return enzymesScore;
return enzymesScore * specializationBonus;
}

public ResolvedMicrobeTolerances GetEnvironmentalTolerances(MicrobeSpecies species,
Expand Down
8 changes: 8 additions & 0 deletions src/microbe_stage/ICellDefinition.cs
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,12 @@ public interface ICellDefinition : IReadOnlyCellDefinition, ISimulationPhotograp

public string FormattedName { get; }

/// <summary>
/// A multiplier starting from 1 and going up based on how specialized this cell type is. This is eventually
/// applied to <see cref="Components.BioProcesses.OverallSpeedModifier"/>
/// </summary>
public float SpecializationBonus { get; }

/// <summary>
/// Repositions the cell to the origin and recalculates any properties dependent on its position.
/// </summary>
Expand All @@ -49,6 +55,8 @@ public interface IReadOnlyCellDefinition
public interface ICellTypeDefinition : ICellDefinition, IReadOnlyCellTypeDefinition
{
public new int MPCost { get; set; }

public new float SpecializationBonus { get; }
}

public interface IReadOnlyCellTypeDefinition : IReadOnlyCellDefinition, IPlayerReadableName
Expand Down
4 changes: 3 additions & 1 deletion src/microbe_stage/IOrganelleComponent.cs
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@ public interface IOrganelleComponent
/// <see cref="UpdateSync"/>
/// </summary>
/// <param name="organelleContainer">Organelle container instance this organelle is inside</param>
/// <param name="specializationFactor"> Organelle effect bonus cell specialization and adjacency</param>
/// <param name="microbeEntity">Entity reference of the entity that contains this organelle</param>
/// <param name="worldSimulation">
/// The simulation this entity is in. Care needs to be taken on what operations are safe to perform here in an
Expand All @@ -27,7 +28,8 @@ public interface IOrganelleComponent
/// functionality.
/// </param>
/// <param name="delta">Time since the last update in seconds</param>
public void UpdateAsync(ref OrganelleContainer organelleContainer, in Entity microbeEntity,
public void UpdateAsync(ref OrganelleContainer organelleContainer, ref SpecializationFactor specializationFactor,
in Entity microbeEntity,
IWorldSimulation worldSimulation, float delta);

/// <summary>
Expand Down
49 changes: 35 additions & 14 deletions src/microbe_stage/MicrobeEnvironmentalToleranceCalculations.cs
Original file line number Diff line number Diff line change
Expand Up @@ -97,11 +97,17 @@ public static ToleranceResult CalculateTolerancesWithoutOrganelleModifiers(
public static void ApplyOrganelleEffectsOnTolerances(IReadOnlyList<IReadOnlyOrganelleTemplate> organelles,
ref ToleranceValues tolerances)
{
float temperatureChange = 0;
float oxygenChange = 0;
float uvChange = 0;
float pressureMinimumChange = 0;
float pressureToleranceChange = 0;
float totalTemperatureChange = 0;
float totalOxygenChange = 0;
float totalUvChange = 0;
float totalPressureMinimumChange = 0;
float totalPressureToleranceChange = 0;

var nucleusDefinition = SimulationParameters.Instance.GetOrganelleType("nucleus");

// Note this assumes this is only used just for single cell types or microbe species!
var specialization = MicrobeInternalCalculations.CalculateSpecializationBonus(organelles,
new Dictionary<OrganelleDefinition, int>(), nucleusDefinition);

int organelleCount = organelles.Count;
for (int i = 0; i < organelleCount; ++i)
Expand All @@ -110,20 +116,35 @@ public static void ApplyOrganelleEffectsOnTolerances(IReadOnlyList<IReadOnlyOrga

if (organelleDefinition.AffectsTolerances)
{
var temperatureChange = organelleDefinition.ToleranceModifierTemperatureRange;
var oxygenChange = organelleDefinition.ToleranceModifierOxygen;
var uvChange = organelleDefinition.ToleranceModifierUV;
var pressureToleranceChange = organelleDefinition.ToleranceModifierPressureTolerance;

// apply specialization bonus
if (temperatureChange > 0)
temperatureChange *= specialization;
if (oxygenChange > 0)
oxygenChange *= specialization;
if (uvChange > 0)
uvChange *= specialization;
if (pressureToleranceChange > 0)
pressureToleranceChange *= specialization;

// Buffer all changes so that float rounding doesn't cause us issues
temperatureChange += organelleDefinition.ToleranceModifierTemperatureRange;
oxygenChange += organelleDefinition.ToleranceModifierOxygen;
uvChange += organelleDefinition.ToleranceModifierUV;
pressureToleranceChange += organelleDefinition.ToleranceModifierPressureTolerance;
totalTemperatureChange += temperatureChange;
totalOxygenChange += oxygenChange;
totalUvChange += uvChange;
totalPressureToleranceChange += pressureToleranceChange;
}
}

// Then apply all at once
tolerances.TemperatureTolerance += temperatureChange;
tolerances.OxygenResistance += oxygenChange;
tolerances.UVResistance += uvChange;
tolerances.PressureMinimum -= pressureMinimumChange;
tolerances.PressureTolerance += pressureToleranceChange;
tolerances.TemperatureTolerance += totalTemperatureChange;
tolerances.OxygenResistance += totalOxygenChange;
tolerances.UVResistance += totalUvChange;
tolerances.PressureMinimum -= totalPressureMinimumChange;
tolerances.PressureTolerance += totalPressureToleranceChange;
}

public static void ApplyOrganelleEffectsOnTolerances(IReadOnlyCollection<IReadOnlyOrganelleTemplate> organelles,
Expand Down
Loading