unnatural organisms/more community creations

This commit is contained in:
MaxRobinsonTheGreat
2023-04-23 18:56:41 -05:00
parent d77e8c12f6
commit 53118e9340
24 changed files with 177 additions and 49 deletions

View File

@@ -1,14 +1,16 @@
# Changelog
## 1.0.5 (tbd)
## 1.0.5 (4/23/2023)
### UI Enhancements:
- Improved "Community Creations" list panel
- Added Mod list to Community Creations
- Added brush size slider
- Added unnatural organism warning
### Simulation Enhancements:
- Added links to community mods
- Added more worlds and organisms to community creations
## 1.0.4 (9/17/2022)

View File

@@ -1,14 +1,17 @@
[
{
"name": "Life Engine Extended",
"value": "https://lifeengineextended.github.io/"
"value": "https://lifeengineextended.github.io/",
"subname" : "SpaceEye"
},
{
"name": "Camo/Healer Cells",
"value": "https://lifeenginelocal.netlify.app/"
"value": "https://lifeenginelocal.netlify.app/",
"subname" : "Xiko"
},
{
"name": "Neural Networks",
"value": "https://bboettcher3.github.io/LifeEngine/"
"value": "https://bboettcher3.github.io/LifeEngine/",
"subname" : "bradyb"
}
]

1
dist/assets/organisms/NED.json vendored Normal file
View File

@@ -0,0 +1 @@
{"c":7,"r":7,"lifetime":0,"food_collected":0,"living":true,"direction":2,"rotation":0,"can_rotate":true,"move_count":0,"move_range":2,"ignore_brain_for":0,"mutability":13,"damage":0,"anatomy":{"birth_distance":12,"is_producer":false,"is_mover":true,"has_eyes":true,"cells":[{"loc_col":5,"loc_row":5,"state":{"name":"mouth"}},{"loc_col":5,"loc_row":5,"direction":0,"state":{"name":"eye"}},{"loc_col":5,"loc_row":5,"direction":1,"state":{"name":"eye"}},{"loc_col":5,"loc_row":5,"direction":2,"state":{"name":"eye"}},{"loc_col":5,"loc_row":5,"direction":3,"state":{"name":"eye"}},{"loc_col":5,"loc_row":5,"state":{"name":"mover"}},{"loc_col":5,"loc_row":5,"state":{"name":"armor"}},{"loc_col":5,"loc_row":5,"state":{"name":"killer"}}]},"brain":{"decisions":{"empty":0,"food":2,"wall":0,"mouth":2,"producer":2,"mover":2,"killer":0,"armor":0,"eye":2}},"species_name":"7ofozvw8tx"}

View File

@@ -30,5 +30,17 @@
{
"name": "Napoleon",
"value": "Napoleon"
},
{
"name": "NED",
"value": "NED"
},
{
"name": "Spinner",
"value": "spinner"
},
{
"name": "Sword",
"value": "sword"
}
]

1
dist/assets/organisms/spinner.json vendored Normal file
View File

@@ -0,0 +1 @@
{"c":7,"r":7,"lifetime":0,"food_collected":0,"living":true,"direction":2,"rotation":0,"can_rotate":true,"move_count":0,"move_range":20,"ignore_brain_for":0,"mutability":0,"damage":0,"species_name":"1fpa7zg0ng","anatomy":{"birth_distance":8,"is_producer":false,"is_mover":true,"has_eyes":true,"cells":[{"loc_col":0,"loc_row":-1,"direction":0,"state":{"name":"eye"}},{"loc_col":-1,"loc_row":0,"direction":3,"state":{"name":"eye"}},{"loc_col":1,"loc_row":0,"direction":1,"state":{"name":"eye"}},{"loc_col":0,"loc_row":1,"direction":2,"state":{"name":"eye"}},{"loc_col":-1,"loc_row":-3,"state":{"name":"mouth"}},{"loc_col":1,"loc_row":-3,"state":{"name":"killer"}},{"loc_col":3,"loc_row":-3,"state":{"name":"mouth"}},{"loc_col":3,"loc_row":-1,"state":{"name":"killer"}},{"loc_col":3,"loc_row":1,"state":{"name":"mouth"}},{"loc_col":3,"loc_row":3,"state":{"name":"killer"}},{"loc_col":1,"loc_row":3,"state":{"name":"mouth"}},{"loc_col":-1,"loc_row":3,"state":{"name":"killer"}},{"loc_col":-3,"loc_row":3,"state":{"name":"mouth"}},{"loc_col":-3,"loc_row":-1,"state":{"name":"mouth"}},{"loc_col":-3,"loc_row":-3,"state":{"name":"killer"}},{"loc_col":-3,"loc_row":1,"state":{"name":"killer"}},{"loc_col":1,"loc_row":-2,"state":{"name":"mouth"}},{"loc_col":-1,"loc_row":2,"state":{"name":"mouth"}},{"loc_col":-2,"loc_row":1,"state":{"name":"mouth"}},{"loc_col":2,"loc_row":-1,"state":{"name":"mouth"}},{"loc_col":0,"loc_row":0,"state":{"name":"mover"}}]},"brain":{"decisions":{"empty":0,"food":2,"wall":0,"mouth":0,"producer":2,"mover":0,"killer":1,"armor":0,"eye":1}}}

1
dist/assets/organisms/sword.json vendored Normal file
View File

@@ -0,0 +1 @@
{"c":7,"r":7,"lifetime":0,"food_collected":0,"living":true,"direction":2,"rotation":0,"can_rotate":true,"move_count":0,"move_range":4,"ignore_brain_for":0,"mutability":0,"damage":0,"anatomy":{"birth_distance":16,"is_producer":true,"is_mover":true,"has_eyes":true,"cells":[{"loc_col":-1,"loc_row":-1,"state":{"name":"mouth"}},{"loc_col":0,"loc_row":-2,"state":{"name":"mouth"}},{"loc_col":1,"loc_row":-3,"state":{"name":"mouth"}},{"loc_col":2,"loc_row":-4,"state":{"name":"mouth"}},{"loc_col":3,"loc_row":-5,"state":{"name":"mouth"}},{"loc_col":4,"loc_row":-6,"state":{"name":"mouth"}},{"loc_col":1,"loc_row":1,"state":{"name":"mouth"}},{"loc_col":2,"loc_row":0,"state":{"name":"mouth"}},{"loc_col":3,"loc_row":-1,"state":{"name":"mouth"}},{"loc_col":4,"loc_row":-2,"state":{"name":"mouth"}},{"loc_col":5,"loc_row":-3,"state":{"name":"mouth"}},{"loc_col":6,"loc_row":-4,"state":{"name":"mouth"}},{"loc_col":5,"loc_row":-5,"state":{"name":"producer"}},{"loc_col":4,"loc_row":-4,"state":{"name":"producer"}},{"loc_col":3,"loc_row":-3,"state":{"name":"producer"}},{"loc_col":2,"loc_row":-2,"state":{"name":"producer"}},{"loc_col":1,"loc_row":-1,"state":{"name":"producer"}},{"loc_col":0,"loc_row":0,"state":{"name":"producer"}},{"loc_col":-1,"loc_row":1,"state":{"name":"producer"}},{"loc_col":6,"loc_row":-6,"state":{"name":"producer"}},{"loc_col":-5,"loc_row":4,"state":{"name":"armor"}},{"loc_col":-5,"loc_row":5,"state":{"name":"armor"}},{"loc_col":-4,"loc_row":5,"state":{"name":"armor"}},{"loc_col":-3,"loc_row":4,"state":{"name":"armor"}},{"loc_col":-4,"loc_row":3,"state":{"name":"armor"}},{"loc_col":-4,"loc_row":1,"state":{"name":"armor"}},{"loc_col":-5,"loc_row":0,"state":{"name":"armor"}},{"loc_col":-5,"loc_row":-1,"state":{"name":"armor"}},{"loc_col":-5,"loc_row":-2,"state":{"name":"armor"}},{"loc_col":-4,"loc_row":-2,"state":{"name":"armor"}},{"loc_col":-3,"loc_row":-1,"state":{"name":"armor"}},{"loc_col":-1,"loc_row":4,"state":{"name":"armor"}},{"loc_col":0,"loc_row":5,"state":{"name":"armor"}},{"loc_col":1,"loc_row":5,"state":{"name":"armor"}},{"loc_col":2,"loc_row":5,"state":{"name":"armor"}},{"loc_col":2,"loc_row":4,"state":{"name":"armor"}},{"loc_col":1,"loc_row":3,"state":{"name":"armor"}},{"loc_col":-2,"loc_row":3,"state":{"name":"armor"}},{"loc_col":-3,"loc_row":2,"state":{"name":"armor"}},{"loc_col":-2,"loc_row":2,"state":{"name":"mover"}},{"loc_col":-1,"loc_row":2,"direction":0,"state":{"name":"eye"}},{"loc_col":-2,"loc_row":1,"direction":1,"state":{"name":"eye"}},{"loc_col":-3,"loc_row":1,"direction":2,"state":{"name":"eye"}},{"loc_col":-3,"loc_row":0,"direction":0,"state":{"name":"eye"}},{"loc_col":-4,"loc_row":0,"direction":3,"state":{"name":"eye"}},{"loc_col":-4,"loc_row":-1,"direction":1,"state":{"name":"eye"}},{"loc_col":-1,"loc_row":3,"direction":3,"state":{"name":"eye"}},{"loc_col":0,"loc_row":3,"direction":1,"state":{"name":"eye"}},{"loc_col":0,"loc_row":4,"direction":2,"state":{"name":"eye"}},{"loc_col":1,"loc_row":4,"direction":0,"state":{"name":"eye"}},{"loc_col":-3,"loc_row":3,"direction":1,"state":{"name":"eye"}},{"loc_col":-4,"loc_row":4,"direction":3,"state":{"name":"eye"}},{"loc_col":0,"loc_row":2,"state":{"name":"armor"}},{"loc_col":-2,"loc_row":0,"state":{"name":"armor"}},{"loc_col":7,"loc_row":-7,"state":{"name":"killer"}},{"loc_col":7,"loc_row":-5,"state":{"name":"mouth"}},{"loc_col":5,"loc_row":-7,"state":{"name":"mouth"}},{"loc_col":7,"loc_row":-6,"state":{"name":"mouth"}},{"loc_col":6,"loc_row":-7,"state":{"name":"mouth"}}]},"brain":{"decisions":{"empty":0,"food":2,"wall":0,"mouth":0,"producer":0,"mover":0,"killer":1,"armor":2,"eye":0}},"species_name":"v5i5g7zqq8"}

1
dist/assets/worlds/ArthursWorld.json vendored Normal file

File diff suppressed because one or more lines are too long

1
dist/assets/worlds/Chains.json vendored Normal file

File diff suppressed because one or more lines are too long

1
dist/assets/worlds/Epic.json vendored Normal file

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

1
dist/assets/worlds/Sand_Grid.json vendored Normal file

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

View File

@@ -34,5 +34,33 @@
{
"name": "Life Engine of Nurgle",
"value": "Life_Engine_of_Nurgle"
},
{
"name": "Zoo",
"value": "zoo"
},
{
"name": "Chains",
"value": "Chains"
},
{
"name": "Symbiotic Colony",
"value": "SymbioticColony"
},
{
"name": "Sand Grid",
"value": "Sand_Grid"
},
{
"name": "Epic",
"value": "Epic"
},
{
"name": "Ostracod Slide",
"value": "Ostracod_Slide"
},
{
"name": "Altruistic Arthurs",
"value": "ArthursWorld"
}
]

1
dist/assets/worlds/zoo.json vendored Normal file

File diff suppressed because one or more lines are too long

22
dist/css/style.css vendored
View File

@@ -178,6 +178,7 @@ input:hover,input:active {
display: none;
padding: 10px;
overflow-y: auto;
height: 100%;
}
.tab#about {
@@ -196,7 +197,6 @@ input:hover,input:active {
display: none;
}
#editor-panel{
display: flex;
}
@@ -211,6 +211,10 @@ input:hover,input:active {
#clear-walls {
margin-top: 5px;
}
#brush-size-container {
display: flex;
align-items: center;
}
#organism-options {
display: none;
}
@@ -223,7 +227,21 @@ input:hover,input:active {
image-rendering: pixelated;
image-rendering: crisp-edges;
height: 195px;
width: 195px;
width: 195px;
display: block;
}
#unnatural-org-warning {
color: red;
text-align: center;
font-size: 22px;
border-radius: 10px;
margin: 2px;
border: 2px solid red;
}
#unnatural-org-warning:hover {
color: darkred;
border: 2px solid darkred;
}
#cell-selections {
display: none;

13
dist/index.html vendored
View File

@@ -32,6 +32,10 @@
<p id='fps-actual'></p>
<button id='reset-env' title='Restarts simulation with default organism.'>Reset</button>
<button id='clear-env' title="Removes all organisms.">Clear</button>
<div id="brush-size-container">
<label id="brush-slider-label" for="brush-slider" title='Size of the brush for food, walls, and killing'><i class="fa fa-brush"></i> Brush Size </label>
<input id="brush-slider" type="range" min="0" max="15" value="2">
</div>
</div>
<div id='tab-container' class='control-set'>
@@ -80,6 +84,7 @@
<button class="edit-mode-btn drop-org" id="drop-org" title="Drop organism in world. Hotkey: C"><i class="fa fa-plus"></i></button>
<button id="save-org" title="Save Organism"><i class="fa fa-save"></i></button>
<button id="load-org" title="Load Organism"><i class="fa fa-upload"></i></button>
<b id="unnatural-org-warning" title="Unnatural Organism: It has overlapping cells or genetic changes that cannot evolve naturally"><i class="fa fa-biohazard"></i></i></b>
</div>
<div id='editor-env'>
<canvas id='editor-canvas'></canvas>
@@ -211,7 +216,7 @@
<label for="rot-enabled" title='Organisms rotate when born and while moving.'>Rotation Enabled</label>
<input type="checkbox" id="rot-enabled" checked>
<br>
<label for="insta-kill" title='When on, killer cells immediatly kill organisms they touch. When off, organisms have as much health as they have cells and only take 1 damage from killer cells.'>One touch kill</label>
<label for="insta-kill" title='When on, killer cells immediately kill organisms they touch. When off, organisms have as much health as they have cells and only take 1 damage from killer cells.'>One touch kill</label>
<input type="checkbox" id="insta-kill">
<br>
<label for="look-range" title='How far an eye cell can see (in number of cells)'>Look range:</label>
@@ -284,19 +289,19 @@
</div><br>
<div class="all-list-container">
<div class="list-title-container">
<h2>Worlds</h2>
<h2>🌍Worlds</h2>
<div id="worlds-list-container" class="list-container">
<ul id="worlds-list"></ul>
</div>
</div>
<div class="list-title-container">
<h2>Organisms</h2>
<h2>🦠Organisms</h2>
<div id="organisms-list-container" class="list-container">
<ul id="organisms-list"></ul>
</div>
</div>
<div class="list-title-container">
<h2>Mods</h2>
<h2>🔧Mods</h2>
<div id="mods-list-container" class="list-container">
<ul id="mods-list"></ul>
</div>

View File

@@ -427,6 +427,9 @@ class ControlPanel {
env.reset(true, false);
this.stats_panel.reset();
});
$('#brush-slider').on('input change', function () {
WorldConfig.brush_size = this.value;
});
$('#random-walls').click( function() {
this.env_controller.randomizeWalls();
}.bind(this));
@@ -434,7 +437,7 @@ class ControlPanel {
this.engine.env.clearWalls();
}.bind(this));
$('#clear-editor').click( function() {
this.engine.organism_editor.clear();
this.engine.organism_editor.setDefaultOrg();
this.editor_controller.setEditorPanel();
}.bind(this));
$('#generate-random').click( function() {

View File

@@ -54,6 +54,12 @@ class EditorController extends CanvasController{
updateDetails() {
$('.cell-count').text("Cell count: "+this.env.organism.anatomy.cells.length);
if (this.env.organism.isNatural()){
$('#unnatural-org-warning').css('display', 'none');
}
else {
$('#unnatural-org-warning').css('display', 'block');
}
}
defineCellTypeSelection() {
@@ -150,13 +156,14 @@ class EditorController extends CanvasController{
this.setEditorPanel();
else
this.setDetailsPanel();
}
setDetailsPanel() {
this.clearDetailsPanel();
var org = this.env.organism;
$('.cell-count').text("Cell count: "+org.anatomy.cells.length);
this.updateDetails();
$('#move-range').text("Move Range: "+org.move_range);
$('#mutation-rate').text("Mutation Rate: "+org.mutability);

View File

@@ -110,19 +110,18 @@ class EnvironmentController extends CanvasController{
switch(mode) {
case Modes.FoodDrop:
if (left_click){
this.dropCellType(cell.col, cell.row, CellStates.food, false);
this.dropCellType(cell.col, cell.row, CellStates.food, false, CellStates.wall);
}
else if (right_click){
this.dropCellType(cell.col, cell.row, CellStates.empty, false);
this.dropCellType(cell.col, cell.row, CellStates.empty, false, CellStates.wall);
}
break;
case Modes.WallDrop:
if (left_click){
this.dropCellType(cell.col, cell.row, CellStates.wall, true);
}
else if (right_click){
this.dropCellType(cell.col, cell.row, CellStates.empty, false);
this.dropCellType(cell.col, cell.row, CellStates.empty, false, CellStates.food);
}
break;
case Modes.ClickKill:
@@ -144,26 +143,25 @@ class EnvironmentController extends CanvasController{
}
break;
case Modes.Drag:
var cur_top = parseInt($('#env-canvas').css('top'), 10);
var cur_left = parseInt($('#env-canvas').css('left'), 10);
var new_top = cur_top + ((this.mouse_y - this.start_y)*this.scale);
var new_left = cur_left + ((this.mouse_x - this.start_x)*this.scale);
$('#env-canvas').css('top', new_top+'px');
$('#env-canvas').css('left', new_left+'px');
this.dragScreen();
break;
}
}
else if (this.middle_click) {
//drag on middle click
var cur_top = parseInt($('#env-canvas').css('top'), 10);
var cur_left = parseInt($('#env-canvas').css('left'), 10);
var new_top = cur_top + ((this.mouse_y - this.start_y)*this.scale);
var new_left = cur_left + ((this.mouse_x - this.start_x)*this.scale);
$('#env-canvas').css('top', new_top+'px');
$('#env-canvas').css('left', new_left+'px');
this.dragScreen();
}
}
dragScreen() {
var cur_top = parseInt($('#env-canvas').css('top'), 10);
var cur_left = parseInt($('#env-canvas').css('left'), 10);
var new_top = cur_top + ((this.mouse_y - this.start_y)*this.scale);
var new_left = cur_left + ((this.mouse_x - this.start_x)*this.scale);
$('#env-canvas').css('top', new_top+'px');
$('#env-canvas').css('left', new_left+'px');
}
dropOrganism(organism, col, row) {
// close the organism and drop it in the world
@@ -187,8 +185,8 @@ class EnvironmentController extends CanvasController{
return false;
}
dropCellType(col, row, state, killBlocking=false) {
for (var loc of Neighbors.allSelf){
dropCellType(col, row, state, killBlocking=false, ignoreState=null) {
for (var loc of Neighbors.inRange(WorldConfig.brush_size)){
var c=col + loc[0];
var r=row + loc[1];
var cell = this.env.grid_map.cellAt(c, r);
@@ -200,23 +198,32 @@ class EnvironmentController extends CanvasController{
else if (cell.owner != null) {
continue;
}
if (ignoreState != null && cell.state == ignoreState)
continue;
this.env.changeCell(c, r, state, null);
}
}
findNearOrganism() {
for (var loc of Neighbors.all){
var c = this.cur_cell.col + loc[0];
var r = this.cur_cell.row + loc[1];
var cell = this.env.grid_map.cellAt(c, r);
if (cell != null && cell.owner != null)
return cell.owner;
let closest = null;
let closest_dist = 100;
for (let loc of Neighbors.inRange(WorldConfig.brush_size)){
let c = this.cur_cell.col + loc[0];
let r = this.cur_cell.row + loc[1];
let cell = this.env.grid_map.cellAt(c, r);
let dist = Math.abs(loc[0]) + Math.abs(loc[1]);
if (cell != null && cell.owner != null) {
if (closest === null || dist < closest_dist) {
closest = cell.owner;
closest_dist = dist;
}
}
}
return null;
return closest;
}
killNearOrganisms() {
for (var loc of Neighbors.allSelf){
for (var loc of Neighbors.inRange(WorldConfig.brush_size)){
var c = this.cur_cell.col + loc[0];
var r = this.cur_cell.row + loc[1];
var cell = this.env.grid_map.cellAt(c, r);

View File

@@ -11,7 +11,6 @@ const LoadController = {
});
let panel = this;
$(".load-panel").on('click', '.list-item', async function() {
console.log('howdy')
let list_name = $(this).closest(".list-container").attr('id');
let value = $(this).find('.hidden-value').text();
if (list_name === 'worlds-list-container') {
@@ -61,12 +60,13 @@ const LoadController = {
let id = `#${name}-list`
$(id).empty();
for (let item of list) {
$(id).append(
`<li class="list-item">
${item.name}
<div class="hidden-value" hidden>${item.value}</div>
</li>`
);
let html = `<li class="list-item">
${item.name}`;
if (item.subname)
html += `<br>(${item.subname})`;
html +=`<div class="hidden-value" hidden>${item.value}</div>
</li>`;
$(id).append(html);
}
},

View File

@@ -15,7 +15,7 @@ class OrganismEditor extends Environment{
this.renderer = new Renderer('editor-canvas', 'editor-env', cell_size);
this.controller = new EditorController(this, this.renderer.canvas);
this.grid_map = new GridMap(15, 15, cell_size);
this.clear();
this.setDefaultOrg();
}
update() {
@@ -81,6 +81,10 @@ class OrganismEditor extends Environment{
clear() {
this.grid_map.fillGrid(CellStates.empty);
}
setDefaultOrg() {
this.clear();
var center = this.grid_map.getCenter();
this.organism = new Organism(center[0], center[1], this, null);
this.organism.anatomy.addDefaultCell(CellStates.mouth, 0, 0);

View File

@@ -20,7 +20,16 @@ const Neighbors = {
all: [[0, 1],[0, -1],[1, 0],[-1, 0],[-1, -1],[1, 1],[-1, 1],[1, -1]],
adjacent: [[0, 1],[0, -1],[1, 0],[-1, 0]],
corners: [[-1, -1],[1, 1],[-1, 1],[1, -1]],
allSelf: [[0, 0],[0, 1],[0, -1],[1, 0],[-1, 0],[-1, -1],[1, 1],[-1, 1],[1, -1]]
allSelf: [[0, 0],[0, 1],[0, -1],[1, 0],[-1, 0],[-1, -1],[1, 1],[-1, 1],[1, -1]],
inRange: function (range) {
var neighbors = [];
for (var i = -range; i <= range; i++) {
for (var j = -range; j <= range; j++) {
neighbors.push([i, j]);
}
}
return neighbors;
}
}
module.exports = Neighbors;

View File

@@ -307,7 +307,6 @@ class Organism {
}
}
}
return this.living;
}
@@ -317,6 +316,26 @@ class Organism {
return this.env.grid_map.cellAt(real_c, real_r);
}
isNatural() {
let found_center = false;
if (this.anatomy.cells.length === 0) {
return false;
}
for (let i=0; i<this.anatomy.cells.length; i++) {
let cell = this.anatomy.cells[i];
for (let j=i+1; j<this.anatomy.cells.length; j++) {
let toCompare = this.anatomy.cells[j];
if (cell.loc_col === toCompare.loc_col && cell.loc_row === toCompare.loc_row) {
return false;
}
}
if (cell.loc_col === 0 && cell.loc_row === 0) {
found_center = true;
}
}
return found_center;
}
serialize() {
let org = SerializeHelper.copyNonObjects(this);
org.anatomy = this.anatomy.serialize();

View File

@@ -3,6 +3,7 @@ const WorldConfig = {
clear_walls_on_reset: false,
auto_reset: true,
auto_pause: false,
brush_size: 2,
}
module.exports = WorldConfig;