Skip to content
Open
Show file tree
Hide file tree
Changes from 13 commits
Commits
Show all changes
36 commits
Select commit Hold shift + click to select a range
224cb54
AI: Use move to me command if entity has binding agent
IdfbAn Feb 11, 2026
51c70e1
AI Signaling Agent: Add else condition for no command
IdfbAn Feb 11, 2026
8d88abe
MicrobeAISystem.UseSignalingAgent()
IdfbAn Feb 11, 2026
d5ed2a0
Make UseSignalingAgent() return the command
IdfbAn Feb 12, 2026
e491f3d
Make returning no command outside of conditions
IdfbAn Feb 12, 2026
2d9a1c6
Start adding conditions for predation
IdfbAn Feb 12, 2026
a45ef6b
Comply with JetBrains check
IdfbAn Feb 12, 2026
144a74b
Make UseSignalingAgent() set commands directly again
IdfbAn Feb 13, 2026
4d8bc43
Add "or has toxins" to pili condition
IdfbAn Feb 14, 2026
e9f1932
MicrobeControl.Fleeing
IdfbAn Feb 14, 2026
8195e59
Set control.Fleeing in ChooseActions()
IdfbAn Feb 14, 2026
ecca883
Use flee from me command if fleeing
IdfbAn Feb 15, 2026
36de1a4
Remove control.Fleeing = false line
IdfbAn Feb 15, 2026
f5fc4c8
Remove exact chance from comment
IdfbAn Feb 16, 2026
07f62e2
Move Fleeing to MicrobeAI and increment SERIALIZATION_VERSION
IdfbAn Feb 16, 2026
08cbe44
Handle reading Fleeing for SERIALIZATION_VERSION == 1
IdfbAn Feb 16, 2026
c758755
Correct control.Fleeing to ai.Fleeing
IdfbAn Feb 16, 2026
0920682
Add else conditions that set command to none
IdfbAn Feb 16, 2026
74ac805
Add and use AI_MOVE_DISTANCE_SQUARED
IdfbAn Feb 17, 2026
4c1708e
Add and use AI_BECOME_AGGRESSIVE_DISTANCE_SQUARED
IdfbAn Feb 17, 2026
d471a74
Fix indentation
IdfbAn Feb 17, 2026
43032a9
Fix indentation MicrobeAISystem.cs:273
IdfbAn Feb 17, 2026
16a1d7e
Edit ternary operator to comply with JetBrains
IdfbAn Feb 17, 2026
b98eb16
Move flee from me command to outside of UseSignalingAgent()
IdfbAn Feb 18, 2026
880c09f
Remove MicrobeAI.Fleeing as it is now useless
IdfbAn Feb 18, 2026
6340dba
Remove unused parameter
IdfbAn Feb 18, 2026
ef56fc8
Fix signalerPosition
IdfbAn Feb 18, 2026
66cff35
Fix AI use of flee from me command
IdfbAn Feb 18, 2026
8ae66c4
Improve signalerPosition assignment
IdfbAn Feb 23, 2026
3426b61
Use signalExists in signalerPosition condition
IdfbAn Feb 24, 2026
01abd06
Fulfill (some of) Patryk26g's requests
IdfbAn Feb 24, 2026
0301823
Resolve JetBrains check fail and fulfill new Patryk26g requests
IdfbAn Feb 25, 2026
e1d3cc1
Change comment as suggested by hhyyrylainen
IdfbAn Feb 26, 2026
9179fa4
Add condition for sending become aggressive command
IdfbAn Mar 9, 2026
8d134db
Send follow me command if prey is confident enough
IdfbAn Mar 31, 2026
9d5b1f8
Merge branch 'master' into 5118_ai_signaling_agent
IdfbAn Apr 2, 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
2 changes: 2 additions & 0 deletions simulation_parameters/Constants.cs
Original file line number Diff line number Diff line change
Expand Up @@ -1280,6 +1280,8 @@ public static class Constants
public const float AI_FOLLOW_DISTANCE_SQUARED = 60 * 60;
public const float AI_FLEE_DISTANCE_SQUARED = 85 * 85;

public const float AI_SIGNALING_CHANCE = 0.05f;

public const float AI_BASE_TOXIN_SHOOT_ANGLE_PRECISION = 5;

/// <summary>
Expand Down
8 changes: 8 additions & 0 deletions src/microbe_stage/components/MicrobeControl.cs
Original file line number Diff line number Diff line change
Expand Up @@ -94,6 +94,11 @@ public struct MicrobeControl : IArchivableComponent
/// </summary>
public bool MucocystEffectsApplied;

/// <summary>
/// Whether this microbe is currently fleeing
/// </summary>
public bool Fleeing;

/// <summary>
/// Constructs an instance with a sensible <see cref="LookAtPoint"/> set
/// </summary>
Expand All @@ -111,6 +116,7 @@ public MicrobeControl(Vector3 startingPosition)
SlowedBySlime = false;
Sprinting = false;
MucocystEffectsApplied = false;
Fleeing = false;
}

public ushort CurrentArchiveVersion => SERIALIZATION_VERSION;
Expand All @@ -133,6 +139,7 @@ public void WriteToArchive(ISArchiveWriter writer)
writer.Write(OutOfSprint);
writer.Write(Sprinting);
writer.Write(MucocystEffectsApplied);
writer.Write(Fleeing);
}
}

Expand All @@ -159,6 +166,7 @@ public static MicrobeControl ReadFromArchive(ISArchiveReader reader, ushort vers
OutOfSprint = reader.ReadBool(),
Sprinting = reader.ReadBool(),
MucocystEffectsApplied = reader.ReadBool(),
Fleeing = reader.ReadBool(),
};
}

Expand Down
44 changes: 44 additions & 0 deletions src/microbe_stage/systems/MicrobeAISystem.cs
Original file line number Diff line number Diff line change
Expand Up @@ -286,6 +286,7 @@ private void ChooseActions(in Entity entity, ref MicrobeAI ai, ref CompoundAbsor
float speciesOpportunism = speciesBehaviour.Opportunism;

control.Sprinting = false;
control.Fleeing = false;

// If nothing is engulfing me right now, see if there's something that might want to hunt me
(Entity Entity, Vector3 Position, float EngulfSize)? predator =
Expand All @@ -297,6 +298,8 @@ private void ChooseActions(in Entity entity, ref MicrobeAI ai, ref CompoundAbsor
if (control.State == MicrobeState.MucocystShield)
return;

control.Fleeing = true;

FleeFromPredators(ref position, ref ai, ref control, ref organelles, ref compoundStorage, entity,
predator.Value.Position, predator.Value.Entity, speciesFocus,
speciesActivity, speciesAggression, speciesFear, strain, random);
Expand Down Expand Up @@ -377,6 +380,12 @@ private void ChooseActions(in Entity entity, ref MicrobeAI ai, ref CompoundAbsor
ai.ATPThreshold = 0.0f;
}

// Use signaling agent if I have any with a chance of 5% per think
if (organelles.HasSignalingAgent && random.NextSingle() < Constants.AI_SIGNALING_CHANCE)
{
UseSignalingAgent(ref organelles, speciesAggression, ref signaling, ref control, random);
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

It seems like there's only one case where the signalling command is set to None. That means that cells do not stop signalling! That's a very, very major bug in my opinion because eventually I think most cells will just be signalling all the time.

Also I think another key part still missing is that cells should decide to ignore an incoming signalling command in certain situations (like if become aggressive signal is too far away, or a move signal is far away and the cell is not that full on resources).

Without those two things I think the signals will quite effectively destroy any useful AI behaviours as they'll get permanently locked into following the signal of the first species member of them that triggered it.

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

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

Do you have suggestions for when it should be set to no command?

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

I'd say whenever the original condition to set a signal is gone, or like after 15-30 seconds of the cell not feeling like it should send the same signal again. Something like that, but I'm sure someone else more familiar with the AI could come up with a more advanced codnitions.

}

// Follow received commands if we have them
if (organelles.HasSignalingAgent && signaling.ReceivedCommand != MicrobeSignalCommand.None)
{
Expand Down Expand Up @@ -525,6 +534,41 @@ private void ChooseActions(in Entity entity, ref MicrobeAI ai, ref CompoundAbsor
}
}

private void UseSignalingAgent(ref OrganelleContainer organelles, float speciesAggression,
ref CommandSignaler signaling, ref MicrobeControl control, Random random)
{
var willBeAggressiveThisTime = RollCheck(speciesAggression, Constants.MAX_SPECIES_AGGRESSION, random);
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.

willBeAggressiveThisTime -> shouldBecomeAggresive

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

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

Personally, I think that's an inaccurate name considering what the variable is being used for.

Copy link
Copy Markdown
Contributor

@Patryk26g Patryk26g Feb 24, 2026

Choose a reason for hiding this comment

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

As I said in other comment, future tense variables should be omitted.


if (organelles.HasBindingAgent)
{
signaling.QueuedSignalingCommand = MicrobeSignalCommand.MoveToMe;
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

This line seems useless so should be deleted (there's no early exit so we always execute the line signaling.QueuedSignalingCommand = MicrobeSignalCommand.None; after this).

Or alternatively it could be use some logic to detect when cells would be good to group together and would then set this but only if already in binding mode / going into binding mode, as otherwise it is useless to trigger this signal.

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

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

Doesn't it make more sense to remove the signaling.QueuedSignalingCommand = MicrobeSignalCommand.None; right at the end of the function?

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

Well there has to be a some quite common condition to reset the signal as I don't want the AI to be entirely made so that it is assumed that there's almost always a signal. It is better for signals to only be sent occasionally so that the AI just doesn't become a total mess where it is always just forced to respond to other signals.

Also for safety I think most "non-urgent" signals should not be activated if the current cell is receiving another signal as that just adds to the signal noise.

}

if (willBeAggressiveThisTime)
{
foreach (var organelle in organelles.Organelles!)
{
// Has pili or toxins
if (organelle.Definition.HasPilusComponent || organelles.AgentVacuoleCount > 0)
{
signaling.QueuedSignalingCommand = MicrobeSignalCommand.FollowMe;
break;
}

signaling.QueuedSignalingCommand = MicrobeSignalCommand.None;
Comment on lines +570 to +594
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

This loop looks very suspicious to me. I think instead what you actually want to do is first setup variables for pilus count, and then do a count of pili, and only then would you do the membersNearEnough calculation as that's an expensive calculation to do each loop iteration so I'm quite sure you didn't meant to put that logic inside this loop.

}
}
else if (!willBeAggressiveThisTime)
{
// TOOD
}

if (control.Fleeing)
{
signaling.QueuedSignalingCommand = MicrobeSignalCommand.FleeFromMe;
}
}

private bool CheckForHuntingConditions(ref MicrobeAI ai, ref WorldPosition position,
ref OrganelleContainer organelles, ref SpeciesMember ourSpecies,
ref Engulfer engulfer, ref CellProperties cellProperties, ref MicrobeControl control, ref Health health,
Expand Down