diff --git a/Changelog.md b/Changelog.md
index 844c04a..c6df355 100644
--- a/Changelog.md
+++ b/Changelog.md
@@ -3,23 +3,29 @@
## 1.0.2 (current development)
### UI Enhancements:
-- New tab for world controls
- - Relocated grid controls, auto reset to this tab
+- New tab "World Controls"
+ - Relocated grid controls and auto reset to this tab
- Button to generate random walls with perlin noise
- - Options for starting state, including simple producer and empty state
- - Option to not clear walls when resetting
+ - Button to reset the environment with many randomly generated organisms
+ - Option to not clear walls on reset
- Option to pause on total extinction
-- Combined `Movers can rotate` and `Offspring rotate` simulation controls into `Rotation enabled`
-- Can now drag view while rendering is off
+- "Simulation controls" tab renamed to "Evolution Controls"
+- Button to save/load Evolution Controls in a `.json` file
+- Button to randomize the organism in the editor window
+- Can now use drag view tool while rendering is off
+- Reorganized "About" tab and left panel, embedded explanation video
### Simulation Enhancements:
--
+- New evolution control `Extra Mover Reproduction Cost`, which adds additional food cost for movers to reproduce
+- Combined `Movers can rotate` and `Offspring rotate` evolution controls into `Rotation enabled`
+- Fully max out simulation speed when slider is all the way to the right
### Bug Fixes:
- Armor is no longer ignored when checking for clear reproduction space
+- Chart data is now properly loaded/discarded when paused
-Thanks to contributors:
+Thanks to contributors: @Chrispykins @M4YX0R
## 1.0.1 (12/4/2021)
diff --git a/dist/css/style.css b/dist/css/style.css
index 0a1747d..5c7d20c 100644
--- a/dist/css/style.css
+++ b/dist/css/style.css
@@ -178,9 +178,6 @@ button:active{
.edit-mode-btn.selected {
background-color: #81d2c7;
}
-.randomize-button {
- margin-top: 5px;
-}
#clear-walls {
margin-top: 5px;
}
@@ -278,4 +275,8 @@ button:active{
margin: auto;
margin-bottom: 0;
padding-bottom: 0;
+}
+
+#reset-with-editor-org{
+ margin-top: 5px;
}
\ No newline at end of file
diff --git a/dist/index.html b/dist/index.html
index 829704c..d2fe274 100644
--- a/dist/index.html
+++ b/dist/index.html
@@ -42,9 +42,8 @@
About
Editor
World Controls
-
Simulation Controls
+
Evolution Controls
Statistics
-
@@ -79,7 +78,6 @@
-
@@ -97,6 +95,8 @@
+
+
@@ -126,7 +126,7 @@
-
+
Brain
@@ -151,25 +151,8 @@
Move Away From: killer
-
-
-
Generate Random Organism
-
-
-
- 5
-
-
-
-
- 75%
-
-
-
-
-
-
-
+
+
@@ -185,23 +168,20 @@
-
Reset Options
-
-
Auto reset count:
+
+
+
+
@@ -211,7 +191,7 @@
-
Simulation Controls
+
Evolution Controls
@@ -255,8 +235,8 @@
-
-
+
+
@@ -283,22 +263,6 @@
-
-
-
Challenges
-
-
-
-
-
-
-
-
-
Select a Challenge
-
-
Challenge yourself to create interesting ecosystems and organisms. There is no formal way to win or lose, its just for fun!
-
-
diff --git a/src/Controllers/ControlModes.js b/src/Controllers/ControlModes.js
index 97ecfa2..3213e4e 100644
--- a/src/Controllers/ControlModes.js
+++ b/src/Controllers/ControlModes.js
@@ -7,7 +7,6 @@ const Modes = {
Edit: 5,
Clone: 6,
Drag: 7,
- Randomize: 8,
}
module.exports = Modes;
\ No newline at end of file
diff --git a/src/Controllers/ControlPanel.js b/src/Controllers/ControlPanel.js
index fc86ce6..37f0aff 100644
--- a/src/Controllers/ControlPanel.js
+++ b/src/Controllers/ControlPanel.js
@@ -14,7 +14,6 @@ class ControlPanel {
this.defineHyperparameterControls();
this.defineWorldControls();
this.defineModeControls();
- this.defineChallenges();
this.fps = engine.fps;
this.organism_record=0;
this.env_controller = this.engine.env.controller;
@@ -198,11 +197,15 @@ class ControlPanel {
});
$('#clear-walls-reset').change(function() {
WorldConfig.clear_walls_on_reset = this.checked;
- })
-
- $('#start-state').change ( function() {
- WorldConfig.start_state = $("#start-state").val();
- }.bind(this));
+ });
+ $('#reset-with-editor-org').click( () => {
+ let env = this.engine.env;
+ if (!env.reset(true, false)) return;
+ let center = env.grid_map.getCenter();
+ let org = this.editor_controller.env.getCopyOfOrg();
+ this.env_controller.add_new_species = true;
+ this.env_controller.dropOrganism(org, center[0], center[1])
+ });
}
defineHyperparameterControls() {
@@ -226,7 +229,6 @@ class ControlPanel {
Hyperparams.foodDropProb = $('#food-drop-rate').val();
});
$('#extra-mover-cost').change(function() {
- console.log(parseInt($('#extra-mover-cost').val()))
Hyperparams.extraMoverFoodCost = parseInt($('#extra-mover-cost').val());
});
@@ -346,9 +348,6 @@ class ControlPanel {
case "edit":
self.setMode(Modes.Edit);
break;
- case "randomize":
- self.setMode(Modes.Randomize);
- self.editor_controller.setRandomizePanel();
case "drop-org":
self.setMode(Modes.Clone);
break;
@@ -358,7 +357,6 @@ class ControlPanel {
$('.edit-mode-btn').removeClass('selected');
$('.'+this.id).addClass('selected');
});
-
$('.reset-view').click( function(){
this.env_controller.resetView();
}.bind(this));
@@ -382,25 +380,13 @@ class ControlPanel {
this.engine.organism_editor.clear();
this.editor_controller.setEditorPanel();
}.bind(this));
- document.getElementById("random-width").addEventListener('input', function() {
- var width = 2 * this.value + 1;
- $('#random-width-display').text(width);
- RandomOrganismGenerator.organismLayers = this.value;
- });
- document.getElementById("cell-spawn-chance").addEventListener("input", function() {
- var value = parseFloat(this.value);
- $('#spawn-chance-display').text((value * 100).toFixed(1) + "%");
- RandomOrganismGenerator.cellSpawnChance = value;
- });
$('#generate-random').click( function() {
this.engine.organism_editor.createRandom();
+ this.editor_controller.refreshDetailsPanel();
}.bind(this));
-
- $('#create-random-world').click( function() {
- this.setPaused(true);
- this.engine.organism_editor.createRandomWorld(this.engine.env);
+ $('.reset-random').click( function() {
+ this.engine.organism_editor.resetWithRandomOrgs(this.engine.env);
}.bind(this));
- }.bind(this))
window.onbeforeunload = function (e) {
e = e || window.event;
@@ -412,13 +398,6 @@ class ControlPanel {
};
}
- defineChallenges() {
- $('.challenge-btn').click(function() {
- $('#challenge-title').text($(this).text());
- $('#challenge-description').text($(this).val());
- });
- }
-
setPaused(paused) {
if (paused) {
diff --git a/src/Controllers/EnvironmentController.js b/src/Controllers/EnvironmentController.js
index ea16248..93f3ddb 100644
--- a/src/Controllers/EnvironmentController.js
+++ b/src/Controllers/EnvironmentController.js
@@ -169,20 +169,23 @@ class EnvironmentController extends CanvasController{
// close the organism and drop it in the world
var new_org = new Organism(col, row, this.env, organism);
- if (this.add_new_species){
- FossilRecord.addSpeciesObj(new_org.species);
- new_org.species.start_tick = this.env.total_ticks;
- this.add_new_species = false;
- new_org.species.population = 0;
- }
- else if (this.org_to_clone.species.extinct){
- FossilRecord.resurrect(this.org_to_clone.species);
- }
- if (new_org.isClear(this.mouse_c, this.mouse_r)){
+ if (new_org.isClear(col, row)) {
+ if (this.add_new_species){
+ FossilRecord.addSpeciesObj(new_org.species);
+ new_org.species.start_tick = this.env.total_ticks;
+ this.add_new_species = false;
+ new_org.species.population = 0;
+ }
+ else if (this.org_to_clone.species.extinct){
+ FossilRecord.resurrect(this.org_to_clone.species);
+ }
+
this.env.addOrganism(new_org);
new_org.species.addPop();
+ return true;
}
+ return false;
}
dropCellType(col, row, state, killBlocking=false) {
diff --git a/src/Environments/OrganismEditor.js b/src/Environments/OrganismEditor.js
index c9d48e1..6aadc0b 100644
--- a/src/Environments/OrganismEditor.js
+++ b/src/Environments/OrganismEditor.js
@@ -90,7 +90,6 @@ class OrganismEditor extends Environment{
}
createRandom() {
-
this.grid_map.fillGrid(CellStates.empty);
this.organism = RandomOrganismGenerator.generate(this);
@@ -98,26 +97,20 @@ class OrganismEditor extends Environment{
this.organism.species = new Species(this.organism.anatomy, null, 0);
}
- createRandomWorld(worldEnvironment) {
+ resetWithRandomOrgs(env) {
+ let reset_confirmed = env.reset(true, false);
+ if (!reset_confirmed) return;
+ let numOrganisms = parseInt($('#num-random-orgs').val());
- worldEnvironment.clear();
+ let size = Math.ceil(8);
- var numOrganismCols = Math.floor(worldEnvironment.grid_map.cols / this.grid_map.cols);
- var numOrganismRows = Math.floor(worldEnvironment.grid_map.rows / this.grid_map.rows);
- var center = this.grid_map.getCenter();
-
- for (var x = 0; x < numOrganismCols; x++) {
- for (var y = 0; y < numOrganismRows; y++) {
-
- var newOrganism = RandomOrganismGenerator.generate(this);
- //newOrganism.updateGrid();
- newOrganism.species = new Species(newOrganism.anatomy, null, 0);
-
- var col = x * this.grid_map.cols + center[0];
- var row = y * this.grid_map.rows + center[1];
- worldEnvironment.controller.add_new_species = true;
- worldEnvironment.controller.dropOrganism(newOrganism, col, row);
- }
+ for (let i=0; i0) {
- newest_t = this.data[0].dataPoints[this.data[0].dataPoints.length-1].x;
- newest_t = this.data[0].dataPoints[0].x;
+ let record_size = FossilRecord.tick_record.length;
+ let data_points = this.data[0].dataPoints;
+ let newest_t = -1;
+ if (data_points.length>0) {
+ newest_t = this.data[0].dataPoints[data_points.length-1].x;
}
- if (newest_t < FossilRecord.tick_record[r_len-1]) {
- this.addNewest();
+ let to_add = 0;
+ let cur_t = FossilRecord.tick_record[record_size-1];
+ // first count up the number of new datapoints the chart is missing
+ while (cur_t !== newest_t) {
+ to_add++;
+ cur_t = FossilRecord.tick_record[record_size-to_add-1]
}
- if (oldest_t < FossilRecord.tick_record[0]) {
+ // then add them in order
+ this.addNewest(to_add)
+
+ // remove oldest datapoints until the chart is the same size as the saved records
+ while (data_points.length > FossilRecord.tick_record.length) {
this.removeOldest();
}
}
- addNewest() {
- var i = FossilRecord.tick_record.length-1;
- this.addDataPoint(i);
- }
-
- addDataPoint(i) {
- alert("Must override addDataPoint")
+ addNewest(to_add) {
+ for (let i=to_add; i>0; i--) {
+ let j = FossilRecord.tick_record.length-i;
+ this.addDataPoint(j);
+ }
}
removeOldest() {
@@ -75,6 +80,10 @@ class ChartController {
}
}
+ addDataPoint(i) {
+ alert("Must override addDataPoint")
+ }
+
clear() {
this.data.length = 0;
this.chart.render();
diff --git a/src/Stats/FossilRecord.js b/src/Stats/FossilRecord.js
index c33b822..3189f7a 100644
--- a/src/Stats/FossilRecord.js
+++ b/src/Stats/FossilRecord.js
@@ -82,8 +82,7 @@ const FossilRecord = {
this.species_counts.push(this.extant_species.length);
this.av_mut_rates.push(this.env.averageMutability());
this.calcCellCountAverages();
-
- if (this.tick_record.length > this.record_size_limit) {
+ while (this.tick_record.length > this.record_size_limit) {
this.tick_record.shift();
this.pop_counts.shift();
this.species_counts.shift();
diff --git a/src/WorldConfig.js b/src/WorldConfig.js
index 1923453..2c8f432 100644
--- a/src/WorldConfig.js
+++ b/src/WorldConfig.js
@@ -1,7 +1,6 @@
const WorldConfig = {
headless: false,
clear_walls_on_reset: false,
- start_state: 'simple-prod',
auto_reset: true,
auto_pause: false,
}