update 1.0.4 (see changelog)

This commit is contained in:
MaxRobinsonTheGreat
2022-09-17 19:48:10 -05:00
parent c13aee254b
commit 734bb7165e
29 changed files with 337 additions and 70 deletions

View File

@@ -1,5 +1,20 @@
# Changelog # Changelog
## 1.0.4 (9/17/2022)
### UI Enhancements:
- Added "Community Creations" button
- Updated icons
- Standardized Colors
### Simulation Enhancements:
- Added ability to load premade organisms and worlds from backend
- Added SeeThroughSelf param that allows eyes to see through their own cells
### Bug Fixes:
- Mutation rate now properly saves and loads with world
## 1.0.3 (4/15/2022) ## 1.0.3 (4/15/2022)
### UI Enhancements: ### UI Enhancements:

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":5,"damage":0,"anatomy":{"birth_distance":16,"is_producer":false,"is_mover":true,"has_eyes":true,"cells":[{"loc_col":-1,"loc_row":-1,"direction":0,"state":{"name":"eye"}},{"loc_col":1,"loc_row":-1,"direction":0,"state":{"name":"eye"}},{"loc_col":0,"loc_row":-3,"state":{"name":"armor"}},{"loc_col":0,"loc_row":-5,"state":{"name":"killer"}},{"loc_col":0,"loc_row":-7,"state":{"name":"killer"}},{"loc_col":2,"loc_row":-4,"state":{"name":"armor"}},{"loc_col":3,"loc_row":-2,"state":{"name":"armor"}},{"loc_col":-2,"loc_row":-4,"state":{"name":"armor"}},{"loc_col":-3,"loc_row":-2,"state":{"name":"armor"}},{"loc_col":-2,"loc_row":0,"state":{"name":"killer"}},{"loc_col":2,"loc_row":0,"state":{"name":"killer"}},{"loc_col":0,"loc_row":1,"direction":2,"state":{"name":"eye"}},{"loc_col":0,"loc_row":0,"state":{"name":"mover"}},{"loc_col":1,"loc_row":4,"state":{"name":"killer"}},{"loc_col":-1,"loc_row":4,"state":{"name":"killer"}}]},"brain":{"decisions":{"empty":0,"food":1,"wall":0,"mouth":2,"producer":2,"mover":2,"killer":1,"armor":2,"eye":2}},"species_name":"0nrwql39i6"}

1
dist/assets/organisms/Napoleon.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":5,"damage":0,"anatomy":{"birth_distance":8,"is_producer":false,"is_mover":true,"has_eyes":true,"cells":[{"loc_col":0,"loc_row":0,"direction":0,"state":{"name":"eye"}},{"loc_col":0,"loc_row":1,"direction":3,"state":{"name":"eye"}},{"loc_col":1,"loc_row":1,"direction":1,"state":{"name":"eye"}},{"loc_col":1,"loc_row":-2,"state":{"name":"killer"}},{"loc_col":-1,"loc_row":-2,"state":{"name":"killer"}},{"loc_col":3,"loc_row":0,"state":{"name":"killer"}},{"loc_col":-3,"loc_row":0,"state":{"name":"killer"}},{"loc_col":-2,"loc_row":2,"state":{"name":"killer"}},{"loc_col":2,"loc_row":2,"state":{"name":"killer"}},{"loc_col":1,"loc_row":2,"state":{"name":"mover"}},{"loc_col":1,"loc_row":3,"state":{"name":"armor"}},{"loc_col":0,"loc_row":3,"state":{"name":"armor"}},{"loc_col":-1,"loc_row":3,"state":{"name":"armor"}},{"loc_col":-2,"loc_row":-1,"state":{"name":"armor"}},{"loc_col":2,"loc_row":-1,"state":{"name":"armor"}}]},"brain":{"decisions":{"empty":0,"food":2,"wall":0,"mouth":2,"producer":2,"mover":2,"killer":1,"armor":2,"eye":2}},"species_name":"k5rjhsat1z"}

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":5,"damage":0,"anatomy":{"birth_distance":10,"is_producer":true,"is_mover":false,"has_eyes":false,"cells":[{"loc_col":0,"loc_row":0,"state":{"name":"producer"}},{"loc_col":1,"loc_row":-1,"state":{"name":"producer"}},{"loc_col":-1,"loc_row":-1,"state":{"name":"producer"}},{"loc_col":1,"loc_row":1,"state":{"name":"producer"}},{"loc_col":-1,"loc_row":1,"state":{"name":"producer"}},{"loc_col":0,"loc_row":-2,"state":{"name":"mouth"}},{"loc_col":-2,"loc_row":0,"state":{"name":"mouth"}},{"loc_col":2,"loc_row":0,"state":{"name":"mouth"}},{"loc_col":0,"loc_row":2,"state":{"name":"mouth"}},{"loc_col":2,"loc_row":-2,"state":{"name":"killer"}},{"loc_col":-2,"loc_row":-2,"state":{"name":"killer"}},{"loc_col":-2,"loc_row":2,"state":{"name":"killer"}},{"loc_col":2,"loc_row":2,"state":{"name":"killer"}}]},"species_name":"te6jbz54t5"}

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":7,"damage":0,"anatomy":{"birth_distance":4,"is_producer":false,"is_mover":true,"has_eyes":true,"cells":[{"loc_col":-1,"loc_row":1,"state":{"name":"mouth"}},{"loc_col":0,"loc_row":0,"direction":3,"state":{"name":"eye"}},{"loc_col":0,"loc_row":-1,"direction":0,"state":{"name":"eye"}},{"loc_col":1,"loc_row":0,"direction":1,"state":{"name":"eye"}},{"loc_col":0,"loc_row":1,"state":{"name":"mover"}},{"loc_col":1,"loc_row":1,"direction":2,"state":{"name":"eye"}},{"loc_col":-1,"loc_row":-1,"direction":3,"state":{"name":"eye"}},{"loc_col":1,"loc_row":-1,"state":{"name":"armor"}}]},"brain":{"decisions":{"empty":0,"food":2,"wall":0,"mouth":1,"producer":1,"mover":1,"killer":1,"armor":1,"eye":1}},"species_name":"8y7z6hfjal"}

34
dist/assets/organisms/_list.json vendored Normal file
View File

@@ -0,0 +1,34 @@
[
{
"name": "Purple Flower",
"file": "purple_flower"
},
{
"name": "Rosa Finalis",
"file": "RosaFinalis"
},
{
"name": "Quadratus Anxius",
"file": "The_Anxious_Square"
},
{
"name": "Hunter",
"file": "hunter"
},
{
"name": "Small Bush Killer",
"file": "smallbushkiller"
},
{
"name": "Fly Catcher",
"file": "flycatcher"
},
{
"name": "Heart Locket",
"file": "HeartLocket"
},
{
"name": "Napoleon",
"file": "Napoleon"
}
]

1
dist/assets/organisms/flycatcher.json vendored Normal file

File diff suppressed because one or more lines are too long

1
dist/assets/organisms/hunter.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":3,"damage":0,"anatomy":{"birth_distance":4,"is_producer":false,"is_mover":true,"has_eyes":true,"cells":[{"loc_col":1,"loc_row":0,"direction":0,"state":{"name":"eye"}},{"loc_col":-1,"loc_row":0,"direction":0,"state":{"name":"eye"}},{"loc_col":0,"loc_row":0,"state":{"name":"mover"}},{"loc_col":0,"loc_row":-1,"state":{"name":"mouth"}},{"loc_col":0,"loc_row":1,"state":{"name":"killer"}}]},"brain":{"decisions":{"empty":0,"food":2,"wall":0,"mouth":0,"producer":2,"mover":0,"killer":1,"armor":0,"eye":0}}}

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":5,"damage":0,"anatomy":{"birth_distance":6,"is_producer":true,"is_mover":false,"has_eyes":false,"cells":[{"loc_col":0,"loc_row":0,"state":{"name":"mouth"}},{"loc_col":-1,"loc_row":-2,"state":{"name":"armor"}},{"loc_col":-2,"loc_row":-1,"state":{"name":"armor"}},{"loc_col":1,"loc_row":-2,"state":{"name":"armor"}},{"loc_col":2,"loc_row":-1,"state":{"name":"armor"}},{"loc_col":2,"loc_row":1,"state":{"name":"armor"}},{"loc_col":1,"loc_row":2,"state":{"name":"armor"}},{"loc_col":-2,"loc_row":1,"state":{"name":"armor"}},{"loc_col":-1,"loc_row":2,"state":{"name":"armor"}},{"loc_col":-1,"loc_row":-1,"state":{"name":"producer"}},{"loc_col":1,"loc_row":-1,"state":{"name":"producer"}},{"loc_col":1,"loc_row":1,"state":{"name":"producer"}},{"loc_col":-1,"loc_row":1,"state":{"name":"producer"}}]},"brain":{"decisions":{"empty":0,"food":2,"wall":0,"mouth":0,"producer":0,"mover":0,"killer":1,"armor":0,"eye":0}}}

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":1,"ignore_brain_for":0,"mutability":10,"damage":0,"anatomy":{"birth_distance":4,"is_producer":false,"is_mover":true,"has_eyes":true,"cells":[{"loc_col":0,"loc_row":0,"state":{"name":"mover"}},{"loc_col":0,"loc_row":-1,"state":{"name":"mouth"}},{"loc_col":0,"loc_row":1,"state":{"name":"killer"}},{"loc_col":1,"loc_row":0,"direction":0,"state":{"name":"eye"}},{"loc_col":-1,"loc_row":0,"state":{"name":"killer"}}]},"brain":{"decisions":{"empty":0,"food":2,"wall":0,"mouth":0,"producer":0,"mover":0,"killer":1,"armor":0,"eye":1}},"species_name":"sdkambtti7"}

File diff suppressed because one or more lines are too long

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

File diff suppressed because one or more lines are too long

38
dist/assets/worlds/_list.json vendored Normal file
View File

@@ -0,0 +1,38 @@
[
{
"name": "Colony",
"file": "colony"
},
{
"name": "Ephemeral World",
"file": "ephemeral"
},
{
"name": "Trailblazer",
"file": "Trailblazer3"
},
{
"name": "Scarcity",
"file": "scarcity"
},
{
"name": "High Def Sweepers",
"file": "world_HighDefSweepers_start"
},
{
"name": "Shrub Swamp",
"file": "shrubland"
},
{
"name": "Computer (unprogrammed)",
"file": "computer_unprogrammed"
},
{
"name": "Computer (fibonacci)",
"file": "compV2_fixed_labeled_fibofancy"
},
{
"name": "Life Engine of Nurgle",
"file": "Life_Engine_of_Nurgle"
}
]

1
dist/assets/worlds/colony.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

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/ephemeral.json vendored Normal file

File diff suppressed because one or more lines are too long

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

File diff suppressed because one or more lines are too long

1
dist/assets/worlds/shrubland.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

72
dist/css/style.css vendored
View File

@@ -1,5 +1,16 @@
:root {
/* Colors */
--border:#3a4b68;
--panel-bg:#e1e3ec;
--btn: #9099c2;
--btn-hover: #81d2c7;
--btn-click: #595e77;
--tab: #416788;
--tab-active: #66a39b;
}
body{ body{
background: #3a4b68; background: var(--border);
margin: 0; margin: 0;
padding: 0; padding: 0;
height: 100%; height: 100%;
@@ -36,7 +47,7 @@ body{
width: 100%; width: 100%;
bottom: 0; bottom: 0;
position: fixed; position: fixed;
background-color: #3a4b68; background-color: var(--border);
display: none; display: none;
grid-template-columns: repeat(3, 1fr); grid-template-columns: repeat(3, 1fr);
/* opacity: 0.8; */ /* opacity: 0.8; */
@@ -51,7 +62,7 @@ body{
padding: 5px; padding: 5px;
border: 10px; border: 10px;
border-radius: 15px; border-radius: 15px;
background-color: #e1e3ec; background-color: var(--panel-bg);
grid-row: 1; grid-row: 1;
} }
@@ -71,7 +82,7 @@ img {
button { button {
border: none; border: none;
color: black; color: black;
background-color: #9099c2; background-color: var(--btn);
border-radius: 8px; border-radius: 8px;
padding: 5px 5px; padding: 5px 5px;
text-align: center; text-align: center;
@@ -82,15 +93,15 @@ button {
margin: 2px; margin: 2px;
} }
button:hover{ button:hover{
background-color: #81d2c7; background-color: var(--btn-hover);
} }
button:active{ button:active{
background-color: #595e77; background-color: var(--btn-click);
} }
input,select { input,select {
border-radius: 5px; border-radius: 5px;
border: 2px solid #9099c2; border: 2px solid var(--btn);
padding: 2px; padding: 2px;
background-color: white; background-color: white;
outline: none; outline: none;
@@ -136,7 +147,7 @@ input:hover,input:active {
.tabnav { .tabnav {
overflow: hidden; overflow: hidden;
background-color: #416788; background-color: var(--tab);
border-radius: 15px; border-radius: 15px;
} }
.tabnav p { .tabnav p {
@@ -149,11 +160,11 @@ input:hover,input:active {
user-select: none; user-select: none;
} }
.tabnav p:hover { .tabnav p:hover {
background-color: #81d2c7; background-color: var(--btn-hover);
color: black; color: black;
} }
.open-tab { .open-tab {
background-color: #66a39b; background-color: var(--tab-active);
color: black; color: black;
} }
@@ -190,7 +201,7 @@ input:hover,input:active {
margin-top: 5px; margin-top: 5px;
} }
.edit-mode-btn.selected { .edit-mode-btn.selected {
background-color: #81d2c7; background-color: var(--btn-hover);
} }
#clear-walls { #clear-walls {
margin-top: 5px; margin-top: 5px;
@@ -236,10 +247,6 @@ input:hover,input:active {
height: 50px; height: 50px;
margin: 1px; margin: 1px;
} }
.cell-legend-hover {
border-color: black;
border: 5px;
}
#editor-mode-cont{ #editor-mode-cont{
padding-top: 20px; padding-top: 20px;
} }
@@ -254,6 +261,11 @@ input:hover,input:active {
width: 100%; width: 100%;
} }
.community-section {
position: fixed;
right: 10px;
top: 10px;
}
.hot-controls { .hot-controls {
position: fixed; position: fixed;
@@ -291,6 +303,34 @@ input:hover,input:active {
padding-bottom: 0; padding-bottom: 0;
} }
#reset-with-editor-org{ #reset-with-editor-org {
margin-top: 5px; margin-top: 5px;
} }
.load-panel {
width: 300px;
background-color: var(--panel-bg);
position: fixed;
display: none;
left: 50%;
top: 50%;
transform: translate(-50%, -50%);
border-style: solid;
border-width: 0px;
border-radius: 10px;
box-shadow: 0 0 0 10px var(--border);
padding: 10px;
}
#close-load-btn {
float: right;
}
#load-panel-title {
white-space: nowrap;
}
#load-panel-title * {
display: inline;
}

43
dist/index.html vendored
View File

@@ -5,9 +5,8 @@
<title>The Life Engine</title> <title>The Life Engine</title>
<link rel="icon" href="./img/icon.png"> <link rel="icon" href="./img/icon.png">
<link rel="stylesheet" href="./css/style.css"> <link rel="stylesheet" href="./css/style.css">
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/4.7.0/css/font-awesome.min.css"> <link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/6.1.2/css/all.min.css">
<script type="text/javascript" src="https://canvasjs.com/assets/script/canvasjs.min.js"></script> <script type="text/javascript" src="https://canvasjs.com/assets/script/canvasjs.min.js"></script>
</head> </head>
<body> <body>
<script src="./js/bundle.js"></script> <script src="./js/bundle.js"></script>
@@ -22,7 +21,7 @@
<button class="edit-mode-btn drag-view" id="drag-view" title="Drag View. Hotkey: S"><i class="fa fa-arrows"></i></button> <button class="edit-mode-btn drag-view" id="drag-view" title="Drag View. Hotkey: S"><i class="fa fa-arrows"></i></button>
<button class="edit-mode-btn wall-drop" id="wall-drop" title="Drop/Remove Wall. Hotkey: D"><i class="fa fa-th"></i></button> <button class="edit-mode-btn wall-drop" id="wall-drop" title="Drop/Remove Wall. Hotkey: D"><i class="fa fa-th"></i></button>
<button class="edit-mode-btn food-drop selected" id="food-drop" title="Drop/Remove Food. Hotkey: F"><i class="fa fa-cutlery"></i></button> <button class="edit-mode-btn food-drop selected" id="food-drop" title="Drop/Remove Food. Hotkey: F"><i class="fa fa-cutlery"></i></button>
<button class="edit-mode-btn click-kill" id="click-kill" title="Click to kill. Hotkey: G"><i class="fa fa-bolt"></i></button> <button class="edit-mode-btn click-kill" id="click-kill" title="Click to kill. Hotkey: G"><i class="fa fa-skull"></i></button>
</div> </div>
<img src="./img/title.png" alt="Life Engine"> <img src="./img/title.png" alt="Life Engine">
<h3>Simulation Speed</h3> <h3>Simulation Speed</h3>
@@ -66,20 +65,21 @@
<iframe id="video" src="https://www.youtube.com/embed/iSAKEnRfles"></iframe> <iframe id="video" src="https://www.youtube.com/embed/iSAKEnRfles"></iframe>
</div> </div>
<div class='icon-links'> <div class='icon-links'>
<a href=https://github.com/MaxRobinsonTheGreat/EvolutionSimulatorV2 title='View the code'><i class="fa fa-github"></i></a> <a href=https://github.com/MaxRobinsonTheGreat/EvolutionSimulatorV2 title='View the code'><i class="fa-brands fa-github"></i></a>
<a href="https://twitter.com/max_romana"><i class="fa fa-twitter"></i></a> <a href="https://discord.gg/ZsrAAByEnr" title='Join the community'><i class="fa-brands fa-discord"></i></a>
<a href=" https://www.patreon.com/emergentgarden" title='Support the project'><i class="fa-brands fa-patreon"></i></a>
</div> </div>
</div> </div>
<div id='editor' class='tab'> <div id='editor' class='tab'>
<div class='left-half' id='editor-panel'> <div class='left-half' id='editor-panel'>
<div class='editor-buttons'> <div class='editor-buttons'>
<button class="edit-mode-btn select" id="select" title="Select organism from world. Hotkey: Z"><i class="fa fa-hand-pointer-o"></i></button> <button class="edit-mode-btn select" id="select" title="Select organism from world. Hotkey: Z"><i class="fa-regular fa-hand-pointer"></i></button>
<button class="edit-mode-btn edit" id="edit" title="Edit organism. Hotkey: X"><i class="fa fa-pencil"></i></button> <button class="edit-mode-btn edit" id="edit" title="Edit organism. Hotkey: X"><i class="fa fa-pen-to-square"></i></button>
<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 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="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> <button id="load-org" title="Load Organism"><i class="fa fa-upload"></i></button>
<input id="upload-org" style="display: none;" type="file">
</div> </div>
<div id='editor-env'> <div id='editor-env'>
<canvas id='editor-canvas'></canvas> <canvas id='editor-canvas'></canvas>
@@ -197,7 +197,6 @@
<button id='load-env' title="Load world save file">Load World</button> <button id='load-env' title="Load world save file">Load World</button>
<label for="override-controls" title='Override the current evolution controls with those from the loaded world'>Override Evolution Controls</label> <label for="override-controls" title='Override the current evolution controls with those from the loaded world'>Override Evolution Controls</label>
<input type="checkbox" id="override-controls" checked> <input type="checkbox" id="override-controls" checked>
<input id="upload-env" style="display: none;" type="file">
</div> </div>
</div> </div>
<div id='hyperparameters' class='tab'> <div id='hyperparameters' class='tab'>
@@ -218,12 +217,16 @@
<label for="look-range" title='How far an eye cell can see (in number of cells)'>Look range:</label> <label for="look-range" title='How far an eye cell can see (in number of cells)'>Look range:</label>
<input type="number" id="look-range" min="1" max="50" value=20 step="1"> <input type="number" id="look-range" min="1" max="50" value=20 step="1">
<br> <br>
<label for="see-through-self" title='Allows eyes to see through an organisms own cells'>See through self:</label>
<input type="checkbox" id="see-through-self">
<br>
<label for="food-drop-rate" title='Rate at which food is automatically generated and dropped in the world'>Auto food drop rate:</label> <label for="food-drop-rate" title='Rate at which food is automatically generated and dropped in the world'>Auto food drop rate:</label>
<input type="number" id="food-drop-rate" value=0 max="1000"> <input type="number" id="food-drop-rate" value=0 max="1000">
<br> <br>
<label for="extra-mover-cost" title='Additional food cost for movers to reproduce'>Extra mover reproduction cost:</label> <label for="extra-mover-cost" title='Additional food cost for movers to reproduce'>Extra mover reproduction cost:</label>
<input type="number" id="extra-mover-cost" value=0 max="1000" step="1"> <input type="number" id="extra-mover-cost" value=0 max="1000" step="1">
</div> </div>
<div class='right-half'> <div class='right-half'>
<button id='reset-rules'>Reset all controls</button> <button id='reset-rules'>Reset all controls</button>
@@ -231,7 +234,7 @@
<label for="evolved-mutation" title='When on, each organism has its own mutation rate that can increase or decrease. When off, all organisms have the same mutation rate.'>Use evolved mutation rate</label> <label for="evolved-mutation" title='When on, each organism has its own mutation rate that can increase or decrease. When off, all organisms have the same mutation rate.'>Use evolved mutation rate</label>
<input type="checkbox" id="evolved-mutation" checked> </br> <input type="checkbox" id="evolved-mutation" checked> </br>
<label class="global-mutation-in" for="global-mutation">Global mutation rate: </label> <label class="global-mutation-in" for="global-mutation">Global mutation rate: </label>
<input class="global-mutation-in" type="number" id="global-mutation" min="1" max="100" value=5 step="1"> <input class="global-mutation-in" type="number" id="global-mutation" min="0" max="100" value=5 step="1">
<h4 title='When an organism mutates, it can choose from one of the following mutation types.'>Mutation Type Probabilities</h4> <h4 title='When an organism mutates, it can choose from one of the following mutation types.'>Mutation Type Probabilities</h4>
<label for="add-prob" title='A new cell will stem from an existing one'>Add Cell:</label> <label for="add-prob" title='A new cell will stem from an existing one'>Add Cell:</label>
<input class="mut-prob" type="number" id="add-prob" min="0" max="100" value=33> <input class="mut-prob" type="number" id="add-prob" min="0" max="100" value=33>
@@ -267,21 +270,35 @@
<option value="mut-rate">Mutation Rate</option> <option value="mut-rate">Mutation Rate</option>
</select> </select>
<p id='chart-note'></p> <p id='chart-note'></p>
</div> </div>
<div class='right-half'> <div class='right-half'>
<div id="chartContainer"></div> <div id="chartContainer"></div>
</div> </div>
</div> </div>
</div> </div>
</div> </div>
<div class='load-panel'>
<div class="load-panel-title">
<button id='close-load-btn'><i class="fa fa-times"></i></button>
<h2 id="load-title">Community Creations</h2>
</div><br>
Worlds<br>
<select id="worlds-load-dropdown"></select>
<button id='load-env-btn'>Load</button><br>
Organisms<br>
<select id="organisms-load-dropdown"></select>
<button id='load-org-btn'>Load</button><br><br>
<input id="upload-json" style="display: none;" type="file">
</div>
<div class='community-section'>
<button id="community-creations-btn" title="See worlds and organisms made by the community">Community Creations <i class="fa fa-users"></i></button>
</div>
<div class='hot-controls'> <div class='hot-controls'>
<button class="reset-view" title="Reset View. Hotkey: A"><i class="fa fa-video-camera"></i></button> <button class="reset-view" title="Reset View. Hotkey: A"><i class="fa fa-video-camera"></i></button>
<button class="edit-mode-btn drag-view" id="drag-view" title="Drag View. Hotkey: S"><i class="fa fa-arrows"></i></button> <button class="edit-mode-btn drag-view" id="drag-view" title="Drag View. Hotkey: S"><i class="fa fa-arrows"></i></button>
<button class="edit-mode-btn wall-drop" id="wall-drop" title="Drop/Remove Wall. Hotkey: D"><i class="fa fa-th"></i></button> <button class="edit-mode-btn wall-drop" id="wall-drop" title="Drop/Remove Wall. Hotkey: D"><i class="fa fa-th"></i></button>
<button class="edit-mode-btn food-drop selected" id="food-drop" title="Drop/Remove Food. Hotkey: F"><i class="fa fa-cutlery"></i></button> <button class="edit-mode-btn food-drop selected" id="food-drop" title="Drop/Remove Food. Hotkey: F"><i class="fa fa-cutlery"></i></button>
<button class="edit-mode-btn click-kill" id="click-kill" title="Click to kill. Hotkey: G"><i class="fa fa-bolt"></i></button> <button class="edit-mode-btn click-kill" id="click-kill" title="Click to kill. Hotkey: G"><i class="fa fa-skull"></i></button>
<button class="headless" title="Toggle rendering. Hotkey: H"><i class="fa fa-eye-slash"></i></button> <button class="headless" title="Toggle rendering. Hotkey: H"><i class="fa fa-eye-slash"></i></button>
<button class='pause-button' title="Play/Pause. Hotkey: Spacebar"><i class="fa fa-pause"></i></button> <button class='pause-button' title="Play/Pause. Hotkey: Spacebar"><i class="fa fa-pause"></i></button>
</div> </div>

View File

@@ -2,6 +2,7 @@ const Hyperparams = require("../Hyperparameters");
const Modes = require("./ControlModes"); const Modes = require("./ControlModes");
const StatsPanel = require("../Stats/StatsPanel"); const StatsPanel = require("../Stats/StatsPanel");
const WorldConfig = require("../WorldConfig"); const WorldConfig = require("../WorldConfig");
const LoadController = require("./LoadController");
class ControlPanel { class ControlPanel {
constructor(engine) { constructor(engine) {
@@ -24,10 +25,11 @@ class ControlPanel {
this.opacity_change_rate = -0.8; this.opacity_change_rate = -0.8;
this.paused=false; this.paused=false;
this.setHyperparamDefaults(); this.setHyperparamDefaults();
LoadController.control_panel = this;
} }
defineMinMaxControls(){ defineMinMaxControls(){
this.control_panel_active = true; this.control_panel_active = false;
this.no_hud = false; this.no_hud = false;
$('#minimize').click ( () => { $('#minimize').click ( () => {
$('.control-panel').css('display', 'none'); $('.control-panel').css('display', 'none');
@@ -100,10 +102,13 @@ class ControlPanel {
}; };
$('.control-panel').css('display', control_panel_display); $('.control-panel').css('display', control_panel_display);
$('.hot-controls').css('display', hot_control_display); $('.hot-controls').css('display', hot_control_display);
$('.community-section').css('display', 'block');
} }
else { else {
$('.control-panel').css('display', 'none'); $('.control-panel').css('display', 'none');
$('.hot-controls').css('display', 'none'); $('.hot-controls').css('display', 'none');
$('.community-section').css('display', 'none');
LoadController.close();
} }
this.no_hud = !this.no_hud; this.no_hud = !this.no_hud;
break; break;
@@ -219,7 +224,9 @@ class ControlPanel {
this.setPaused(false); this.setPaused(false);
}); });
$('#load-env').click(() => { $('#load-env').click(() => {
$('#upload-env').click(); LoadController.loadJson((env)=>{
this.loadEnv(env);
});
}); });
$('#upload-env').change((e)=>{ $('#upload-env').change((e)=>{
let files = e.target.files; let files = e.target.files;
@@ -227,14 +234,8 @@ class ControlPanel {
let reader = new FileReader(); let reader = new FileReader();
reader.onload = (e) => { reader.onload = (e) => {
try { try {
let was_running = this.engine.running;
this.setPaused(true);
let env = JSON.parse(e.target.result); let env = JSON.parse(e.target.result);
this.engine.env.loadRaw(env); this.loadEnv(env);
if (was_running)
this.setPaused(false);
this.updateHyperparamUIValues();
this.env_controller.resetView();
} catch(except) { } catch(except) {
console.error(except) console.error(except)
alert('Failed to load world'); alert('Failed to load world');
@@ -245,6 +246,20 @@ class ControlPanel {
}); });
} }
loadEnv(env) {
if (this.tab_id == 'stats')
this.stats_panel.stopAutoRender();
let was_running = this.engine.running;
this.setPaused(true);
this.engine.env.loadRaw(env);
if (was_running)
this.setPaused(false);
this.updateHyperparamUIValues();
this.env_controller.resetView();
if (this.tab_id == 'stats')
this.stats_panel.startAutoRender();
}
defineHyperparameterControls() { defineHyperparameterControls() {
$('#food-prod-prob').change(function() { $('#food-prod-prob').change(function() {
Hyperparams.foodProdProb = $('#food-prod-prob').val(); Hyperparams.foodProdProb = $('#food-prod-prob').val();
@@ -262,6 +277,9 @@ class ControlPanel {
$('#look-range').change(function() { $('#look-range').change(function() {
Hyperparams.lookRange = $('#look-range').val(); Hyperparams.lookRange = $('#look-range').val();
}); });
$('#see-through-self').change(function() {
Hyperparams.seeThroughSelf = this.checked;
});
$('#food-drop-rate').change(function() { $('#food-drop-rate').change(function() {
Hyperparams.foodDropProb = $('#food-drop-rate').val(); Hyperparams.foodDropProb = $('#food-drop-rate').val();
}); });
@@ -352,6 +370,8 @@ class ControlPanel {
$('#food-drop-rate').val(Hyperparams.foodDropProb); $('#food-drop-rate').val(Hyperparams.foodDropProb);
$('#extra-mover-cost').val(Hyperparams.extraMoverFoodCost); $('#extra-mover-cost').val(Hyperparams.extraMoverFoodCost);
$('#look-range').val(Hyperparams.lookRange); $('#look-range').val(Hyperparams.lookRange);
$('#see-through-self').prop('checked', Hyperparams.seeThroughSelf);
$('#global-mutation').val(Hyperparams.globalMutability);
if (!Hyperparams.useGlobalMutability) { if (!Hyperparams.useGlobalMutability) {
$('.global-mutation-in').css('display', 'none'); $('.global-mutation-in').css('display', 'none');
@@ -436,9 +456,7 @@ class ControlPanel {
} }
setPaused(paused) { setPaused(paused) {
if (paused) { if (paused) {
$('.pause-button').find("i").removeClass("fa-pause"); $('.pause-button').find("i").removeClass("fa-pause");
$('.pause-button').find("i").addClass("fa-play"); $('.pause-button').find("i").addClass("fa-play");
if (this.engine.running) if (this.engine.running)

View File

@@ -4,6 +4,7 @@ const CellStates = require("../Organism/Cell/CellStates");
const Directions = require("../Organism/Directions"); const Directions = require("../Organism/Directions");
const Hyperparams = require("../Hyperparameters"); const Hyperparams = require("../Hyperparameters");
const Species = require("../Stats/Species"); const Species = require("../Stats/Species");
const LoadController = require("./LoadController");
class EditorController extends CanvasController{ class EditorController extends CanvasController{
constructor(env, canvas) { constructor(env, canvas) {
@@ -119,36 +120,25 @@ class EditorController extends CanvasController{
downloadEl.click(); downloadEl.click();
}); });
$('#load-org').click(() => { $('#load-org').click(() => {
$('#upload-org').click(); LoadController.loadJson((org)=>{
}); this.loadOrg(org);
$('#upload-org').change((e)=>{ });
let files = e.target.files;
if (!files.length) {return;};
let reader = new FileReader();
reader.onload = (e) => {
try {
let org=JSON.parse(e.target.result);
this.env.clear();
this.env.organism.loadRaw(org);
this.refreshDetailsPanel();
this.env.organism.updateGrid();
this.env.renderFull();
this.env.organism.species = new Species(this.env.organism.anatomy, null, 0);
if (org.species_name)
this.env.organism.species.name = org.species_name;
if (this.mode === Modes.Clone)
$('#drop-org').click();
// have to clear the value so change() will be triggered if the same file is uploaded again
$('#upload-org')[0].value = '';
} catch(except) {
console.error(except)
alert('Failed to load organism');
}
};
reader.readAsText(files[0]);
}); });
} }
loadOrg(org) {
this.env.clear();
this.env.organism.loadRaw(org);
this.refreshDetailsPanel();
this.env.organism.updateGrid();
this.env.renderFull();
this.env.organism.species = new Species(this.env.organism.anatomy, null, 0);
if (org.species_name)
this.env.organism.species.name = org.species_name;
if (this.mode === Modes.Clone)
$('#drop-org').click();
}
clearDetailsPanel() { clearDetailsPanel() {
$('#organism-details').css('display', 'none'); $('#organism-details').css('display', 'none');
$('#edit-organism-details').css('display', 'none'); $('#edit-organism-details').css('display', 'none');

View File

@@ -0,0 +1,94 @@
const LoadController = {
init() {
$('#close-load-btn').click(()=>{
this.close();
});
$('#load-custom-btn').click(()=>{
$('#upload-json').click();
});
$('#community-creations-btn').click(()=>{
this.open();
});
$('#load-env-btn').click(async ()=>{
let file = $('#worlds-load-dropdown').val();
const base = `./assets/worlds/`;
let resp = await fetch(base+file+'.json');
let json = await resp.json();
this.control_panel.loadEnv(json);
this.close();
});
$('#load-org-btn').click(async ()=>{
let file = $('#organisms-load-dropdown').val();
const base = `./assets/organisms/`;
let resp = await fetch(base+file+'.json');
let json = await resp.json();
this.control_panel.editor_controller.loadOrg(json);
this.close();
$('#maximize').click();
$('#editor').click();
});
this.loadDropdown('worlds');
this.loadDropdown('organisms');
},
async loadDropdown(name) {
const base = `./assets/${name}/`;
let list = [];
try {
let resp = await fetch(base+'_list.json');
list = await resp.json();
} catch(e) {
console.error('Failed to load list: ', e);
}
let id = `#${name}-load-dropdown`
$(id).empty();
for (let opt of list) {
$(id).append(
`<option value="${opt.file}">
${opt.name}
</option>`
);
}
},
async open() {
$('.load-panel').css('display','block');
},
loadJson(callback) {
$('#upload-json').change((e)=>{
let files = e.target.files;
if (!files.length) {return;};
let reader = new FileReader();
reader.onload = (e) => {
try {
let json=JSON.parse(e.target.result);
callback(json);
this.close();
} catch(e) {
console.error(e)
alert('Failed to load');
}
$('#upload-json')[0].value = '';
};
reader.readAsText(files[0]);
});
$('#upload-json').click();
},
close() {
$('.load-panel').css('display','none');
$('#load-selected-btn').off('click');
$('#upload-json').off('change');
}
}
$(document).ready(() => {
LoadController.init();
});
module.exports = LoadController;

View File

@@ -22,6 +22,7 @@ const Hyperparams = {
this.instaKill = false; this.instaKill = false;
this.lookRange = 20; this.lookRange = 20;
this.seeThroughSelf = false;
this.foodDropProb = 0; this.foodDropProb = 0;

View File

@@ -69,7 +69,10 @@ class EyeCell extends BodyCell{
if (cell == null) { if (cell == null) {
break; break;
} }
if (cell.state != CellStates.empty){ if (cell.owner === this.org && Hyperparams.seeThroughSelf) {
continue;
}
if (cell.state !== CellStates.empty) {
var distance = Math.abs(start_col-col) + Math.abs(start_row-row); var distance = Math.abs(start_col-col) + Math.abs(start_row-row);
return new Observation(cell, distance, direction); return new Observation(cell, distance, direction);
} }

View File

@@ -5,8 +5,7 @@ import Engine from './Engine';
$('document').ready(function(){ $('document').ready(function(){
let isMobile = mobileCheck(); let isMobile = mobileCheck();
if (isMobile) { if (isMobile) {
alert("Though the simulation still works on mobile, most features are disabled. Try it on desktop for the full experience!"); alert("Welcome to the Life Engine! Be aware the website is not built for mobile, so try on desktop for the best experience!");
$('.control-panel').css('display', 'none');
} }
var engine = new Engine(); var engine = new Engine();
engine.start(60); engine.start(60);