Multiple GenePool sets 

I'm trying to work with 2 Genepool sets instead of just one. I create the second genepool in the onExpDefLoad() function .
If I populate both GenePool with genotypes, and then save the experiment state, and then reload the experiment state only the first Genepool genotypes are there. The second genepool is always empty. The same happens if I do a 'save genotypes as' and then reload them - the second genepool is always empty.
Is there any way to save both genepools?

Does the GenePools.random() function return an index from the currently selected group or does it return the index of a genotype in any genepool? It isn't too important, right now I'm just using Math.random(GenePool.size) to be safe.

Further - once a random Genotype is selected in this manner, what is the best way to access the Creature object for it? (in this case all Genotypes have a creature in simulation). I tried to use the UID but discovered that the creature's uid is not the same as the genotype's uid.
I'm pretty sure i could just cycle through and check every creature in the Population to match the name, but is there a better method that I'm missing?

Thanks again for all your help. Loving this Framsticks program!

Forums: 
Szymon Ulatowski's picture

> Is there any way to save both genepools?

Yes, you can do it by implementing your own onExpSave and onExpLoad (similarly like you did for onExpDefLoad).
Start by replacing @include "standard_loadsave.inc" in your expdef by the contents of this .inc file, and then adjust it to handle more than one group.

The saving function is quite simple - just a series of File.writeXXX calls.
Add GenePools.group=1; File.writeObject(GenotypeGroup.*); to save your additional gene pool parameters, and then duplicate the loop to save individual genotypes.

Loading is more complicated because the script has to react to the incoming data. If we know that our file only contains one object of a given class, it can be handled automatically by declaring this object to the loader (Loader.addClass(...)). Multiple objects must be handled by event handlers that redirect data to an existing object (like population parameters) or create new objects (like genotypes).

I think you only need to make 2 changes to handle multiple groups:

1. Select the second group after loading the first one (in onExpLoad_Object(), check if we are loading a GenotypeGroup and react accordingly). standard_loadsave.inc uses a variable in ExpState to determine if the incoming group is "Creatures" or "Food". Another approach could use Loader.setBreakLabel(Loader.AfterObject, "onExpLoad_AfterObject") to increment the GenePools.group after an object of the class "GenotypeGroup" is loaded.

2. onExpLoad_Unknown() currently can only create new genotypes in group 0 because of the GenePools.copySelected(0) call. This should be changed to GenePools.copySelected(GenePools.group);

NOTE: standard_loadsave.inc uses the old names for GenePool and Population (GenotypeGroup and CreaturesGroup) in all File/Loader related calls to keep the resulting files compatible with older versions of Framsticks.




> Does the GenePools.random() function return an index from the currently selected group?

Yes.




> What is the best way to access the Creature object for the selected Genotype?

Sorry, there is no built-in function for it, so you will have to iterate through population(s). Matching the genotype is probably a better idea than using the name field (as the name is not guaranteed to be unique), or, even better, assign the genotype.uid to the creature's user field and later use it to identify the correct creature.

Perfect! Works great... thanks for the help guys :)