# Auto-Evo refactor to reduce memory usage

**URL:** https://forum.revolutionarygamesstudio.com/t/auto-evo-refactor-to-reduce-memory-usage/1276
**Category:** Programming
**Created:** [September 7, 2026, 1:57pm UTC](https://forum.revolutionarygamesstudio.com/t/auto-evo-refactor-to-reduce-memory-usage/1276 "2026-09-07T13:57:22Z")
**Posts on this page:** 20
**Page:** 1

<div class="post-metadata">

### Author: ![Rathalos](https://thrivedevforum-cdn.b-cdn.net/user_avatar/forum.revolutionarygamesstudio.com/rathalos/32/2504_2.png) [@Rathalos](https://forum.revolutionarygamesstudio.com/u/Rathalos)
#### Post date: [September 7, 2026, 1:57pm UTC](https://forum.revolutionarygamesstudio.com/t/auto-evo-refactor-to-reduce-memory-usage/1276/1 "2026-09-07T13:57:23Z")

</div>

There’s been [a thread](https://forum.revolutionarygamesstudio.com/t/auto-evo-performance/1226) earlier this year about auto-evo performance, but I want to discuss a more specific project here.

I will note that there is now also a separate [Github project](https://github.com/orgs/Revolutionary-Games/projects/9/views/1) to handle auto-evo optimisation. And a lot of other work to optimise auto-evo is currently happening (since I started writing this, actually).

* * *

For a while now, there’s been a consensus that the current auto-evo method of making a full clone of species for every mutation attempted is wasting a lot of memory. This causes problems on systems with limited memory available, and may slow down auto-evo as a whole. As far as I am aware, there are also two proposals to handle this.

As:

- I suspect further additions to the auto-evo system will just make attempting this more difficult.
- Any kind of performance improvement at all for auto-evo would be greatly appreciated to:
  - Ensure further Multicellular additions do not bloat waiting times.
  - Allow more species in parallel so that prokaryote, eukaryote and Multicellular Species can actually all exist in parallel instead of one dominating.

- Even after moving to Macroscopic in the near future, we probably will still use a system related to this for Macroscopic auto-evo.

I think this may be a good time to attempt this architectural change.

The proposals I have seen, as I understand them:

- Hhyyrylainen has often suggested switching to a system where “auto-evo is only allowed to work with readonly species + a mutation list wrapper and never directly modify species.”
- @Gamedungeon has suggested that we look at immutable data structures, designed so when you clone them it only stores the changes and links back for everything else.

For the first option I at least know that the first step would be to ensure all the auto-evo calculations use ReadOnly interfaces. However, those ReadOnly interfaces themselves are not always set up with the best memory allocation efficiency. So those would likely also have to be updated. For example the ReadOnly interfaces do not allow using indexes to iterate in a loop over organelles as:  
“implementing that for facade classes would be difficult. The only way it would work with good performance is that on first index call after each modification it would need to generate a list of organelles to use indexing on. Right now it avoids that by just creating a single enumerator instance instead.”  
So this would likely have to be updated as well.

I do not yet have a good grasp on what the second option would entail in a practical sense.

* * *

The objective of this post is to keep track of the discussion thus far, and not let it be lost in Discord mentions that nobody ever sees again. Please let me know if I misunderstood or missed anything.

I also hope that we can come to some consensus on what should be done so that anyone who _is_ interested in working on this has some idea of what to do to complete the plan. So any suggestions on that front are more than welcome.

---

<div class="post-metadata">

### Author: ![hhyyrylainen](https://thrivedevforum-cdn.b-cdn.net/user_avatar/forum.revolutionarygamesstudio.com/hhyyrylainen/32/2243_2.png) [@hhyyrylainen](https://forum.revolutionarygamesstudio.com/u/hhyyrylainen)
#### Post date: [September 7, 2026, 2:29pm UTC](https://forum.revolutionarygamesstudio.com/t/auto-evo-refactor-to-reduce-memory-usage/1276/2 "2026-09-07T14:29:16Z")

</div>

> [@Rathalos](#):
>
> I do not yet have a good grasp on what the second option would entail in a practical sense.

I feel like that the second suggestion is very similar to mine, just worded differently. Though immutable data structures here might mean that we would first move data from species → immutable version → then calculate with immutable and select results → move the data back. My idea tries to avoid that by just providing the readonly interface to the species data, so any species object can just be interacted with as if it was readonly. So we don’t need to shuffle the data to a secondary source and then do something on it and then move it back.

Of course if we were so ambitious as to remake auto-evo calculations as data oriented calculation, SIMD, or even as a compute shader, these would build upon the base of immutable species data representation in a flat structure. But I think this further step would be even harder and would make modifying auto-evo a lot harder in the future as anyone working on it needs to really understand the data patterns and how the processing flow works. So I don’t really see this option as realistic due to the amount of work, and ongoing problems if the person who manages this conversion then ever leaves the team and there isn’t anyone who is as skilled in these techniques around to continue the work.

But yeah my point is that my idea and GameDungeon’s is basically the same core idea.

---

<div class="post-metadata">

### Author: ![CheviLevi](https://thrivedevforum-cdn.b-cdn.net/letter_avatar_proxy/v4/letter/c/82dd89/32.png) [@CheviLevi](https://forum.revolutionarygamesstudio.com/u/CheviLevi)
#### Post date: [September 8, 2026, 3:34pm UTC](https://forum.revolutionarygamesstudio.com/t/auto-evo-refactor-to-reduce-memory-usage/1276/3 "2026-09-08T15:34:17Z")

</div>

I’m still trying to understand everything, but currently I got an idea that at least we can reuse some small data chunks that can be used in different calculation branches, and we might can further delay some of the calculation relates to the data chunks so that if the branches are pruned, we won’t need to do those delayed calculation.  
Now this is more related to performance improvement and might lead to more memory allocation, but I’ll leave the comment here as it might affect the final architecture.

---

<div class="post-metadata">

### Author: ![xfractalino](https://thrivedevforum-cdn.b-cdn.net/user_avatar/forum.revolutionarygamesstudio.com/xfractalino/32/2659_2.png) [@xfractalino](https://forum.revolutionarygamesstudio.com/u/xfractalino)
#### Post date: [September 8, 2026, 4:54pm UTC](https://forum.revolutionarygamesstudio.com/t/auto-evo-refactor-to-reduce-memory-usage/1276/4 "2026-09-08T16:54:02Z")

</div>

My idea to make the Auto-Evo algorithm both faster and less heavy on the memory is to use readonly structures as intermediate data containers for the species, and run matrix math for the scoring system and the mutation strategies that can be vectorized. The algorithm goes roughly like this:

- Represent each species as an immutable structure that contains all the data, roughly:

```auto
[InlineArray(OrganelleTypeCount)]
public struct OrganelleCounts { private ushort element0; }

public readonly struct SpeciesTraits
{
    public const int OrganelleTypeCount = 32;

    public readonly OrganelleCounts Organelles; // 64 bytes

    public readonly float Inertia;
    public readonly float CiliaFactor;
    // ... force

    // ...membrane

    public readonly float SpecializationBonus;
    public readonly bool IsBacteria;

    // Upgrade fields that scoring actually reads
    public readonly float FlagellumLengthTotal;
    public readonly ToxinType DominantToxin;
    public readonly Compound ChemoreceptorTarget;

    public readonly BehaviourValues Behaviour;
    public readonly ToleranceValues Tolerances; 

    public readonly ulong ContentHash; // this would be calculated by hashing the above
}

```

- And then have an AoS of the above struct for the calculations. That should be around 128 to 256 bytes per species.One could also have analogously a SoA of the above data to batch the mutations.

- On AutoEvo run begin, we convert each species to the above struct.

- Each mutation strategy becomes a delta on the count row. A batch of K candidates from one parent is the parent row broadcast plus a sparse delta matrix, and MP cost is a dot product against the per-organelle cost vector. This is easily vectorizable on the CPU using SIMD. AddOrganelleAnywhere is exempt in this step, because it can’t be vectorized, so it remains unchanged.

- Scoring system: hex size, mass, osmoregulation, storage capacity, process rates are one matrix product against a property table, precomputed. Predation canm be roughly a N×M interaction between candidates and prey

- Selection algorithm is unchanged

- Back to species for the survivals by going from the struct to the species

---

<div class="post-metadata">

### Author: ![Rathalos](https://thrivedevforum-cdn.b-cdn.net/user_avatar/forum.revolutionarygamesstudio.com/rathalos/32/2504_2.png) [@Rathalos](https://forum.revolutionarygamesstudio.com/u/Rathalos)
#### Post date: [September 9, 2026, 8:02am UTC](https://forum.revolutionarygamesstudio.com/t/auto-evo-refactor-to-reduce-memory-usage/1276/5 "2026-09-09T08:02:36Z")

</div>

> [@hhyyrylainen](#):
>
> I feel like that the second suggestion is very similar to mine, just worded differently. Though immutable data structures here might mean that we would first move data from species → immutable version → then calculate with immutable and select results → move the data back. My idea tries to avoid that by just providing the readonly interface to the species data, so any species object can just be interacted with as if it was readonly. So we don’t need to shuffle the data to a secondary source and then do something on it and then move it back.

The shuffling back and forth would itself also cost time and use some memory I am guessing? If yes I guess that’s a point in favour of your solution?

> [@hhyyrylainen](#):
>
> But yeah my point is that my idea and GameDungeon’s is basically the same core idea.

Similar enough that GameDungeon’s would also still require shifting the existing calculations to ReadOnly interfaces? Or is that a point of difference?

> [@xfractalino](#):
>
> My idea to make the Auto-Evo algorithm both faster and less heavy on the memory is to use readonly structures as intermediate data containers for the species, and run matrix math for the scoring system and the mutation strategies that can be vectorized.
> 
> …
> 
> - Selection algorithm is unchanged

To clarify, the architecture of the score conditions and which mutationStrategies to use would also be the same, just with the “cloning system” being replaced?

> [@xfractalino](#):
>
> - AddOrganelleAnywhere is exempt in this step, because it can’t be vectorized, so it remains unchanged.

AddOrganelle makes up a large proportion of the the mutations unfortunately. I am guessing the same also goes for removing organelles?

Is your solution compatible with using one of the other mentioned strategies?

---

<div class="post-metadata">

### Author: ![hhyyrylainen](https://thrivedevforum-cdn.b-cdn.net/user_avatar/forum.revolutionarygamesstudio.com/hhyyrylainen/32/2243_2.png) [@hhyyrylainen](https://forum.revolutionarygamesstudio.com/u/hhyyrylainen)
#### Post date: [September 9, 2026, 8:39am UTC](https://forum.revolutionarygamesstudio.com/t/auto-evo-refactor-to-reduce-memory-usage/1276/6 "2026-09-09T08:39:21Z")

</div>

> [@Rathalos](#):
>
> The shuffling back and forth would itself also cost time and use some memory I am guessing? If yes I guess that’s a point in favour of your solution?

Yeah, a little bit. But considering the overall auto-evo cost, it wouldn’t be that much, but still a little bit.

> [@Rathalos](#):
>
> Similar enough that GameDungeon’s would also still require shifting the existing calculations to ReadOnly interfaces? Or is that a point of difference?

GameDungeon’s suggestion would require totally duplicate calculations. Because the existing methods couldn’t work whatsoever with the different representation. That’s why I want to use the readonly interfaces as those could share math between gameplay, editor, and auto-evo. If auto-evo uses a totally incompatible representation then that means more calculation code duplication.

> [@Rathalos](#):
>
> To clarify, the architecture of the score conditions and which mutationStrategies to use would also be the same, just with the “cloning system” being replaced?

From my understanding this would be a radical difference.

So instead of being allowed to calculate organelle counts and stats etc. of species and compare them.

So it would be like each species would get a vector of some length of data, for example species might be

0xfa231abfed234

and

0xffa126293bda3

and the speedup would come from having then some bit operations that would work on those lists of bits and that would somehow score each species. This would be extremely fast, but I don’t foresee anyone else ever being able to add any new operations to auto-evo if we convert it to that. It would be super fast but would basically lock in the basic operations auto-evo supports and then that’s it.

> [@Rathalos](#):
>
> AddOrganelle makes up a large proportion of the the mutations unfortunately. I am guessing the same also goes for removing organelles?

Organelle removal can probably be encoded into the bit representations of species, adding organelles is much harder to fit in. So that’s probably why fractalino said that.

---

<div class="post-metadata">

### Author: ![xfractalino](https://thrivedevforum-cdn.b-cdn.net/user_avatar/forum.revolutionarygamesstudio.com/xfractalino/32/2659_2.png) [@xfractalino](https://forum.revolutionarygamesstudio.com/u/xfractalino)
#### Post date: [September 9, 2026, 2:36pm UTC](https://forum.revolutionarygamesstudio.com/t/auto-evo-refactor-to-reduce-memory-usage/1276/7 "2026-09-09T14:36:42Z")

</div>

> [@Rathalos](#):
>
> The shuffling back and forth would itself also cost time and use some memory I am guessing? If yes I guess that’s a point in favour of your solution?

Actually I think much of that time doing indirections accessing objects is very cache-unfriendly, so the idea of using immutable data structures as intermediate representations to calculate and then move the data back would be best in my opinion. Using a readonly interface to the data has one indirection per access, and one indirection per whatever internal object there is in the readonly view. That’s why I’m in favour of using only immutable representations, ideally structs with primitive data in them.

> [@Rathalos](#):
>
> To clarify, the architecture of the score conditions and which mutationStrategies to use would also be the same, just with the “cloning system” being replaced?

My idea is to keep the same architecture of score conditions and mutation strategies to keep the hypothetical new algorithm as faithful as the current one. The only thing being replaced is the cloning operations and the math is vectorized.

> [@Rathalos](#):
>
> AddOrganelle makes up a large proportion of the the mutations unfortunately.

I agree but AddOrganelle can’t be vectorized as it’s a spatial search operation over the hex layout, so yeah that’s unfortunate. Anyway, having a readonly view on that will probably prevent a couple of indirections. This specific optimisation also works _without_ my proposed solution, just by using immutable data.

> [@hhyyrylainen](#):
>
> and the speedup would come from having then some bit operations that would work on those lists of bits and that would somehow score each species.

Not necessarily bit operations, but vector operations over the data, but you get the idea.

> [@hhyyrylainen](#):
>
> Organelle removal can probably be encoded into the bit representations of species, adding organelles is much harder to fit in. So that’s probably why fractalino said that.

Yes, that’s it.

---

<div class="post-metadata">

### Author: ![hhyyrylainen](https://thrivedevforum-cdn.b-cdn.net/user_avatar/forum.revolutionarygamesstudio.com/hhyyrylainen/32/2243_2.png) [@hhyyrylainen](https://forum.revolutionarygamesstudio.com/u/hhyyrylainen)
#### Post date: [September 9, 2026, 5:37pm UTC](https://forum.revolutionarygamesstudio.com/t/auto-evo-refactor-to-reduce-memory-usage/1276/8 "2026-09-09T17:37:44Z")

</div>

I am interested to see how such an approach would work.

I think a big problem will be the organelle addition, because if I’m not totally wrong quite a significant (if not the biggest) part of time in auto-evo is spent in processing organelle addition (or cell addition) operations.

> [@xfractalino](#):
>
> Actually I think much of that time doing indirections accessing objects is very cache-unfriendly, so the idea of using immutable data structures as intermediate representations to calculate and then move the data back would be best in my opinion. Using a readonly interface to the data has one indirection per access, and one indirection per whatever internal object there is in the readonly view. That’s why I’m in favour of using only immutable representations, ideally structs with primitive data in them.

That is true, blasting through contiguous data in memory is very fast.

---

<div class="post-metadata">

### Author: ![xfractalino](https://thrivedevforum-cdn.b-cdn.net/user_avatar/forum.revolutionarygamesstudio.com/xfractalino/32/2659_2.png) [@xfractalino](https://forum.revolutionarygamesstudio.com/u/xfractalino)
#### Post date: [September 9, 2026, 6:03pm UTC](https://forum.revolutionarygamesstudio.com/t/auto-evo-refactor-to-reduce-memory-usage/1276/9 "2026-09-09T18:03:44Z")

</div>

> [@hhyyrylainen](#):
>
> I think a big problem will be the organelle addition, because if I’m not totally wrong quite a significant (if not the biggest) part of time in auto-evo is spent in processing organelle addition (or cell addition) operations.

I counted the total samples taken in `AutoEvo.AddOrganelleAnywhere::MutationsOf` from the latest flame graph and it accounts for 2.88% of total. So, it’s definitely a good part of it, but apparently there are calculations _more_ expensive than that:

```auto
217.3B ns 4.03% AutoEvo.SimulationCache::CalculatePredationScore
205.3B ns 3.80% Systems.ProcessSystem::ComputeCompoundBalance
174.2B ns 3.23% Systems.ProcessSystem::CalculateProcessMaximumSpeed
165.1B ns 3.06% AutoEvo.ReproductionCompoundPressure::Score
149.2B ns 2.76% CollectionsMarshal::GetValueRefOrNullRef (most of this is likely from the cache)
147.3B ns 2.73% AutoEvo.SimulationCache::GetPressureScore
141.8B ns 2.63% AutoEvo.ModifyExistingSpecies::PruneMutations (self)
133.2B ns 2.47% MicrobeInternalCalculations::GetTotalSpecificCapacity
127.0B ns 2.35% MicrobeInternalCalculations::AddSpecificCapacity
125.1B ns 2.32% HexLayout<T>::GetElementAt (mostly from addition)
119.9B ns 2.22% Hex::Equals (mostly from addition)

```

These are ranked by **self-time** , so there’s no dependence from child nodes.

---

<div class="post-metadata">

### Author: ![hhyyrylainen](https://thrivedevforum-cdn.b-cdn.net/user_avatar/forum.revolutionarygamesstudio.com/hhyyrylainen/32/2243_2.png) [@hhyyrylainen](https://forum.revolutionarygamesstudio.com/u/hhyyrylainen)
#### Post date: [September 9, 2026, 6:13pm UTC](https://forum.revolutionarygamesstudio.com/t/auto-evo-refactor-to-reduce-memory-usage/1276/10 "2026-09-09T18:13:09Z")

</div>

Well that doesn’t really tell anything, unfortunately… as mutation tests will all basically call for the scoring and those then call the predation, compound balance, etc.

So I think sorting by self time is kind of the bad way to look at the data. Of course if you look at self time and you _can_ see something to improve, that’s good. But if most of the predation etc. score requests are triggered by a certain kind of mutation, then that’s going to be totally invisible when sorting by self time, which is why I haven’t looked at auto-evo that way at all…

---

<div class="post-metadata">

### Author: ![xfractalino](https://thrivedevforum-cdn.b-cdn.net/user_avatar/forum.revolutionarygamesstudio.com/xfractalino/32/2659_2.png) [@xfractalino](https://forum.revolutionarygamesstudio.com/u/xfractalino)
#### Post date: [September 11, 2026, 10:28am UTC](https://forum.revolutionarygamesstudio.com/t/auto-evo-refactor-to-reduce-memory-usage/1276/11 "2026-09-11T10:28:10Z")

</div>

> [@hhyyrylainen](#):
>
> So I think sorting by self time is kind of the bad way to look at the data.

Oh yeah, that’s probably true. I sorted them by actual time. This is for the strategies:

```auto
time time% calls strategy
899,866,354,962 16.67% 101 RemoveOrganelle
155,581,791,979 2.88% 62 AddOrganelleAnywhere
 42,259,152,200 0.78% 19 ChangeBehaviorScore
  3,796,322,515 0.07% 6 ModifyOrganelleBase
  3,143,802,321 0.06% 6 ChangeMembraneType

```

And the following for the pressure system:

```auto
1,358,175,921,280 25.16% 120 GeneralAvoidPredationSelectionPressure
  439,220,168,490 8.14% 108 ReproductionCompoundPressure
  233,999,541,855 4.33% 44 ChunkCompoundPressure
  105,204,232,193 1.95% 17 PredationEffectivenessPressure
   94,491,092,883 1.75% 30 CompoundCloudPressure
   58,797,225,787 1.09% 38 EnergyConsumptionPressure
   57,694,058,070 1.07% 35 CompoundConversionEfficiencyPressure
   34,876,901,786 0.65% 25 MaintainCompoundPressure
   32,721,076,793 0.61% 24 EnvironmentalTolerancePressure
    7,664,773,880 0.14% 9 EnvironmentalCompoundPressure
    1,485,405,983 0.03% 3 MetabolicStabilityPressure

```

So, apparently the most expensive strategy is the `RemoveOrganelle` one, which is pretty interesting since it takes _most_ of the time.

As for the pressures, 25% is just from `GeneralAvoidPredationSelectionPressure`, but this is already well known.

---

<div class="post-metadata">

### Author: ![hhyyrylainen](https://thrivedevforum-cdn.b-cdn.net/user_avatar/forum.revolutionarygamesstudio.com/hhyyrylainen/32/2243_2.png) [@hhyyrylainen](https://forum.revolutionarygamesstudio.com/u/hhyyrylainen)
#### Post date: [September 11, 2026, 10:42am UTC](https://forum.revolutionarygamesstudio.com/t/auto-evo-refactor-to-reduce-memory-usage/1276/12 "2026-09-11T10:42:31Z")

</div>

> [@xfractalino](#):
>
> So, apparently the most expensive strategy is the `RemoveOrganelle` one, which is pretty interesting since it takes _most_ of the time.

Way back in time, the remove organelle code was allowed like just a few attempts, but I believe the new code has been changed to almost allow it to try to remove every organelle one by one (as long as there’s enough MP). So in truth I’ve been kind of scared of the performance implications of that. And I think this profiling does reveal that.

So I think we need a smarter algorithm for determining what to remove, and to put a very hard cap on the max removal attempts to curb the performance impact of it.

---

<div class="post-metadata">

### Author: ![xfractalino](https://thrivedevforum-cdn.b-cdn.net/user_avatar/forum.revolutionarygamesstudio.com/xfractalino/32/2659_2.png) [@xfractalino](https://forum.revolutionarygamesstudio.com/u/xfractalino)
#### Post date: [September 11, 2026, 11:17am UTC](https://forum.revolutionarygamesstudio.com/t/auto-evo-refactor-to-reduce-memory-usage/1276/13 "2026-09-11T11:17:16Z")

</div>

> [@hhyyrylainen](#):
>
> So I think we need a smarter algorithm for determining what to remove, and to put a very hard cap on the max removal attempts to curb the performance impact of it.

Yeah, and it seems like most of the time is concentrated in few parts, so before doing any huge refactor, it would probably be wiser to see how much we gain from these isolated optimisations alone.

> [@hhyyrylainen](#):
>
> Way back in time, the remove organelle code was allowed like just a few attempts, but I believe the new code has been changed to almost allow it to try to remove every organelle one by one (as long as there’s enough MP)

I can imagine why has it been changed to do this. Surely it’s much more accurate to try every possible combination, and I really can’t think of a better way, because if we were to pick a random subset of organelles and only try to remove those, that might cause bigger statistical fluctuations, even though it’s a stochastically equivalent approach. But we don’t run infinitely many generations, so picking a random subset would surely make the remove strategy _less_ stable.

So, we either find a way to run some heuristics to select the organelles that may be worth to remove, or make removal itself less expensive.

---

<div class="post-metadata">

### Author: ![Kashnox](https://thrivedevforum-cdn.b-cdn.net/letter_avatar_proxy/v4/letter/k/85e7bf/32.png) [@Kashnox](https://forum.revolutionarygamesstudio.com/u/Kashnox)
#### Post date: [September 11, 2026, 11:32am UTC](https://forum.revolutionarygamesstudio.com/t/auto-evo-refactor-to-reduce-memory-usage/1276/14 "2026-09-11T11:32:10Z")

</div>

If we’re not already doing this, we should be able to significantly speed things up by making sure we don’t check functionally equivalent combinations of removals more than once. For example, if a cell has 10 cytoplasms and 5 ferroplasts, I don’t think we need to check removing cytoplasm A and ferroplast A, then cytoplasm A and ferroplast B, all the way up to cytoplasm J and ferroplast E. Technically, each cytoplasm and ferroplast removed would have a slightly different impact on cell rotation speed, but that doesn’t seem worth all the extra calculations to me.

---

<div class="post-metadata">

### Author: ![Rathalos](https://thrivedevforum-cdn.b-cdn.net/user_avatar/forum.revolutionarygamesstudio.com/rathalos/32/2504_2.png) [@Rathalos](https://forum.revolutionarygamesstudio.com/u/Rathalos)
#### Post date: [September 11, 2026, 12:05pm UTC](https://forum.revolutionarygamesstudio.com/t/auto-evo-refactor-to-reduce-memory-usage/1276/15 "2026-09-11T12:05:12Z")

</div>

> [@hhyyrylainen](#):
>
> > [@xfractalino](#):
> >
> > So, apparently the most expensive strategy is the `RemoveOrganelle` one, which is pretty interesting since it takes _most_ of the time.
> 
> Way back in time, the remove organelle code was allowed like just a few attempts, but I believe the new code has been changed to almost allow it to try to remove every organelle one by one (as long as there’s enough MP).

![afbeelding](https://thrivedevforum-uploads.b-cdn.net/original/2X/4/44b93e0063aa61acaeb68baa6a173bc9212e235e.png)  
Looks like it’s currently set to 10 (which is higher than I thought it was), and keep in mind that’s for every existing mutant that gets fed into it. And that’s indeed just a random subset:  
 ![afbeelding](https://thrivedevforum-uploads.b-cdn.net/optimized/2X/6/691066ee90e5adf6ad119c66bba3169bf1345187_2_690x32.png)

> [@xfractalino](#):
>
> So, we either find a way to run some heuristics to select the organelles that may be worth to remove, or make removal itself less expensive.

Well, the expense of the removal itself is just that it needs to run all the score calculations. And the mutation strategy for “delete anything” pretty much _has_ to be at the bottom of the tree, or it will make nonsensical deletion whose resulting mutants will just get pruned later anyway.

But making smarter deletions is possible I think. In particular:

> [@Kashnox](#):
>
> If we’re not already doing this, we should be able to significantly speed things up by making sure we don’t check functionally equivalent combinations of removals more than once. For example, if a cell has 10 cytoplasms and 5 ferroplasts, I don’t think we need to check removing cytoplasm A and ferroplast A, then cytoplasm A and ferroplast B, all the way up to cytoplasm J and ferroplast E. Technically, each cytoplasm and ferroplast removed would have a slightly different impact on cell rotation speed, but that doesn’t seem worth all the extra calculations to me.

I agree with Kashnox here, and think we can change to only attempting to delete one of each organelle _type_ (though maybe accounting for upgrades?). We can either have one of each type picked at random or (if it can be computed cheaply enough) determine which would have the most positive effect on rotation/movement speed.

---

<div class="post-metadata">

### Author: ![xfractalino](https://thrivedevforum-cdn.b-cdn.net/user_avatar/forum.revolutionarygamesstudio.com/xfractalino/32/2659_2.png) [@xfractalino](https://forum.revolutionarygamesstudio.com/u/xfractalino)
#### Post date: [September 11, 2026, 12:21pm UTC](https://forum.revolutionarygamesstudio.com/t/auto-evo-refactor-to-reduce-memory-usage/1276/16 "2026-09-11T12:21:18Z")

</div>

> [@Rathalos](#):
>
> And that’s indeed just a random subset

I agree, but 10 is a big enough subset to prevent the effect I described.

> [@Rathalos](#):
>
> Well, the expense of the removal itself is just that it needs to run all the score calculations.

That’s not quite it. Almost all of the expense of the removal is actually due to `AddIfPossible`, and `AttachIslandHexes`. I’m currently studying the safest way to replace `AddIfPossible` with `AddFast`, as @hhyyrylainen said it caused a rare error in the past. `AttachIslandHexes`, however, can’t be replaced.

 ![image](https://thrivedevforum-uploads.b-cdn.net/original/2X/a/a2e376681b62b52aa84ab41732d7465d91504a5e.png)

> [@Rathalos](#):
>
> We can either have one of each type picked at random

This would have the effect I described, because picking one at random requires many generations to become equivalent to the current method, and would have a potentially dramatic difference from the current algorithm. It would basically turn into a Montecarlo algorithm, but over generations.

---

<div class="post-metadata">

### Author: ![Rathalos](https://thrivedevforum-cdn.b-cdn.net/user_avatar/forum.revolutionarygamesstudio.com/rathalos/32/2504_2.png) [@Rathalos](https://forum.revolutionarygamesstudio.com/u/Rathalos)
#### Post date: [September 11, 2026, 12:26pm UTC](https://forum.revolutionarygamesstudio.com/t/auto-evo-refactor-to-reduce-memory-usage/1276/17 "2026-09-11T12:26:48Z")

</div>

> [@xfractalino](#):
>
> > [@Rathalos](#):
> >
> > Well, the expense of the removal itself is just that it needs to run all the score calculations.
> 
> That’s not quite it. Almost all of the expense of the removal is actually due to `AddIfPossible`, and `AttachIslandHexes`. I’m currently studying the safest way to replace `AddIfPossible` with `AddFast`, as @hhyyrylainen said it caused a rare error in the past. `AttachIslandHexes`, however, can’t be replaced.
> 
> ![image](https://thrivedevforum-uploads.b-cdn.net/original/2X/a/a2e376681b62b52aa84ab41732d7465d91504a5e.png)

Well that certainly is also worth investigating!

But what I was referring to is that with apparently a lot of mutants being generated by RemoveOrganelle, that directly makes up a decent percentage of the number of times  
GeneralAvoidPredationSelectionPressure gets called.

So reducing the number of mutants output is also worth trying.

---

<div class="post-metadata">

### Author: ![Kashnox](https://thrivedevforum-cdn.b-cdn.net/letter_avatar_proxy/v4/letter/k/85e7bf/32.png) [@Kashnox](https://forum.revolutionarygamesstudio.com/u/Kashnox)
#### Post date: [September 11, 2026, 12:30pm UTC](https://forum.revolutionarygamesstudio.com/t/auto-evo-refactor-to-reduce-memory-usage/1276/18 "2026-09-11T12:30:33Z")

</div>

I don’t think we need to limit it to one removal per type, we just need to stop it from trying to remove the same combination of organelle types more than once.

It’s okay if it wants to remove 3 cytoplasms, but it doesn’t need to try removing Cytoplasm 1 alone, then removing Cytoplasm 2 alone, then removing Cytoplasm 3 alone, then removing Cytoplasm 1 and Cytoplasm 2, then removing Cytoplasm 1 and Cytoplasm 3, then removing Cytoplasm 2 and Cytoplasm 3, then removing Cytoplasm 1, Cytoplasm 2, and Cytoplasm 3. (7 removals total)

Instead, it can try removing Cytoplasm 1 alone, then removing Cytoplasm 1 and Cytoplasm 2, then removing Cytoplasm 1, Cytoplasm 2, and Cytoplasm 3. (3 removals total)

Sorry for the long example, but I think being long helps emphasize the point.

---

<div class="post-metadata">

### Author: ![Rathalos](https://thrivedevforum-cdn.b-cdn.net/user_avatar/forum.revolutionarygamesstudio.com/rathalos/32/2504_2.png) [@Rathalos](https://forum.revolutionarygamesstudio.com/u/Rathalos)
#### Post date: [September 11, 2026, 12:41pm UTC](https://forum.revolutionarygamesstudio.com/t/auto-evo-refactor-to-reduce-memory-usage/1276/19 "2026-09-11T12:41:01Z")

</div>

That’s actually not quite how it works I believe? For every organelle it tries, it removes only _that_ organelle and then creates a mutant for it. If that mutant does not score positively, it’s not used as a base to try anything else to begin with. (though like most other mutation strategies, this one _is_ repeated a few times)

I guess it _could_ be changed to instead produce mutants with combinations of several organelles deleted at once, with the strategy made non-repeatable. But if we try every combination possible via the current system I don’t know if that would actually reduce the number of mutants tested?

---

<div class="post-metadata">

### Author: ![Kashnox](https://thrivedevforum-cdn.b-cdn.net/letter_avatar_proxy/v4/letter/k/85e7bf/32.png) [@Kashnox](https://forum.revolutionarygamesstudio.com/u/Kashnox)
#### Post date: [September 11, 2026, 12:45pm UTC](https://forum.revolutionarygamesstudio.com/t/auto-evo-refactor-to-reduce-memory-usage/1276/20 "2026-09-11T12:45:05Z")

</div>

Ah, okay, then I think what you said is basically what I was thinking. If the mutant with Cytoplasm 1 removed didn’t survive, we don’t need to check if the mutant with Cytoplasm 2 will survive. I just assumed all the removals happened at once.

[Next page](https://forum.revolutionarygamesstudio.com/t/auto-evo-refactor-to-reduce-memory-usage/1276.md?page=2)
