Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
41 commits
Select commit Hold shift + click to select a range
0244d34
Applied addiitonal restriction on prey toxin firing following AI beha…
Accidental-Explorer Apr 11, 2026
e8a5fc1
Copied storage and energy balance logic from ChunkCompoundPressure.cs…
Accidental-Explorer Apr 12, 2026
56e228a
Moved storage score to a place in the calculation that is less separa…
Accidental-Explorer Apr 13, 2026
f5d11fa
Added fear and aggression behaviour penalties to CompoundCloudPressur…
Accidental-Explorer Apr 13, 2026
391d1f1
Adjusted night activity effect to affect activity instead of score di…
Accidental-Explorer Apr 13, 2026
64b2941
Apply nighttime activity effect to ChunkCompoundPressure.cs
Accidental-Explorer Apr 13, 2026
15a4188
Format
Accidental-Explorer Apr 13, 2026
19649cf
Slight rework of ReproductionCompoundPressure.cs
Accidental-Explorer Apr 13, 2026
2c4914f
fixed comment
Accidental-Explorer Apr 13, 2026
a1e4d29
Applied aggression and fear behaviour penalties to ReproductionCompou…
Accidental-Explorer Apr 13, 2026
27b1bf6
Removed using directive
Accidental-Explorer Apr 13, 2026
38e6d32
Format
Accidental-Explorer Apr 13, 2026
415ed2f
Added simulation of hunting and fleeing energy consumption to EnergyC…
Accidental-Explorer Apr 13, 2026
2a0526e
Merge branch 'master' into auto-evo-predator-separation
Accidental-Explorer Apr 13, 2026
e9bdb6d
Redundant using directive
Accidental-Explorer Apr 13, 2026
3a1b595
Adjusted Fear effect balancing.
Accidental-Explorer Apr 13, 2026
275ec7e
Increased valuation of engulfment
Accidental-Explorer Apr 13, 2026
ae6feb8
Made defensive measures more mitigate instead of nullify predation score
Accidental-Explorer Apr 13, 2026
be6260e
Put some diminishing returns on predator agression score effect on to…
Accidental-Explorer Apr 14, 2026
6fe3174
Put in some more downsides for prey agression score
Accidental-Explorer Apr 14, 2026
ea91205
Reduced fear reduction mutation size
Accidental-Explorer Apr 14, 2026
528fe0a
Behaviour penalty number balance
Accidental-Explorer Apr 14, 2026
4bd1947
Gave aggression and fear effect on Energy consumption an accelerating…
Accidental-Explorer Apr 14, 2026
2efb427
Put Agression and Fear behaviour changes in additional locations for …
Accidental-Explorer Apr 14, 2026
8bb975c
Made activity effect on compound gathering have diminishing returns.
Accidental-Explorer Apr 14, 2026
ea3dd7c
Made PredatorRoot.cs ensure potential predators get greater than 0 ag…
Accidental-Explorer Apr 14, 2026
c5f2b41
Fixed error in calculating inactivity
Accidental-Explorer Apr 14, 2026
11ab022
Number tweak
Accidental-Explorer Apr 14, 2026
dd349e7
Added opportunism handling and mutation
Accidental-Explorer Apr 14, 2026
8e019fe
Implemented auto-evo Focus behaviour handling and mutation
Accidental-Explorer Apr 14, 2026
8af4df9
Moved most behaviour mutation to leaf nodes
Accidental-Explorer Apr 15, 2026
2be6f2a
Balancing
Accidental-Explorer Apr 15, 2026
d399eed
Line too long.
Accidental-Explorer Apr 15, 2026
e4b37f3
Better backwards save compatibility for CompoundCloudPressure.cs
Accidental-Explorer Apr 15, 2026
9444482
Fix saving
Accidental-Explorer Apr 15, 2026
ebd4414
Fixed fixing save reading
Accidental-Explorer Apr 15, 2026
45c210a
Merge branch 'master' into auto-evo-predator-separation
Accidental-Explorer Apr 16, 2026
15f1768
Added a "remove any organelle" mutation strategy in every leaf node t…
Accidental-Explorer Apr 17, 2026
1f499cd
Merge branch 'master' into auto-evo-predator-separation
Accidental-Explorer Apr 30, 2026
353dc47
Added braces to follow styleguide
Accidental-Explorer May 4, 2026
363efbb
Merge branch 'master' into auto-evo-predator-separation
Accidental-Explorer May 4, 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
13 changes: 12 additions & 1 deletion simulation_parameters/Constants.cs
Original file line number Diff line number Diff line change
Expand Up @@ -1352,7 +1352,7 @@ public static class Constants
public const float AUTO_EVO_MINIMUM_MOVE_POPULATION_FRACTION = 0.1f;
public const float AUTO_EVO_MAXIMUM_MOVE_POPULATION_FRACTION = 0.4f;

public const float AUTO_EVO_ENGULF_PREDATION_SCORE = 100;
public const float AUTO_EVO_ENGULF_PREDATION_SCORE = 150;
public const float AUTO_EVO_PILUS_PREDATION_SCORE = 5000;
public const float AUTO_EVO_PILUS_DEFENSE_SCORE = 2000;
public const float AUTO_EVO_TOXIN_PREDATION_SCORE = 90000;
Expand All @@ -1377,6 +1377,17 @@ public static class Constants
public const float AUTO_EVO_PASSIVE_COMPOUND_COLLECTION_FRACTION = 0.1f;
public const float AUTO_EVO_REPRODUCTION_COMPOUND_PRODUCTION_SCORE = 3000.0f;
public const float AUTO_EVO_REPRODUCTION_COMPOUND_COST_WEAKENING_MODIFIER = 0.2f;
public const float AUTO_EVO_SPRINTING_CONSUMPTION = 0.1f;

public const float AUTO_EVO_MAX_AGGRESSION_ENERGY_PENALTY = 0.8f;
public const float AUTO_EVO_MAX_AGGRESSION_GATHERING_PENALTY = 0.1f;
public const float AUTO_EVO_MAX_FEAR_ENERGY_PENALTY = 0.005f;
public const float AUTO_EVO_MAX_FEAR_GATHERING_PENALTY = 0.000f;
public const float AUTO_EVO_MAX_OPPORTUNISM_BONUS = 0.4f;
public const float AUTO_EVO_MAX_OPPORTUNISM_PENALTY = 0.05f;
public const float AUTO_EVO_MAX_FOCUS_CHUNK_BONUS = 0.9f;
public const float AUTO_EVO_MAX_FOCUS_CLOUD_BONUS = 0.5f;
public const float AUTO_EVO_MAX_FOCUS_PENALTY = 0.1f;

public const float AUTO_EVO_PREDATION_DEFENSE_SCORE_MODIFIER = 0.5f;

Expand Down
23 changes: 14 additions & 9 deletions src/auto-evo/AutoEvoGlobalCache.cs
Original file line number Diff line number Diff line change
Expand Up @@ -50,7 +50,7 @@ public AutoEvoGlobalCache(WorldGenerationSettings worldSettings)
RootPressure = new RootPressure();
MetabolicStabilityPressure = new MetabolicStabilityPressure(10.0f);
GeneralAvoidPredationSelectionPressure = new GeneralAvoidPredationSelectionPressure(1.0f);
EnergyConsumptionPressure = new EnergyConsumptionPressure(0.3f);
EnergyConsumptionPressure = new EnergyConsumptionPressure(0.4f);
EnvironmentalTolerancesPressure = new EnvironmentalTolerancePressure(3);

PhosphatePressure = new ReproductionCompoundPressure(
Expand All @@ -63,25 +63,29 @@ public AutoEvoGlobalCache(WorldGenerationSettings worldSettings)

GlucoseConversionEfficiencyPressure =
new CompoundConversionEfficiencyPressure(Compound.Glucose, Compound.ATP, true, 1.5f);
GlucoseCloudPressure = new CompoundCloudPressure(Compound.Glucose, worldSettings.DayNightCycleEnabled, 1.0f);
GlucoseCloudPressure = new CompoundCloudPressure(Compound.Glucose, Compound.ATP,
worldSettings.DayNightCycleEnabled, 1.0f);

IronConversionEfficiencyPressure =
new CompoundConversionEfficiencyPressure(Compound.Iron, Compound.ATP, true, 1.5f);
SmallIronChunkPressure = new ChunkCompoundPressure("ironSmallChunk", new LocalizedString("SMALL_IRON_CHUNK"),
Compound.Iron, Compound.ATP, 2.0f);
Compound.Iron, Compound.ATP, worldSettings.DayNightCycleEnabled, 2.0f);
BigIronChunkPressure = new ChunkCompoundPressure("ironBigChunk", new LocalizedString("BIG_IRON_CHUNK"),
Compound.Iron, Compound.ATP, 2.0f);
Compound.Iron, Compound.ATP, worldSettings.DayNightCycleEnabled, 2.0f);

HydrogenSulfideConversionEfficiencyPressure = new CompoundConversionEfficiencyPressure(Compound.Hydrogensulfide,
Compound.Glucose, true, 1.5f);
HydrogenSulfideCloudPressure = new CompoundCloudPressure(Compound.Hydrogensulfide,
HydrogenSulfideCloudPressure = new CompoundCloudPressure(Compound.Hydrogensulfide, Compound.Glucose,
worldSettings.DayNightCycleEnabled, 1.0f);
SmallSulfurChunkPressure = new ChunkCompoundPressure("sulfurSmallChunk",
new LocalizedString("SMALL_SULFUR_CHUNK"), Compound.Hydrogensulfide, Compound.Glucose, 2.0f);
new LocalizedString("SMALL_SULFUR_CHUNK"), Compound.Hydrogensulfide, Compound.Glucose,
worldSettings.DayNightCycleEnabled, 2.0f);
MediumSulfurChunkPressure = new ChunkCompoundPressure("sulfurMediumChunk",
new LocalizedString("MEDIUM_SULFUR_CHUNK"), Compound.Hydrogensulfide, Compound.Glucose, 2.0f);
new LocalizedString("MEDIUM_SULFUR_CHUNK"), Compound.Hydrogensulfide, Compound.Glucose,
worldSettings.DayNightCycleEnabled, 2.0f);
LargeSulfurChunkPressure = new ChunkCompoundPressure("sulfurLargeChunk",
new LocalizedString("LARGE_SULFUR_CHUNK"), Compound.Hydrogensulfide, Compound.Glucose, 2.0f);
new LocalizedString("LARGE_SULFUR_CHUNK"), Compound.Hydrogensulfide, Compound.Glucose,
worldSettings.DayNightCycleEnabled, 2.0f);

SunlightConversionEfficiencyPressure =
new CompoundConversionEfficiencyPressure(Compound.Sunlight, Compound.Glucose, true, 1.5f);
Expand All @@ -90,7 +94,8 @@ public AutoEvoGlobalCache(WorldGenerationSettings worldSettings)
RadiationConversionEfficiencyPressure =
new CompoundConversionEfficiencyPressure(Compound.Radiation, Compound.ATP, true, 1.0f);
RadioactiveChunkPressure = new ChunkCompoundPressure("radioactiveChunk",
new LocalizedString("RADIOACTIVE_CHUNK"), Compound.Radiation, Compound.ATP, 1.0f);
new LocalizedString("RADIOACTIVE_CHUNK"), Compound.Radiation, Compound.ATP,
worldSettings.DayNightCycleEnabled, 1.0f);

TemperatureConversionEfficiencyPressure =
new CompoundConversionEfficiencyPressure(Compound.Temperature, Compound.Glucose, true, 1.5f);
Expand Down
86 changes: 72 additions & 14 deletions src/auto-evo/selection_pressure/ChunkCompoundPressure.cs
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@

public class ChunkCompoundPressure : SelectionPressure
{
public const ushort SERIALIZATION_VERSION = 1;
public const ushort SERIALIZATION_VERSION = 2;

// Needed for translation extraction
// ReSharper disable ArrangeObjectCreationWhenTypeEvident
Expand All @@ -22,9 +22,11 @@ public class ChunkCompoundPressure : SelectionPressure
private readonly CompoundDefinition compound;
private readonly CompoundDefinition compoundOut;

private readonly bool isDayNightCycleEnabled;

public ChunkCompoundPressure(string chunkType, LocalizedString readableName, Compound compound,
Compound compoundOut, float weight) : base(weight, [
RemoveOrganelle.ThatCreateCompound(compoundOut),
Compound compoundOut, bool isDayNightCycleEnabled, float weight) : base(weight, [
new RemoveOrganelle(_ => true),
new AddOrganelleAnywhere(organelle => organelle.HasChemoreceptorComponent),
new AddOrganelleAnywhere(organelle => organelle.InternalName == "vacuole"),
AddOrganelleAnywhere.ThatConvertBetweenCompounds(compound, compoundOut),
Expand All @@ -33,6 +35,15 @@ public ChunkCompoundPressure(string chunkType, LocalizedString readableName, Com
new ChemoreceptorUpgrades(compound, null, Constants.CHEMORECEPTOR_RANGE_DEFAULT,
Constants.CHEMORECEPTOR_AMOUNT_DEFAULT, SimulationParameters.GetCompound(compound).Colour)),
new ChangeBehaviorScore(ChangeBehaviorScore.BehaviorAttribute.Activity, 150.0f),
new ChangeBehaviorScore(ChangeBehaviorScore.BehaviorAttribute.Activity, -150.0f),
new ChangeBehaviorScore(ChangeBehaviorScore.BehaviorAttribute.Aggression, 50.0f),
new ChangeBehaviorScore(ChangeBehaviorScore.BehaviorAttribute.Aggression, -150.0f),
Comment on lines +39 to +40
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

If adding more aggression is always a negative for this pressure (it appears to be?) then I'm not sure having a mutation that increases it is ever helpful? Any other pressures that has a positive score for should have that mutation already.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is the case with many of the other behaviours as well. But the point is that it evaluates the whole pressure stack. In this case it can improve predator resistance for some species.

I previously had it in that pressure, but then it often got used when it would not be used if already taking the compound pressure into account.

Copy link
Copy Markdown
Contributor Author

@Accidental-Explorer Accidental-Explorer Apr 16, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

To emphasise why the above could be a problem: ModifyExistingSpecies regularly prunes against the base species (rather than just pre-this-mutation) for the pressurestack to that point. So I don't want to create a situation where for some species nearly every mutant that gets out of GeneralAvoidPredationSelectionPressure has increased Aggression, but then any further mutation based on them gets pruned in the leaf nodes before it gets a chance to lower the Aggression to what is more fitting)

(Edit: and even if not explicitly pruning, I guess the frequent "top selection" would catch them as well?)

But the mutation system is quite complex so I could be missing something.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

There's also the fact that ChangeBehaviourScore as far as I can tell just gives a single mutant with a random change within the given range, so that seems like likely to overshoot the optimal point. The opposit gives some opportunity to compensate in the other direction.

new ChangeBehaviorScore(ChangeBehaviorScore.BehaviorAttribute.Fear, 150.0f),
new ChangeBehaviorScore(ChangeBehaviorScore.BehaviorAttribute.Fear, -150.0f),
new ChangeBehaviorScore(ChangeBehaviorScore.BehaviorAttribute.Focus, 150.0f),
new ChangeBehaviorScore(ChangeBehaviorScore.BehaviorAttribute.Focus, -150.0f),
new ChangeBehaviorScore(ChangeBehaviorScore.BehaviorAttribute.Opportunism, 150.0f),
new ChangeBehaviorScore(ChangeBehaviorScore.BehaviorAttribute.Opportunism, -150.0f),
new ChangeMembraneType("single"),
new ChangeMembraneType("double"),
])
Expand All @@ -41,6 +52,7 @@ public ChunkCompoundPressure(string chunkType, LocalizedString readableName, Com
this.compoundOut = SimulationParameters.GetCompound(compoundOut);
this.chunkType = chunkType;
this.readableName = readableName;
this.isDayNightCycleEnabled = isDayNightCycleEnabled;
}

public override LocalizedString Name => NameString;
Expand All @@ -50,15 +62,29 @@ public ChunkCompoundPressure(string chunkType, LocalizedString readableName, Com
public override ArchiveObjectType ArchiveObjectType =>
(ArchiveObjectType)ThriveArchiveObjectType.ChunkCompoundPressure;

public static ChunkCompoundPressure ReadFromArchive(ISArchiveReader reader, ushort version,
int referenceId)
public static ChunkCompoundPressure ReadFromArchive(ISArchiveReader reader, ushort version, int referenceId)
{
if (version is > SERIALIZATION_VERSION or <= 0)
throw new InvalidArchiveVersionException(version, SERIALIZATION_VERSION);

var instance = new ChunkCompoundPressure(reader.ReadString() ?? throw new NullArchiveObjectException(),
reader.ReadObject<LocalizedString>(), (Compound)reader.ReadInt32(), (Compound)reader.ReadInt32(),
reader.ReadFloat());
var chunkType = reader.ReadString();
var readableName = reader.ReadObject<LocalizedString>();
var compound = (Compound)reader.ReadInt32();
var compoundOut = (Compound)reader.ReadInt32();
bool isDayNightCycleEnabled;

if (version >= 2)
{
isDayNightCycleEnabled = reader.ReadBool();
}
else
{
isDayNightCycleEnabled = true;
}

var instance = new ChunkCompoundPressure(chunkType ?? throw new NullArchiveObjectException(),
readableName, compound, compoundOut,
isDayNightCycleEnabled, reader.ReadFloat());

instance.ReadBasePropertiesFromArchive(reader, 1);
return instance;
Expand All @@ -70,6 +96,7 @@ public override void WriteToArchive(ISArchiveWriter writer)
writer.WriteObject(readableName);
writer.Write((int)compound.ID);
writer.Write((int)compoundOut.ID);
writer.Write(isDayNightCycleEnabled);
base.WriteToArchive(writer);
}

Expand All @@ -86,23 +113,54 @@ public override float Score(Species species, Patch patch, SimulationCache cache)
// Speed is not too important to chunk microbes, but all else being the same faster is better than slower
score += MathF.Pow(cache.GetSpeedForSpecies(microbeSpecies), 0.4f);

// Diminishing returns on storage
score += (MathF.Pow(microbeSpecies.StorageCapacities.Nominal + 1, 0.8f) - 1) / 0.8f;

// Additional bonus from chemoreceptor
var chemoreceptorScore = cache.GetChemoreceptorChunkScore(microbeSpecies, chunk, compound);

// modify score by activity
var activityFraction = microbeSpecies.Behaviour.Activity / Constants.MAX_SPECIES_ACTIVITY;
var activity = microbeSpecies.Behaviour.Activity;

score = (score + chemoreceptorScore) * activityFraction
+ score * (1 - activityFraction) * Constants.AUTO_EVO_PASSIVE_COMPOUND_COLLECTION_FRACTION;
// Species that are less active during the night get a penalty to their activity
if (isDayNightCycleEnabled && cache.GetUsesVaryingCompoundsForSpecies(microbeSpecies, patch.Biome))
{
var multiplier = activity / Constants.AI_ACTIVITY_TO_BE_FULLY_ACTIVE_DURING_NIGHT;

// Diminishing returns on storage
score += (MathF.Pow(microbeSpecies.StorageCapacities.Nominal + 1, 0.8f) - 1) / 0.8f;
multiplier = Math.Max(multiplier, Constants.AUTO_EVO_MAX_NIGHT_SESSILITY_COLLECTING_PENALTY);

if (multiplier <= 1)
activity *= multiplier;
}

// modify score by activity and focus
var activityScore = MathF.Pow(activity / Constants.MAX_SPECIES_ACTIVITY, 0.4f);
var focusScore = 1 + MathF.Pow(microbeSpecies.Behaviour.Focus / Constants.MAX_SPECIES_ACTIVITY, 0.4f)
* Constants.AUTO_EVO_MAX_FOCUS_CHUNK_BONUS;

score = (score + chemoreceptorScore) * activityScore * focusScore
+ score * (1 - activityScore * focusScore) * Constants.AUTO_EVO_PASSIVE_COMPOUND_COLLECTION_FRACTION;

// compound collection is reduced if you are running away from predators instead
var fearFraction = microbeSpecies.Behaviour.Fear / Constants.MAX_SPECIES_FEAR;

score *= 1 - fearFraction * Constants.AUTO_EVO_MAX_FEAR_GATHERING_PENALTY;

// If the species can't engulf, then they are dependent on only eating the runoff compounds
if (!microbeSpecies.CanEngulf ||
cache.GetBaseHexSizeForSpecies(microbeSpecies) < chunk.Size * Constants.ENGULF_SIZE_RATIO_REQ)
{
score *= Constants.AUTO_EVO_CHUNK_LEAK_MULTIPLIER;

// cloud compound collection is reduced if you are chasing prey instead
var aggressionFraction = microbeSpecies.Behaviour.Aggression / Constants.MAX_SPECIES_AGGRESSION;

score *= 1 - aggressionFraction * Constants.AUTO_EVO_MAX_AGGRESSION_GATHERING_PENALTY;
}
else
{
var opportunismFraction = MathF.Pow(
microbeSpecies.Behaviour.Opportunism / Constants.MAX_SPECIES_ACTIVITY, 0.5f);
score *= 1 + opportunismFraction * Constants.AUTO_EVO_MAX_OPPORTUNISM_BONUS;
}

float compoundATP;
Expand Down
Loading