public IncreaseBiodiversity(AutoEvoConfiguration configuration, PatchMap map, Patch patch, Random random)
 {
     this.map           = map;
     this.patch         = patch;
     this.configuration = configuration;
     this.random        = new Random(random.Next());
 }
Exemple #2
0
 public SimulationConfiguration(AutoEvoConfiguration autoEvoConfiguration, PatchMap initialConditions,
                                int steps = 1)
 {
     AutoEvoConfiguration = autoEvoConfiguration;
     OriginalMap          = initialConditions;
     StepsLeft            = Math.Max(1, steps);
 }
Exemple #3
0
 public FindBestMigration(AutoEvoConfiguration configuration, PatchMap map, Species species,
                          Random random, int migrationsToTry, bool allowNoMigration) : base(migrationsToTry, allowNoMigration)
 {
     this.configuration = configuration;
     this.map           = map;
     this.species       = species;
     this.random        = new Random(random.Next());
 }
Exemple #4
0
    /// <summary>
    ///   Loads the simulation configuration parameters from JSON files
    /// </summary>
    /// <remarks>
    ///   This is now loaded in _Ready as otherwise the <see cref="ModLoader"/>'s _Ready would run after simulation
    ///   parameters are loaded causing some data that might want to be overridden by mods to be loaded too early.
    /// </remarks>
    public override void _Ready()
    {
        base._Ready();

        // Compounds are referenced by the other json files so it is loaded first and instance is assigned here
        instance = this;

        // Loading the compounds needs a custom JSON deserializer that can load the Compound objects, but the loader
        // can't always be active because that breaks saving
        {
            var compoundDeserializer = new JsonConverter[] { new CompoundLoader(null) };

            compounds = LoadRegistry <Compound>(
                "res://simulation_parameters/microbe_stage/compounds.json", compoundDeserializer);
        }

        membranes = LoadRegistry <MembraneType>(
            "res://simulation_parameters/microbe_stage/membranes.json");
        backgrounds = LoadRegistry <Background>(
            "res://simulation_parameters/microbe_stage/backgrounds.json");
        biomes = LoadRegistry <Biome>(
            "res://simulation_parameters/microbe_stage/biomes.json");
        bioProcesses = LoadRegistry <BioProcess>(
            "res://simulation_parameters/microbe_stage/bio_processes.json");
        organelles = LoadRegistry <OrganelleDefinition>(
            "res://simulation_parameters/microbe_stage/organelles.json");

        NameGenerator = LoadDirectObject <NameGenerator>(
            "res://simulation_parameters/microbe_stage/species_names.json");

        musicCategories = LoadRegistry <MusicCategory>("res://simulation_parameters/common/music_tracks.json");

        helpTexts = LoadRegistry <HelpTexts>("res://simulation_parameters/common/help_texts.json");

        inputGroups = LoadListRegistry <NamedInputGroup>("res://simulation_parameters/common/input_options.json");

        autoEvoConfiguration =
            LoadDirectObject <AutoEvoConfiguration>("res://simulation_parameters/common/auto-evo_parameters.json");

        gallery = LoadRegistry <Gallery>("res://simulation_parameters/common/gallery.json");

        translationsInfo =
            LoadDirectObject <TranslationsInfo>("res://simulation_parameters/common/translations_info.json");

        gameCredits =
            LoadDirectObject <GameCredits>("res://simulation_parameters/common/credits.json");

        GD.Print("SimulationParameters loading ended");

        CheckForInvalidValues();
        ResolveValueRelationships();

        // Apply translations here to ensure that initial translations are correct when the game starts.
        // This is done this way to allow StartupActions to run before SimulationParameters are loaded
        ApplyTranslations();

        GD.Print("SimulationParameters are good");
    }
Exemple #5
0
 public CalculatePopulation(AutoEvoConfiguration configuration, PatchMap map,
                            List <Species> extraSpecies = null, List <Species> excludedSpecies = null,
                            bool collectEnergyInfo      = false)
 {
     this.configuration     = configuration;
     this.map               = map;
     this.extraSpecies      = extraSpecies;
     this.excludedSpecies   = excludedSpecies;
     this.collectEnergyInfo = collectEnergyInfo;
 }
Exemple #6
0
 private static void RunSimulationStep(SimulationConfiguration parameters, List <Species> species,
                                       IEnumerable <KeyValuePair <int, Patch> > patchesToSimulate, Random random, SimulationCache cache,
                                       AutoEvoConfiguration autoEvoConfiguration)
 {
     foreach (var entry in patchesToSimulate)
     {
         // Simulate the species in each patch taking into account the already computed populations
         SimulatePatchStep(parameters, entry.Value,
                           species.Where(item => parameters.Results.GetPopulationInPatch(item, entry.Value) > 0),
                           random, cache, autoEvoConfiguration);
     }
 }
    /// <summary>
    ///   Loads the simulation configuration parameters from JSON files
    /// </summary>
    private SimulationParameters()
    {
        // Compounds are referenced by the other json files so it is loaded first and instance is assigned here
        instance = this;

        // Loading the compounds needs a custom JSON deserializer that can load the Compound objects, but the loader
        // can't always be active because that breaks saving
        {
            var compoundDeserializer = new JsonConverter[] { new CompoundLoader(null) };

            compounds = LoadRegistry <Compound>(
                "res://simulation_parameters/microbe_stage/compounds.json", compoundDeserializer);
        }

        membranes = LoadRegistry <MembraneType>(
            "res://simulation_parameters/microbe_stage/membranes.json");
        backgrounds = LoadRegistry <Background>(
            "res://simulation_parameters/microbe_stage/backgrounds.json");
        biomes = LoadRegistry <Biome>(
            "res://simulation_parameters/microbe_stage/biomes.json");
        bioProcesses = LoadRegistry <BioProcess>(
            "res://simulation_parameters/microbe_stage/bio_processes.json");
        organelles = LoadRegistry <OrganelleDefinition>(
            "res://simulation_parameters/microbe_stage/organelles.json");

        NameGenerator = LoadDirectObject <NameGenerator>(
            "res://simulation_parameters/microbe_stage/species_names.json");

        musicCategories = LoadRegistry <MusicCategory>("res://simulation_parameters/common/music_tracks.json");

        helpTexts = LoadRegistry <HelpTexts>("res://simulation_parameters/common/help_texts.json");

        inputGroups = LoadListRegistry <NamedInputGroup>("res://simulation_parameters/common/input_options.json");

        autoEvoConfiguration =
            LoadDirectObject <AutoEvoConfiguration>("res://simulation_parameters/common/autoevo_parameters.json");

        gallery = LoadRegistry <Gallery>("res://simulation_parameters/common/gallery.json");

        GD.Print("SimulationParameters loading ended");

        CheckForInvalidValues();
        ResolveValueRelationships();

        GD.Print("SimulationParameters are good");
    }
Exemple #8
0
        /// <summary>
        ///   The heart of the simulation that handles the processed parameters and calculates future populations.
        /// </summary>
        private static void SimulatePatchStep(SimulationConfiguration simulationConfiguration, Patch patch,
                                              IEnumerable <Species> genericSpecies, Random random, SimulationCache cache,
                                              AutoEvoConfiguration autoEvoConfiguration)
        {
            _ = random;

            var  populations = simulationConfiguration.Results;
            bool trackEnergy = simulationConfiguration.CollectEnergyInformation;

            // This algorithm version is for microbe species
            var species = genericSpecies.Select(s => (MicrobeSpecies)s).ToList();

            // Skip if there aren't any species in this patch
            if (species.Count < 1)
            {
                return;
            }

            var energyBySpecies = new Dictionary <MicrobeSpecies, float>();

            foreach (var currentSpecies in species)
            {
                energyBySpecies[currentSpecies] = 0.0f;
            }

            bool strictCompetition = autoEvoConfiguration.StrictNicheCompetition;

            var niches = new List <FoodSource>
            {
                new EnvironmentalFoodSource(patch, Sunlight, Constants.AUTO_EVO_SUNLIGHT_ENERGY_AMOUNT),
                new CompoundFoodSource(patch, Glucose),
                new CompoundFoodSource(patch, HydrogenSulfide),
                new CompoundFoodSource(patch, Iron),
                new ChunkFoodSource(patch, "marineSnow"),
                new ChunkFoodSource(patch, "ironSmallChunk"),
                new ChunkFoodSource(patch, "ironBigChunk"),
            };

            foreach (var currentSpecies in species)
            {
                niches.Add(new HeterotrophicFoodSource(patch, currentSpecies));
            }

            foreach (var niche in niches)
            {
                // If there isn't a source of energy here, no need for more calculations
                if (niche.TotalEnergyAvailable() <= MathUtils.EPSILON)
                {
                    continue;
                }

                var fitnessBySpecies  = new Dictionary <MicrobeSpecies, float>();
                var totalNicheFitness = 0.0f;
                foreach (var currentSpecies in species)
                {
                    float thisSpeciesFitness;

                    if (strictCompetition)
                    {
                        // Softly enforces https://en.wikipedia.org/wiki/Competitive_exclusion_principle
                        // by exaggerating fitness differences
                        thisSpeciesFitness =
                            Mathf.Max(Mathf.Pow(niche.FitnessScore(currentSpecies, cache), 2.5f), 0.0f);
                    }
                    else
                    {
                        thisSpeciesFitness = Mathf.Max(niche.FitnessScore(currentSpecies, cache), 0.0f);
                    }

                    fitnessBySpecies[currentSpecies] = thisSpeciesFitness;
                    totalNicheFitness += thisSpeciesFitness;
                }

                // If no species can get energy this way, no need for more calculations
                if (totalNicheFitness <= MathUtils.EPSILON)
                {
                    continue;
                }

                foreach (var currentSpecies in species)
                {
                    var energy = fitnessBySpecies[currentSpecies] * niche.TotalEnergyAvailable() / totalNicheFitness;

                    // If this species can't gain energy here, don't count it (this also prevents it from appearing
                    // in food sources (if that's not what we want), if the species doesn't use this food source
                    if (energy <= MathUtils.EPSILON)
                    {
                        continue;
                    }

                    energyBySpecies[currentSpecies] += energy;

                    if (trackEnergy)
                    {
                        populations.AddTrackedEnergyForSpecies(currentSpecies, patch, niche,
                                                               fitnessBySpecies[currentSpecies], energy, totalNicheFitness);
                    }
                }
            }

            foreach (var currentSpecies in species)
            {
                var energyBalanceInfo = cache.GetEnergyBalanceForSpecies(currentSpecies, patch);

                // Modify populations based on energy
                var newPopulation = (long)(energyBySpecies[currentSpecies]
                                           / energyBalanceInfo.FinalBalanceStationary);

                if (trackEnergy)
                {
                    populations.AddTrackedEnergyConsumptionForSpecies(currentSpecies, patch, newPopulation,
                                                                      energyBySpecies[currentSpecies], energyBalanceInfo.FinalBalanceStationary);
                }

                // TODO: this is a hack for now to make the player experience better, try to get the same rules working
                // for the player and AI species in the future.
                if (currentSpecies.PlayerSpecies)
                {
                    // Severely penalize a species that can't osmoregulate
                    if (energyBalanceInfo.FinalBalanceStationary < 0)
                    {
                        newPopulation /= 10;
                    }
                }
                else
                {
                    // Severely penalize a species that can't move indefinitely
                    if (energyBalanceInfo.FinalBalance < 0)
                    {
                        newPopulation /= 10;
                    }
                }

                // Can't survive without enough population
                if (newPopulation < Constants.AUTO_EVO_MINIMUM_VIABLE_POPULATION)
                {
                    newPopulation = 0;
                }

                populations.AddPopulationResultForSpecies(currentSpecies, patch, newPopulation);
            }
        }
Exemple #9
0
 public ForceExtinction(List <Patch> patches, AutoEvoConfiguration configuration)
 {
     this.patches       = patches;
     this.configuration = configuration;
 }