If I remember correctly, a while back we decided to treat a species as the total number of compound (free and locked) that it contains. In this case, the number of "points" you are talking about is simply a transfer of compounds from species to species or to/from the environment.
A. I am guessing these buckets are refilled using the co2 and nitrogen cycles you wrote a prototype on as well as organisms dying or releasing compounds into the environment.
B. Why do we have to split up into B1 and B2? Wouldn't it be better if we simply did both?
B1. Can't we simply run the process system you made (implemented by moopli in the current version) for an individual cells compound onto the whole species? From the above, we already have that a species is simply a compound bag, we can then just iterate and run all of the processes.
B2. Simply choosing random wouldn't work, since it will result in an interaction rate between species A equal for the following distribution (1 member of A and 1 member of B in huge patch; 1 member of A and 10000 members of B in huge patch, 10000 members of A and 10000 members of B in tiny patch). I'd say this is the hardest step of the whole CPA since we need to calculate the number of interactions using the species density and then calculate the outcome of the encounter).
C. How would similarity be determined? This will also lower diversity since two similar species could split into two separate and different species. I suggest changing this step to lowering the points of two species that occupy the same niche (since they are in direct competition for resources). If we do the above (B2) right, we wouldn't even need these steps, since the species that is better in its niche will automatically score more points than the other.
D. Again, why are we directly penalizing for being big? Having a large size has two consequences—a greater a compound requirement and slower movement. The former will decrease population size (since population size = compounds / compounds per cell) and autoevo will automatically work against a smaller population size, so only species that actually need more organelles will be able to justify having them. The slower movment will factor into B2, both for decreasing encounter rate and from decreasing speed to be able to run away.
In my movement thread we can calculate maximum speed by looking at cell shape, stokes' drag, and the number of movement organelles, which could be useful. An issue that arises is that it isn't directly speed vs speed, since a lot of slow cells (amoebas) can slowly envelop small and unsuspecting, but extremely fast cells since most cells are pretty blind.
I think we could have something along a behavior tree or finite state machine, where we check if the small cell noticed that large one and if it did we do a speed vs speed comparison and if it didn't we check attack vs defense. Alternatively we could try using the neural network we have planned for the AI and "solve" it to determine outcomes, which will be better in the long run, but much harder to do. Probably a simply offensive organelle count - defensive organelle count check for both species could do for now to test if other mechanics work.
In the beginning of the game there are huge amounts of compounds, so it isn't an issue, but you're right that it will be really problematic once compounds get locked and rarer. I think a better solution than random selection would be to, in pseudocode using glucose as an example:
local glucoseAmount = currentPatch.getGlucose()
for each species in species
local glucoseTaken = species.tryProcess(glucoseAmount, dt) // Doesn't actually take
totalGlucoseTaken += glucoseTaken
for each species in species do
species.runProcess(glucoseAmount / totalGlucoseTaken, dt) // Actually takes compounds
Basically, we see how much glucose each cell would take if it were chosen first and then given it proportionally that amount. This mimics that cells are all continuously running their processes simultaneously.
The only difference is the rate of process, so using my above code as an example, a cell with more mitochondria would be able to use much more glucose than other cells and as a result would have more ATP.
I think we should run them at the same time.
If a species keeps loosing compounds (due to predation in B2), it will eventually get to zero, which means that it has no more cells, so it goes extinct. At this point we can take the largest species population and split it into two species that go through the CPA system on their own. More realistically, we can take the most successful species in a neighboring patch and move it here. This keeps the total number of species constant, ideally one for each niche.
Wait... but wasn't it decided that each species is literally defined by a species-shared compounds store? Or are we no longer doing that?
We could use a probability distribution using the number of cells in one species, its average speed, and the average distance between members of a species to find out the total number of encounters between Species A and Species B. Then, if species B wins in step B2, it gets (numberOfEncounters(A,B) / totalNumberInSpecies(A) * totalCompoundsStored(A)) while the other species loses this amount. If you guys think this is a good idea, I could try writing a prototype, hopefully we'll get some sine curves.
Could you explain why you're subtracting organelles and compounds? I also think we could do without log10, just use mitoCount as it is. Large cells will be penalized in a different step.
No worries, you just need to put 4 spaces before each line. Here, I'll edit it for you to improve readability.
Great job so far everyone! A lot of great thoughts in this thread.